/*
 * 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
 */

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

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

#include "avifile_private.h"
#include "extrachunk.h"

#include "wine/unicode.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(avifile);

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

#define formtypeWAVE    mmioFOURCC('W','A','V','E')
#define ckidWAVEFORMAT  mmioFOURCC('f','m','t',' ')
#define ckidWAVEFACT    mmioFOURCC('f','a','c','t')
#define ckidWAVEDATA    mmioFOURCC('d','a','t','a')

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

#define ENDIAN_SWAPWORD(x)  ((((x) >> 8) & 0xFF) | (((x) & 0xFF) << 8))
#define ENDIAN_SWAPDWORD(x) (ENDIAN_SWAPWORD((x >> 16) & 0xFFFF) | \
                             ENDIAN_SWAPWORD(x & 0xFFFF) << 16)

#ifdef WORDS_BIGENDIAN
#define BE2H_WORD(x)  (x)
#define BE2H_DWORD(x) (x)
#define LE2H_WORD(x)  ENDIAN_SWAPWORD(x)
#define LE2H_DWORD(x) ENDIAN_SWAPDWORD(x)
#else
#define BE2H_WORD(x)  ENDIAN_SWAPWORD(x)
#define BE2H_DWORD(x) ENDIAN_SWAPDWORD(x)
#define LE2H_WORD(x)  (x)
#define LE2H_DWORD(x) (x)
#endif

typedef struct {
  FOURCC  fccType;
  DWORD   offset;
  DWORD   size;
  INT     encoding;
  DWORD   sampleRate;
  DWORD   channels;
} SUNAUDIOHEADER;

#define AU_ENCODING_ULAW_8                 1
#define AU_ENCODING_PCM_8                  2
#define AU_ENCODING_PCM_16                 3
#define AU_ENCODING_PCM_24                 4
#define AU_ENCODING_PCM_32                 5
#define AU_ENCODING_FLOAT                  6
#define AU_ENCODING_DOUBLE                 7
#define AU_ENCODING_ADPCM_G721_32         23
#define AU_ENCODING_ADPCM_G722            24
#define AU_ENCODING_ADPCM_G723_24         25
#define AU_ENCODING_ADPCM_G723_5          26
#define AU_ENCODING_ALAW_8                27

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

typedef struct _IAVIFileImpl {
  IUnknown          IUnknown_inner;
  IAVIFile          IAVIFile_iface;
  IPersistFile      IPersistFile_iface;
  IAVIStream        IAVIStream_iface;
  IUnknown          *outer_unk;
  LONG              ref;
  /* IAVIFile, IAVIStream stuff... */
  AVIFILEINFOW      fInfo;
  AVISTREAMINFOW    sInfo;

  LPWAVEFORMATEX    lpFormat;
  LONG              cbFormat;

  MMCKINFO          ckData;

  EXTRACHUNKS       extra;

  /* IPersistFile stuff ... */
  HMMIO             hmmio;
  LPWSTR            szFileName;
  UINT              uMode;
  BOOL              fDirty;
} IAVIFileImpl;

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

static HRESULT AVIFILE_LoadFile(IAVIFileImpl *This);
static HRESULT AVIFILE_LoadSunFile(IAVIFileImpl *This);
static HRESULT AVIFILE_SaveFile(const IAVIFileImpl *This);

static inline IAVIFileImpl *impl_from_IUnknown(IUnknown *iface)
{
    return CONTAINING_RECORD(iface, IAVIFileImpl, IUnknown_inner);
}

static HRESULT WINAPI IUnknown_fnQueryInterface(IUnknown *iface, REFIID riid, void **ret_iface)
{
    IAVIFileImpl *This = impl_from_IUnknown(iface);

    TRACE("(%p,%s,%p)\n", This, debugstr_guid(riid), ret_iface);

    if (IsEqualGUID(&IID_IUnknown, riid))
        *ret_iface = &This->IUnknown_inner;
    else if (IsEqualGUID(&IID_IAVIFile, riid))
        *ret_iface = &This->IAVIFile_iface;
    else if (IsEqualGUID(&IID_IAVIStream, riid))
        *ret_iface = &This->IAVIStream_iface;
    else if (IsEqualGUID(&IID_IPersistFile, riid))
        *ret_iface = &This->IPersistFile_iface;
    else {
        WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ret_iface);
        *ret_iface = NULL;
        return E_NOINTERFACE;
    }

    /* Violation of the COM aggregation ref counting rule */
    IUnknown_AddRef(&This->IUnknown_inner);
    return S_OK;
}

static ULONG WINAPI IUnknown_fnAddRef(IUnknown *iface)
{
    IAVIFileImpl *This = impl_from_IUnknown(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p) ref=%d\n", This, ref);

    return ref;
}

static ULONG WINAPI IUnknown_fnRelease(IUnknown *iface)
{
    IAVIFileImpl *This = impl_from_IUnknown(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) ref=%d\n", This, ref);

    if (!ref) {
        /* need to write headers to file */
        if (This->fDirty)
            AVIFILE_SaveFile(This);

        HeapFree(GetProcessHeap(), 0, This->lpFormat);
        This->lpFormat = NULL;
        This->cbFormat = 0;
        HeapFree(GetProcessHeap(), 0, This->extra.lp);
        This->extra.lp = NULL;
        This->extra.cb = 0;
        HeapFree(GetProcessHeap(), 0, This->szFileName);
        This->szFileName = NULL;
        if (This->hmmio) {
            mmioClose(This->hmmio, 0);
            This->hmmio = NULL;
        }
        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}

static const IUnknownVtbl unk_vtbl =
{
    IUnknown_fnQueryInterface,
    IUnknown_fnAddRef,
    IUnknown_fnRelease
};

static inline IAVIFileImpl *impl_from_IAVIFile(IAVIFile *iface)
{
    return CONTAINING_RECORD(iface, IAVIFileImpl, IAVIFile_iface);
}

static HRESULT WINAPI IAVIFile_fnQueryInterface(IAVIFile *iface, REFIID riid, void **ret_iface)
{
    IAVIFileImpl *This = impl_from_IAVIFile(iface);

    return IUnknown_QueryInterface(This->outer_unk, riid, ret_iface);
}

static ULONG WINAPI IAVIFile_fnAddRef(IAVIFile *iface)
{
    IAVIFileImpl *This = impl_from_IAVIFile(iface);

    return IUnknown_AddRef(This->outer_unk);
}

static ULONG WINAPI IAVIFile_fnRelease(IAVIFile *iface)
{
    IAVIFileImpl *This = impl_from_IAVIFile(iface);

    return IUnknown_Release(This->outer_unk);
}

static HRESULT WINAPI IAVIFile_fnInfo(IAVIFile *iface, AVIFILEINFOW *afi, LONG size)
{
  IAVIFileImpl *This = impl_from_IAVIFile(iface);

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

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

  /* update file info */
  This->fInfo.dwFlags = 0;
  This->fInfo.dwCaps  = AVIFILECAPS_CANREAD|AVIFILECAPS_CANWRITE;
  if (This->lpFormat != NULL) {
    assert(This->sInfo.dwScale != 0);

    This->fInfo.dwStreams             = 1;
    This->fInfo.dwScale               = This->sInfo.dwScale;
    This->fInfo.dwRate                = This->sInfo.dwRate;
    This->fInfo.dwLength              = This->sInfo.dwLength;
    This->fInfo.dwSuggestedBufferSize = This->ckData.cksize;
    This->fInfo.dwMaxBytesPerSec =
      MulDiv(This->sInfo.dwSampleSize,This->sInfo.dwRate,This->sInfo.dwScale);
  }

  memcpy(afi, &This->fInfo, min((DWORD)size, sizeof(This->fInfo)));

  if ((DWORD)size < sizeof(This->fInfo))
    return AVIERR_BUFFERTOOSMALL;
  return AVIERR_OK;
}

static HRESULT WINAPI IAVIFile_fnGetStream(IAVIFile *iface, IAVIStream **avis, DWORD fccType,
        LONG lParam)
{
  IAVIFileImpl *This = impl_from_IAVIFile(iface);

  TRACE("(%p,%p,0x%08X,%d)\n", iface, avis, fccType, lParam);

  /* check parameter */
  if (avis == NULL)
    return AVIERR_BADPARAM;

  *avis = NULL;

  /* Does our stream exists? */
  if (lParam != 0 || This->fInfo.dwStreams == 0)
    return AVIERR_NODATA;
  if (fccType != 0 && fccType != streamtypeAUDIO)
    return AVIERR_NODATA;

  *avis = &This->IAVIStream_iface;
  IAVIStream_AddRef(*avis);

  return AVIERR_OK;
}

static HRESULT WINAPI IAVIFile_fnCreateStream(IAVIFile *iface, IAVIStream **avis,
        AVISTREAMINFOW *asi)
{
  IAVIFileImpl *This = impl_from_IAVIFile(iface);

  TRACE("(%p,%p,%p)\n", iface, avis, asi);

  /* check parameters */
  if (avis == NULL || asi == NULL)
    return AVIERR_BADPARAM;

  *avis = NULL;

  /* We only support one audio stream */
  if (This->fInfo.dwStreams != 0 || This->lpFormat != NULL)
    return AVIERR_UNSUPPORTED;
  if (asi->fccType != streamtypeAUDIO)
    return AVIERR_UNSUPPORTED;

  /* Does the user have write permission? */
  if ((This->uMode & MMIO_RWMODE) == 0)
    return AVIERR_READONLY;

  This->cbFormat = 0;
  This->lpFormat = NULL;

  memcpy(&This->sInfo, asi, sizeof(This->sInfo));

  /* make sure streaminfo if okay for us */
  This->sInfo.fccHandler          = 0;
  This->sInfo.dwFlags             = 0;
  This->sInfo.dwCaps              = AVIFILECAPS_CANREAD|AVIFILECAPS_CANWRITE;
  This->sInfo.dwStart             = 0;
  This->sInfo.dwInitialFrames     = 0;
  This->sInfo.dwFormatChangeCount = 0;
  SetRectEmpty(&This->sInfo.rcFrame);

  This->fInfo.dwStreams = 1;
  This->fInfo.dwScale   = This->sInfo.dwScale;
  This->fInfo.dwRate    = This->sInfo.dwRate;
  This->fInfo.dwLength  = This->sInfo.dwLength;

  This->ckData.dwDataOffset = 0;
  This->ckData.cksize       = 0;

  *avis = &This->IAVIStream_iface;
  IAVIStream_AddRef(*avis);

  return AVIERR_OK;
}

static HRESULT WINAPI IAVIFile_fnWriteData(IAVIFile *iface, DWORD ckid, void *lpData, LONG size)
{
  IAVIFileImpl *This = impl_from_IAVIFile(iface);

  TRACE("(%p,0x%08X,%p,%d)\n", iface, ckid, lpData, size);

  /* check parameters */
  if (lpData == NULL)
    return AVIERR_BADPARAM;
  if (size < 0)
    return AVIERR_BADSIZE;

  /* Do we have write permission? */
  if ((This->uMode & MMIO_RWMODE) == 0)
    return AVIERR_READONLY;

  This->fDirty = TRUE;

  return WriteExtraChunk(&This->extra, ckid, lpData, size);
}

static HRESULT WINAPI IAVIFile_fnReadData(IAVIFile *iface, DWORD ckid, void *lpData, LONG *size)
{
  IAVIFileImpl *This = impl_from_IAVIFile(iface);

  TRACE("(%p,0x%08X,%p,%p)\n", iface, ckid, lpData, size);

  return ReadExtraChunk(&This->extra, ckid, lpData, size);
}

static HRESULT WINAPI IAVIFile_fnEndRecord(IAVIFile *iface)
{
  TRACE("(%p)\n",iface);

  /* This is only needed for interleaved files.
   * We have only one stream, which can't be interleaved.
   */
  return AVIERR_OK;
}

static HRESULT WINAPI IAVIFile_fnDeleteStream(IAVIFile *iface, DWORD fccType, LONG lParam)
{
  IAVIFileImpl *This = impl_from_IAVIFile(iface);

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

  /* check parameter */
  if (lParam < 0)
    return AVIERR_BADPARAM;

  /* Do we have our audio stream? */
  if (lParam != 0 || This->fInfo.dwStreams == 0 ||
      (fccType != 0 && fccType != streamtypeAUDIO))
    return AVIERR_NODATA;

  /* Have user write permissions? */
  if ((This->uMode & MMIO_RWMODE) == 0)
    return AVIERR_READONLY;

  HeapFree(GetProcessHeap(), 0, This->lpFormat);
  This->lpFormat = NULL;
  This->cbFormat = 0;

  /* update infos */
  This->ckData.dwDataOffset = 0;
  This->ckData.cksize       = 0;

  This->sInfo.dwScale   = 0;
  This->sInfo.dwRate    = 0;
  This->sInfo.dwLength  = 0;
  This->sInfo.dwSuggestedBufferSize = 0;

  This->fInfo.dwStreams = 0;
  This->fInfo.dwEditCount++;

  This->fDirty = TRUE;

  return AVIERR_OK;
}

static const struct IAVIFileVtbl iwavft = {
    IAVIFile_fnQueryInterface,
    IAVIFile_fnAddRef,
    IAVIFile_fnRelease,
    IAVIFile_fnInfo,
    IAVIFile_fnGetStream,
    IAVIFile_fnCreateStream,
    IAVIFile_fnWriteData,
    IAVIFile_fnReadData,
    IAVIFile_fnEndRecord,
    IAVIFile_fnDeleteStream
};

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

static inline IAVIFileImpl *impl_from_IPersistFile(IPersistFile *iface)
{
    return CONTAINING_RECORD(iface, IAVIFileImpl, IPersistFile_iface);
}

static HRESULT WINAPI IPersistFile_fnQueryInterface(IPersistFile *iface, REFIID riid,
        void **ret_iface)
{
    IAVIFileImpl *This = impl_from_IPersistFile(iface);

    return IUnknown_QueryInterface(This->outer_unk, riid, ret_iface);
}

static ULONG   WINAPI IPersistFile_fnAddRef(IPersistFile *iface)
{
    IAVIFileImpl *This = impl_from_IPersistFile(iface);

    return IUnknown_AddRef(This->outer_unk);
}

static ULONG   WINAPI IPersistFile_fnRelease(IPersistFile *iface)
{
    IAVIFileImpl *This = impl_from_IPersistFile(iface);

    return IUnknown_Release(This->outer_unk);
}

static HRESULT WINAPI IPersistFile_fnGetClassID(IPersistFile *iface,
						LPCLSID pClassID)
{
  TRACE("(%p,%p)\n", iface, pClassID);

  if (pClassID == NULL)
    return AVIERR_BADPARAM;

  *pClassID = CLSID_WAVFile;

  return AVIERR_OK;
}

static HRESULT WINAPI IPersistFile_fnIsDirty(IPersistFile *iface)
{
    IAVIFileImpl *This = impl_from_IPersistFile(iface);

    TRACE("(%p)\n", iface);

    return (This->fDirty ? S_OK : S_FALSE);
}

static HRESULT WINAPI IPersistFile_fnLoad(IPersistFile *iface, LPCOLESTR pszFileName, DWORD dwMode)
{
  IAVIFileImpl *This = impl_from_IPersistFile(iface);
  WCHAR wszStreamFmt[50];
  INT   len;

  TRACE("(%p,%s,0x%08X)\n", iface, debugstr_w(pszFileName), dwMode);

  /* check parameter */
  if (pszFileName == NULL)
    return AVIERR_BADPARAM;

  if (This->hmmio != NULL)
    return AVIERR_ERROR; /* No reuse of this object for another file! */

  /* remember mode and name */
  This->uMode = dwMode;

  len = lstrlenW(pszFileName) + 1;
  This->szFileName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
  if (This->szFileName == NULL)
    return AVIERR_MEMORY;
  lstrcpyW(This->szFileName, pszFileName);

  /* try to open the file */
  This->hmmio = mmioOpenW(This->szFileName, NULL, MMIO_ALLOCBUF | dwMode);
  if (This->hmmio == NULL) {
    /* mmioOpenW not in native DLLs of Win9x -- try mmioOpenA */
    LPSTR szFileName;
    len = WideCharToMultiByte(CP_ACP, 0, This->szFileName, -1,
                              NULL, 0, NULL, NULL);
    szFileName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(CHAR));
    if (szFileName == NULL)
      return AVIERR_MEMORY;

    WideCharToMultiByte(CP_ACP, 0, This->szFileName, -1, szFileName,
			len, NULL, NULL);

    This->hmmio = mmioOpenA(szFileName, NULL, MMIO_ALLOCBUF | dwMode);
    HeapFree(GetProcessHeap(), 0, szFileName);
    if (This->hmmio == NULL)
      return AVIERR_FILEOPEN;
  }

  memset(& This->fInfo, 0, sizeof(This->fInfo));
  memset(& This->sInfo, 0, sizeof(This->sInfo));

  LoadStringW(AVIFILE_hModule, IDS_WAVEFILETYPE, This->fInfo.szFileType,
	      sizeof(This->fInfo.szFileType)/sizeof(This->fInfo.szFileType[0]));
  if (LoadStringW(AVIFILE_hModule, IDS_WAVESTREAMFORMAT,
		  wszStreamFmt, sizeof(wszStreamFmt)/sizeof(wszStreamFmt[0])) > 0) {
    wsprintfW(This->sInfo.szName, wszStreamFmt,
	      AVIFILE_BasenameW(This->szFileName));
  }

  /* should we create a new file? */
  if (dwMode & OF_CREATE) {
    /* nothing more to do */
    return AVIERR_OK;
  } else
    return AVIFILE_LoadFile(This);
}

static HRESULT WINAPI IPersistFile_fnSave(IPersistFile *iface,
					  LPCOLESTR pszFileName,BOOL fRemember)
{
  TRACE("(%p,%s,%d)\n", iface, debugstr_w(pszFileName), fRemember);

  /* We write directly to disk, so nothing to do. */

  return AVIERR_OK;
}

static HRESULT WINAPI IPersistFile_fnSaveCompleted(IPersistFile *iface,
						   LPCOLESTR pszFileName)
{
  TRACE("(%p,%s)\n", iface, debugstr_w(pszFileName));

  /* We write directly to disk, so nothing to do. */

  return AVIERR_OK;
}

static HRESULT WINAPI IPersistFile_fnGetCurFile(IPersistFile *iface, LPOLESTR *ppszFileName)
{
  IAVIFileImpl *This = impl_from_IPersistFile(iface);

  TRACE("(%p,%p)\n", iface, ppszFileName);

  if (ppszFileName == NULL)
    return AVIERR_BADPARAM;

  *ppszFileName = NULL;

  if (This->szFileName) {
    int len = lstrlenW(This->szFileName) + 1;

    *ppszFileName = CoTaskMemAlloc(len * sizeof(WCHAR));
    if (*ppszFileName == NULL)
      return AVIERR_MEMORY;

    strcpyW(*ppszFileName, This->szFileName);
  }

  return AVIERR_OK;
}

static const struct IPersistFileVtbl iwavpft = {
    IPersistFile_fnQueryInterface,
    IPersistFile_fnAddRef,
    IPersistFile_fnRelease,
    IPersistFile_fnGetClassID,
    IPersistFile_fnIsDirty,
    IPersistFile_fnLoad,
    IPersistFile_fnSave,
    IPersistFile_fnSaveCompleted,
    IPersistFile_fnGetCurFile
};

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

static inline IAVIFileImpl *impl_from_IAVIStream(IAVIStream *iface)
{
    return CONTAINING_RECORD(iface, IAVIFileImpl, IAVIStream_iface);
}

static HRESULT WINAPI IAVIStream_fnQueryInterface(IAVIStream *iface, REFIID riid, void **ret_iface)
{
    IAVIFileImpl *This = impl_from_IAVIStream(iface);

    return IUnknown_QueryInterface(This->outer_unk, riid, ret_iface);
}

static ULONG WINAPI IAVIStream_fnAddRef(IAVIStream *iface)
{
    IAVIFileImpl *This = impl_from_IAVIStream(iface);

    return IUnknown_AddRef(This->outer_unk);
}

static ULONG WINAPI IAVIStream_fnRelease(IAVIStream* iface)
{
    IAVIFileImpl *This = impl_from_IAVIStream(iface);

    return IUnknown_Release(This->outer_unk);
}

static HRESULT WINAPI IAVIStream_fnCreate(IAVIStream *iface, LPARAM lParam1,
					  LPARAM lParam2)
{
  TRACE("(%p,0x%08lX,0x%08lX)\n", iface, lParam1, lParam2);

  /* This IAVIStream interface needs an WAVFile */
  return AVIERR_UNSUPPORTED;
}

static HRESULT WINAPI IAVIStream_fnInfo(IAVIStream *iface, AVISTREAMINFOW *psi, LONG size)
{
  IAVIFileImpl *This = impl_from_IAVIStream(iface);

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

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

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

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

static LONG WINAPI IAVIStream_fnFindSample(IAVIStream *iface, LONG pos, LONG flags)
{
  IAVIFileImpl *This = impl_from_IAVIStream(iface);

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

  /* Do we have data? */
  if (This->lpFormat == NULL)
    return -1;

  /* We don't have an index */
  if (flags & FIND_INDEX)
    return -1;

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

  if (flags & FIND_FORMAT) {
    if ((flags & FIND_NEXT) && pos > 0)
      pos = -1;
    else
      pos = 0;
  }

  if ((flags & FIND_RET) == FIND_LENGTH ||
      (flags & FIND_RET) == FIND_SIZE)
    return This->sInfo.dwSampleSize;
  if ((flags & FIND_RET) == FIND_OFFSET)
    return This->ckData.dwDataOffset + pos * This->sInfo.dwSampleSize;

  return pos;
}

static HRESULT WINAPI IAVIStream_fnReadFormat(IAVIStream *iface, LONG pos, void *format,
        LONG *formatsize)
{
  IAVIFileImpl *This = impl_from_IAVIStream(iface);

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

  if (formatsize == NULL)
    return AVIERR_BADPARAM;

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

    return AVIERR_OK;
  }

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

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

static HRESULT WINAPI IAVIStream_fnSetFormat(IAVIStream *iface, LONG pos, void *format,
        LONG formatsize)
{
  IAVIFileImpl *This = impl_from_IAVIStream(iface);

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

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

  /* We can only do this to an empty wave file, but ignore call
   * if still same format */
  if (This->lpFormat != NULL) {
    if (formatsize != This->cbFormat ||
	memcmp(format, This->lpFormat, formatsize) != 0)
      return AVIERR_UNSUPPORTED;

    return AVIERR_OK;
  }

  /* only support start at position 0 */
  if (pos != 0)
    return AVIERR_UNSUPPORTED;

  /* Do we have write permission? */
  if ((This->uMode & MMIO_RWMODE) == 0)
    return AVIERR_READONLY;

  /* get memory for format and copy it */
  This->lpFormat = HeapAlloc(GetProcessHeap(), 0, formatsize);
  if (This->lpFormat == NULL)
    return AVIERR_MEMORY;

  This->cbFormat = formatsize;
  memcpy(This->lpFormat, format, formatsize);

  /* update info's about 'data' chunk */
  This->ckData.dwDataOffset = formatsize + 7 * sizeof(DWORD);
  This->ckData.cksize       = 0;

  /* for non-pcm format we need also a 'fact' chunk */
  if (This->lpFormat->wFormatTag != WAVE_FORMAT_PCM)
    This->ckData.dwDataOffset += 3 * sizeof(DWORD);

  /* update stream and file info */
  This->sInfo.dwSampleSize = This->lpFormat->nBlockAlign;
  This->sInfo.dwScale      = This->lpFormat->nBlockAlign;
  This->sInfo.dwRate       = This->lpFormat->nAvgBytesPerSec;
  This->sInfo.dwLength     = 0;
  This->sInfo.dwSuggestedBufferSize = 0;

  return AVIERR_OK;
}

static HRESULT WINAPI IAVIStream_fnRead(IAVIStream *iface, LONG start, LONG samples, void *buffer,
        LONG buffersize, LONG *bytesread, LONG *samplesread)
{
  IAVIFileImpl *This = impl_from_IAVIStream(iface);

  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;

  /* positions without data */
  if (start < 0 || (DWORD)start > This->sInfo.dwLength)
    return AVIERR_OK;

  /* check samples */
  if (samples < 0)
    samples = 0;
  if (buffersize > 0) {
    if (samples > 0)
      samples = min((DWORD)samples, buffersize / This->sInfo.dwSampleSize);
    else
      samples = buffersize / This->sInfo.dwSampleSize;
  }

  /* limit to end of stream */
  if ((DWORD)(start + samples) > This->sInfo.dwLength)
    samples = This->sInfo.dwLength - start;

  /* request only the sizes? */
  if (buffer == NULL || buffersize <= 0) {
    /* then I need at least one parameter for it */
    if (bytesread == NULL && samplesread == NULL)
      return AVIERR_BADPARAM;

    if (bytesread != NULL)
      *bytesread = samples * This->sInfo.dwSampleSize;
    if (samplesread != NULL)
      *samplesread = samples;

    return AVIERR_OK;
  }

  /* nothing to read? */
  if (samples == 0)
    return AVIERR_OK;

  /* Can I read at least one sample? */
  if ((DWORD)buffersize < This->sInfo.dwSampleSize)
    return AVIERR_BUFFERTOOSMALL;

  buffersize = samples * This->sInfo.dwSampleSize;

  if (mmioSeek(This->hmmio, This->ckData.dwDataOffset
	       + start * This->sInfo.dwSampleSize, SEEK_SET) == -1)
    return AVIERR_FILEREAD;
  if (mmioRead(This->hmmio, buffer, buffersize) != buffersize)
    return AVIERR_FILEREAD;

  /* fill out return parameters if given */
  if (bytesread != NULL)
    *bytesread = buffersize;
  if (samplesread != NULL)
    *samplesread = samples;  

  return AVIERR_OK;
}

static HRESULT WINAPI IAVIStream_fnWrite(IAVIStream *iface, LONG start, LONG samples, void *buffer,
        LONG buffersize, DWORD flags, LONG *sampwritten, LONG *byteswritten)
{
  IAVIFileImpl *This = impl_from_IAVIStream(iface);

  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;

  /* Do we have write permission? */
  if ((This->uMode & MMIO_RWMODE) == 0)
    return AVIERR_READONLY;

  /* < 0 means "append" */
  if (start < 0)
    start = This->sInfo.dwStart + This->sInfo.dwLength;

  /* check buffersize -- must multiple of samplesize */
  if (buffersize & ~(This->sInfo.dwSampleSize - 1))
    return AVIERR_BADSIZE;

  /* do we have anything to write? */
  if (buffer != NULL && buffersize > 0) {
    This->fDirty = TRUE;

    if (mmioSeek(This->hmmio, This->ckData.dwDataOffset +
		 start * This->sInfo.dwSampleSize, SEEK_SET) == -1)
      return AVIERR_FILEWRITE;
    if (mmioWrite(This->hmmio, buffer, buffersize) != buffersize)
      return AVIERR_FILEWRITE;

    This->sInfo.dwLength = max(This->sInfo.dwLength, (DWORD)start + samples);
    This->ckData.cksize  = max(This->ckData.cksize,
			       start * This->sInfo.dwSampleSize + buffersize);

    /* fill out return parameters if given */
    if (sampwritten != NULL)
      *sampwritten = samples;
    if (byteswritten != NULL)
      *byteswritten = buffersize;
  }

  return AVIERR_OK;
}

static HRESULT WINAPI IAVIStream_fnDelete(IAVIStream *iface, LONG start, LONG samples)
{
  IAVIFileImpl *This = impl_from_IAVIStream(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 permissions */
  if ((This->uMode & MMIO_RWMODE) == 0)
    return AVIERR_READONLY;

  if ((DWORD)(start + samples) >= This->sInfo.dwLength) {
    /* deletion at end */
    samples = This->sInfo.dwLength - start;
    This->sInfo.dwLength -= samples;
    This->ckData.cksize  -= samples * This->sInfo.dwSampleSize;
  } else if ((DWORD)start <= This->sInfo.dwStart) {
    /* deletion at start */
    samples = This->sInfo.dwStart - start;
    start   = This->sInfo.dwStart;
    This->ckData.dwDataOffset += samples * This->sInfo.dwSampleSize;
    This->ckData.cksize       -= samples * This->sInfo.dwSampleSize;
  } else {
    /* deletion inside stream -- needs playlist and cue's */
    FIXME(": deletion inside of stream not supported!\n");

    return AVIERR_UNSUPPORTED;
  }

  This->fDirty = TRUE;

  return AVIERR_OK;
}

static HRESULT WINAPI IAVIStream_fnReadData(IAVIStream *iface, DWORD fcc, void *lp, LONG *lpread)
{
  IAVIFileImpl *This = impl_from_IAVIStream(iface);

  return IAVIFile_ReadData(&This->IAVIFile_iface, fcc, lp, lpread);
}

static HRESULT WINAPI IAVIStream_fnWriteData(IAVIStream *iface, DWORD fcc, void *lp, LONG size)
{
  IAVIFileImpl *This = impl_from_IAVIStream(iface);

  return IAVIFile_WriteData(&This->IAVIFile_iface, fcc, lp, size);
}

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

  return E_FAIL;
}

static const struct IAVIStreamVtbl iwavst = {
    IAVIStream_fnQueryInterface,
    IAVIStream_fnAddRef,
    IAVIStream_fnRelease,
    IAVIStream_fnCreate,
    IAVIStream_fnInfo,
    IAVIStream_fnFindSample,
    IAVIStream_fnReadFormat,
    IAVIStream_fnSetFormat,
    IAVIStream_fnRead,
    IAVIStream_fnWrite,
    IAVIStream_fnDelete,
    IAVIStream_fnReadData,
    IAVIStream_fnWriteData,
    IAVIStream_fnSetInfo
};

HRESULT AVIFILE_CreateWAVFile(IUnknown *outer_unk, REFIID riid, void **ret_iface)
{
    IAVIFileImpl *pfile;
    HRESULT hr;

    *ret_iface = NULL;

    pfile = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pfile));
    if (!pfile)
        return AVIERR_MEMORY;

    pfile->IUnknown_inner.lpVtbl = &unk_vtbl;
    pfile->IAVIFile_iface.lpVtbl = &iwavft;
    pfile->IPersistFile_iface.lpVtbl = &iwavpft;
    pfile->IAVIStream_iface.lpVtbl = &iwavst;
    pfile->ref = 1;
    if (outer_unk)
        pfile->outer_unk = outer_unk;
    else
        pfile->outer_unk = &pfile->IUnknown_inner;

    hr = IUnknown_QueryInterface(&pfile->IUnknown_inner, riid, ret_iface);
    IUnknown_Release(&pfile->IUnknown_inner);

    return hr;
}

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

static HRESULT AVIFILE_LoadFile(IAVIFileImpl *This)
{
  MMCKINFO ckRIFF;
  MMCKINFO ck;

  This->sInfo.dwLength = 0; /* just to be sure */
  This->fDirty = FALSE;

  /* search for RIFF chunk */
  ckRIFF.fccType = 0; /* find any */
  if (mmioDescend(This->hmmio, &ckRIFF, NULL, MMIO_FINDRIFF) != S_OK) {
    return AVIFILE_LoadSunFile(This);
  }

  if (ckRIFF.fccType != formtypeWAVE)
    return AVIERR_BADFORMAT;

  /* search WAVE format chunk */
  ck.ckid = ckidWAVEFORMAT;
  if (FindChunkAndKeepExtras(&This->extra, This->hmmio, &ck,
			     &ckRIFF, MMIO_FINDCHUNK) != S_OK)
    return AVIERR_FILEREAD;

  /* get memory for format and read it */
  This->lpFormat = HeapAlloc(GetProcessHeap(), 0, ck.cksize);
  if (This->lpFormat == NULL)
    return AVIERR_FILEREAD;
  This->cbFormat = ck.cksize;

  if (mmioRead(This->hmmio, (HPSTR)This->lpFormat, ck.cksize) != ck.cksize)
    return AVIERR_FILEREAD;
  if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
    return AVIERR_FILEREAD;

  /* Non-pcm formats have a fact chunk.
   * We don't need it, so simply add it to the extra chunks.
   */

  /* find the big data chunk */
  This->ckData.ckid = ckidWAVEDATA;
  if (FindChunkAndKeepExtras(&This->extra, This->hmmio, &This->ckData,
			     &ckRIFF, MMIO_FINDCHUNK) != S_OK)
    return AVIERR_FILEREAD;

  memset(&This->sInfo, 0, sizeof(This->sInfo));
  This->sInfo.fccType      = streamtypeAUDIO;
  This->sInfo.dwRate       = This->lpFormat->nAvgBytesPerSec;
  This->sInfo.dwSampleSize =
    This->sInfo.dwScale    = This->lpFormat->nBlockAlign;
  This->sInfo.dwLength     = This->ckData.cksize / This->lpFormat->nBlockAlign;
  This->sInfo.dwSuggestedBufferSize = This->ckData.cksize;

  This->fInfo.dwStreams = 1;

  if (mmioAscend(This->hmmio, &This->ckData, 0) != S_OK) {
    /* seems to be truncated */
    WARN(": file seems to be truncated!\n");
    This->ckData.cksize  = mmioSeek(This->hmmio, 0, SEEK_END) -
      This->ckData.dwDataOffset;
    This->sInfo.dwLength = This->ckData.cksize / This->lpFormat->nBlockAlign;
    This->sInfo.dwSuggestedBufferSize = This->ckData.cksize;
  }

  /* ignore errors */
  FindChunkAndKeepExtras(&This->extra, This->hmmio, &ck, &ckRIFF, 0);

  return AVIERR_OK;
}

static HRESULT AVIFILE_LoadSunFile(IAVIFileImpl *This)
{
  SUNAUDIOHEADER auhdr;

  mmioSeek(This->hmmio, 0, SEEK_SET);
  if (mmioRead(This->hmmio, (HPSTR)&auhdr, sizeof(auhdr)) != sizeof(auhdr))
    return AVIERR_FILEREAD;

  if (auhdr.fccType == 0x0064732E) {
    /* header in little endian */
    This->ckData.dwDataOffset = LE2H_DWORD(auhdr.offset);
    This->ckData.cksize       = LE2H_DWORD(auhdr.size);

    auhdr.encoding   = LE2H_DWORD(auhdr.encoding);
    auhdr.sampleRate = LE2H_DWORD(auhdr.sampleRate);
    auhdr.channels   = LE2H_DWORD(auhdr.channels);
  } else if (auhdr.fccType == mmioFOURCC('.','s','n','d')) {
    /* header in big endian */
    This->ckData.dwDataOffset = BE2H_DWORD(auhdr.offset);
    This->ckData.cksize       = BE2H_DWORD(auhdr.size);

    auhdr.encoding   = BE2H_DWORD(auhdr.encoding);
    auhdr.sampleRate = BE2H_DWORD(auhdr.sampleRate);
    auhdr.channels   = BE2H_DWORD(auhdr.channels);
  } else
    return AVIERR_FILEREAD;

  if (auhdr.channels < 1)
    return AVIERR_BADFORMAT;

  /* get size of header */
  switch(auhdr.encoding) {
  case AU_ENCODING_ADPCM_G721_32:
    This->cbFormat = sizeof(G721_ADPCMWAVEFORMAT); break;
  case AU_ENCODING_ADPCM_G723_24:
    This->cbFormat = sizeof(G723_ADPCMWAVEFORMAT); break;
  case AU_ENCODING_ADPCM_G722:
  case AU_ENCODING_ADPCM_G723_5:
    WARN("unsupported Sun audio format %d\n", auhdr.encoding);
    return AVIERR_UNSUPPORTED; /* FIXME */
  default:
    This->cbFormat = sizeof(WAVEFORMATEX); break;
  };

  This->lpFormat = HeapAlloc(GetProcessHeap(), 0, This->cbFormat);
  if (This->lpFormat == NULL)
    return AVIERR_MEMORY;

  This->lpFormat->nChannels      = auhdr.channels;
  This->lpFormat->nSamplesPerSec = auhdr.sampleRate;
  switch(auhdr.encoding) {
  case AU_ENCODING_ULAW_8:
    This->lpFormat->wFormatTag     = WAVE_FORMAT_MULAW;
    This->lpFormat->wBitsPerSample = 8;
    break;
  case AU_ENCODING_PCM_8:
    This->lpFormat->wFormatTag     = WAVE_FORMAT_PCM;
    This->lpFormat->wBitsPerSample = 8;
    break;
  case AU_ENCODING_PCM_16:
    This->lpFormat->wFormatTag     = WAVE_FORMAT_PCM;
    This->lpFormat->wBitsPerSample = 16;
    break;
  case AU_ENCODING_PCM_24:
    This->lpFormat->wFormatTag     = WAVE_FORMAT_PCM;
    This->lpFormat->wBitsPerSample = 24;
    break;
  case AU_ENCODING_PCM_32:
    This->lpFormat->wFormatTag     = WAVE_FORMAT_PCM;
    This->lpFormat->wBitsPerSample = 32;
    break;
  case AU_ENCODING_ALAW_8:
    This->lpFormat->wFormatTag     = WAVE_FORMAT_ALAW;
    This->lpFormat->wBitsPerSample = 8;
    break;
  case AU_ENCODING_ADPCM_G721_32:
    This->lpFormat->wFormatTag     = WAVE_FORMAT_G721_ADPCM;
    This->lpFormat->wBitsPerSample = (3*5*8);
    This->lpFormat->nBlockAlign    = 15*15*8;
    This->lpFormat->cbSize         = sizeof(WORD);
    ((LPG721_ADPCMWAVEFORMAT)This->lpFormat)->nAuxBlockSize = 0;
    break;
  case AU_ENCODING_ADPCM_G723_24:
    This->lpFormat->wFormatTag     = WAVE_FORMAT_G723_ADPCM;
    This->lpFormat->wBitsPerSample = (3*5*8);
    This->lpFormat->nBlockAlign    = 15*15*8;
    This->lpFormat->cbSize         = 2*sizeof(WORD);
    ((LPG723_ADPCMWAVEFORMAT)This->lpFormat)->cbExtraSize   = 0;
    ((LPG723_ADPCMWAVEFORMAT)This->lpFormat)->nAuxBlockSize = 0;
    break;
  default:
    WARN("unsupported Sun audio format %d\n", auhdr.encoding);
    return AVIERR_UNSUPPORTED;
  };

  This->lpFormat->nBlockAlign =
    (This->lpFormat->nChannels * This->lpFormat->wBitsPerSample) / 8;
  if (This->lpFormat->nBlockAlign == 0 && This->lpFormat->wBitsPerSample < 8)
    This->lpFormat->nBlockAlign++;
  This->lpFormat->nAvgBytesPerSec =
    This->lpFormat->nBlockAlign * This->lpFormat->nSamplesPerSec;

  This->fDirty = FALSE;

  This->sInfo.fccType               = streamtypeAUDIO;
  This->sInfo.fccHandler            = 0;
  This->sInfo.dwFlags               = 0;
  This->sInfo.wPriority             = 0;
  This->sInfo.wLanguage             = 0;
  This->sInfo.dwInitialFrames       = 0;
  This->sInfo.dwScale               = This->lpFormat->nBlockAlign;
  This->sInfo.dwRate                = This->lpFormat->nAvgBytesPerSec;
  This->sInfo.dwStart               = 0;
  This->sInfo.dwLength              =
    This->ckData.cksize / This->lpFormat->nBlockAlign;
  This->sInfo.dwSuggestedBufferSize = This->sInfo.dwLength;
  This->sInfo.dwSampleSize          = This->lpFormat->nBlockAlign;

  This->fInfo.dwStreams = 1;
  This->fInfo.dwScale   = 1;
  This->fInfo.dwRate    = This->lpFormat->nSamplesPerSec;
  This->fInfo.dwLength  =
    MulDiv(This->ckData.cksize, This->lpFormat->nSamplesPerSec,
	   This->lpFormat->nAvgBytesPerSec);

  return AVIERR_OK;
}

static HRESULT AVIFILE_SaveFile(const IAVIFileImpl *This)
{
  MMCKINFO ckRIFF;
  MMCKINFO ck;

  mmioSeek(This->hmmio, 0, SEEK_SET);

  /* create the RIFF chunk with formtype WAVE */
  ckRIFF.fccType = formtypeWAVE;
  ckRIFF.cksize  = 0;
  if (mmioCreateChunk(This->hmmio, &ckRIFF, MMIO_CREATERIFF) != S_OK)
    return AVIERR_FILEWRITE;

  /* the next chunk is the format */
  ck.ckid   = ckidWAVEFORMAT;
  ck.cksize = This->cbFormat;
  if (mmioCreateChunk(This->hmmio, &ck, 0) != S_OK)
    return AVIERR_FILEWRITE;
  if (This->lpFormat != NULL && This->cbFormat > 0) {
    if (mmioWrite(This->hmmio, (HPSTR)This->lpFormat, ck.cksize) != ck.cksize)
      return AVIERR_FILEWRITE;
  }
  if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
    return AVIERR_FILEWRITE;

  /* fact chunk is needed for non-pcm waveforms */
  if (This->lpFormat != NULL && This->cbFormat > sizeof(PCMWAVEFORMAT) &&
      This->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
    WAVEFORMATEX wfx;
    DWORD        dwFactLength;
    HACMSTREAM   has;

    /* try to open an appropriate audio codec to figure out
     * data for fact-chunk */
    wfx.wFormatTag = WAVE_FORMAT_PCM;
    if (acmFormatSuggest(NULL, This->lpFormat, &wfx,
			 sizeof(wfx), ACM_FORMATSUGGESTF_WFORMATTAG)) {
      acmStreamOpen(&has, NULL, This->lpFormat, &wfx, NULL,
		    0, 0, ACM_STREAMOPENF_NONREALTIME);
      acmStreamSize(has, This->ckData.cksize, &dwFactLength,
		    ACM_STREAMSIZEF_SOURCE);
      dwFactLength /= wfx.nBlockAlign;
      acmStreamClose(has, 0);

      /* create the fact chunk */
      ck.ckid   = ckidWAVEFACT;
      ck.cksize = sizeof(dwFactLength);

      /* test for enough space before data chunk */
      if (mmioSeek(This->hmmio, 0, SEEK_CUR) > This->ckData.dwDataOffset
	  - ck.cksize - 4 * sizeof(DWORD))
	return AVIERR_FILEWRITE;
      if (mmioCreateChunk(This->hmmio, &ck, 0) != S_OK)
	return AVIERR_FILEWRITE;
      if (mmioWrite(This->hmmio, (HPSTR)&dwFactLength, ck.cksize) != ck.cksize)
	return AVIERR_FILEWRITE;
      if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
	return AVIERR_FILEWRITE;
    } else
      ERR(": fact chunk is needed for non-pcm files -- currently no codec found, so skipped!\n");
  }

  /* if there was extra stuff, we need to fill it with JUNK */
  if (mmioSeek(This->hmmio, 0, SEEK_CUR) + 2 * sizeof(DWORD) < This->ckData.dwDataOffset) {
    ck.ckid   = ckidAVIPADDING;
    ck.cksize = 0;
    if (mmioCreateChunk(This->hmmio, &ck, 0) != S_OK)
      return AVIERR_FILEWRITE;

    if (mmioSeek(This->hmmio, This->ckData.dwDataOffset
		 - 2 * sizeof(DWORD), SEEK_SET) == -1)
      return AVIERR_FILEWRITE;
    if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
      return AVIERR_FILEWRITE;
  }

  /* create the data chunk */
  ck.ckid   = ckidWAVEDATA;
  ck.cksize = This->ckData.cksize;
  if (mmioCreateChunk(This->hmmio, &ck, 0) != S_OK)
    return AVIERR_FILEWRITE;
  if (mmioSeek(This->hmmio, This->ckData.cksize, SEEK_CUR) == -1)
    return AVIERR_FILEWRITE;
  if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
    return AVIERR_FILEWRITE;

  /* some optional extra chunks? */
  if (This->extra.lp != NULL && This->extra.cb > 0) {
    /* chunk headers are already in structure */
    if (mmioWrite(This->hmmio, This->extra.lp, This->extra.cb) != This->extra.cb)
      return AVIERR_FILEWRITE;
  }

  /* close RIFF chunk */
  if (mmioAscend(This->hmmio, &ckRIFF, 0) != S_OK)
    return AVIERR_FILEWRITE;
  if (mmioFlush(This->hmmio, 0) != S_OK)
    return AVIERR_FILEWRITE;

  return AVIERR_OK;
}
