You've already forked wine-staging
mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-09-12 18:50:20 -07:00
msvfw32-ICGetDisplayFormat: Added various fixes for stride handling.
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
From 6c25d94295130d7ab3e07dd985311520d303aad2 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
|
||||
Date: Sun, 3 Apr 2016 17:47:43 +0200
|
||||
Subject: msvfw32: Take stride into account and ask for palette in
|
||||
ICGetDisplayFormat.
|
||||
|
||||
---
|
||||
dlls/msvfw32/msvideo_main.c | 15 ++++++++++++---
|
||||
dlls/msvfw32/tests/msvfw.c | 45 ++++++++++++++++++++++++++++++++++++++-------
|
||||
2 files changed, 50 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/dlls/msvfw32/msvideo_main.c b/dlls/msvfw32/msvideo_main.c
|
||||
index 6f91859..e3a7719 100644
|
||||
--- a/dlls/msvfw32/msvideo_main.c
|
||||
+++ b/dlls/msvfw32/msvideo_main.c
|
||||
@@ -98,6 +98,11 @@ static const char *wine_dbgstr_icerr( int ret )
|
||||
return str;
|
||||
}
|
||||
|
||||
+static inline int get_stride(int width, int depth)
|
||||
+{
|
||||
+ return ((depth * width + 31) >> 3) & ~3;
|
||||
+}
|
||||
+
|
||||
static WINE_HIC* MSVIDEO_FirstHic /* = NULL */;
|
||||
|
||||
typedef struct _reg_driver reg_driver;
|
||||
@@ -770,23 +775,27 @@ HIC VFWAPI ICGetDisplayFormat(
|
||||
found = TRUE;
|
||||
lpbiOut->biBitCount = try_depths[i].depth;
|
||||
lpbiOut->biCompression = try_depths[i].compression;
|
||||
- lpbiOut->biSizeImage = dx * dy * lpbiOut->biBitCount / 8;
|
||||
+ lpbiOut->biSizeImage = dx * get_stride(dy, lpbiOut->biBitCount);
|
||||
|
||||
if (ICDecompressQuery(tmphic, lpbiIn, lpbiOut) == ICERR_OK)
|
||||
+ {
|
||||
+ if (try_depths[i].depth == 8)
|
||||
+ ICDecompressGetPalette(tmphic, lpbiIn, lpbiOut);
|
||||
goto success;
|
||||
+ }
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
lpbiOut->biBitCount = depth;
|
||||
lpbiOut->biCompression = BI_RGB;
|
||||
- lpbiOut->biSizeImage = (dx * dy * depth) / 8;
|
||||
+ lpbiOut->biSizeImage = dx * get_stride(dy, lpbiOut->biBitCount);
|
||||
if (ICDecompressQuery(tmphic, lpbiIn, lpbiOut) == ICERR_OK)
|
||||
goto success;
|
||||
|
||||
lpbiOut->biBitCount = screen_depth;
|
||||
lpbiOut->biCompression = BI_RGB;
|
||||
- lpbiOut->biSizeImage = dx * dy * screen_depth / 8;
|
||||
+ lpbiOut->biSizeImage = dx * get_stride(dy, lpbiOut->biBitCount);
|
||||
if (ICDecompressQuery(tmphic, lpbiIn, lpbiOut) == ICERR_OK)
|
||||
goto success;
|
||||
}
|
||||
diff --git a/dlls/msvfw32/tests/msvfw.c b/dlls/msvfw32/tests/msvfw.c
|
||||
index 252aba2..91628e2 100644
|
||||
--- a/dlls/msvfw32/tests/msvfw.c
|
||||
+++ b/dlls/msvfw32/tests/msvfw.c
|
||||
@@ -25,6 +25,11 @@
|
||||
|
||||
#include "wine/test.h"
|
||||
|
||||
+static inline int get_stride(int width, int depth)
|
||||
+{
|
||||
+ return ((depth * width + 31) >> 3) & ~3;
|
||||
+}
|
||||
+
|
||||
static void test_OpenCase(void)
|
||||
{
|
||||
HIC h;
|
||||
@@ -367,9 +372,30 @@ static struct msg_result expected_msgs[] =
|
||||
{40, ICM_DECOMPRESS_GET_FORMAT, TRUE, 320, 240, 16, BI_RGB, ICERR_OK, FALSE},
|
||||
{41, ICM_DECOMPRESS_QUERY, TRUE, 640, 480, 32, BI_RGB, ICERR_OK, FALSE},
|
||||
|
||||
+ /* test 11 */
|
||||
+ {42, ICM_DECOMPRESS_QUERY, FALSE, 0, 0, 0, 0, ICERR_OK, FALSE},
|
||||
+ {43, ICM_DECOMPRESS_GET_FORMAT, TRUE, 320, 240, 16, BI_RGB, ICERR_OK, FALSE},
|
||||
+ {44, ICM_DECOMPRESS_QUERY, TRUE, 270, 270, 8, BI_RGB, ICERR_OK, FALSE},
|
||||
+ {45, ICM_DECOMPRESS_GET_PALETTE, FALSE, 0, 0, 0, 0, ICERR_UNSUPPORTED, FALSE},
|
||||
+
|
||||
+ /* test 12 */
|
||||
+ {46, ICM_DECOMPRESS_QUERY, FALSE, 0, 0, 0, 0, ICERR_OK, FALSE},
|
||||
+ {47, ICM_DECOMPRESS_GET_FORMAT, TRUE, 320, 240, 16, BI_RGB, ICERR_OK, FALSE},
|
||||
+ {48, ICM_DECOMPRESS_QUERY, TRUE, 270, 270, 16, BI_RGB, ICERR_OK, FALSE},
|
||||
+
|
||||
+ /* test 13 */
|
||||
+ {49, ICM_DECOMPRESS_QUERY, FALSE, 0, 0, 0, 0, ICERR_OK, FALSE},
|
||||
+ {50, ICM_DECOMPRESS_GET_FORMAT, TRUE, 320, 240, 16, BI_RGB, ICERR_OK, FALSE},
|
||||
+ {51, ICM_DECOMPRESS_QUERY, TRUE, 270, 270, 24, BI_RGB, ICERR_OK, FALSE},
|
||||
+
|
||||
+ /* test 14 */
|
||||
+ {52, ICM_DECOMPRESS_QUERY, FALSE, 0, 0, 0, 0, ICERR_OK, FALSE},
|
||||
+ {53, ICM_DECOMPRESS_GET_FORMAT, TRUE, 320, 240, 16, BI_RGB, ICERR_OK, FALSE},
|
||||
+ {54, ICM_DECOMPRESS_QUERY, TRUE, 640, 480, 4, BI_RGB, ICERR_OK, FALSE},
|
||||
+
|
||||
/* Wine bug - shouldn't be called */
|
||||
- {42, DRV_DISABLE, FALSE, 0, 0, 0, 0, ICERR_OK, TRUE},
|
||||
- {42, DRV_FREE, FALSE, 0, 0, 0, 0, ICERR_OK, TRUE},
|
||||
+ {55, DRV_DISABLE, FALSE, 0, 0, 0, 0, ICERR_OK, TRUE},
|
||||
+ {55, DRV_FREE, FALSE, 0, 0, 0, 0, ICERR_OK, TRUE},
|
||||
};
|
||||
|
||||
static int msg_index = 0;
|
||||
@@ -429,8 +455,8 @@ LRESULT WINAPI driver_proc_test(DWORD_PTR dwDriverId, HDRVR hdrvr, UINT msg,
|
||||
"Expected biBitCount %d, got %d\n", expected->bits, out->biBitCount);
|
||||
ok(out->biCompression == expected->compression,
|
||||
"Expected compression %d, got %d\n", expected->compression, out->biCompression);
|
||||
- ok(out->biSizeImage == (out->biWidth * out->biHeight * out->biBitCount) / 8,
|
||||
- "Expected biSizeImage %d, got %d\n", (out->biWidth * out->biHeight * out->biBitCount) / 8,
|
||||
+ ok(out->biSizeImage == get_stride(out->biWidth, out->biBitCount) * out->biHeight,
|
||||
+ "Expected biSizeImage %d, got %d\n", get_stride(out->biWidth, out->biBitCount) * out->biHeight,
|
||||
out->biSizeImage);
|
||||
|
||||
trace("query -> width: %d, height: %d, bit: %d, compression: %d, size: %d\n",
|
||||
@@ -496,6 +522,10 @@ void test_ICGetDisplayFormat(void)
|
||||
{32, 32, 800, 800, 600, 600, 36},
|
||||
{32, 32, -1, 640, -1, 480, 39},
|
||||
{32, 32, -90, 640, -60, 480, 42},
|
||||
+ { 8, 8, 270, 270, 270, 270, 46},
|
||||
+ {16, 16, 270, 270, 270, 270, 49},
|
||||
+ {24, 24, 270, 270, 270, 270, 52},
|
||||
+ { 4, 4, 0, 640, 0, 480, 55},
|
||||
};
|
||||
|
||||
HIC ic, ic2;
|
||||
@@ -533,9 +563,10 @@ void test_ICGetDisplayFormat(void)
|
||||
"Expected biWidth %d, got %d\n", tests[i].width_expected, out.biWidth);
|
||||
ok(out.biHeight == tests[i].height_expected,
|
||||
"Expected biHeight %d, got %d\n", tests[i].height_expected, out.biHeight);
|
||||
- real_depth = (out.biBitCount > 32) ? 4 : out.biBitCount / 8;
|
||||
- ok(out.biSizeImage == out.biWidth * out.biHeight * real_depth,
|
||||
- "Expected biSizeImage %d, got %d\n", out.biWidth * out.biHeight * real_depth, out.biSizeImage);
|
||||
+ real_depth = (out.biBitCount > 32) ? 32 : out.biBitCount;
|
||||
+ ok(out.biSizeImage == get_stride(out.biWidth, real_depth) * out.biHeight,
|
||||
+ "Expected biSizeImage %d, got %d\n", get_stride(out.biWidth, real_depth) * out.biHeight,
|
||||
+ out.biSizeImage);
|
||||
ok(msg_index == tests[i].msg_index,
|
||||
"Expected msg_index %d, got %d\n", tests[i].msg_index, msg_index);
|
||||
}
|
||||
--
|
||||
2.7.1
|
||||
|
@@ -0,0 +1,107 @@
|
||||
From 855c99952103f3f76d2c38e1471570dee8dbf2c3 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
|
||||
Date: Sun, 3 Apr 2016 18:22:29 +0200
|
||||
Subject: iccvid: Fix calculation of stride and size.
|
||||
|
||||
---
|
||||
dlls/iccvid/iccvid.c | 10 +++++++---
|
||||
dlls/msvfw32/tests/msvfw.c | 40 ++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 47 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/dlls/iccvid/iccvid.c b/dlls/iccvid/iccvid.c
|
||||
index 1ef2db6..0531f31 100644
|
||||
--- a/dlls/iccvid/iccvid.c
|
||||
+++ b/dlls/iccvid/iccvid.c
|
||||
@@ -91,6 +91,10 @@ static inline BOOL heap_free( LPVOID ptr )
|
||||
return HeapFree( GetProcessHeap(), 0, ptr );
|
||||
}
|
||||
|
||||
+static inline int get_stride(int width, int depth)
|
||||
+{
|
||||
+ return ((depth * width + 31) >> 3) & ~3;
|
||||
+}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
static unsigned char *in_buffer, uiclip[1024], *uiclp = NULL;
|
||||
@@ -459,7 +463,7 @@ static void decode_cinepak(cinepak_info *cvinfo, unsigned char *buf, int size,
|
||||
break;
|
||||
}
|
||||
|
||||
- frm_stride = out_width * bpp;
|
||||
+ frm_stride = get_stride(out_width, bpp * 8);
|
||||
frm_ptr = output;
|
||||
|
||||
if(frame.length != size)
|
||||
@@ -844,9 +848,9 @@ static LRESULT ICCVID_DecompressGetFormat( ICCVID_Info *info, LPBITMAPINFO in, L
|
||||
if( out )
|
||||
{
|
||||
memcpy( out, in, size );
|
||||
+ out->bmiHeader.biBitCount = 24;
|
||||
out->bmiHeader.biCompression = BI_RGB;
|
||||
- out->bmiHeader.biSizeImage = in->bmiHeader.biHeight
|
||||
- * in->bmiHeader.biWidth *4;
|
||||
+ out->bmiHeader.biSizeImage = get_stride(in->bmiHeader.biWidth, 24) * in->bmiHeader.biHeight;
|
||||
return ICERR_OK;
|
||||
}
|
||||
return size;
|
||||
diff --git a/dlls/msvfw32/tests/msvfw.c b/dlls/msvfw32/tests/msvfw.c
|
||||
index 91628e2..7943184 100644
|
||||
--- a/dlls/msvfw32/tests/msvfw.c
|
||||
+++ b/dlls/msvfw32/tests/msvfw.c
|
||||
@@ -93,6 +93,7 @@ static void test_Locate(void)
|
||||
{
|
||||
static BITMAPINFOHEADER bi = {sizeof(BITMAPINFOHEADER),32,8, 1,8, BI_RLE8, 0,100000,100000, 0,0};
|
||||
static BITMAPINFOHEADER bo = {sizeof(BITMAPINFOHEADER),32,8, 1,8, BI_RGB, 0,100000,100000, 0,0};
|
||||
+ BITMAPINFOHEADER tmp = {sizeof(BITMAPINFOHEADER)};
|
||||
HIC h;
|
||||
DWORD err;
|
||||
|
||||
@@ -128,6 +129,45 @@ static void test_Locate(void)
|
||||
ok(err == ICERR_OK, "Query cvid->RGB32 height<0: %d\n", err);
|
||||
bo.biHeight = -bo.biHeight;
|
||||
|
||||
+ bi.biWidth = 17;
|
||||
+
|
||||
+ bi.biBitCount = 8;
|
||||
+ err = ICDecompressGetFormat(h, &bi, &tmp);
|
||||
+ ok(err == ICERR_OK, "Query cvid output format: %d\n", err);
|
||||
+ ok(tmp.biBitCount == 24, "Expected 24 bit, got %d bit\n", tmp.biBitCount);
|
||||
+ ok(tmp.biSizeImage == get_stride(17, 24) * 8, "Expected size %d, got %d\n",
|
||||
+ get_stride(17, 24) * 8, tmp.biSizeImage);
|
||||
+
|
||||
+ bi.biBitCount = 15;
|
||||
+ err = ICDecompressGetFormat(h, &bi, &tmp);
|
||||
+ ok(err == ICERR_OK, "Query cvid output format: %d\n", err);
|
||||
+ ok(tmp.biBitCount == 24, "Expected 24 bit, got %d bit\n", tmp.biBitCount);
|
||||
+ ok(tmp.biSizeImage == get_stride(17, 24) * 8, "Expected size %d, got %d\n",
|
||||
+ get_stride(17, 24) * 8, tmp.biSizeImage);
|
||||
+
|
||||
+ bi.biBitCount = 16;
|
||||
+ err = ICDecompressGetFormat(h, &bi, &tmp);
|
||||
+ ok(err == ICERR_OK, "Query cvid output format: %d\n", err);
|
||||
+ ok(tmp.biBitCount == 24, "Expected 24 bit, got %d bit\n", tmp.biBitCount);
|
||||
+ ok(tmp.biSizeImage == get_stride(17, 24) * 8, "Expected size %d, got %d\n",
|
||||
+ get_stride(17, 24) * 8, tmp.biSizeImage);
|
||||
+
|
||||
+ bi.biBitCount = 24;
|
||||
+ err = ICDecompressGetFormat(h, &bi, &tmp);
|
||||
+ ok(err == ICERR_OK, "Query cvid output format: %d\n", err);
|
||||
+ ok(tmp.biBitCount == 24, "Expected 24 bit, got %d bit\n", tmp.biBitCount);
|
||||
+ ok(tmp.biSizeImage == get_stride(17, 24) * 8, "Expected size %d, got %d\n",
|
||||
+ get_stride(17, 24) * 8, tmp.biSizeImage);
|
||||
+
|
||||
+ bi.biBitCount = 32;
|
||||
+ err = ICDecompressGetFormat(h, &bi, &tmp);
|
||||
+ ok(err == ICERR_OK, "Query cvid output format: %d\n", err);
|
||||
+ ok(tmp.biBitCount == 24, "Expected 24 bit, got %d bit\n", tmp.biBitCount);
|
||||
+ ok(tmp.biSizeImage == get_stride(17, 24) * 8, "Expected size %d, got %d\n",
|
||||
+ get_stride(17, 24) * 8, tmp.biSizeImage);
|
||||
+
|
||||
+ bi.biWidth = 32;
|
||||
+
|
||||
ok(ICClose(h) == ICERR_OK,"ICClose failed\n");
|
||||
|
||||
bo.biBitCount = bi.biBitCount = 8;
|
||||
--
|
||||
2.7.1
|
||||
|
@@ -0,0 +1,190 @@
|
||||
From ef25f64580a12fba30413f34c1a9c72e31089e29 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
|
||||
Date: Sat, 2 Apr 2016 22:15:37 +0200
|
||||
Subject: msvidc32: Add support for converting 16 bit depth to 24 bit.
|
||||
|
||||
---
|
||||
dlls/msvfw32/tests/msvfw.c | 5 +++
|
||||
dlls/msvidc32/msvideo1.c | 91 ++++++++++++++++++++++++++++++++++++++++------
|
||||
2 files changed, 84 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/dlls/msvfw32/tests/msvfw.c b/dlls/msvfw32/tests/msvfw.c
|
||||
index 125cac5..66956aa 100644
|
||||
--- a/dlls/msvfw32/tests/msvfw.c
|
||||
+++ b/dlls/msvfw32/tests/msvfw.c
|
||||
@@ -202,6 +202,11 @@ static void test_Locate(void)
|
||||
todo_wine ok(err == ICERR_OK, "Query MSVC->RGB16 height<0: %d\n", err);
|
||||
bo.biHeight = -bo.biHeight;
|
||||
|
||||
+ bo.biBitCount = 24;
|
||||
+ err = ICDecompressQuery(h, &bi, &bo);
|
||||
+ ok(err == ICERR_OK, "Query MSVC 16->24: %d\n", err);
|
||||
+ bo.biBitCount = 16;
|
||||
+
|
||||
bi.biCompression = mmioFOURCC('m','s','v','c');
|
||||
err = ICDecompressQuery(h, &bi, &bo);
|
||||
ok(err == ICERR_BADFORMAT, "Query msvc->RGB16: %d\n", err);
|
||||
diff --git a/dlls/msvidc32/msvideo1.c b/dlls/msvidc32/msvideo1.c
|
||||
index b3faaf6..ab7cc3e 100644
|
||||
--- a/dlls/msvidc32/msvideo1.c
|
||||
+++ b/dlls/msvidc32/msvideo1.c
|
||||
@@ -67,7 +67,7 @@ typedef BYTE uint8_t;
|
||||
|
||||
typedef struct Msvideo1Context {
|
||||
DWORD dwMagic;
|
||||
- BOOL mode_8bit; /* if it's not 8-bit, it's 16-bit */
|
||||
+ int depth;
|
||||
} Msvideo1Context;
|
||||
|
||||
static void
|
||||
@@ -327,8 +327,15 @@ CRAM_DecompressQuery( Msvideo1Context *info, LPBITMAPINFO in, LPBITMAPINFO out )
|
||||
TRACE("out->bpp = %d\n", out->bmiHeader.biBitCount );
|
||||
TRACE("out->height = %d\n", out->bmiHeader.biHeight );
|
||||
TRACE("out->width = %d\n", out->bmiHeader.biWidth );
|
||||
- if(( in->bmiHeader.biBitCount != out->bmiHeader.biBitCount ) ||
|
||||
- ( in->bmiHeader.biPlanes != out->bmiHeader.biPlanes ) ||
|
||||
+
|
||||
+ if ((in->bmiHeader.biBitCount != out->bmiHeader.biBitCount) &&
|
||||
+ (in->bmiHeader.biBitCount != 16 || out->bmiHeader.biBitCount != 24))
|
||||
+ {
|
||||
+ TRACE("incompatible depth requested\n");
|
||||
+ return ICERR_BADFORMAT;
|
||||
+ }
|
||||
+
|
||||
+ if(( in->bmiHeader.biPlanes != out->bmiHeader.biPlanes ) ||
|
||||
( in->bmiHeader.biHeight != out->bmiHeader.biHeight ) ||
|
||||
( in->bmiHeader.biWidth != out->bmiHeader.biWidth ))
|
||||
{
|
||||
@@ -376,21 +383,52 @@ static LRESULT CRAM_DecompressBegin( Msvideo1Context *info, LPBITMAPINFO in, LPB
|
||||
|
||||
TRACE("bitmap is %d bpp\n", in->bmiHeader.biBitCount);
|
||||
if( in->bmiHeader.biBitCount == 8 )
|
||||
- info->mode_8bit = TRUE;
|
||||
+ info->depth = 8;
|
||||
else if( in->bmiHeader.biBitCount == 16 )
|
||||
- info->mode_8bit = FALSE;
|
||||
+ info->depth = 16;
|
||||
else
|
||||
{
|
||||
- info->mode_8bit = FALSE;
|
||||
+ info->depth = 0;
|
||||
FIXME("Unsupported output format %i\n", in->bmiHeader.biBitCount);
|
||||
}
|
||||
|
||||
return ICERR_OK;
|
||||
}
|
||||
|
||||
+static void convert_depth(char *input, int depth_in, char *output, BITMAPINFOHEADER *out_hdr)
|
||||
+{
|
||||
+ int x, y;
|
||||
+
|
||||
+ if (depth_in == 16 && out_hdr->biBitCount == 24)
|
||||
+ {
|
||||
+ static const unsigned char convert_5to8[] =
|
||||
+ {
|
||||
+ 0x00, 0x08, 0x10, 0x19, 0x21, 0x29, 0x31, 0x3a,
|
||||
+ 0x42, 0x4a, 0x52, 0x5a, 0x63, 0x6b, 0x73, 0x7b,
|
||||
+ 0x84, 0x8c, 0x94, 0x9c, 0xa5, 0xad, 0xb5, 0xbd,
|
||||
+ 0xc5, 0xce, 0xd6, 0xde, 0xe6, 0xef, 0xf7, 0xff,
|
||||
+ };
|
||||
+
|
||||
+ WORD *src = (WORD *)input;
|
||||
+ for (y = 0; y < out_hdr->biHeight; y++)
|
||||
+ {
|
||||
+ for (x = 0; x < out_hdr->biWidth; x++)
|
||||
+ {
|
||||
+ WORD pixel = *src++;
|
||||
+ *output++ = convert_5to8[(pixel & 0x7c00u) >> 10];
|
||||
+ *output++ = convert_5to8[(pixel & 0x03e0u) >> 5];
|
||||
+ *output++ = convert_5to8[(pixel & 0x001fu)];
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ FIXME("Conversion from %d to %d bit unimplemented\n", depth_in, out_hdr->biBitCount);
|
||||
+}
|
||||
+
|
||||
static LRESULT CRAM_Decompress( Msvideo1Context *info, ICDECOMPRESS *icd, DWORD size )
|
||||
{
|
||||
LONG width, height, stride, sz;
|
||||
+ void *output;
|
||||
|
||||
TRACE("ICM_DECOMPRESS %p %p %d\n", info, icd, size);
|
||||
|
||||
@@ -404,15 +442,29 @@ static LRESULT CRAM_Decompress( Msvideo1Context *info, ICDECOMPRESS *icd, DWORD
|
||||
stride = width; /* in bytes or 16bit words */
|
||||
sz = icd->lpbiInput->biSizeImage;
|
||||
|
||||
- if (info->mode_8bit)
|
||||
+ output = icd->lpOutput;
|
||||
+
|
||||
+ if (icd->lpbiOutput->biBitCount != info->depth)
|
||||
+ {
|
||||
+ output = HeapAlloc(GetProcessHeap(), 0, icd->lpbiOutput->biWidth * icd->lpbiOutput->biHeight * info->depth / 8);
|
||||
+ if (!output) return ICERR_MEMORY;
|
||||
+ }
|
||||
+
|
||||
+ if (info->depth == 8)
|
||||
{
|
||||
msvideo1_decode_8bit( width, height, icd->lpInput, sz,
|
||||
- icd->lpOutput, stride);
|
||||
+ output, stride );
|
||||
}
|
||||
else
|
||||
{
|
||||
msvideo1_decode_16bit( width, height, icd->lpInput, sz,
|
||||
- icd->lpOutput, stride);
|
||||
+ output, stride );
|
||||
+ }
|
||||
+
|
||||
+ if (icd->lpbiOutput->biBitCount != info->depth)
|
||||
+ {
|
||||
+ convert_depth(output, info->depth, icd->lpOutput, icd->lpbiOutput);
|
||||
+ HeapFree(GetProcessHeap(), 0, output);
|
||||
}
|
||||
|
||||
return ICERR_OK;
|
||||
@@ -421,6 +473,7 @@ static LRESULT CRAM_Decompress( Msvideo1Context *info, ICDECOMPRESS *icd, DWORD
|
||||
static LRESULT CRAM_DecompressEx( Msvideo1Context *info, ICDECOMPRESSEX *icd, DWORD size )
|
||||
{
|
||||
LONG width, height, stride, sz;
|
||||
+ void *output;
|
||||
|
||||
TRACE("ICM_DECOMPRESSEX %p %p %d\n", info, icd, size);
|
||||
|
||||
@@ -434,15 +487,29 @@ static LRESULT CRAM_DecompressEx( Msvideo1Context *info, ICDECOMPRESSEX *icd, DW
|
||||
stride = width;
|
||||
sz = icd->lpbiSrc->biSizeImage;
|
||||
|
||||
- if (info->mode_8bit)
|
||||
+ output = icd->lpDst;
|
||||
+
|
||||
+ if (icd->lpbiDst->biBitCount != info->depth)
|
||||
+ {
|
||||
+ output = HeapAlloc(GetProcessHeap(), 0, icd->lpbiDst->biWidth * icd->lpbiDst->biHeight * info->depth / 8);
|
||||
+ if (!output) return ICERR_MEMORY;
|
||||
+ }
|
||||
+
|
||||
+ if (info->depth == 8)
|
||||
{
|
||||
msvideo1_decode_8bit( width, height, icd->lpSrc, sz,
|
||||
- icd->lpDst, stride);
|
||||
+ output, stride );
|
||||
}
|
||||
else
|
||||
{
|
||||
msvideo1_decode_16bit( width, height, icd->lpSrc, sz,
|
||||
- icd->lpDst, stride);
|
||||
+ output, stride );
|
||||
+ }
|
||||
+
|
||||
+ if (icd->lpbiDst->biBitCount != info->depth)
|
||||
+ {
|
||||
+ convert_depth(output, info->depth, icd->lpDst, icd->lpbiDst);
|
||||
+ HeapFree(GetProcessHeap(), 0, output);
|
||||
}
|
||||
|
||||
return ICERR_OK;
|
||||
--
|
||||
2.7.1
|
||||
|
@@ -0,0 +1,175 @@
|
||||
From 5d4bb7073d6674407a0a677732805e4d24988f24 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
|
||||
Date: Sun, 3 Apr 2016 19:10:42 +0200
|
||||
Subject: msvidc32: Fix calculation of stride and size.
|
||||
|
||||
---
|
||||
dlls/msvfw32/tests/msvfw.c | 39 +++++++++++++++++++++++++++++++++++++++
|
||||
dlls/msvidc32/msvideo1.c | 34 +++++++++++++++++++++++++---------
|
||||
2 files changed, 64 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/dlls/msvfw32/tests/msvfw.c b/dlls/msvfw32/tests/msvfw.c
|
||||
index b546150..03ebaa7 100644
|
||||
--- a/dlls/msvfw32/tests/msvfw.c
|
||||
+++ b/dlls/msvfw32/tests/msvfw.c
|
||||
@@ -252,6 +252,45 @@ static void test_Locate(void)
|
||||
ok(err == ICERR_OK, "Query MSVC 16->24: %d\n", err);
|
||||
bo.biBitCount = 16;
|
||||
|
||||
+ bi.biWidth = 553;
|
||||
+
|
||||
+ bi.biBitCount = 8;
|
||||
+ err = ICDecompressGetFormat(h, &bi, &tmp);
|
||||
+ ok(err == ICERR_OK, "Query MSVC output format: %d\n", err);
|
||||
+ ok(tmp.biBitCount == 8, "Expected 8 bit, got %d bit\n", tmp.biBitCount);
|
||||
+ ok(tmp.biWidth == 552, "Expected width 552, got %d\n", tmp.biWidth);
|
||||
+ ok(tmp.biSizeImage == get_stride(552, 8) * 8, "Expected size %d, got %d\n",
|
||||
+ get_stride(552, 8) * 8, tmp.biSizeImage);
|
||||
+
|
||||
+ bi.biBitCount = 15;
|
||||
+ err = ICDecompressGetFormat(h, &bi, &tmp);
|
||||
+ ok(err == ICERR_BADFORMAT, "Query MSVC output format: %d\n", err);
|
||||
+
|
||||
+ bi.biBitCount = 16;
|
||||
+ err = ICDecompressGetFormat(h, &bi, &tmp);
|
||||
+ ok(err == ICERR_OK, "Query MSVC output format: %d\n", err);
|
||||
+ ok(tmp.biBitCount == 16, "Expected 16 bit, got %d bit\n", tmp.biBitCount);
|
||||
+ ok(tmp.biWidth == 552, "Expected width 552, got %d\n", tmp.biWidth);
|
||||
+ ok(tmp.biSizeImage == get_stride(552, 16) * 8, "Expected size %d, got %d\n",
|
||||
+ get_stride(552, 16) * 8, tmp.biSizeImage);
|
||||
+
|
||||
+ bi.biBitCount = 24;
|
||||
+ err = ICDecompressGetFormat(h, &bi, &tmp);
|
||||
+ ok(err == ICERR_BADFORMAT, "Query MSVC output format: %d\n", err);
|
||||
+
|
||||
+ bi.biBitCount = 32;
|
||||
+ err = ICDecompressGetFormat(h, &bi, &tmp);
|
||||
+ ok(err == ICERR_BADFORMAT, "Query MSVC output format: %d\n", err);
|
||||
+
|
||||
+ bi.biHeight = 17;
|
||||
+ bi.biBitCount = 8;
|
||||
+ err = ICDecompressGetFormat(h, &bi, &tmp);
|
||||
+ ok(err == ICERR_OK, "Query MSVC output format: %d\n", err);
|
||||
+ ok(tmp.biHeight == 16, "Expected height 16, got %d\n", tmp.biHeight);
|
||||
+ bi.biHeight = 8;
|
||||
+
|
||||
+ bi.biWidth = 32;
|
||||
+
|
||||
bi.biCompression = mmioFOURCC('m','s','v','c');
|
||||
err = ICDecompressQuery(h, &bi, &bo);
|
||||
ok(err == ICERR_BADFORMAT, "Query msvc->RGB16: %d\n", err);
|
||||
diff --git a/dlls/msvidc32/msvideo1.c b/dlls/msvidc32/msvideo1.c
|
||||
index ab7cc3e..b999b52 100644
|
||||
--- a/dlls/msvidc32/msvideo1.c
|
||||
+++ b/dlls/msvidc32/msvideo1.c
|
||||
@@ -70,6 +70,11 @@ typedef struct Msvideo1Context {
|
||||
int depth;
|
||||
} Msvideo1Context;
|
||||
|
||||
+static inline int get_stride(int width, int depth)
|
||||
+{
|
||||
+ return ((depth * width + 31) >> 3) & ~3;
|
||||
+}
|
||||
+
|
||||
static void
|
||||
msvideo1_decode_8bit( int width, int height, const unsigned char *buf, int buf_size,
|
||||
unsigned char *pixels, int stride)
|
||||
@@ -362,12 +367,17 @@ CRAM_DecompressGetFormat( Msvideo1Context *info, LPBITMAPINFO in, LPBITMAPINFO o
|
||||
if (in->bmiHeader.biBitCount <= 8)
|
||||
size += in->bmiHeader.biClrUsed * sizeof(RGBQUAD);
|
||||
|
||||
+ if (in->bmiHeader.biBitCount != 8 && in->bmiHeader.biBitCount != 16)
|
||||
+ return ICERR_BADFORMAT;
|
||||
+
|
||||
if( out )
|
||||
{
|
||||
memcpy( out, in, size );
|
||||
+ out->bmiHeader.biWidth = in->bmiHeader.biWidth & ~1;
|
||||
+ out->bmiHeader.biHeight = in->bmiHeader.biHeight & ~1;
|
||||
out->bmiHeader.biCompression = BI_RGB;
|
||||
- out->bmiHeader.biSizeImage = in->bmiHeader.biHeight
|
||||
- * in->bmiHeader.biWidth *4;
|
||||
+ out->bmiHeader.biSizeImage = in->bmiHeader.biHeight *
|
||||
+ get_stride(out->bmiHeader.biWidth, out->bmiHeader.biBitCount);
|
||||
return ICERR_OK;
|
||||
}
|
||||
|
||||
@@ -398,6 +408,8 @@ static LRESULT CRAM_DecompressBegin( Msvideo1Context *info, LPBITMAPINFO in, LPB
|
||||
static void convert_depth(char *input, int depth_in, char *output, BITMAPINFOHEADER *out_hdr)
|
||||
{
|
||||
int x, y;
|
||||
+ int stride_in = get_stride(out_hdr->biWidth, depth_in);
|
||||
+ int stride_out = get_stride(out_hdr->biWidth, out_hdr->biBitCount);
|
||||
|
||||
if (depth_in == 16 && out_hdr->biBitCount == 24)
|
||||
{
|
||||
@@ -409,15 +421,17 @@ static void convert_depth(char *input, int depth_in, char *output, BITMAPINFOHEA
|
||||
0xc5, 0xce, 0xd6, 0xde, 0xe6, 0xef, 0xf7, 0xff,
|
||||
};
|
||||
|
||||
- WORD *src = (WORD *)input;
|
||||
for (y = 0; y < out_hdr->biHeight; y++)
|
||||
{
|
||||
+ WORD *src_row = (WORD *)(input + y * stride_in);
|
||||
+ char *out_row = output + y * stride_out;
|
||||
+
|
||||
for (x = 0; x < out_hdr->biWidth; x++)
|
||||
{
|
||||
- WORD pixel = *src++;
|
||||
- *output++ = convert_5to8[(pixel & 0x7c00u) >> 10];
|
||||
- *output++ = convert_5to8[(pixel & 0x03e0u) >> 5];
|
||||
- *output++ = convert_5to8[(pixel & 0x001fu)];
|
||||
+ WORD pixel = *src_row++;
|
||||
+ *out_row++ = convert_5to8[(pixel & 0x7c00u) >> 10];
|
||||
+ *out_row++ = convert_5to8[(pixel & 0x03e0u) >> 5];
|
||||
+ *out_row++ = convert_5to8[(pixel & 0x001fu)];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -439,7 +453,6 @@ static LRESULT CRAM_Decompress( Msvideo1Context *info, ICDECOMPRESS *icd, DWORD
|
||||
|
||||
width = icd->lpbiInput->biWidth;
|
||||
height = icd->lpbiInput->biHeight;
|
||||
- stride = width; /* in bytes or 16bit words */
|
||||
sz = icd->lpbiInput->biSizeImage;
|
||||
|
||||
output = icd->lpOutput;
|
||||
@@ -452,11 +465,13 @@ static LRESULT CRAM_Decompress( Msvideo1Context *info, ICDECOMPRESS *icd, DWORD
|
||||
|
||||
if (info->depth == 8)
|
||||
{
|
||||
+ stride = get_stride(width, 8);
|
||||
msvideo1_decode_8bit( width, height, icd->lpInput, sz,
|
||||
output, stride );
|
||||
}
|
||||
else
|
||||
{
|
||||
+ stride = get_stride(width, 16) / 2;
|
||||
msvideo1_decode_16bit( width, height, icd->lpInput, sz,
|
||||
output, stride );
|
||||
}
|
||||
@@ -484,7 +499,6 @@ static LRESULT CRAM_DecompressEx( Msvideo1Context *info, ICDECOMPRESSEX *icd, DW
|
||||
|
||||
width = icd->lpbiSrc->biWidth;
|
||||
height = icd->lpbiSrc->biHeight;
|
||||
- stride = width;
|
||||
sz = icd->lpbiSrc->biSizeImage;
|
||||
|
||||
output = icd->lpDst;
|
||||
@@ -497,11 +511,13 @@ static LRESULT CRAM_DecompressEx( Msvideo1Context *info, ICDECOMPRESSEX *icd, DW
|
||||
|
||||
if (info->depth == 8)
|
||||
{
|
||||
+ stride = get_stride(width, 8);
|
||||
msvideo1_decode_8bit( width, height, icd->lpSrc, sz,
|
||||
output, stride );
|
||||
}
|
||||
else
|
||||
{
|
||||
+ stride = get_stride(width, 16) / 2;
|
||||
msvideo1_decode_16bit( width, height, icd->lpSrc, sz,
|
||||
output, stride );
|
||||
}
|
||||
--
|
||||
2.7.1
|
||||
|
@@ -1,2 +1,3 @@
|
||||
Fixes: [23175] Fix implementation of ICGetDisplayFormat
|
||||
Fixes: [25180] Fix rendering of Clonk Endeavour's intro video
|
||||
Fixes: [14695] Implement support for converting 16 bit depth to 24 bit in msvidc32
|
||||
|
Reference in New Issue
Block a user