/*
 * Copyright 2002 Michael Günnewig
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include <assert.h>
#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winerror.h"
#include "mmsystem.h"
#include "vfw.h"
#include "msacm.h"

#include "avifile_private.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(avifile);

/***********************************************************************/

static HRESULT WINAPI ACMStream_fnQueryInterface(IAVIStream*iface,REFIID refiid,LPVOID *obj);
static ULONG   WINAPI ACMStream_fnAddRef(IAVIStream*iface);
static ULONG   WINAPI ACMStream_fnRelease(IAVIStream* iface);
static HRESULT WINAPI ACMStream_fnCreate(IAVIStream*iface,LPARAM lParam1,LPARAM lParam2);
static HRESULT WINAPI ACMStream_fnInfo(IAVIStream*iface,AVISTREAMINFOW *psi,LONG size);
static LONG    WINAPI ACMStream_fnFindSample(IAVIStream*iface,LONG pos,LONG flags);
static HRESULT WINAPI ACMStream_fnReadFormat(IAVIStream*iface,LONG pos,LPVOID format,LONG *formatsize);
static HRESULT WINAPI ACMStream_fnSetFormat(IAVIStream*iface,LONG pos,LPVOID format,LONG formatsize);
static HRESULT WINAPI ACMStream_fnRead(IAVIStream*iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,LONG *bytesread,LONG *samplesread);
static HRESULT WINAPI ACMStream_fnWrite(IAVIStream*iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,DWORD flags,LONG *sampwritten,LONG *byteswritten);
static HRESULT WINAPI ACMStream_fnDelete(IAVIStream*iface,LONG start,LONG samples);
static HRESULT WINAPI ACMStream_fnReadData(IAVIStream*iface,DWORD fcc,LPVOID lp,LONG *lpread);
static HRESULT WINAPI ACMStream_fnWriteData(IAVIStream*iface,DWORD fcc,LPVOID lp,LONG size);
static HRESULT WINAPI ACMStream_fnSetInfo(IAVIStream*iface,AVISTREAMINFOW*info,LONG infolen);

static const struct IAVIStreamVtbl iacmst = {
  ACMStream_fnQueryInterface,
  ACMStream_fnAddRef,
  ACMStream_fnRelease,
  ACMStream_fnCreate,
  ACMStream_fnInfo,
  ACMStream_fnFindSample,
  ACMStream_fnReadFormat,
  ACMStream_fnSetFormat,
  ACMStream_fnRead,
  ACMStream_fnWrite,
  ACMStream_fnDelete,
  ACMStream_fnReadData,
  ACMStream_fnWriteData,
  ACMStream_fnSetInfo
};

typedef struct _IAVIStreamImpl {
  /* IUnknown stuff */
  const IAVIStreamVtbl *lpVtbl;
  LONG		  ref;

  /* IAVIStream stuff */
  PAVISTREAM      pStream;
  AVISTREAMINFOW  sInfo;

  HACMSTREAM      has;

  LPWAVEFORMATEX  lpInFormat;
  LONG            cbInFormat;

  LPWAVEFORMATEX  lpOutFormat;
  LONG            cbOutFormat;

  ACMSTREAMHEADER acmStreamHdr;
} IAVIStreamImpl;

/***********************************************************************/

#define CONVERT_STREAM_to_THIS(a) do { \
           DWORD __bytes; \
           acmStreamSize(This->has,*(a) * This->lpInFormat->nBlockAlign,\
                         &__bytes, ACM_STREAMSIZEF_SOURCE); \
           *(a) = __bytes / This->lpOutFormat->nBlockAlign; } while(0)

#define CONVERT_THIS_to_STREAM(a) do { \
           DWORD __bytes; \
           acmStreamSize(This->has,*(a) * This->lpOutFormat->nBlockAlign,\
                         &__bytes, ACM_STREAMSIZEF_DESTINATION); \
           *(a) = __bytes / This->lpInFormat->nBlockAlign; } while(0)

static HRESULT AVIFILE_OpenCompressor(IAVIStreamImpl *This);

HRESULT AVIFILE_CreateACMStream(REFIID riid, LPVOID *ppv)
{
  IAVIStreamImpl *pstream;
  HRESULT         hr;

  assert(riid != NULL && ppv != NULL);

  *ppv = NULL;

  pstream = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IAVIStreamImpl));
  if (pstream == NULL)
    return AVIERR_MEMORY;

  pstream->lpVtbl = &iacmst;

  hr = IAVIStream_QueryInterface((IAVIStream*)pstream, riid, ppv);
  if (FAILED(hr))
    HeapFree(GetProcessHeap(), 0, pstream);

  return hr;
}

static HRESULT WINAPI ACMStream_fnQueryInterface(IAVIStream *iface,
						  REFIID refiid, LPVOID *obj)
{
  IAVIStreamImpl *This = (IAVIStreamImpl *)iface;

  TRACE("(%p,%s,%p)\n", iface, debugstr_guid(refiid), obj);

  if (IsEqualGUID(&IID_IUnknown, refiid) ||
      IsEqualGUID(&IID_IAVIStream, refiid)) {
    *obj = This;
    IAVIStream_AddRef(iface);

    return S_OK;
  }

  return OLE_E_ENUM_NOMORE;
}

static ULONG WINAPI ACMStream_fnAddRef(IAVIStream *iface)
{
  IAVIStreamImpl *This = (IAVIStreamImpl *)iface;
  ULONG ref = InterlockedIncrement(&This->ref);

  TRACE("(%p) -> %d\n", iface, ref);

  /* also add reference to the nested stream */
  if (This->pStream != NULL)
    IAVIStream_AddRef(This->pStream);

  return ref;
}

static ULONG WINAPI ACMStream_fnRelease(IAVIStream* iface)
{
  IAVIStreamImpl *This = (IAVIStreamImpl *)iface;
  ULONG ref = InterlockedDecrement(&This->ref);

  TRACE("(%p) -> %d\n", iface, ref);

  if (ref == 0) {
    /* destruct */
    if (This->has != NULL) {
      if (This->acmStreamHdr.fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED)
	acmStreamUnprepareHeader(This->has, &This->acmStreamHdr, 0);
      acmStreamClose(This->has, 0);
      This->has = NULL;
    }
    HeapFree(GetProcessHeap(), 0, This->acmStreamHdr.pbSrc);
    This->acmStreamHdr.pbSrc = NULL;
    HeapFree(GetProcessHeap(), 0, This->acmStreamHdr.pbDst);
    This->acmStreamHdr.pbDst = NULL;
    if (This->lpInFormat != NULL) {
      HeapFree(GetProcessHeap(), 0, This->lpInFormat);
      This->lpInFormat = NULL;
      This->cbInFormat = 0;
    }
    if (This->lpOutFormat != NULL) {
      HeapFree(GetProcessHeap(), 0, This->lpOutFormat);
      This->lpOutFormat = NULL;
      This->cbOutFormat = 0;
    }
    if (This->pStream != NULL) {
      IAVIStream_Release(This->pStream);
      This->pStream = NULL;
    }
    HeapFree(GetProcessHeap(), 0, This);

    return 0;
  }

  /* also release reference to the nested stream */
  if (This->pStream != NULL)
    IAVIStream_Release(This->pStream);

  return ref;
}

/* lParam1: PAVISTREAM
 * lParam2: LPAVICOMPRESSOPTIONS -- even if doc's say LPWAVEFORMAT
 */
static HRESULT WINAPI ACMStream_fnCreate(IAVIStream *iface, LPARAM lParam1,
					  LPARAM lParam2)
{
  IAVIStreamImpl *This = (IAVIStreamImpl *)iface;

  TRACE("(%p,0x%08lX,0x%08lX)\n", iface, lParam1, lParam2);

  /* check for swapped parameters */
  if ((LPVOID)lParam1 != NULL &&
      ((LPAVICOMPRESSOPTIONS)lParam1)->fccType == streamtypeAUDIO) {
    register LPARAM tmp = lParam1;

    lParam1 = lParam2;
    lParam2 = tmp;
  }

  if ((LPVOID)lParam1 == NULL)
    return AVIERR_BADPARAM;

  IAVIStream_Info((PAVISTREAM)lParam1, &This->sInfo, sizeof(This->sInfo));
  if (This->sInfo.fccType != streamtypeAUDIO)
    return AVIERR_ERROR; /* error in registry or AVIMakeCompressedStream */

  This->sInfo.fccHandler = 0; /* be paranoid */

  /* FIXME: check ACM version? Which version does we need? */

  if ((LPVOID)lParam2 != NULL) {
    /* We only need the format from the compress-options */
    if (((LPAVICOMPRESSOPTIONS)lParam2)->fccType == streamtypeAUDIO)
      lParam2 = (LPARAM)((LPAVICOMPRESSOPTIONS)lParam2)->lpFormat;

    if (((LPWAVEFORMATEX)lParam2)->wFormatTag != WAVE_FORMAT_PCM)
      This->cbOutFormat = sizeof(WAVEFORMATEX) + ((LPWAVEFORMATEX)lParam2)->cbSize;
    else
      This->cbOutFormat = sizeof(PCMWAVEFORMAT);

    This->lpOutFormat = HeapAlloc(GetProcessHeap(), 0, This->cbOutFormat);
    if (This->lpOutFormat == NULL)
      return AVIERR_MEMORY;

    memcpy(This->lpOutFormat, (LPVOID)lParam2, This->cbOutFormat);
  } else {
    This->lpOutFormat = NULL;
    This->cbOutFormat = 0;
  }

  This->pStream = (PAVISTREAM)lParam1;
  IAVIStream_AddRef(This->pStream);

  return AVIERR_OK;
}

static HRESULT WINAPI ACMStream_fnInfo(IAVIStream *iface,LPAVISTREAMINFOW psi,
					LONG size)
{
  IAVIStreamImpl *This = (IAVIStreamImpl *)iface;

  TRACE("(%p,%p,%d)\n", iface, psi, size);

  if (psi == NULL)
    return AVIERR_BADPARAM;
  if (size < 0)
    return AVIERR_BADSIZE;

  /* Need codec to correct some values in structure */
  if (This->has == NULL) {
    HRESULT hr = AVIFILE_OpenCompressor(This);

    if (FAILED(hr))
      return hr;
  }

  memcpy(psi, &This->sInfo, min(size, (LONG)sizeof(This->sInfo)));

  if (size < (LONG)sizeof(This->sInfo))
    return AVIERR_BUFFERTOOSMALL;
  return AVIERR_OK;
}

static LONG WINAPI ACMStream_fnFindSample(IAVIStream *iface, LONG pos,
					   LONG flags)
{
  IAVIStreamImpl *This = (IAVIStreamImpl *)iface;

  TRACE("(%p,%d,0x%08X)\n",iface,pos,flags);

  if (flags & FIND_FROM_START) {
    pos = This->sInfo.dwStart;
    flags &= ~(FIND_FROM_START|FIND_PREV);
    flags |= FIND_NEXT;
  }

  /* convert pos from our 'space' to This->pStream's one */
  CONVERT_THIS_to_STREAM(&pos);

  /* ask stream */
  pos = IAVIStream_FindSample(This->pStream, pos, flags);

  if (pos != -1) {
    /* convert pos back to our 'space' if it's no size or physical pos */
    if ((flags & FIND_RET) == 0)
      CONVERT_STREAM_to_THIS(&pos);
  }

  return pos;
}

static HRESULT WINAPI ACMStream_fnReadFormat(IAVIStream *iface, LONG pos,
					      LPVOID format, LONG *formatsize)
{
  IAVIStreamImpl *This = (IAVIStreamImpl *)iface;

  TRACE("(%p,%d,%p,%p)\n", iface, pos, format, formatsize);

  if (formatsize == NULL)
    return AVIERR_BADPARAM;

  if (This->has == NULL) {
    HRESULT hr = AVIFILE_OpenCompressor(This);

    if (FAILED(hr))
      return hr;
  }

  /* only interested in needed buffersize? */
  if (format == NULL || *formatsize <= 0) {
    *formatsize = This->cbOutFormat;

    return AVIERR_OK;
  }

  /* copy initial format (only as much as will fit) */
  memcpy(format, This->lpOutFormat, min(*formatsize, This->cbOutFormat));
  if (*formatsize < This->cbOutFormat) {
    *formatsize = This->cbOutFormat;
    return AVIERR_BUFFERTOOSMALL;
  }

  *formatsize = This->cbOutFormat;
  return AVIERR_OK;
}

static HRESULT WINAPI ACMStream_fnSetFormat(IAVIStream *iface, LONG pos,
					     LPVOID format, LONG formatsize)
{
  IAVIStreamImpl *This = (IAVIStreamImpl *)iface;

  HRESULT hr;

  TRACE("(%p,%d,%p,%d)\n", iface, pos, format, formatsize);

  /* check parameters */
  if (format == NULL || formatsize <= 0)
    return AVIERR_BADPARAM;

  /* Input format already known?
   * Changing is unsupported, but be quiet if it's the same */
  if (This->lpInFormat != NULL) {
    if (This->cbInFormat != formatsize ||
	memcmp(format, This->lpInFormat, formatsize) != 0)
      return AVIERR_UNSUPPORTED;

    return AVIERR_OK;
  }

  /* Does the nested stream support writing? */
  if ((This->sInfo.dwCaps & AVIFILECAPS_CANWRITE) == 0)
    return AVIERR_READONLY;

  This->lpInFormat = HeapAlloc(GetProcessHeap(), 0, formatsize);
  if (This->lpInFormat == NULL)
    return AVIERR_MEMORY;
  This->cbInFormat = formatsize;
  memcpy(This->lpInFormat, format, formatsize);

  /* initialize formats and get compressor */
  hr = AVIFILE_OpenCompressor(This);
  if (FAILED(hr))
    return hr;

  CONVERT_THIS_to_STREAM(&pos);

  /* tell the nested stream the new format */
  return IAVIStream_SetFormat(This->pStream, pos, This->lpOutFormat,
			      This->cbOutFormat);
}

static HRESULT WINAPI ACMStream_fnRead(IAVIStream *iface, LONG start,
					LONG samples, LPVOID buffer,
					LONG buffersize, LPLONG bytesread,
					LPLONG samplesread)
{
  IAVIStreamImpl *This = (IAVIStreamImpl *)iface;

  HRESULT hr;
  DWORD   size;

  TRACE("(%p,%d,%d,%p,%d,%p,%p)\n", iface, start, samples, buffer,
 	buffersize, bytesread, samplesread);

  /* clear return parameters if given */
  if (bytesread != NULL)
    *bytesread = 0;
  if (samplesread != NULL)
    *samplesread = 0;

  /* Do we have our compressor? */
  if (This->has == NULL) {
    hr = AVIFILE_OpenCompressor(This);

    if (FAILED(hr))
      return hr;
  }

  /* only need to pass through? */
  if (This->cbInFormat == This->cbOutFormat &&
      memcmp(This->lpInFormat, This->lpOutFormat, This->cbInFormat) == 0) {
    return IAVIStream_Read(This->pStream, start, samples, buffer, buffersize,
			   bytesread, samplesread);
  }

  /* read as much as fit? */
  if (samples == -1)
    samples = buffersize / This->lpOutFormat->nBlockAlign;
  /* limit to buffersize */
  if (samples * This->lpOutFormat->nBlockAlign > buffersize)
    samples = buffersize / This->lpOutFormat->nBlockAlign;

  /* only return needed size? */
  if (buffer == NULL || buffersize <= 0 || samples == 0) {
    if (bytesread == NULL && samplesread == NULL)
      return AVIERR_BADPARAM;

    if (bytesread != NULL)
      *bytesread = samples * This->lpOutFormat->nBlockAlign;
    if (samplesread != NULL)
      *samplesread = samples;

    return AVIERR_OK;
  }

  /* map our positions to pStream positions */
  CONVERT_THIS_to_STREAM(&start);

  /* our needed internal buffersize */
  size = samples * This->lpInFormat->nBlockAlign;

  /* Need to free destination buffer used for writing? */
  if (This->acmStreamHdr.pbDst != NULL) {
    HeapFree(GetProcessHeap(), 0, This->acmStreamHdr.pbDst);
    This->acmStreamHdr.pbDst     = NULL;
    This->acmStreamHdr.dwDstUser = 0;
  }

  /* need bigger source buffer? */
  if (This->acmStreamHdr.pbSrc == NULL ||
      This->acmStreamHdr.dwSrcUser < size) {
    if (This->acmStreamHdr.pbSrc == NULL)
      This->acmStreamHdr.pbSrc = HeapAlloc(GetProcessHeap(), 0, size);
    else
      This->acmStreamHdr.pbSrc = HeapReAlloc(GetProcessHeap(), 0, This->acmStreamHdr.pbSrc, size);
    if (This->acmStreamHdr.pbSrc == NULL)
      return AVIERR_MEMORY;
    This->acmStreamHdr.dwSrcUser = size;
  }

  This->acmStreamHdr.cbStruct = sizeof(This->acmStreamHdr);
  This->acmStreamHdr.cbSrcLengthUsed = 0;
  This->acmStreamHdr.cbDstLengthUsed = 0;
  This->acmStreamHdr.cbSrcLength     = size;

  /* read source data */
  hr = IAVIStream_Read(This->pStream, start, -1, This->acmStreamHdr.pbSrc,
		       This->acmStreamHdr.cbSrcLength,
		       (LONG *)&This->acmStreamHdr.cbSrcLength, NULL);
  if (FAILED(hr) || This->acmStreamHdr.cbSrcLength == 0)
    return hr;

  /* need to prepare stream? */
  This->acmStreamHdr.pbDst       = buffer;
  This->acmStreamHdr.cbDstLength = buffersize;
  if ((This->acmStreamHdr.fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED) == 0) {
    if (acmStreamPrepareHeader(This->has, &This->acmStreamHdr, 0) != S_OK) {
      This->acmStreamHdr.pbDst       = NULL;
      This->acmStreamHdr.cbDstLength = 0;
      return AVIERR_COMPRESSOR;
    }
  }

  /* now do the conversion */
  /* FIXME: use ACM_CONVERTF_* flags */
  if (acmStreamConvert(This->has, &This->acmStreamHdr, 0) != S_OK)
    hr = AVIERR_COMPRESSOR;

  This->acmStreamHdr.pbDst       = NULL;
  This->acmStreamHdr.cbDstLength = 0;

  /* fill out return parameters if given */
  if (bytesread != NULL)
    *bytesread = This->acmStreamHdr.cbDstLengthUsed;
  if (samplesread != NULL)
    *samplesread =
      This->acmStreamHdr.cbDstLengthUsed / This->lpOutFormat->nBlockAlign;

  return hr;
}

static HRESULT WINAPI ACMStream_fnWrite(IAVIStream *iface, LONG start,
					 LONG samples, LPVOID buffer,
					 LONG buffersize, DWORD flags,
					 LPLONG sampwritten,
					 LPLONG byteswritten)
{
  IAVIStreamImpl *This = (IAVIStreamImpl *)iface;

  HRESULT hr;
  ULONG   size;

  TRACE("(%p,%d,%d,%p,%d,0x%08X,%p,%p)\n", iface, start, samples,
	buffer, buffersize, flags, sampwritten, byteswritten);

  /* clear return parameters if given */
  if (sampwritten != NULL)
    *sampwritten = 0;
  if (byteswritten != NULL)
    *byteswritten = 0;

  /* check parameters */
  if (buffer == NULL && (buffersize > 0 || samples > 0))
    return AVIERR_BADPARAM;

  /* Have we write capability? */
  if ((This->sInfo.dwCaps & AVIFILECAPS_CANWRITE) == 0)
    return AVIERR_READONLY;

  /* also need a compressor */
  if (This->has == NULL)
    return AVIERR_NOCOMPRESSOR;

  /* map our sizes to pStream sizes */
  size = buffersize;
  CONVERT_THIS_to_STREAM(&size);
  CONVERT_THIS_to_STREAM(&start);

  /* no bytes to write? -- short circuit */
  if (size == 0) {
    return IAVIStream_Write(This->pStream, -1, samples, buffer, size,
			    flags, sampwritten, byteswritten);
  }

  /* Need to free source buffer used for reading? */
  if (This->acmStreamHdr.pbSrc != NULL) {
    HeapFree(GetProcessHeap(), 0, This->acmStreamHdr.pbSrc);
    This->acmStreamHdr.pbSrc     = NULL;
    This->acmStreamHdr.dwSrcUser = 0;
  }

  /* Need bigger destination buffer? */
  if (This->acmStreamHdr.pbDst == NULL ||
      This->acmStreamHdr.dwDstUser < size) {
    if (This->acmStreamHdr.pbDst == NULL)
      This->acmStreamHdr.pbDst = HeapAlloc(GetProcessHeap(), 0, size);
    else
      This->acmStreamHdr.pbDst = HeapReAlloc(GetProcessHeap(), 0, This->acmStreamHdr.pbDst, size);
    if (This->acmStreamHdr.pbDst == NULL)
      return AVIERR_MEMORY;
    This->acmStreamHdr.dwDstUser = size;
  }
  This->acmStreamHdr.cbStruct        = sizeof(This->acmStreamHdr);
  This->acmStreamHdr.cbSrcLengthUsed = 0;
  This->acmStreamHdr.cbDstLengthUsed = 0;
  This->acmStreamHdr.cbDstLength     = This->acmStreamHdr.dwDstUser;

  /* need to prepare stream? */
  This->acmStreamHdr.pbSrc       = buffer;
  This->acmStreamHdr.cbSrcLength = buffersize;
  if ((This->acmStreamHdr.fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED) == 0) {
    if (acmStreamPrepareHeader(This->has, &This->acmStreamHdr, 0) != S_OK) {
      This->acmStreamHdr.pbSrc       = NULL;
      This->acmStreamHdr.cbSrcLength = 0;
      return AVIERR_COMPRESSOR;
    }
  }

  /* now do the conversion */
  /* FIXME: use ACM_CONVERTF_* flags */
  if (acmStreamConvert(This->has, &This->acmStreamHdr, 0) != S_OK)
    hr = AVIERR_COMPRESSOR;
  else
    hr = AVIERR_OK;

  This->acmStreamHdr.pbSrc       = NULL;
  This->acmStreamHdr.cbSrcLength = 0;

  if (FAILED(hr))
    return hr;

  return IAVIStream_Write(This->pStream,-1,This->acmStreamHdr.cbDstLengthUsed /
			  This->lpOutFormat->nBlockAlign,This->acmStreamHdr.pbDst,
			  This->acmStreamHdr.cbDstLengthUsed,flags,sampwritten,
			  byteswritten);
}

static HRESULT WINAPI ACMStream_fnDelete(IAVIStream *iface, LONG start,
					  LONG samples)
{
  IAVIStreamImpl *This = (IAVIStreamImpl *)iface;

  TRACE("(%p,%d,%d)\n", iface, start, samples);

  /* check parameters */
  if (start < 0 || samples < 0)
    return AVIERR_BADPARAM;

  /* Delete before start of stream? */
  if ((DWORD)(start + samples) < This->sInfo.dwStart)
    return AVIERR_OK;

  /* Delete after end of stream? */
  if ((DWORD)start > This->sInfo.dwLength)
    return AVIERR_OK;

  /* For the rest we need write capability */
  if ((This->sInfo.dwCaps & AVIFILECAPS_CANWRITE) == 0)
    return AVIERR_READONLY;

  /* A compressor is also necessary */
  if (This->has == NULL)
    return AVIERR_NOCOMPRESSOR;

  /* map our positions to pStream positions */
  CONVERT_THIS_to_STREAM(&start);
  CONVERT_THIS_to_STREAM(&samples);

  return IAVIStream_Delete(This->pStream, start, samples);
}

static HRESULT WINAPI ACMStream_fnReadData(IAVIStream *iface, DWORD fcc,
					    LPVOID lp, LPLONG lpread)
{
  IAVIStreamImpl *This = (IAVIStreamImpl *)iface;

  TRACE("(%p,0x%08X,%p,%p)\n", iface, fcc, lp, lpread);

  assert(This->pStream != NULL);

  return IAVIStream_ReadData(This->pStream, fcc, lp, lpread);
}

static HRESULT WINAPI ACMStream_fnWriteData(IAVIStream *iface, DWORD fcc,
					     LPVOID lp, LONG size)
{
  IAVIStreamImpl *This = (IAVIStreamImpl *)iface;

  TRACE("(%p,0x%08x,%p,%d)\n", iface, fcc, lp, size);

  assert(This->pStream != NULL);

  return IAVIStream_WriteData(This->pStream, fcc, lp, size);
}

static HRESULT WINAPI ACMStream_fnSetInfo(IAVIStream *iface,
					   LPAVISTREAMINFOW info, LONG infolen)
{
  FIXME("(%p,%p,%d): stub\n", iface, info, infolen);

  return E_FAIL;
}

/***********************************************************************/

static HRESULT AVIFILE_OpenCompressor(IAVIStreamImpl *This)
{
  HRESULT hr;

  /* pre-conditions */
  assert(This != NULL);
  assert(This->pStream != NULL);

  if (This->has != NULL)
    return AVIERR_OK;

  if (This->lpInFormat == NULL) {
    /* decode or encode the data from pStream */
    hr = AVIStreamFormatSize(This->pStream, This->sInfo.dwStart, &This->cbInFormat);
    if (FAILED(hr))
      return hr;
    This->lpInFormat = HeapAlloc(GetProcessHeap(), 0, This->cbInFormat);
    if (This->lpInFormat == NULL)
      return AVIERR_MEMORY;

    hr = IAVIStream_ReadFormat(This->pStream, This->sInfo.dwStart,
			       This->lpInFormat, &This->cbInFormat);
    if (FAILED(hr))
      return hr;

    if (This->lpOutFormat == NULL) {
      /* we must decode to default format */
      This->cbOutFormat = sizeof(PCMWAVEFORMAT);
      This->lpOutFormat = HeapAlloc(GetProcessHeap(), 0, This->cbOutFormat);
      if (This->lpOutFormat == NULL)
	return AVIERR_MEMORY;

      This->lpOutFormat->wFormatTag = WAVE_FORMAT_PCM;
      if (acmFormatSuggest(NULL, This->lpInFormat, This->lpOutFormat,
			   This->cbOutFormat, ACM_FORMATSUGGESTF_WFORMATTAG) != S_OK)
	return AVIERR_NOCOMPRESSOR;
    }
  } else if (This->lpOutFormat == NULL)
    return AVIERR_ERROR; /* To what should I encode? */

  if (acmStreamOpen(&This->has, NULL, This->lpInFormat, This->lpOutFormat,
		    NULL, 0, 0, ACM_STREAMOPENF_NONREALTIME) != S_OK)
    return AVIERR_NOCOMPRESSOR;

  /* update AVISTREAMINFO structure */
  This->sInfo.dwSampleSize = This->lpOutFormat->nBlockAlign;
  This->sInfo.dwScale      = This->lpOutFormat->nBlockAlign;
  This->sInfo.dwRate       = This->lpOutFormat->nAvgBytesPerSec;
  This->sInfo.dwQuality    = (DWORD)ICQUALITY_DEFAULT;
  SetRectEmpty(&This->sInfo.rcFrame);

  /* convert positions and sizes to output format */
  CONVERT_STREAM_to_THIS(&This->sInfo.dwStart);
  CONVERT_STREAM_to_THIS(&This->sInfo.dwLength);
  CONVERT_STREAM_to_THIS(&This->sInfo.dwSuggestedBufferSize);

  return AVIERR_OK;
}
