wine/dlls/avifil32: implemented many functions

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hallo.

This patch adds many functionality to the avifil32.dll. It's now
possible to use the wine/programs/avitools/aviinfo programm.

- added DllCanUnloadNow, DllGetClassObject to avifil32.spec
- implemented AVIFileOpenW
- implemented many functions of the AVI filehandler.
- added resources to avifil32
- added FIND_* consts to include/vfw.h
- added registry entries for avifile.dll and avifil32.dll

Index: winedefault.reg
===================================================================
RCS file: /home/wine/wine/winedefault.reg,v
retrieving revision 1.54
diff -u -r1.54 winedefault.reg
--- winedefault.reg	20 Sep 2002 19:38:35 -0000	1.54
+++ winedefault.reg	11 Oct 2002 21:49:09 -0000
@@ -1057,3 +1057,60 @@
 "Times New Roman Greek,161"="Times New Roman,161"
 "Times New Roman TUR,162"="Times New Roman,162"
 "Tms Rmn"="Times New Roman"
+
+[HKEY_CLASSES_ROOT\AVIFile\Compressors\auds]
+@="{0002000F-0000-0000-C000-000000000046}"
+
+[HKEY_CLASSES_ROOT\AVIFile\Compressors\vids]
+@="{00020001-0000-0000-C000-000000000046}"
+
+[HKEY_CLASSES_ROOT\AVIFile\Extensions\AU]
+@="{00020003-0000-0000-C000-000000000046}"
+
+[HKEY_CLASSES_ROOT\AVIFile\Extensions\AVI]
+@="{00020000-0000-0000-C000-000000000046}"
+
+[HKEY_CLASSES_ROOT\AVIFile\Extensions\WAV]
+@="{00020003-0000-0000-C000-000000000046}"
+
+[HKEY_CLASSES_ROOT\AVIFile\RIFFHandlers\AVI]
+@="{00020000-0000-0000-C000-000000000046}"
+
+[HKEY_CLASSES_ROOT\AVIFile\RIFFHandlers\WAVE]
+@="{00020003-0000-0000-C000-000000000046}"
+
+[HKEY_CLASSES_ROOT\CLSID\{00020000-0000-0000-C000-000000000046}\InProcServer]
+@="avifile.dll"
+
+[HKEY_CLASSES_ROOT\CLSID\{00020000-0000-0000-C000-000000000046}\InProcServer32]
+@="avifil32.dll"
+"ThreadingModel"="Apartment"
+
+[HKEY_CLASSES_ROOT\CLSID\{00020001-0000-0000-C000-000000000046}\InProcServer]
+@="avifile.dll"
+
+[HKEY_CLASSES_ROOT\CLSID\{00020001-0000-0000-C000-000000000046}\InProcServer32]
+@="avifil32.dll"
+"ThreadingModel"="Apartment"
+
+[HKEY_CLASSES_ROOT\CLSID\{00020003-0000-0000-C000-000000000046}\InProcServer]
+@="avifile.dll"
+
+[HKEY_CLASSES_ROOT\CLSID\{00020003-0000-0000-C000-000000000046}\InProcServer32]
+@="avifil32.dll"
+"ThreadingModel"="Apartment"
+
+[HKEY_CLASSES_ROOT\CLSID\{0002000D-0000-0000-C000-000000000046}\InProcServer]
+@="avifile.dll"
+
+[HKEY_CLASSES_ROOT\CLSID\{0002000D-0000-0000-C000-000000000046}\InProcServer32]
+@="avifil32.dll"
+"ThreadingModel"="Apartment"
+
+[HKEY_CLASSES_ROOT\CLSID\{0002000F-0000-0000-C000-000000000046}\InProcServer]
+@="avifile.dll"
+
+[HKEY_CLASSES_ROOT\CLSID\{0002000F-0000-0000-C000-000000000046}\InProcServer32]
+@="avifil32.dll"
+"ThreadingModel"="Apartment"
+
Index: dlls/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/Makefile.in,v
retrieving revision 1.156
diff -u -r1.156 Makefile.in
--- dlls/Makefile.in	10 Oct 2002 23:36:52 -0000	1.156
+++ dlls/Makefile.in	11 Oct 2002 21:49:10 -0000
@@ -764,7 +764,7 @@
 advapi32: kernel32.dll$(DLLEXT) ntdll.dll$(DLLEXT)
 avicap32: ntdll.dll$(DLLEXT)
 avifil32: msvfw32.dll$(DLLEXT) shell32.dll$(DLLEXT) user32.dll$(DLLEXT) advapi32.dll$(DLLEXT) \
-          kernel32.dll$(DLLEXT)
+          winmm.dll$(DLLEXT) kernel32.dll$(DLLEXT)
 comcat:   ole32.dll$(DLLEXT) user32.dll$(DLLEXT) advapi32.dll$(DLLEXT) kernel32.dll$(DLLEXT)
 comctl32: user32.dll$(DLLEXT) gdi32.dll$(DLLEXT) advapi32.dll$(DLLEXT) kernel32.dll$(DLLEXT) \
           winmm.dll$(DLLEXT)
Index: dlls/avifil32/.cvsignore
===================================================================
RCS file: /home/wine/wine/dlls/avifil32/.cvsignore,v
retrieving revision 1.9
diff -u -r1.9 .cvsignore
--- dlls/avifil32/.cvsignore	14 May 2002 20:54:58 -0000	1.9
+++ dlls/avifil32/.cvsignore	11 Oct 2002 21:49:10 -0000
@@ -2,3 +2,4 @@
 avifil32.dll.dbg.c
 avifil32.spec.c
 avifile.spec.c
+rsrc.res
Index: dlls/avifil32/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/avifil32/Makefile.in,v
retrieving revision 1.21
diff -u -r1.21 Makefile.in
--- dlls/avifil32/Makefile.in	10 Oct 2002 23:31:13 -0000	1.21
+++ dlls/avifil32/Makefile.in	11 Oct 2002 21:49:10 -0000
@@ -3,7 +3,7 @@
 SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 MODULE    = avifil32.dll
-IMPORTS   = msvfw32 shell32 user32 advapi32 kernel32
+IMPORTS   = msvfw32 advapi32 shell32 winmm user32 kernel32
 ALTNAMES  = avifile.dll
 EXTRALIBS = $(LIBUUID)
 
@@ -13,7 +13,11 @@
 C_SRCS = \
 	api.c \
 	avifile.c \
+	extrachunk.c \
 	factory.c
+
+RC_SRCS = \
+	rsrc.rc
 
 @MAKE_DLL_RULES@
 
Index: dlls/avifil32/api.c
===================================================================
RCS file: /home/wine/wine/dlls/avifil32/api.c,v
retrieving revision 1.6
diff -u -r1.6 api.c
--- dlls/avifil32/api.c	10 Oct 2002 23:31:13 -0000	1.6
+++ dlls/avifil32/api.c	11 Oct 2002 21:49:10 -0000
@@ -125,6 +125,25 @@
   return S_OK;
 }
 
+static BOOL AVIFILE_GetFileHandlerByExtension(LPCWSTR szFile, LPCLSID lpclsid)
+{
+  CHAR   szRegKey[25];
+  CHAR   szValue[100];
+  LPWSTR szExt = strrchrW(szFile, L'.');
+  LONG   len = sizeof(szValue) / sizeof(szValue[0]);
+
+  if (szExt == NULL)
+    return FALSE;
+
+  szExt++;
+
+  wsprintfA(szRegKey, "AVIFile\\Extensions\\%.3ls", szExt);
+  if (RegQueryValueA(HKEY_CLASSES_ROOT, szRegKey, szValue, &len) != ERROR_SUCCESS)
+    return FALSE;
+
+  return (AVIFILE_CLSIDFromString(szValue, lpclsid) == S_OK);
+}
+
 /***********************************************************************
  *		AVIFileInit		(AVIFIL32.@)
  *		AVIFileInit		(AVIFILE.100)
@@ -190,7 +209,7 @@
   CLSID         clsidHandler;
   HRESULT       hr;
 
-  FIXME("(%p,%s,0x%X,%s): stub!\n", ppfile, debugstr_w(szFile), uMode,
+  TRACE("(%p,%s,0x%X,%s)\n", ppfile, debugstr_w(szFile), uMode,
 	debugstr_guid(lpHandler));
 
   /* check parameters */
@@ -201,7 +220,8 @@
 
   /* if no handler then try guessing it by extension */
   if (lpHandler == NULL) {
-    FIXME(": must read HKEY_CLASSES_ROOT\\AVIFile\\Extensions\\%s\n", debugstr_w(strrchrW(szFile, L'.')));
+    if (! AVIFILE_GetFileHandlerByExtension(szFile, &clsidHandler))
+      return AVIERR_UNSUPPORTED;
   } else
     memcpy(&clsidHandler, lpHandler, sizeof(clsidHandler));
 
@@ -820,3 +840,4 @@
 
   return (LONG)(((float)lTime * asiw.dwRate) / asiw.dwScale / 1000.0);
 }
+
Index: dlls/avifil32/avifil32.spec
===================================================================
RCS file: /home/wine/wine/dlls/avifil32/avifil32.spec,v
retrieving revision 1.13
diff -u -r1.13 avifil32.spec
--- dlls/avifil32/avifil32.spec	10 Oct 2002 23:31:13 -0000	1.13
+++ dlls/avifil32/avifil32.spec	11 Oct 2002 21:49:10 -0000
@@ -1,3 +1,5 @@
+init AVIFILE_DllMain
+
 @ stub    AVIBuildFilter
 @ stub    AVIBuildFilterA
 @ stub    AVIBuildFilterW
@@ -59,8 +61,8 @@
 @ stdcall AVIStreamWriteData(ptr long ptr long) AVIStreamWriteData
 @ stub    CLSID_AVISimpleUnMarshal
 @ stub    CreateEditableStream
-@ stub    DllCanUnloadNow
-@ stub    DllGetClassObject
+@ stdcall DllCanUnloadNow() AVIFILE_DllCanUnloadNow
+@ stdcall DllGetClassObject(ptr ptr ptr) AVIFILE_DllGetClassObject
 @ stub    EditStreamClone
 @ stub    EditStreamCopy
 @ stub    EditStreamCut
Index: dlls/avifil32/avifile.c
===================================================================
RCS file: /home/wine/wine/dlls/avifil32/avifile.c,v
retrieving revision 1.26
diff -u -r1.26 avifile.c
--- dlls/avifil32/avifile.c	10 Oct 2002 23:31:13 -0000	1.26
+++ dlls/avifil32/avifile.c	11 Oct 2002 21:49:12 -0000
@@ -20,6 +20,7 @@
 #include <assert.h>
 
 #include "winbase.h"
+#include "winuser.h"
 #include "winnls.h"
 #include "winerror.h"
 #include "windowsx.h"
@@ -27,6 +28,7 @@
 #include "vfw.h"
 
 #include "avifile_private.h"
+#include "extrachunk.h"
 
 #include "wine/debug.h"
 
@@ -132,7 +134,22 @@
 
   /* IAVIStream stuff */
   IAVIFileImpl     *paf;
+  DWORD             nStream;       /* the n-th stream in file */
   AVISTREAMINFOW    sInfo;
+
+  LPVOID            lpFormat;
+  DWORD             cbFormat;
+
+  LPVOID            lpHandlerData;
+  DWORD             cbHandlerData;
+
+  EXTRACHUNKS       extra;
+
+  DWORD             dwLastFrame;    /* last correct index in idxFrames */
+  AVIINDEXENTRY    *idxFrames;
+  DWORD             nIdxFrames;     /* upper index limit of idxFrames */
+  AVIINDEXENTRY    *idxFmtChanges;
+  DWORD             nIdxFmtChanges; /* upper index limit of idxFmtChanges */
 } IAVIStreamImpl;
 
 struct _IAVIFileImpl {
@@ -146,6 +163,13 @@
   AVIFILEINFOW      fInfo;
   IAVIStreamImpl   *ppStreams[MAX_AVISTREAMS];
 
+  EXTRACHUNKS       fileextra;
+
+  DWORD             dwMoviChunkPos;  /* some stuff for saving ... */
+  DWORD             dwIdxChunkPos;
+  DWORD             dwNextFramePos;
+  AVIINDEXENTRY    *idxRecords;      /* won't be updated while loading */
+
   /* IPersistFile stuff ... */
   HMMIO             hmmio;
   LPWSTR            szFileName;
@@ -155,6 +179,17 @@
 
 /***********************************************************************/
 
+static HRESULT AVIFILE_AddFrame(IAVIStreamImpl *This, DWORD ckid, DWORD size,
+				DWORD offset, DWORD flags);
+static void    AVIFILE_ConstructAVIStream(IAVIFileImpl *paf, DWORD nr,
+					  LPAVISTREAMINFOW asi);
+static void    AVIFILE_DestructAVIStream(IAVIStreamImpl *This);
+static HRESULT AVIFILE_LoadFile(IAVIFileImpl *This);
+static void    AVIFILE_SamplesToBlock(IAVIStreamImpl *This, LPLONG pos,
+				      LPLONG offset);
+static ULONG   AVIFILE_SearchStream(IAVIFileImpl *This, DWORD fccType,
+				    LONG lSkip);
+
 HRESULT AVIFILE_CreateAVIFile(REFIID riid, LPVOID *ppv)
 {
   IAVIFileImpl *pfile;
@@ -210,14 +245,40 @@
 static ULONG WINAPI IAVIFile_fnRelease(IAVIFile *iface)
 {
   ICOM_THIS(IAVIFileImpl,iface);
+  UINT i;
+
+  TRACE("(%p)\n",iface);
 
-  FIXME("(%p): partial stub!\n",iface);
   if (!--(This->ref)) {
     if (This->fDirty) {
-      /* FIXME: write headers to disk */
+      FIXME(": need to write headers to file -- not impemented!\n");
+    }
+
+    for (i = 0; i < This->fInfo.dwStreams; i++) {
+      if (This->ppStreams[i] != NULL) {
+	AVIFILE_DestructAVIStream(This->ppStreams[i]);
+	LocalFree((HLOCAL)This->ppStreams[i]);
+	This->ppStreams[i] = NULL;
+      }
+    }
+
+    if (This->idxRecords != NULL) {
+      GlobalFreePtr(This->idxRecords);
+      This->idxRecords = NULL;
     }
 
-    HeapFree(GetProcessHeap(),0,iface);
+    if (This->fileextra.lp != NULL) {
+      GlobalFreePtr(This->fileextra.lp);
+      This->fileextra.lp = NULL;
+      This->fileextra.cb = 0;
+    }
+
+    if (This->szFileName != NULL) {
+      LocalFree((HLOCAL)This->szFileName);
+      This->szFileName = NULL;
+    }
+
+    LocalFree((HLOCAL)This);
     return 0;
   }
   return This->ref;
@@ -245,50 +306,160 @@
 static HRESULT WINAPI IAVIFile_fnGetStream(IAVIFile *iface, PAVISTREAM *avis,
 					   DWORD fccType, LONG lParam)
 {
-  FIXME("(%p,%p,0x%08lX,%ld): stub\n", iface, avis, fccType, lParam);
-  /* FIXME: create interface etc. */
-  return E_FAIL;
+  ICOM_THIS(IAVIFileImpl,iface);
+
+  ULONG nStream;
+
+  TRACE("(%p,%p,0x%08lX,%ld)\n", iface, avis, fccType, lParam);
+
+  if (avis == NULL || lParam < 0)
+    return AVIERR_BADPARAM;
+
+  nStream = AVIFILE_SearchStream(This, fccType, lParam);
+
+  /* Does the requested stream exist? */
+  if (nStream < This->fInfo.dwStreams &&
+      This->ppStreams[nStream] != NULL) {
+    *avis = (PAVISTREAM)This->ppStreams[nStream];
+    IAVIStream_AddRef(*avis);
+
+    return AVIERR_OK;
+  }
+
+  /* Sorry, but the specified stream doesn't exist */
+  return AVIERR_NODATA;
 }
 
 static HRESULT WINAPI IAVIFile_fnCreateStream(IAVIFile *iface,PAVISTREAM *avis,
 					      LPAVISTREAMINFOW asi)
 {
-/*  ICOM_THIS(IAVIStreamImpl,iface); */
+  ICOM_THIS(IAVIFileImpl,iface);
 
-  FIXME("(%p,%p,%p): stub\n", iface, avis, asi);
+  DWORD n;
 
-  return AVIERR_UNSUPPORTED;
+  TRACE("(%p,%p,%p)\n", iface, avis, asi);
+
+  /* check parameters */
+  if (avis == NULL || asi == NULL)
+    return AVIERR_BADPARAM;
+
+  /* Does the user have write permission? */
+  if ((This->uMode & MMIO_RWMODE) == 0)
+    return AVIERR_READONLY;
+
+  /* Can we add another stream? */
+  n = This->fInfo.dwStreams;
+  if (n >= MAX_AVISTREAMS || This->dwMoviChunkPos != 0) {
+    /* already reached max nr of streams
+     * or have already written frames to disk */
+    return AVIERR_UNSUPPORTED;
+  }
+
+  /* check AVISTREAMINFO for some really needed things */
+  if (asi->fccType == 0 || asi->dwScale == 0 || asi->dwRate == 0)
+    return AVIERR_BADFORMAT;
+
+  /* now it seems to be save to add the stream */
+  assert(This->ppStreams[n] == NULL);
+  This->ppStreams[n] = (IAVIStreamImpl*)LocalAlloc(LPTR,
+						   sizeof(IAVIStreamImpl));
+  if (This->ppStreams[n] == NULL)
+    return AVIERR_MEMORY;
+
+  /* initialize the new allocated stream */
+  AVIFILE_ConstructAVIStream(This, n, asi);
+
+  This->fInfo.dwStreams++;
+  This->fDirty = TRUE;
+
+  /* FIXME: here we could update our AVIFILEINFO structure -- should we? */
+
+  return AVIERR_OK;
 }
 
 static HRESULT WINAPI IAVIFile_fnWriteData(IAVIFile *iface, DWORD ckid,
 					   LPVOID lpData, LONG size)
 {
-  FIXME("(%p,0x%08lX,%p,%ld): stub\n", iface, ckid, lpData, size);
-  /* FIXME: write data to file */
-  return E_FAIL;
+  ICOM_THIS(IAVIFileImpl,iface);
+
+  TRACE("(%p,0x%08lX,%p,%ld)\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;
+
+  return WriteExtraChunk(&This->fileextra, ckid, lpData, size);
 }
 
 static HRESULT WINAPI IAVIFile_fnReadData(IAVIFile *iface, DWORD ckid,
 					  LPVOID lpData, LONG *size)
 {
-  FIXME("(%p,0x%08lX,%p,%p): stub\n", iface, ckid, lpData, size);
-  /* FIXME: read at most size bytes from file */
-  return E_FAIL;
+  ICOM_THIS(IAVIFileImpl,iface);
+
+  TRACE("(%p,0x%08lX,%p,%p)\n", iface, ckid, lpData, size);
+
+  return ReadExtraChunk(&This->fileextra, ckid, lpData, size);
 }
 
 static HRESULT WINAPI IAVIFile_fnEndRecord(IAVIFile *iface)
 {
+  ICOM_THIS(IAVIFileImpl,iface);
+
   FIXME("(%p): stub\n",iface);
+
+  if ((This->uMode & MMIO_RWMODE) == 0)
+    return AVIERR_READONLY;
+
+  This->fDirty = TRUE;
+
   /* FIXME: end record -- for interleaved files */
+
   return E_FAIL;
 }
 
 static HRESULT WINAPI IAVIFile_fnDeleteStream(IAVIFile *iface, DWORD fccType,
 					      LONG lParam)
 {
-  FIXME("(%p,0x%08lX,%ld): stub\n", iface, fccType, lParam);
-  /* FIXME: delete stream */
-  return E_FAIL;
+  ICOM_THIS(IAVIFileImpl,iface);
+
+  ULONG nStream;
+
+  TRACE("(%p,0x%08lX,%ld)\n", iface, fccType, lParam);
+
+  /* check parameter */
+  if (lParam < 0)
+    return AVIERR_BADPARAM;
+
+  /* Habe user write permissions? */
+  if ((This->uMode & MMIO_RWMODE) == 0)
+    return AVIERR_READONLY;
+
+  nStream = AVIFILE_SearchStream(This, fccType, lParam);
+
+  /* Does the requested stream exist? */
+  if (nStream < This->fInfo.dwStreams &&
+      This->ppStreams[nStream] != NULL) {
+    /* ... so delete it now */
+    LocalFree((HLOCAL)This->ppStreams[nStream]);
+
+    if (This->fInfo.dwStreams - nStream > 0)
+      memcpy(This->ppStreams + nStream, This->ppStreams + nStream + 1,
+	     (This->fInfo.dwStreams - nStream) * sizeof(IAVIStreamImpl*));
+
+    This->ppStreams[This->fInfo.dwStreams] = NULL;
+    This->fInfo.dwStreams--;
+    This->fDirty = TRUE;
+
+    /* This->fInfo will be updated further when asked for */
+    return AVIERR_OK;
+  } else
+    return AVIERR_NODATA;
 }
 
 /***********************************************************************/
@@ -350,11 +521,41 @@
 {
   ICOM_THIS(IPersistFileImpl,iface);
 
-  FIXME("(%p,%s,0x%08lX): stub\n", iface, debugstr_w(pszFileName), dwMode);
+  int len;
+
+  TRACE("(%p,%s,0x%08lX)\n", iface, debugstr_w(pszFileName), dwMode);
+
+  /* check parameter */
+  if (pszFileName == NULL)
+    return AVIERR_BADPARAM;
 
   assert(This->paf != NULL);
+  if (This->paf->hmmio != (HMMIO)NULL)
+    return AVIERR_ERROR; /* No reuse of this object for another file! */
+
+  /* remeber mode and name */
+  This->paf->uMode = dwMode;
 
-  return AVIERR_ERROR;
+  len = lstrlenW(pszFileName) + 1;
+  This->paf->szFileName = (LPWSTR)LocalAlloc(LPTR, len * sizeof(WCHAR));
+  if (This->paf->szFileName == NULL)
+    return AVIERR_MEMORY;
+  lstrcpyW(This->paf->szFileName, pszFileName);
+
+  /* try to open the file */
+  This->paf->hmmio = mmioOpenW(This->paf->szFileName, NULL,
+			       MMIO_ALLOCBUF | dwMode);
+  if (This->paf->hmmio == (HMMIO)NULL)
+    return AVIERR_FILEOPEN;
+
+  /* should we create a new file? */
+  if (dwMode & OF_CREATE) {
+    memset(& This->paf->fInfo, 0, sizeof(This->paf->fInfo));
+    This->paf->fInfo.dwFlags = AVIFILEINFO_HASINDEX | AVIFILEINFO_TRUSTCKTYPE;
+
+    return AVIERR_OK;
+  } else
+    return AVIFILE_LoadFile(This->paf);
 }
 
 static HRESULT WINAPI IPersistFile_fnSave(IPersistFile *iface,
@@ -477,7 +678,88 @@
 static LONG WINAPI IAVIStream_fnFindSample(IAVIStream *iface, LONG pos,
 					   LONG flags)
 {
-  FIXME("(%p,%ld,0x%08lX): stub\n",iface,pos,flags);
+  ICOM_THIS(IAVIStreamImpl,iface);
+
+  LONG offset = 0;
+
+  TRACE("(%p,%ld,0x%08lX)\n",iface,pos,flags);
+
+  if (flags & FIND_FROM_START) {
+    pos = This->sInfo.dwStart;
+    flags &= ~(FIND_FROM_START|FIND_PREV);
+    flags |= FIND_NEXT;
+  }
+
+  if (This->sInfo.dwSampleSize != 0) {
+    /* convert samples into block number with offset */
+    AVIFILE_SamplesToBlock(This, &pos, &offset);
+  }
+
+  if (flags & FIND_TYPE) {
+    if (flags & FIND_KEY) {
+      while (0 <= pos && pos < This->dwLastFrame) {
+	if (This->idxFrames[pos].dwFlags & AVIIF_KEYFRAME)
+	  goto RETURN_FOUND;
+
+	if (flags & FIND_NEXT)
+	  pos++;
+	else
+	  pos--;
+      }
+    } else if (flags & FIND_ANY) {
+      while (0 <= pos && pos < This->dwLastFrame) {
+	if (This->idxFrames[pos].dwChunkLength > 0)
+	  goto RETURN_FOUND;
+
+	if (flags & FIND_NEXT)
+	  pos++;
+	else
+	  pos--;
+      }
+    } else if ((flags & FIND_FORMAT) && This->idxFmtChanges != NULL &&
+	       This->sInfo.fccType == streamtypeVIDEO) {
+      UINT n;
+
+      if (flags & FIND_NEXT) {
+	for (n = 0; n < This->sInfo.dwFormatChangeCount; n++)
+	  if (This->idxFmtChanges[n].ckid >= pos)
+	    goto RETURN_FOUND;
+      } else {
+	for (n = This->sInfo.dwFormatChangeCount; n >= 0; n--) {
+	  if (This->idxFmtChanges[n].ckid <= pos)
+	    goto RETURN_FOUND;
+	}
+
+	if (pos > This->sInfo.dwStart)
+	  return 0; /* format changes always for first frame */
+      }
+    }
+
+    return -1;
+  }
+
+  if (flags & FIND_RET) {
+  RETURN_FOUND:
+    if (flags & FIND_LENGTH) {
+      /* logical size */
+      if (This->sInfo.dwSampleSize)
+	pos = This->sInfo.dwSampleSize;
+      else
+	pos = 1;
+    } else if (flags & FIND_OFFSET) {
+      /* physical position */
+      pos = This->idxFrames[pos].dwChunkOffset + offset * This->sInfo.dwSampleSize;
+    } else if (flags & FIND_SIZE) {
+      /* physical size */
+      pos = This->idxFrames[pos].dwChunkLength;
+    } else if (flags & FIND_INDEX) {
+      FIXME(": FIND_INDEX flag is not supported!");
+
+      pos = This->paf->dwIdxChunkPos;
+    } /* else logical position */
+
+    return pos;
+  }
 
   return -1;
 }
@@ -485,19 +767,147 @@
 static HRESULT WINAPI IAVIStream_fnReadFormat(IAVIStream *iface, LONG pos,
 					      LPVOID format, LONG *formatsize)
 {
-  FIXME("(%p,%ld,%p,%p): stub\n", iface, pos, format, formatsize);
+  ICOM_THIS(IAVIStreamImpl,iface);
 
-  return E_FAIL;
+  TRACE("(%p,%ld,%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;
+  }
+
+  /* Could format change? When yes will it change? */
+  if ((This->sInfo.dwFlags & AVISTREAMINFO_FORMATCHANGES) &&
+      pos > This->sInfo.dwStart) {
+    LPBITMAPINFOHEADER lpbi = (LPBITMAPINFOHEADER)This->lpFormat;
+    LONG lLastFmt;
+
+    lLastFmt = IAVIStream_fnFindSample(iface, pos, FIND_FORMAT|FIND_PREV);
+    if (lLastFmt > 0) {
+      FIXME(": need to read formatchange for %ld -- unimplemented!\n",lLastFmt);
+    }
+  }
+
+  *formatsize = This->cbFormat;
+  return AVIERR_OK;
 }
 
 static HRESULT WINAPI IAVIStream_fnSetFormat(IAVIStream *iface, LONG pos,
 					     LPVOID format, LONG formatsize)
 {
-/*  ICOM_THIS(IAVIStreamImpl,iface); */
+  ICOM_THIS(IAVIStreamImpl,iface);
 
-  FIXME("(%p,%ld,%p,%ld): stub\n", iface, pos, format, formatsize);
+  LPBITMAPINFOHEADER lpbiNew = (LPBITMAPINFOHEADER)format;
 
-  return E_FAIL;
+  TRACE("(%p,%ld,%p,%ld)\n", iface, pos, format, formatsize);
+
+  /* check parameters */
+  if (format == NULL || formatsize <= 0)
+    return AVIERR_BADPARAM;
+
+  /* Do we have write permission? */
+  if ((This->paf->uMode & MMIO_RWMODE) == 0)
+    return AVIERR_READONLY;
+
+  /* can only set format before frame is written! */
+  if (This->dwLastFrame >= pos)
+    return AVIERR_UNSUPPORTED;
+
+  /* initial format or a formatchange? */
+  if (This->lpFormat != NULL) {
+    /* initial format */
+    if (This->paf->dwMoviChunkPos != 0)
+      return AVIERR_ERROR; /* user has used API in wrong sequnece! */
+
+    This->lpFormat = GlobalAllocPtr(GMEM_MOVEABLE, formatsize);
+    if (This->lpFormat == NULL)
+      return AVIERR_MEMORY;
+    This->cbFormat = formatsize;
+
+    memcpy(This->lpFormat, format, formatsize);
+
+    /* update some infos about stream */
+    if (This->sInfo.fccType == streamtypeVIDEO) {
+      LONG lDim;
+
+      lDim = This->sInfo.rcFrame.right - This->sInfo.rcFrame.left;
+      if (lDim < lpbiNew->biWidth)
+	This->sInfo.rcFrame.right = This->sInfo.rcFrame.left + lpbiNew->biWidth;
+      lDim = This->sInfo.rcFrame.bottom - This->sInfo.rcFrame.top;
+      if (lDim < lpbiNew->biHeight)
+	This->sInfo.rcFrame.bottom = This->sInfo.rcFrame.top + lpbiNew->biHeight;
+    } else if (This->sInfo.fccType == streamtypeAUDIO)
+      This->sInfo.dwSampleSize = ((LPWAVEFORMATEX)This->lpFormat)->nBlockAlign;
+
+    return AVIERR_OK;
+  } else {
+    MMCKINFO           ck;
+    LPBITMAPINFOHEADER lpbiOld = (LPBITMAPINFOHEADER)This->lpFormat;
+    RGBQUAD           *rgbNew  = (RGBQUAD*)((LPBYTE)lpbiNew + lpbiNew->biSize);
+    AVIPALCHANGE      *lppc = NULL;
+    INT                n;
+
+    /* pherhaps formatchange, check it ... */
+    if (This->cbFormat != formatsize)
+      return AVIERR_UNSUPPORTED;
+
+    /* no formatchange, only the initial one */
+    if (memcmp(This->lpFormat, format, formatsize) == 0)
+      return AVIERR_OK;
+
+    /* check that's only the palette, which changes */
+    if (lpbiOld->biSize        != lpbiNew->biSize ||
+	lpbiOld->biWidth       != lpbiNew->biWidth ||
+	lpbiOld->biHeight      != lpbiNew->biHeight ||
+	lpbiOld->biPlanes      != lpbiNew->biPlanes ||
+	lpbiOld->biBitCount    != lpbiNew->biBitCount ||
+	lpbiOld->biCompression != lpbiNew->biCompression ||
+	lpbiOld->biClrUsed     != lpbiNew->biClrUsed)
+      return AVIERR_UNSUPPORTED;
+
+    This->sInfo.dwFlags |= AVISTREAMINFO_FORMATCHANGES;
+
+    /* simply say all colors have changed */
+    ck.ckid   = MAKEAVICKID(cktypePALchange, This->nStream);
+    ck.cksize = 2 * sizeof(WORD) + lpbiOld->biClrUsed * sizeof(PALETTEENTRY);
+    lppc = (AVIPALCHANGE*)GlobalAllocPtr(GMEM_MOVEABLE, ck.cksize);
+    if (lppc == NULL)
+      return AVIERR_MEMORY;
+
+    lppc->bFirstEntry = 0;
+    lppc->bNumEntries = (lpbiOld->biClrUsed < 256 ? lpbiOld->biClrUsed : 0);
+    lppc->wFlags      = 0;
+    for (n = 0; n < lpbiOld->biClrUsed; n++) {
+      lppc->peNew[n].peRed   = rgbNew[n].rgbRed;
+      lppc->peNew[n].peGreen = rgbNew[n].rgbGreen;
+      lppc->peNew[n].peBlue  = rgbNew[n].rgbBlue;
+      lppc->peNew[n].peFlags = 0;
+    }
+
+    if (mmioSeek(This->paf->hmmio, This->paf->dwNextFramePos, SEEK_SET) == -1)
+      return AVIERR_FILEWRITE;
+    if (mmioCreateChunk(This->paf->hmmio, &ck, 0) != S_OK)
+      return AVIERR_FILEWRITE;
+    if (mmioWrite(This->paf->hmmio, (HPSTR)lppc, ck.cksize) != ck.cksize)
+      return AVIERR_FILEWRITE;
+    if (mmioAscend(This->paf->hmmio, &ck, 0) != S_OK)
+      return AVIERR_FILEWRITE;
+    This->paf->dwNextFramePos += ck.cksize + 2 * sizeof(DWORD);
+
+    return AVIFILE_AddFrame(This, cktypePALchange, n, ck.dwDataOffset, 0);
+  }
 }
 
 static HRESULT WINAPI IAVIStream_fnRead(IAVIStream *iface, LONG start,
@@ -551,17 +961,55 @@
 static HRESULT WINAPI IAVIStream_fnReadData(IAVIStream *iface, DWORD fcc,
 					    LPVOID lp, LPLONG lpread)
 {
-  FIXME("(%p,0x%08lX,%p,%p): stub\n", iface, fcc, lp, lpread);
+  ICOM_THIS(IAVIStreamImpl,iface);
 
-  return E_FAIL;
+  TRACE("(%p,0x%08lX,%p,%p)\n", iface, fcc, lp, lpread);
+
+  if (fcc == ckidSTREAMHANDLERDATA) {
+    if (This->lpHandlerData != NULL && This->cbHandlerData > 0) {
+      if (lp == NULL || *lpread <= 0) {
+	*lpread = This->cbHandlerData;
+	return AVIERR_OK;
+      }
+
+      memcpy(lp, This->lpHandlerData, min(This->cbHandlerData, *lpread));
+      if (*lpread < This->cbHandlerData)
+	return AVIERR_BUFFERTOOSMALL;
+      return AVIERR_OK;
+    } else
+      return AVIERR_NODATA;
+  } else
+    return ReadExtraChunk(&This->extra, fcc, lp, lpread);
 }
 
 static HRESULT WINAPI IAVIStream_fnWriteData(IAVIStream *iface, DWORD fcc,
 					     LPVOID lp, LONG size)
 {
-  FIXME("(%p,0x%08lx,%p,%ld): stub\n", iface, fcc, lp, size);
+  ICOM_THIS(IAVIStreamImpl,iface);
 
-  return E_FAIL;
+  TRACE("(%p,0x%08lx,%p,%ld)\n", iface, fcc, lp, size);
+
+  /* check parameters */
+  if (lp == NULL)
+    return AVIERR_BADPARAM;
+  if (size <= 0)
+    return AVIERR_BADSIZE;
+
+  if (fcc == ckidSTREAMHANDLERDATA) {
+    if (This->lpHandlerData != NULL) {
+      FIXME(": handler data already set -- overwirte?\n");
+      return AVIERR_UNSUPPORTED;
+    }
+
+    This->lpHandlerData = GlobalAllocPtr(GMEM_MOVEABLE, size);
+    if (This->lpHandlerData == NULL)
+      return AVIERR_MEMORY;
+    This->cbHandlerData = size;
+    memcpy(This->lpHandlerData, lp, size);
+
+    return AVIERR_OK;
+  } else
+    return WriteExtraChunk(&This->extra, fcc, lp, size);
 }
 
 static HRESULT WINAPI IAVIStream_fnSetInfo(IAVIStream *iface,
@@ -570,4 +1018,512 @@
   FIXME("(%p,%p,%ld): stub\n", iface, info, infolen);
 
   return E_FAIL;
+}
+
+/***********************************************************************/
+
+static HRESULT AVIFILE_AddFrame(IAVIStreamImpl *This, DWORD ckid, DWORD size, DWORD offset, DWORD flags)
+{
+  switch (TWOCCFromFOURCC(ckid)) {
+  case cktypeDIBbits:
+    if (This->paf->fInfo.dwFlags & AVIFILEINFO_TRUSTCKTYPE)
+      flags |= AVIIF_KEYFRAME;
+    break;
+  case cktypeDIBcompressed:
+    if (This->paf->fInfo.dwFlags & AVIFILEINFO_TRUSTCKTYPE)
+      flags &= ~AVIIF_KEYFRAME;
+    break;
+  case cktypePALchange:
+    if (This->sInfo.fccType != streamtypeVIDEO) {
+      ERR(": found palette change in non-video stream!\n");
+      return AVIERR_BADFORMAT;
+    }
+    This->sInfo.dwFlags |= AVISTREAMINFO_FORMATCHANGES;
+    This->sInfo.dwFormatChangeCount++;
+
+    if (This->idxFmtChanges == NULL || This->sInfo.dwFormatChangeCount < This->nIdxFmtChanges) {
+      UINT n = This->sInfo.dwFormatChangeCount;
+
+      This->nIdxFmtChanges += 16;
+      This->idxFmtChanges = GlobalReAllocPtr(This->idxFmtChanges, This->nIdxFmtChanges * sizeof(AVIINDEXENTRY), GHND);
+      if (This->idxFmtChanges == NULL)
+	return AVIERR_MEMORY;
+
+      This->idxFmtChanges[n].ckid          = This->dwLastFrame;
+      This->idxFmtChanges[n].dwFlags       = 0;
+      This->idxFmtChanges[n].dwChunkOffset = offset;
+      This->idxFmtChanges[n].dwChunkLength = size;
+
+      return AVIERR_OK;
+    }
+    break;
+  case cktypeWAVEbytes:
+    if (This->paf->fInfo.dwFlags & AVIFILEINFO_TRUSTCKTYPE)
+      flags |= AVIIF_KEYFRAME;
+    break;
+  default:
+    WARN(": unknown TWOCC 0x%04X found\n", TWOCCFromFOURCC(ckid));
+    break;
+  };
+
+  /* first frame is alwasy a keyframe */
+  if (This->dwLastFrame == -1)
+    flags |= AVIIF_KEYFRAME;
+
+  if (This->sInfo.dwSuggestedBufferSize < size)
+    This->sInfo.dwSuggestedBufferSize = size;
+
+  /* get memory for index */
+  if (This->idxFrames == NULL || This->dwLastFrame + 1 < This->nIdxFrames) {
+    This->nIdxFrames += 512;
+    This->idxFrames = GlobalReAllocPtr(This->idxFrames, This->nIdxFrames * sizeof(AVIINDEXENTRY), GHND);
+    if (This->idxFrames == NULL)
+      return AVIERR_MEMORY;
+  }
+
+  This->dwLastFrame++;
+  This->idxFrames[This->dwLastFrame].ckid          = ckid;
+  This->idxFrames[This->dwLastFrame].dwFlags       = flags;
+  This->idxFrames[This->dwLastFrame].dwChunkOffset = offset;
+  This->idxFrames[This->dwLastFrame].dwChunkLength = size;
+
+  return AVIERR_OK;
+}
+
+static void    AVIFILE_ConstructAVIStream(IAVIFileImpl *paf, DWORD nr, LPAVISTREAMINFOW asi)
+{
+  IAVIStreamImpl *pstream;
+
+  /* pre-conditions */
+  assert(paf != NULL);
+  assert(nr < MAX_AVISTREAMS);
+  assert(paf->ppStreams[nr] != NULL);
+
+  pstream = paf->ppStreams[nr];
+
+  ICOM_VTBL(pstream) = &iavist;
+  pstream->ref         = 1;
+  pstream->paf         = paf;
+  pstream->nStream     = nr;
+  pstream->dwLastFrame = -1;
+
+  if (asi != NULL) {
+    memcpy(&pstream->sInfo, asi, sizeof(pstream->sInfo));
+
+    if (asi->dwLength > 0) {
+      /* pre-allocate mem for frame-index structure */
+      pstream->idxFrames = (AVIINDEXENTRY*)GlobalAllocPtr(GHND, asi->dwLength * sizeof(AVIINDEXENTRY));
+      if (pstream->idxFrames != NULL)
+	pstream->nIdxFrames = asi->dwLength;
+    }
+    if (asi->dwFormatChangeCount > 0) {
+      /* FIXME: pre-allocate mem for formatchange-index structure */
+    }
+
+    pstream->sInfo.dwCaps = AVIFILECAPS_CANREAD|AVIFILECAPS_CANWRITE;
+
+    /* These values will be computed */
+    pstream->sInfo.dwLength              = 0;
+    pstream->sInfo.dwSuggestedBufferSize = 0;
+    pstream->sInfo.dwFormatChangeCount   = 0;
+    pstream->sInfo.dwEditCount           = 1;
+    if (pstream->sInfo.dwSampleSize > 0)
+      SetRectEmpty(&pstream->sInfo.rcFrame);
+
+    /* FIXME? */
+  }
+}
+
+static void    AVIFILE_DestructAVIStream(IAVIStreamImpl *This)
+{
+  /* pre-conditions */
+  assert(This != NULL);
+
+  This->dwLastFrame = -1;
+  if (This->idxFrames != NULL) {
+    GlobalFreePtr(This->idxFrames);
+    This->idxFrames  = NULL;
+    This->nIdxFrames = 0;
+  }
+  if (This->idxFmtChanges != NULL) {
+    GlobalFreePtr(This->idxFmtChanges);
+    This->idxFmtChanges = NULL;
+  }
+  if (This->lpHandlerData != NULL) {
+    GlobalFreePtr(This->lpHandlerData);
+    This->lpHandlerData = NULL;
+    This->cbHandlerData = 0;
+  }
+  if (This->extra.lp != NULL) {
+    GlobalFreePtr(This->extra.lp);
+    This->extra.lp = NULL;
+    This->extra.cb = 0;
+  }
+  if (This->lpFormat != NULL) {
+    GlobalFreePtr(This->lpFormat);
+    This->lpFormat = NULL;
+    This->cbFormat = 0;
+  }
+}
+
+static HRESULT AVIFILE_LoadFile(IAVIFileImpl *This)
+{
+  MainAVIHeader   MainAVIHdr;
+  MMCKINFO        ckRIFF;
+  MMCKINFO        ckLIST1;
+  MMCKINFO        ckLIST2;
+  MMCKINFO        ck;
+  IAVIStreamImpl *pStream;
+  DWORD           nStream;
+  HRESULT         hr;
+
+  if (This->hmmio == (HMMIO)NULL)
+    return AVIERR_FILEOPEN;
+
+  /* initialize stream ptr's */
+  memset(This->ppStreams, 0, sizeof(This->ppStreams));
+
+  /* try to get "RIFF" chunk -- must not be at beginning of file! */
+  ckRIFF.fccType = formtypeAVI;
+  if (mmioDescend(This->hmmio, &ckRIFF, NULL, MMIO_FINDRIFF) != S_OK) {
+    ERR(": not an AVI!\n");
+    return AVIERR_FILEREAD;
+  }
+
+  /* get "LIST" "hdrl" */
+  ckLIST1.fccType = listtypeAVIHEADER;
+  hr = FindChunkAndKeepExtras(&This->fileextra, This->hmmio, &ckLIST1, &ckRIFF, MMIO_FINDLIST);
+  if (FAILED(hr)) {
+    ERR(": no AVI header list found!\n");
+    return hr;
+  }
+
+  /* get "avih" chunk */
+  ck.ckid = ckidAVIMAINHDR;
+  hr = FindChunkAndKeepExtras(&This->fileextra, This->hmmio, &ck, &ckLIST1, MMIO_FINDCHUNK);
+  if (FAILED(hr)) {
+    ERR(": no AVI mainheader found!\n");
+    return hr;
+  }
+
+  if (ck.cksize != sizeof(MainAVIHdr)) {
+    FIXME(": invalid size of %ld for MainAVIHeader!\n", ck.cksize);
+    return AVIERR_BADFORMAT;
+  }
+  if (mmioRead(This->hmmio, (HPSTR)&MainAVIHdr, ck.cksize) != ck.cksize)
+    return AVIERR_FILEREAD;
+
+  /* adjust permissions if copyrighted material in file */
+  if (MainAVIHdr.dwFlags & AVIFILEINFO_COPYRIGHTED) {
+    This->uMode &= ~MMIO_RWMODE;
+    This->uMode |= MMIO_READ;
+  }
+
+  /* convert MainAVIHeader into AVIFILINFOW */
+  memset(&This->fInfo, 0, sizeof(This->fInfo));
+  This->fInfo.dwRate                = MainAVIHdr.dwMicroSecPerFrame;
+  This->fInfo.dwScale               = 1000000;
+  This->fInfo.dwMaxBytesPerSec      = MainAVIHdr.dwMaxBytesPerSec;
+  This->fInfo.dwFlags               = MainAVIHdr.dwFlags;
+  This->fInfo.dwCaps                = AVIFILECAPS_CANREAD|AVIFILECAPS_CANWRITE;
+  This->fInfo.dwLength              = MainAVIHdr.dwTotalFrames;
+  This->fInfo.dwStreams             = MainAVIHdr.dwStreams;
+  This->fInfo.dwSuggestedBufferSize = MainAVIHdr.dwSuggestedBufferSize;
+  This->fInfo.dwWidth               = MainAVIHdr.dwWidth;
+  This->fInfo.dwHeight              = MainAVIHdr.dwHeight;
+  LoadStringW(AVIFILE_hModule, IDS_AVIFILETYPE, This->fInfo.szFileType,
+	      sizeof(This->fInfo.szFileType));
+
+  /* go back to into header list */
+  if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
+    return AVIERR_FILEREAD;
+
+  /* foreach stream exists a "LIST","strl" chunk */
+  for (nStream = 0; nStream < This->fInfo.dwStreams; nStream++) {
+    /* get next nested chunk in this "LIST","strl" */
+    if (mmioDescend(This->hmmio, &ckLIST2, &ckLIST1, 0) != S_OK)
+      return AVIERR_FILEREAD;
+
+    /* nested chunk must be of type "LIST","strl" -- when not normally JUNK */
+    if (ckLIST2.ckid == FOURCC_LIST &&
+	ckLIST2.fccType == listtypeSTREAMHEADER) {
+      pStream = This->ppStreams[nStream] = (IAVIStreamImpl*)LocalAlloc(LPTR, sizeof(IAVIStreamImpl));
+      if (pStream == NULL)
+	return AVIERR_MEMORY;
+      AVIFILE_ConstructAVIStream(This, nStream, NULL);
+
+      ck.ckid = 0;
+      while (mmioDescend(This->hmmio, &ck, &ckLIST2, 0) == S_OK) {
+	switch (ck.ckid) {
+	case ckidSTREAMHANDLERDATA:
+	  if (pStream->lpHandlerData != NULL)
+	    return AVIERR_BADFORMAT;
+	  pStream->lpHandlerData = GlobalAllocPtr(GMEM_DDESHARE|GMEM_MOVEABLE,
+						  ck.cksize);
+	  if (pStream->lpHandlerData == NULL)
+	    return AVIERR_MEMORY;
+	  pStream->cbHandlerData = ck.cksize;
+
+	  if (mmioRead(This->hmmio, (HPSTR)pStream->lpHandlerData, ck.cksize) != ck.cksize)
+	    return AVIERR_FILEREAD;
+	  break;
+	case ckidSTREAMFORMAT:
+	  if (pStream->lpFormat != NULL)
+	    return AVIERR_BADFORMAT;
+	  pStream->lpFormat = GlobalAllocPtr(GMEM_DDESHARE|GMEM_MOVEABLE,
+					     ck.cksize);
+	  if (pStream->lpFormat == NULL)
+	    return AVIERR_MEMORY;
+	  pStream->cbFormat = ck.cksize;
+
+	  if (mmioRead(This->hmmio, (HPSTR)pStream->lpFormat, ck.cksize) != ck.cksize)
+	    return AVIERR_FILEREAD;
+
+	  if (pStream->sInfo.fccType == streamtypeVIDEO) {
+	    LPBITMAPINFOHEADER lpbi = (LPBITMAPINFOHEADER)pStream->lpFormat;
+
+	    /* some corrections to the video format */
+	    if (lpbi->biClrUsed == 0 && lpbi->biBitCount <= 8)
+	      lpbi->biClrUsed = 1u << lpbi->biBitCount;
+	    if (lpbi->biCompression == BI_RGB && lpbi->biSizeImage == 0)
+	      lpbi->biSizeImage = DIBWIDTHBYTES(*lpbi) * lpbi->biHeight;
+	    if (lpbi->biCompression != BI_RGB && lpbi->biBitCount == 8) {
+	      if (pStream->sInfo.fccHandler == mmioFOURCC('R','L','E','0') ||
+		  pStream->sInfo.fccHandler == mmioFOURCC('R','L','E',' '))
+		lpbi->biCompression = BI_RLE8;
+	    }
+	    if (lpbi->biCompression == BI_RGB &&
+		(pStream->sInfo.fccHandler == 0 ||
+		 pStream->sInfo.fccHandler == mmioFOURCC('N','O','N','E')))
+	      pStream->sInfo.fccHandler = comptypeDIB;
+
+	    /* init rcFrame if it's empty */
+	    if (IsRectEmpty(&pStream->sInfo.rcFrame))
+	      SetRect(&pStream->sInfo.rcFrame, 0, 0, lpbi->biWidth, lpbi->biHeight);
+	  }
+	  break;
+	case ckidSTREAMHEADER:
+	  {
+	    static WCHAR streamTypeFmt[] = {'%','4','.','4','h','s'};
+
+	    AVIStreamHeader streamHdr;
+	    WCHAR           szType[25];
+	    WCHAR           streamNameFmt[25];
+	    UINT            count;
+	    LONG            n = ck.cksize;
+
+	    if (ck.cksize > sizeof(streamHdr))
+	      n = sizeof(streamHdr);
+
+	    if (mmioRead(This->hmmio, (HPSTR)&streamHdr, n) != n)
+	      return AVIERR_FILEREAD;
+
+	    pStream->sInfo.fccType               = streamHdr.fccType;
+	    pStream->sInfo.fccHandler            = streamHdr.fccHandler;
+	    pStream->sInfo.dwFlags               = streamHdr.dwFlags;
+	    pStream->sInfo.wPriority             = streamHdr.wPriority;
+	    pStream->sInfo.wLanguage             = streamHdr.wLanguage;
+	    pStream->sInfo.dwInitialFrames       = streamHdr.dwInitialFrames;
+	    pStream->sInfo.dwScale               = streamHdr.dwScale;
+	    pStream->sInfo.dwRate                = streamHdr.dwRate;
+	    pStream->sInfo.dwStart               = streamHdr.dwStart;
+	    pStream->sInfo.dwLength              = streamHdr.dwLength;
+	    pStream->sInfo.dwSuggestedBufferSize =
+	      streamHdr.dwSuggestedBufferSize;
+	    pStream->sInfo.dwQuality             = streamHdr.dwQuality;
+	    pStream->sInfo.dwSampleSize          = streamHdr.dwSampleSize;
+	    pStream->sInfo.rcFrame.left          = streamHdr.rcFrame.left;
+	    pStream->sInfo.rcFrame.top           = streamHdr.rcFrame.top;
+	    pStream->sInfo.rcFrame.right         = streamHdr.rcFrame.right;
+	    pStream->sInfo.rcFrame.bottom        = streamHdr.rcFrame.bottom;
+	    pStream->sInfo.dwEditCount           = 0;
+	    pStream->sInfo.dwFormatChangeCount   = 0;
+
+	    /* generate description for stream like "filename.avi Type #n" */
+	    if (streamHdr.fccType == streamtypeVIDEO)
+	      LoadStringW(AVIFILE_hModule, IDS_VIDEO, szType, sizeof(szType));
+	    else if (streamHdr.fccType == streamtypeAUDIO)
+	      LoadStringW(AVIFILE_hModule, IDS_AUDIO, szType, sizeof(szType));
+	    else
+	      wsprintfW(szType, streamTypeFmt, (char*)&streamHdr.fccType);
+
+	    /* get count of this streamtype up to this stream */
+	    count = 0;
+	    for (n = nStream; 0 <= n; n--) {
+	      if (This->ppStreams[n]->sInfo.fccHandler == streamHdr.fccType)
+		count++;
+	    }
+
+	    memset(pStream->sInfo.szName, 0, sizeof(pStream->sInfo.szName));
+
+	    LoadStringW(AVIFILE_hModule, IDS_AVISTREAMFORMAT, streamNameFmt, sizeof(streamNameFmt));
+
+	    /* FIXME: avoid overflow -- better use wsnprintfW, which doesn't exists ! */
+	    wsprintfW(pStream->sInfo.szName, streamNameFmt,
+		      AVIFILE_BasenameW(This->szFileName), szType, count);
+	  }
+	  break;
+	case ckidSTREAMNAME:
+	  { /* streamname will be saved as ASCII string */
+	    LPSTR str = (LPSTR)LocalAlloc(LMEM_FIXED, ck.cksize);
+	    if (str == NULL)
+	      return AVIERR_MEMORY;
+
+	    if (mmioRead(This->hmmio, (HPSTR)str, ck.cksize) != ck.cksize)
+	      return AVIERR_FILEREAD;
+
+	    MultiByteToWideChar(CP_ACP, 0, str, -1, pStream->sInfo.szName, sizeof(pStream->sInfo.szName)/sizeof(pStream->sInfo.szName[0]));
+
+	    LocalFree((HLOCAL)str);
+	  }
+	  break;
+	case ckidAVIPADDING:
+	case mmioFOURCC('p','a','d','d'):
+	  break;
+	case 0:
+	  ERR(": Oops, internal error at line %d\n", __LINE__);
+	  return AVIERR_INTERNAL;
+	default:
+	  WARN(": found extra chunk 0x%08lX\n", ck.ckid);
+	  hr = ReadChunkIntoExtra(&pStream->extra, This->hmmio, &ck);
+	  if (FAILED(hr))
+	    return hr;
+	};
+
+	if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
+	  return AVIERR_FILEREAD;
+      }
+    } else {
+      /* nested chunks in "LIST","hdrl" which are not of type "LIST","strl" */
+      hr = ReadChunkIntoExtra(&This->fileextra, This->hmmio, &ckLIST2);
+      if (FAILED(hr))
+	return hr;
+      if (mmioAscend(This->hmmio, &ckLIST2, 0) != S_OK)
+	return AVIERR_FILEREAD;
+    }
+  }
+
+  /* read any extra headers in "LIST","hdrl" */
+  FindChunkAndKeepExtras(&This->fileextra, This->hmmio, &ck, &ckLIST1, 0);
+  if (mmioAscend(This->hmmio, &ckLIST1, 0) != S_OK)
+    return AVIERR_FILEREAD;
+
+  /* search "LIST","movi" chunk in "RIFF","AVI " */
+  ckLIST1.fccType = listtypeAVIMOVIE;
+  hr = FindChunkAndKeepExtras(&This->fileextra, This->hmmio, &ckLIST1, &ckRIFF,
+			      MMIO_FINDLIST);
+  if (FAILED(hr))
+    return hr;
+
+  This->dwMoviChunkPos = ckLIST1.dwDataOffset - 2 * sizeof(DWORD);
+  This->dwIdxChunkPos  = ckLIST1.cksize + ckLIST1.dwDataOffset;
+  if (mmioAscend(This->hmmio, &ckLIST1, 0) != S_OK)
+    return AVIERR_FILEREAD;
+
+  /* try to find an index */
+  ck.ckid = ckidAVINEWINDEX;
+  hr = FindChunkAndKeepExtras(&This->fileextra, This->hmmio, &ck, &ckRIFF, MMIO_FINDCHUNK);
+  if (SUCCEEDED(hr) && ck.cksize > 0) {
+    FIXME(": parse 'idx1' chunk -- not implemented\n");
+
+    This->fInfo.dwFlags &= ~AVIFILEINFO_HASINDEX;
+  }
+
+  /* when we haven't found an index or it's bad, then build one
+   * by parsing 'movi' chunk */
+  if ((This->fInfo.dwFlags & AVIFILEINFO_HASINDEX) == 0) {
+    for (nStream = 0; nStream < This->fInfo.dwStreams; nStream++)
+      This->ppStreams[nStream]->dwLastFrame = -1;
+
+    if (mmioSeek(This->hmmio, ckLIST1.dwDataOffset + sizeof(DWORD), SEEK_SET) == -1) {
+      ERR(": Oops, can't seek back to 'movi' chunk!\n");
+      return AVIERR_FILEREAD;
+    }
+
+    /* seek through the 'movi' list until end */
+    while (mmioDescend(This->hmmio, &ck, &ckLIST1, 0) == S_OK) {
+      if (ck.ckid != FOURCC_LIST) {
+	if (mmioAscend(This->hmmio, &ck, 0) == S_OK) {
+	  nStream = StreamFromFOURCC(ck.ckid);
+
+	  AVIFILE_AddFrame(This->ppStreams[nStream], ck.ckid, ck.cksize,
+			   ck.dwDataOffset - 2 * sizeof(DWORD), 0);
+	} else {
+	  nStream = StreamFromFOURCC(ck.ckid);
+	  WARN(": file seems to be truncated!\n");
+	  if (nStream <= This->fInfo.dwStreams &&
+	      This->ppStreams[nStream]->sInfo.dwSampleSize > 0) {
+	    ck.cksize = mmioSeek(This->hmmio, 0, SEEK_END);
+	    if (ck.cksize != -1) {
+	      ck.cksize -= ck.dwDataOffset;
+	      ck.cksize &= ~(This->ppStreams[nStream]->sInfo.dwSampleSize - 1);
+
+	      AVIFILE_AddFrame(This->ppStreams[nStream], ck.ckid, ck.cksize,
+			       ck.dwDataOffset - 2 * sizeof(DWORD), 0);
+	    }
+	  }
+	}
+      }
+    }
+  }
+
+  /* find other chunks */
+  FindChunkAndKeepExtras(&This->fileextra, This->hmmio, &ck, &ckRIFF, 0);
+
+  return AVIERR_OK;
+}
+
+static void    AVIFILE_SamplesToBlock(IAVIStreamImpl *This, LPLONG pos,
+				      LPLONG offset)
+{
+  DWORD block;
+
+  /* pre-conditions */
+  assert(This != NULL);
+  assert(pos != NULL);
+  assert(offset != NULL);
+  assert(This->sInfo.dwSampleSize != 0);
+  assert(*pos >= This->sInfo.dwStart);
+
+  /* convert start sample to start bytes */
+  (*offset)  = (*pos) - This->sInfo.dwStart;
+  (*offset) *= This->sInfo.dwSampleSize;
+
+  /* convert bytes to block number */
+  for (block = 0; block < This->dwLastFrame; block++) {
+    if (This->idxFrames[block].dwChunkLength <= *offset)
+      (*offset) -= This->idxFrames[block].dwChunkLength;
+    else
+      break;
+  }
+
+  *pos = block;
+}
+
+static ULONG  AVIFILE_SearchStream(IAVIFileImpl *This, DWORD fcc, LONG lSkip)
+{
+  UINT i;
+  UINT nStream;
+
+  /* pre-condition */
+  assert(lSkip >= 0);
+
+  if (fcc != 0) {
+    /* search the number of the specified stream */
+    nStream = (ULONG)-1;
+    for (i = 0; i < This->fInfo.dwStreams; i++) {
+      assert(This->ppStreams[i] != NULL);
+
+      if (This->ppStreams[i]->sInfo.fccType == fcc) {
+	if (lSkip == 0) {
+	  nStream = i;
+	  break;
+	} else
+	  lSkip--;
+      }
+    }
+  } else
+    nStream = lSkip;
+
+  return nStream;
 }
Index: dlls/avifil32/avifile_private.h
===================================================================
RCS file: /home/wine/wine/dlls/avifil32/avifile_private.h,v
retrieving revision 1.4
diff -u -r1.4 avifile_private.h
--- dlls/avifil32/avifile_private.h	10 Oct 2002 23:31:13 -0000	1.4
+++ dlls/avifil32/avifile_private.h	11 Oct 2002 21:49:12 -0000
@@ -23,6 +23,23 @@
 #define MAX_AVISTREAMS 4
 #endif
 
+#ifndef comptypeDIB
+#define comptypeDIB  mmioFOURCC('D','I','B',' ')
+#endif
+
+#ifndef DIBWIDTHBYTES
+#define WIDTHBYTES(i)     (((i+31)&(~31))/8)
+#define DIBWIDTHBYTES(bi) WIDTHBYTES((bi).biWidth * (bi).biBitCount)
+#endif
+
+#define IDS_WAVESTREAMFORMAT 0x0100
+#define IDS_WAVEFILETYPE     0x0101
+#define IDS_VIDEO            0x0189
+#define IDS_AUDIO            0x0190
+#define IDS_AVISTREAMFORMAT  0x0191
+#define IDS_AVIFILETYPE      0x0192
+#define IDS_UNCOMPRESSED     0x0193
+
 DEFINE_AVIGUID(CLSID_ICMStream, 0x00020001, 0, 0);
 DEFINE_AVIGUID(CLSID_WAVFile,   0x00020003, 0, 0);
 DEFINE_AVIGUID(CLSID_ACMStream, 0x0002000F, 0, 0);
@@ -33,5 +50,7 @@
 extern HRESULT AVIFILE_CreateWAVFile(REFIID riid, LPVOID *ppobj);
 extern HRESULT AVIFILE_CreateACMStream(REFIID riid, LPVOID *ppobj);
 extern HRESULT AVIFILE_CreateICMStream(REFIID riid, LPVOID *ppobj);
+
+extern LPCWSTR  AVIFILE_BasenameW(LPCWSTR szFileName);
 
 #endif
Index: dlls/avifil32/factory.c
===================================================================
RCS file: /home/wine/wine/dlls/avifil32/factory.c,v
retrieving revision 1.1
diff -u -r1.1 factory.c
--- dlls/avifil32/factory.c	10 Oct 2002 23:31:13 -0000	1.1
+++ dlls/avifil32/factory.c	11 Oct 2002 21:49:12 -0000
@@ -19,6 +19,7 @@
 #include <assert.h>
 
 #include "winbase.h"
+#include "winnls.h"
 #include "winerror.h"
 
 #include "ole2.h"
@@ -126,7 +127,8 @@
 {
   ICOM_THIS(IClassFactoryImpl,iface);
 
-  FIXME("(%p,%p,%s,%p): stub!\n", iface, pOuter, debugstr_guid(riid), ppobj);
+  FIXME("(%p,%p,%s,%p): partial stub!\n", iface, pOuter, debugstr_guid(riid),
+	ppobj);
 
   if (ppobj == NULL || pOuter != NULL)
     return E_FAIL;
@@ -153,6 +155,23 @@
   return S_OK;
 }
 
+#define SLASH(w) ((w) == L'/' || (w) == L'\\')
+
+LPCWSTR AVIFILE_BasenameW(LPCWSTR szPath)
+{
+  LPCWSTR szCur;
+
+  for (szCur = szPath + lstrlenW(szPath);
+       szCur > szPath && !SLASH(*szCur) && *szCur != L':';)
+    szCur--;
+
+  if (szCur == szPath)
+    return szCur;
+  else
+    return szCur + 1;
+}
+
+#undef SLASH
 
 /***********************************************************************
  *		DllGetClassObject (AVIFIL32.@)
@@ -181,7 +200,7 @@
 BOOL WINAPI AVIFILE_DllMain(HINSTANCE hInstDll, DWORD fdwReason,
 			    LPVOID lpvReserved)
 {
-  TRACE("(%d,%lu,%p)\n", hInstDll, fdwReason, lpvReserved);
+  TRACE("(0x%X,%lu,%p)\n", hInstDll, fdwReason, lpvReserved);
 
   switch (fdwReason) {
   case DLL_PROCESS_ATTACH:
Index: include/vfw.h
===================================================================
RCS file: /home/wine/wine/include/vfw.h,v
retrieving revision 1.28
diff -u -r1.28 vfw.h
--- include/vfw.h	10 Oct 2002 23:31:13 -0000	1.28
+++ include/vfw.h	11 Oct 2002 21:49:16 -0000
@@ -907,6 +907,7 @@
 #define AVIFILEINFO_HASINDEX		0x00000010
 #define AVIFILEINFO_MUSTUSEINDEX	0x00000020
 #define AVIFILEINFO_ISINTERLEAVED	0x00000100
+#define AVIFILEINFO_TRUSTCKTYPE         0x00000800
 #define AVIFILEINFO_WASCAPTUREFILE	0x00010000
 #define AVIFILEINFO_COPYRIGHTED		0x00020000
 
@@ -967,6 +968,23 @@
     DWORD	cbParms;
     DWORD	dwInterleaveEvery;	/* for non-video streams only */
 } AVICOMPRESSOPTIONS, *LPAVICOMPRESSOPTIONS,*PAVICOMPRESSOPTIONS;
+
+#define FIND_DIR        0x0000000fL     /* direction mask */
+#define FIND_NEXT       0x00000001L     /* search forward */
+#define FIND_PREV       0x00000004L     /* seacrh backward */
+#define FIND_FROM_START 0x00000008L     /* start at the logical beginning */
+
+#define FIND_TYPE       0x000000f0L     /* type mask */
+#define FIND_KEY        0x00000010L     /* find a key frame */
+#define FIND_ANY        0x00000020L     /* find any (non-empty) sample */
+#define FIND_FORMAT     0x00000040L     /* find a formatchange */
+
+#define FIND_RET        0x0000f000L     /* return mask */
+#define FIND_POS        0x00000000L     /* return logical position */
+#define FIND_LENGTH     0x00001000L     /* return logical size */
+#define FIND_OFFSET     0x00002000L     /* return physical position */
+#define FIND_SIZE       0x00003000L     /* return physical size */
+#define FIND_INDEX      0x00004000L     /* return physical index position */
 
 #include "ole2.h"
 
--- /dev/null	Sat Feb 23 16:05:24 2002
+++ dlls/avifil32/extrachunk.c	Fri Oct 11 23:36:39 2002
@@ -0,0 +1,196 @@
+/*
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <assert.h>
+
+#include "extrachunk.h"
+#include "winbase.h"
+#include "windowsx.h"
+#include "vfw.h"
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(avifile);
+
+/* reads a chunk outof the extrachunk-structure */
+HRESULT ReadExtraChunk(LPEXTRACHUNKS extra,FOURCC ckid,LPVOID lpData,
+		       LPLONG size)
+{
+  LPBYTE lp;
+  LONG   cb;
+
+  /* pre-conditions */
+  assert(extra != NULL);
+  assert(size != NULL);
+
+  lp = extra->lp;
+  cb = extra->cb;
+
+  if (lp != NULL) {
+    while (cb > 0) {
+      if (((FOURCC*)lp)[0] == ckid) {
+	/* found correct chunk */
+	if (lpData != NULL && *size > 0)
+	  memcpy(lpData, lp + 2 * sizeof(DWORD), min(((LPDWORD)lp)[1],*size));
+
+	*size = ((LPDWORD)lp)[1];
+
+	return AVIERR_OK;
+      } else {
+	/* skip to next chunk */
+	cb -= ((LPDWORD)lp)[1] + 2 * sizeof(DWORD);
+	lp += ((LPDWORD)lp)[1] + 2 * sizeof(DWORD);
+      }
+    }
+  }
+
+  /* wanted chunk doesn't exist */
+  *size = 0;
+
+  return AVIERR_NODATA;
+}
+
+/* writes a chunk into the extrachunk-structure */
+HRESULT WriteExtraChunk(LPEXTRACHUNKS extra,FOURCC ckid,LPVOID lpData,
+			LONG size)
+{
+  LPDWORD lp;
+
+  /* pre-conditions */
+  assert(extra != NULL);
+  assert(lpData != NULL);
+  assert(size > 0);
+
+  if (extra->lp)
+    lp = (LPDWORD)GlobalReAllocPtr(extra->lp, extra->cb + size + 2 * sizeof(DWORD), GHND);
+  else
+    lp = (LPDWORD)GlobalAllocPtr(GHND, size + 2 * sizeof(DWORD));
+
+  if (lp == NULL)
+    return AVIERR_MEMORY;
+
+  extra->lp  = lp;
+  ((LPBYTE)lp) += extra->cb;
+  extra->cb += size + 2 * sizeof(DWORD);
+
+  /* insert chunk-header in block */
+  lp[0] = ckid;
+  lp[1] = size;
+
+  if (lpData != NULL && size > 0)
+    memcpy(lp + 2, lpData, size);
+
+  return AVIERR_OK;
+}
+
+/* reads a chunk fomr the HMMIO into the extrachunk-structure */
+HRESULT ReadChunkIntoExtra(LPEXTRACHUNKS extra,HMMIO hmmio,MMCKINFO *lpck)
+{
+  LPDWORD lp;
+  LONG    cb;
+
+  /* pre-conditions */
+  assert(extra != NULL);
+  assert(hmmio != (HMMIO)NULL);
+  assert(lpck  != NULL);
+
+  cb  = lpck->cksize + 2 * sizeof(DWORD);
+  cb += (cb & 1);
+
+  if (extra->lp != NULL) {
+    lp = (LPDWORD)GlobalReAllocPtr(extra->lp, extra->cb + cb, GHND);
+  } else
+    lp = (LPDWORD)GlobalAllocPtr(GHND, cb);
+
+  if (lp == NULL)
+    return AVIERR_MEMORY;
+
+  extra->lp  = lp;
+  ((LPBYTE)lp) += extra->cb;
+  extra->cb += cb;
+
+  /* insert chunk-header in block */
+  lp[0] = lpck->ckid;
+  lp[1] = lpck->cksize;
+
+  if (lpck->cksize > 0) {
+    if (mmioSeek(hmmio, lpck->dwDataOffset, SEEK_SET) == -1)
+      return AVIERR_FILEREAD;
+    if (mmioRead(hmmio, (HPSTR)&lp[2], lpck->cksize) != lpck->cksize)
+      return AVIERR_FILEREAD;
+  }
+
+  return AVIERR_OK;
+}
+
+/* reads all non-junk chunks into the extrachunk-structure until it founds
+ * the given chunk or the optional parent-chunk is at the end */
+HRESULT FindChunkAndKeepExtras(LPEXTRACHUNKS extra,HMMIO hmmio,MMCKINFO *lpck,
+			       MMCKINFO *lpckParent,UINT flags)
+{
+  FOURCC  ckid;
+  FOURCC  fccType;
+  HRESULT hr;
+
+  /* pre-conditions */
+  assert(extra != NULL);
+  assert(hmmio != (HMMIO)NULL);
+  assert(lpck  != NULL);
+
+  TRACE("({%p,%lu},%d,%p,%p,0x%X)\n", extra->lp, extra->cb, hmmio, lpck,
+	lpckParent, flags);
+
+  /* what chunk id and form/list type shoiuld we search? */
+  if (flags & MMIO_FINDCHUNK) {
+    ckid    = lpck->ckid;
+    fccType = 0;
+  } else if (flags & MMIO_FINDLIST) {
+    ckid    = FOURCC_LIST;
+    fccType = lpck->fccType;
+  } else if (flags & MMIO_FINDRIFF) {
+    ckid    = FOURCC_RIFF;
+    fccType = lpck->fccType;
+  } else
+    ckid = fccType = (FOURCC)-1; /* collect everything into extra! */
+
+  TRACE(": find ckid=0x%08lX fccType=0x%08lX\n", ckid, fccType);
+
+  for (;;) {
+    hr = mmioDescend(hmmio, lpck, lpckParent, 0);
+    if (hr != S_OK) {
+      /* No extra chunks infront of desired chunk? */
+      if (flags == 0 && hr == MMIOERR_CHUNKNOTFOUND)
+	hr = AVIERR_OK;
+      return hr;
+    }
+
+    /* Have we found what we search for? */
+    if ((lpck->ckid == ckid) &&
+	(fccType == (FOURCC)0 || lpck->fccType == fccType))
+      return AVIERR_OK;
+
+    /* Skip padding chunks, the others put into the extrachunk-structure */
+    if (lpck->ckid == ckidAVIPADDING ||
+	lpck->ckid == mmioFOURCC('p','a','d','d'))
+      hr = mmioAscend(hmmio, lpck, 0);
+    else
+      hr = ReadChunkIntoExtra(extra, hmmio, lpck);
+    if (FAILED(hr))
+      return hr;
+  }
+}
--- /dev/null	Sat Feb 23 16:05:24 2002
+++ dlls/avifil32/extrachunk.h	Fri Oct 11 23:36:55 2002
@@ -0,0 +1,52 @@
+/*
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __WINE_EXTRACHUNK_H
+#define __WINE_EXTRACHUNK_H
+
+#include "windef.h"
+#include "mmsystem.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _EXTRACHUNKS {
+  LPVOID lp;
+  DWORD  cb;
+} EXTRACHUNKS, *LPEXTRACHUNKS;
+
+/* reads a chunk outof the extrachunk-structure */
+HRESULT ReadExtraChunk(LPEXTRACHUNKS extra,FOURCC ckid,LPVOID lp,LPLONG size);
+
+/* writes a chunk into the extrachunk-structure */
+HRESULT WriteExtraChunk(LPEXTRACHUNKS extra,FOURCC ckid,LPVOID lp,LONG size);
+
+/* reads a chunk fomr the HMMIO into the extrachunk-structure */
+HRESULT ReadChunkIntoExtra(LPEXTRACHUNKS extra,HMMIO hmmio,MMCKINFO *lpck);
+
+/* reads all non-junk chunks into the extrachunk-structure until it founds
+ * the given chunk or the optional parent-chunk is at the end */
+HRESULT FindChunkAndKeepExtras(LPEXTRACHUNKS extra,HMMIO hmmio,
+			       MMCKINFO *lpck,MMCKINFO *lpckParent,UINT flags);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null	Sat Feb 23 16:05:24 2002
+++ dlls/avifil32/rsrc.rc	Fri Oct 11 21:13:40 2002
@@ -0,0 +1,46 @@
+/*
+ * Top level resource file for avifil32.dll
+ *
+ */
+
+#include "windef.h"
+#include "winuser.h"
+#include "winver.h"
+#include "avifile_private.h"
+
+LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
+
+1 VERSIONINFO
+FILEVERSION	4, 3, 0, 1998
+PRODUCTVERSION	4, 3, 0, 1998
+FILEFLAGSMASK	VS_FFI_FILEFLAGSMASK
+#ifdef NDEBUG
+FILEFLAGS	0
+#else
+FILEFLAGS	VS_FF_DEBUG
+#endif
+FILEOS		VOS_DOS_WINDOWS32
+FILETYPE	VFT_DLL
+{
+  BLOCK "StringFileInfo"
+  {
+    BLOCK "040604B0" /* Deutschland (Standard) */
+    {
+      VALUE "CompanyName", "Wine Developer Team\000"
+      VALUE "FileDescription", "Wine Bibliothek zur Unterstützung von AVI-Dateien\000"
+      VALUE "FileVersion", "4.03.1998\000"
+      VALUE "InternalName", "AVIFIL32\000"
+      VALUE "LegalCopyright", "Copyright \251 Michael Günnewig 2002\000"
+      VALUE "OriginalFileName", "AVIFIL32.DLL\000"
+      VALUE "ProductName", "Wine\000"
+      VALUE "ProductVersion", "1.00\000"
+    }
+  }
+}
+
+/*
+ * Everything specific to any language goes
+ * in one of the specific files.
+ */
+#include "avifile_De.rc"
+#include "avifile_En.rc"
--- /dev/null	Sat Feb 23 16:05:24 2002
+++ dlls/avifil32/avifile_De.rc	Fri Oct 11 21:13:49 2002
@@ -0,0 +1,12 @@
+LANGUAGE LANG_GERMAN, SUBLANG_GERMAN
+
+STRINGTABLE DISCARDABLE
+{
+  IDS_WAVESTREAMFORMAT	"Waveform: %s"
+  IDS_WAVEFILETYPE	"Waveform"
+  IDS_VIDEO		"Video"
+  IDS_AUDIO		"Audio"
+  IDS_AVISTREAMFORMAT	"%s %s #%d"
+  IDS_AVIFILETYPE	"Wine AVI-Standard-Dateibehandlungsroutine"
+  IDS_UNCOMPRESSED      "Unkomprimiert"
+}
--- /dev/null	Sat Feb 23 16:05:24 2002
+++ dlls/avifil32/avifile_En.rc	Fri Oct 11 21:30:16 2002
@@ -0,0 +1,12 @@
+LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
+
+STRINGTABLE DISCARDABLE
+{
+  IDS_WAVESTREAMFORMAT	"Waveform: %s"
+  IDS_WAVEFILETYPE	"Waveform"
+  IDS_VIDEO		"video"
+  IDS_AUDIO		"audio"
+  IDS_AVISTREAMFORMAT	"%s %s #%d"
+  IDS_AVIFILETYPE	"Wine AVI-default-filehandler"
+  IDS_UNCOMPRESSED      "uncompressed"
+}


  Michael Günnewig

[Index of Archives]     [Gimp for Windows]     [Red Hat]     [Samba]     [Yosemite Camping]     [Graphics Cards]     [Wine Home]

  Powered by Linux