dlls/avifil32: Bug fixes, saving of wave files

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

 



Hallo.

The following patch fixes the following issues:

dlls/avifil32/avifile.c:
- very slow loading of index

dlls/avifil32/wavfile.c:
- Fixed loading of wave files.
- Corrected AVIFILEINFOW structure updates.
- Implemented saving of wave files.

diff -dur wine-old/dlls/Makefile.in wine/dlls/Makefile.in
--- wine-old/dlls/Makefile.in	Fri Oct 18 15:55:43 2002
+++ wine/dlls/Makefile.in	Fri Oct 18 15:38:57 2002
@@ -763,8 +763,8 @@
 
 advapi32: kernel32.dll$(DLLEXT) ntdll.dll$(DLLEXT)
 avicap32: ntdll.dll$(DLLEXT)
-avifil32: msvfw32.dll$(DLLEXT) shell32.dll$(DLLEXT) winmm.dll$(DLLEXT) user32.dll$(DLLEXT) \
-          advapi32.dll$(DLLEXT) kernel32.dll$(DLLEXT)
+avifil32: msacm32.dll$(DLLEXT) msvfw32.dll$(DLLEXT) shell32.dll$(DLLEXT) \
+	  winmm.dll$(DLLEXT) user32.dll$(DLLEXT) advapi32.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)
diff -dur wine-old/dlls/avifil32/Makefile.in wine/dlls/avifil32/Makefile.in
--- wine-old/dlls/avifil32/Makefile.in	Fri Oct 18 15:55:00 2002
+++ wine/dlls/avifil32/Makefile.in	Fri Oct 18 15:50:50 2002
@@ -3,7 +3,7 @@
 SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 MODULE    = avifil32.dll
-IMPORTS   = msvfw32 shell32 winmm user32 advapi32 kernel32
+IMPORTS   = msacm32 msvfw32 shell32 winmm user32 advapi32 kernel32
 ALTNAMES  = avifile.dll
 EXTRALIBS = $(LIBUUID)
 
diff -dur wine-old/dlls/avifil32/avifile.c wine/dlls/avifil32/avifile.c
--- wine-old/dlls/avifil32/avifile.c	Fri Oct 18 15:55:00 2002
+++ wine/dlls/avifil32/avifile.c	Fri Oct 18 15:54:00 2002
@@ -1348,7 +1348,7 @@
     This->sInfo.dwSuggestedBufferSize = size;
 
   /* get memory for index */
-  if (This->idxFrames == NULL || This->dwLastFrame + 1 < This->nIdxFrames) {
+  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)
@@ -1812,7 +1812,7 @@
 
     if (pStream->sInfo.dwSampleSize != 0) {
       if (n > 0 && This->fInfo.dwFlags & AVIFILEINFO_ISINTERLEAVED) {
-	pStream->nIdxFrames = pStream->nIdxFrames;
+	pStream->nIdxFrames = This->ppStreams[0]->nIdxFrames;
       } else if (pStream->sInfo.dwSuggestedBufferSize) {
 	pStream->nIdxFrames =
 	  pStream->sInfo.dwLength / pStream->sInfo.dwSuggestedBufferSize;
diff -dur wine-old/dlls/avifil32/wavfile.c wine/dlls/avifil32/wavfile.c
--- wine-old/dlls/avifil32/wavfile.c	Fri Oct 18 15:55:00 2002
+++ wine/dlls/avifil32/wavfile.c	Fri Oct 18 15:44:17 2002
@@ -25,6 +25,7 @@
 #include "windowsx.h"
 #include "mmsystem.h"
 #include "vfw.h"
+#include "msacm.h"
 
 #include "avifile_private.h"
 #include "extrachunk.h"
@@ -285,11 +286,15 @@
   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(size, sizeof(This->fInfo)));
@@ -1000,6 +1005,7 @@
   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);
   }
@@ -1010,7 +1016,7 @@
   /* search WAVE format chunk */
   ck.ckid = ckidWAVEFORMAT;
   if (FindChunkAndKeepExtras(&This->extra, This->hmmio, &ck,
-			     &ckRIFF, MMIO_FINDCHUNK != S_OK))
+			     &ckRIFF, MMIO_FINDCHUNK) != S_OK)
     return AVIERR_FILEREAD;
 
   /* get memory for format and read it */
@@ -1024,14 +1030,9 @@
   if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
     return AVIERR_FILEREAD;
 
-  /* non-pcm formats have a fact chunk */
-  if (This->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
-    ck.ckid = ckidWAVEFACT;
-    if (mmioDescend(This->hmmio, &ck, NULL, MMIO_FINDCHUNK) != S_OK) {
-      /* FIXME: if codec is installed could ask him */
-      return AVIERR_BADFORMAT;
-    }
-  }
+  /* 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;
@@ -1047,6 +1048,8 @@
   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");
@@ -1064,12 +1067,109 @@
 
 static HRESULT AVIFILE_LoadSunFile(IAVIFileImpl *This)
 {
-  FIXME(": pherhpas sun-audio file -- not implemented !\n");
+  FIXME(": pherhaps sun-audio file -- not implemented !\n");
 
   return AVIERR_UNSUPPORTED;
 }
 
 static HRESULT AVIFILE_SaveFile(IAVIFileImpl *This)
 {
-  return AVIERR_UNSUPPORTED;
+  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((HACMDRIVER)NULL, This->lpFormat, &wfx,
+			 sizeof(wfx), ACM_FORMATSUGGESTF_WFORMATTAG)) {
+      acmStreamOpen(&has, (HACMDRIVER)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);
+
+      /* crete 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 here 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;
+  }
+
+  /* crete 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;
 }


  Michael Günnewig

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

  Powered by Linux