[MSADP32.ACM] Sync with Wine Staging 4.0. CORE-15682
[reactos.git] / dll / win32 / msadp32.acm / msadp32.c
index 435b34f..78d99a2 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-#define WIN32_NO_STATUS
-
 #include <assert.h>
 #include <stdarg.h>
-//#include <string.h>
-#include <windef.h>
-#include <winbase.h>
-#include <wingdi.h>
-#include <winuser.h>
-#include <winnls.h>
-//#include "mmsystem.h"
-//#include "mmreg.h"
-//#include "msacm.h"
-#include <msacmdrv.h>
-#include <wine/debug.h>
+#include <string.h>
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "winnls.h"
+#include "mmsystem.h"
+#include "mmreg.h"
+#include "msacm.h"
+#include "msacmdrv.h"
+#include "wine/debug.h"
 
 /* see http://www.pcisys.net/~melanson/codecs/adpcm.txt for the details */
 
@@ -85,9 +83,6 @@ static const Format ADPCM_Formats[] =
     {1,  4, 22050}, {2,        4, 22050},  {1,  4, 44100}, {2,  4, 44100},
 };
 
-#define        NUM_PCM_FORMATS         (sizeof(PCM_Formats) / sizeof(PCM_Formats[0]))
-#define        NUM_ADPCM_FORMATS       (sizeof(ADPCM_Formats) / sizeof(ADPCM_Formats[0]))
-
 static int MS_Delta[] =
 {
     230, 230, 230, 230, 307, 409, 512, 614,
@@ -111,11 +106,11 @@ static    DWORD   ADPCM_GetFormatIndex(const WAVEFORMATEX* wfx)
     switch (wfx->wFormatTag)
     {
     case WAVE_FORMAT_PCM:
-       hi = NUM_PCM_FORMATS;
+       hi = ARRAY_SIZE(PCM_Formats);
        fmts = PCM_Formats;
        break;
     case WAVE_FORMAT_ADPCM:
-       hi = NUM_ADPCM_FORMATS;
+       hi = ARRAY_SIZE(ADPCM_Formats);
        fmts = ADPCM_Formats;
        break;
     default:
@@ -251,9 +246,17 @@ static     void cvtSSms16K(const ACMDRVSTREAMINSTANCE *adsi,
     {
         const unsigned char*    in_src = src;
 
-        assert(*src <= 6);
+        /* Catch a problem from Tomb Raider III (bug 21000) where it passes
+         * invalid data after a valid sequence of blocks */
+        if (*src > 6 || *(src + 1) > 6)
+        {
+            /* Recalculate the amount of used output buffer. We are not changing
+             * nsrc, let's assume the bad data was parsed */
+            *ndst -= nblock * nsamp_blk * adsi->pwfxDst->nBlockAlign;
+            WARN("Invalid ADPCM data, stopping conversion\n");
+            break;
+        }
         coeffL = MSADPCM_CoeffSet[*src++];
-        assert(*src <= 6);
         coeffR = MSADPCM_CoeffSet[*src++];
 
         ideltaL  = R16(src);    src += 2;
@@ -374,8 +377,8 @@ static      LRESULT ADPCM_DriverDetails(PACMDRIVERDETAILSW add)
 {
     add->fccType = ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC;
     add->fccComp = ACMDRIVERDETAILS_FCCCOMP_UNDEFINED;
-    add->wMid = 0xFF;
-    add->wPid = 0x00;
+    add->wMid = MM_MICROSOFT;
+    add->wPid = MM_MSFT_ACM_MSADPCM;
     add->vdwACM = 0x01000000;
     add->vdwDriver = 0x01000000;
     add->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
@@ -383,13 +386,13 @@ static    LRESULT ADPCM_DriverDetails(PACMDRIVERDETAILSW add)
     add->cFilterTags = 0;
     add->hicon = NULL;
     MultiByteToWideChar( CP_ACP, 0, "MS-ADPCM", -1,
-                         add->szShortName, sizeof(add->szShortName)/sizeof(WCHAR) );
+                         add->szShortName, ARRAY_SIZE( add->szShortName ));
     MultiByteToWideChar( CP_ACP, 0, "Wine MS ADPCM converter", -1,
-                         add->szLongName, sizeof(add->szLongName)/sizeof(WCHAR) );
+                         add->szLongName, ARRAY_SIZE( add->szLongName ));
     MultiByteToWideChar( CP_ACP, 0, "Brought to you by the Wine team...", -1,
-                         add->szCopyright, sizeof(add->szCopyright)/sizeof(WCHAR) );
+                         add->szCopyright, ARRAY_SIZE( add->szCopyright ));
     MultiByteToWideChar( CP_ACP, 0, "Refer to LICENSE file", -1,
-                         add->szLicensing, sizeof(add->szLicensing)/sizeof(WCHAR) );
+                         add->szLicensing, ARRAY_SIZE( add->szLicensing ));
     add->szFeatures[0] = 0;
 
     return MMSYSERR_NOERROR;
@@ -435,13 +438,13 @@ static    LRESULT ADPCM_FormatTagDetails(PACMFORMATTAGDETAILSW aftd, DWORD dwQuery)
     case 0:
        aftd->dwFormatTag = WAVE_FORMAT_PCM;
        aftd->cbFormatSize = sizeof(PCMWAVEFORMAT);
-       aftd->cStandardFormats = NUM_PCM_FORMATS;
+       aftd->cStandardFormats = ARRAY_SIZE(PCM_Formats);
         lstrcpyW(aftd->szFormatTag, szPcm);
         break;
     case 1:
        aftd->dwFormatTag = WAVE_FORMAT_ADPCM;
        aftd->cbFormatSize = sizeof(ADPCMWAVEFORMAT) + (7 - 1) * sizeof(ADPCMCOEFSET);
-       aftd->cStandardFormats = NUM_ADPCM_FORMATS;
+       aftd->cStandardFormats = ARRAY_SIZE(ADPCM_Formats);
         lstrcpyW(aftd->szFormatTag, szMsAdPcm);
        break;
     }
@@ -464,7 +467,7 @@ static      LRESULT ADPCM_FormatDetails(PACMFORMATDETAILSW afd, DWORD dwQuery)
        switch (afd->dwFormatTag)
         {
        case WAVE_FORMAT_PCM:
-           if (afd->dwFormatIndex >= NUM_PCM_FORMATS) return ACMERR_NOTPOSSIBLE;
+           if (afd->dwFormatIndex >= ARRAY_SIZE(PCM_Formats)) return ACMERR_NOTPOSSIBLE;
            afd->pwfx->nChannels = PCM_Formats[afd->dwFormatIndex].nChannels;
            afd->pwfx->nSamplesPerSec = PCM_Formats[afd->dwFormatIndex].rate;
            afd->pwfx->wBitsPerSample = PCM_Formats[afd->dwFormatIndex].nBits;
@@ -477,7 +480,7 @@ static      LRESULT ADPCM_FormatDetails(PACMFORMATDETAILSW afd, DWORD dwQuery)
                afd->pwfx->nSamplesPerSec * afd->pwfx->nBlockAlign;
            break;
        case WAVE_FORMAT_ADPCM:
-           if (afd->dwFormatIndex >= NUM_ADPCM_FORMATS) return ACMERR_NOTPOSSIBLE;
+           if (afd->dwFormatIndex >= ARRAY_SIZE(ADPCM_Formats)) return ACMERR_NOTPOSSIBLE;
             if (afd->cbwfx < sizeof(ADPCMWAVEFORMAT) + (7 - 1) * sizeof(ADPCMCOEFSET))
                 return ACMERR_NOTPOSSIBLE;
            afd->pwfx->nChannels = ADPCM_Formats[afd->dwFormatIndex].nChannels;
@@ -544,6 +547,8 @@ static      LRESULT ADPCM_FormatSuggest(PACMDRVFORMATSUGGEST adfs)
         if (ADPCM_GetFormatIndex(adfs->pwfxDst) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE;
         break;
     case WAVE_FORMAT_ADPCM:
+        if (adfs->cbwfxDst < sizeof(ADPCMWAVEFORMAT) + (7 - 1) * sizeof(ADPCMCOEFSET))
+            return ACMERR_NOTPOSSIBLE;
         init_wfx_adpcm((ADPCMWAVEFORMAT*)adfs->pwfxDst);
         /* check if result is ok */
         if (ADPCM_GetFormatIndex(adfs->pwfxDst) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE;