[2/2] msrle32: Add support to decompress uncompressed frames
Bruno Jesus
00cpxxx at gmail.com
Thu Nov 5 07:01:39 CST 2015
Signed-off-by: Bruno Jesus <00cpxxx at gmail.com>
Required to decompress Starship Titanic (game) mouse cursors which are
stored in an uncompressed AVI file.
The patch is not big, the problem is a long shift of lines. Also it
touches 2 DLLs otherwise msvfw32 would stop working.
-------------- next part --------------
---
dlls/msrle32/msrle32.c | 98 +++++++++++++++++++++++++---------------------
dlls/msrle32/tests/msrle.c | 3 +-
dlls/msvfw32/tests/msvfw.c | 2 +-
3 files changed, 56 insertions(+), 47 deletions(-)
diff --git a/dlls/msrle32/msrle32.c b/dlls/msrle32/msrle32.c
index bd02ae6..2682812 100644
--- a/dlls/msrle32/msrle32.c
+++ b/dlls/msrle32/msrle32.c
@@ -1596,7 +1596,7 @@ static LRESULT DecompressQuery(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn,
/* check input format if given */
if (lpbiIn != NULL) {
- if (!isSupportedMRLE(lpbiIn))
+ if (!isSupportedMRLE(lpbiIn) && !isSupportedDIB(lpbiIn))
return ICERR_BADFORMAT;
}
@@ -1607,11 +1607,11 @@ static LRESULT DecompressQuery(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn,
if (lpbiIn != NULL) {
if (lpbiIn->biWidth != lpbiOut->biWidth)
- hr = ICERR_UNSUPPORTED;
+ hr = ICERR_UNSUPPORTED;
if (lpbiIn->biHeight != lpbiOut->biHeight)
- hr = ICERR_UNSUPPORTED;
+ hr = ICERR_UNSUPPORTED;
if (lpbiIn->biBitCount > lpbiOut->biBitCount)
- hr = ICERR_UNSUPPORTED;
+ hr = ICERR_UNSUPPORTED;
}
}
@@ -1645,49 +1645,51 @@ static LRESULT DecompressBegin(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn,
if (pi->bDecompress)
DecompressEnd(pi);
- rgbIn = (const RGBQUAD*)((const BYTE*)lpbiIn + lpbiIn->biSize);
- rgbOut = (const RGBQUAD*)((const BYTE*)lpbiOut + lpbiOut->biSize);
-
- switch (lpbiOut->biBitCount) {
- case 4:
- case 8:
- pi->palette_map = LocalAlloc(LPTR, lpbiIn->biClrUsed);
- if (pi->palette_map == NULL)
- return ICERR_MEMORY;
-
- for (i = 0; i < lpbiIn->biClrUsed; i++) {
- pi->palette_map[i] = MSRLE32_GetNearestPaletteIndex(lpbiOut->biClrUsed, rgbOut, rgbIn[i]);
- }
- break;
- case 15:
- case 16:
- pi->palette_map = LocalAlloc(LPTR, lpbiIn->biClrUsed * 2);
- if (pi->palette_map == NULL)
- return ICERR_MEMORY;
-
- for (i = 0; i < lpbiIn->biClrUsed; i++) {
- WORD color;
+ if (lpbiIn->biCompression != BI_RGB)
+ {
+ rgbIn = (const RGBQUAD*)((const BYTE*)lpbiIn + lpbiIn->biSize);
+ rgbOut = (const RGBQUAD*)((const BYTE*)lpbiOut + lpbiOut->biSize);
- if (lpbiOut->biBitCount == 15)
- color = ((rgbIn[i].rgbRed >> 3) << 10)
- | ((rgbIn[i].rgbGreen >> 3) << 5) | (rgbIn[i].rgbBlue >> 3);
- else
- color = ((rgbIn[i].rgbRed >> 3) << 11)
- | ((rgbIn[i].rgbGreen >> 3) << 5) | (rgbIn[i].rgbBlue >> 3);
+ switch (lpbiOut->biBitCount) {
+ case 4:
+ case 8:
+ pi->palette_map = LocalAlloc(LPTR, lpbiIn->biClrUsed);
+ if (pi->palette_map == NULL)
+ return ICERR_MEMORY;
- pi->palette_map[i * 2 + 1] = color >> 8;
- pi->palette_map[i * 2 + 0] = color & 0xFF;
+ for (i = 0; i < lpbiIn->biClrUsed; i++) {
+ pi->palette_map[i] = MSRLE32_GetNearestPaletteIndex(lpbiOut->biClrUsed, rgbOut, rgbIn[i]);
+ }
+ break;
+ case 15:
+ case 16:
+ pi->palette_map = LocalAlloc(LPTR, lpbiIn->biClrUsed * 2);
+ if (pi->palette_map == NULL)
+ return ICERR_MEMORY;
+
+ for (i = 0; i < lpbiIn->biClrUsed; i++) {
+ WORD color;
+
+ if (lpbiOut->biBitCount == 15)
+ color = ((rgbIn[i].rgbRed >> 3) << 10)
+ | ((rgbIn[i].rgbGreen >> 3) << 5) | (rgbIn[i].rgbBlue >> 3);
+ else
+ color = ((rgbIn[i].rgbRed >> 3) << 11)
+ | ((rgbIn[i].rgbGreen >> 3) << 5) | (rgbIn[i].rgbBlue >> 3);
+
+ pi->palette_map[i * 2 + 1] = color >> 8;
+ pi->palette_map[i * 2 + 0] = color & 0xFF;
+ };
+ break;
+ case 24:
+ case 32:
+ pi->palette_map = LocalAlloc(LPTR, lpbiIn->biClrUsed * sizeof(RGBQUAD));
+ if (pi->palette_map == NULL)
+ return ICERR_MEMORY;
+ memcpy(pi->palette_map, rgbIn, lpbiIn->biClrUsed * sizeof(RGBQUAD));
+ break;
};
- break;
- case 24:
- case 32:
- pi->palette_map = LocalAlloc(LPTR, lpbiIn->biClrUsed * sizeof(RGBQUAD));
- if (pi->palette_map == NULL)
- return ICERR_MEMORY;
- memcpy(pi->palette_map, rgbIn, lpbiIn->biClrUsed * sizeof(RGBQUAD));
- break;
- };
-
+ }
pi->bDecompress = TRUE;
return ICERR_OK;
@@ -1718,6 +1720,14 @@ static LRESULT Decompress(CodecInfo *pi, ICDECOMPRESS *pic, DWORD dwSize)
assert(pic->lpbiInput->biWidth == pic->lpbiOutput->biWidth);
assert(pic->lpbiInput->biHeight == pic->lpbiOutput->biHeight);
+ /* Uncompressed frame? */
+ if (pic->lpbiInput->biCompression == BI_RGB)
+ {
+ pic->lpbiOutput->biSizeImage = pic->lpbiInput->biSizeImage;
+ memcpy(pic->lpOutput, pic->lpInput, pic->lpbiOutput->biSizeImage);
+ return ICERR_OK;
+ }
+
pic->lpbiOutput->biSizeImage = DIBWIDTHBYTES(*pic->lpbiOutput) * pic->lpbiOutput->biHeight;
if (pic->lpbiInput->biBitCount == 4)
return MSRLE32_DecompressRLE4(pi, pic->lpbiOutput, pic->lpInput, pic->lpOutput);
diff --git a/dlls/msrle32/tests/msrle.c b/dlls/msrle32/tests/msrle.c
index 654a38e..38e74a6 100644
--- a/dlls/msrle32/tests/msrle.c
+++ b/dlls/msrle32/tests/msrle.c
@@ -132,7 +132,7 @@ static void test_raw_decompress(void)
for (i = 0; i < sizeof(codecs) / sizeof(codecs[0]); i++)
{
memset(bits, i + 0xAF, bih->biSizeImage);
-todo_wine {
+
/* Check which codec is able to decompress uncompressed data */
hic = ICLocate(FCC('V', 'I', 'D', 'C'), codecs[i], bih, NULL, ICMODE_DECOMPRESS);
ok(hic != NULL, "Test[%d]: Expected non-NULL return\n", i);
@@ -154,7 +154,6 @@ todo_wine {
hr = ICClose(hic);
ok(hr == ICERR_OK, "Test[%d]: Expected ICERR_OK, got %d\n", i, hr);
-}
}
HeapFree(GetProcessHeap(), 0, bits);
HeapFree(GetProcessHeap(), 0, outbits);
diff --git a/dlls/msvfw32/tests/msvfw.c b/dlls/msvfw32/tests/msvfw.c
index b3e7b19..125cac5 100644
--- a/dlls/msvfw32/tests/msvfw.c
+++ b/dlls/msvfw32/tests/msvfw.c
@@ -212,7 +212,7 @@ static void test_Locate(void)
bi.biCompression = BI_RGB;
bo.biBitCount = bi.biBitCount = 8;
h = ICLocate(ICTYPE_VIDEO, 0, &bi, &bo, ICMODE_DECOMPRESS);
- todo_wine ok(h != 0, "RGB8->RGB identity failed\n");
+ ok(h != 0, "RGB8->RGB identity failed\n");
if (h) ok(ICClose(h) == ICERR_OK,"ICClose failed\n");
bi.biCompression = BI_RLE8;
--
2.1.4
More information about the wine-patches
mailing list