From 681f407a814c6185af14fa27b6e7a7fa63a6f017 Mon Sep 17 00:00:00 2001 From: Anton Baskanov Date: Sun, 3 Nov 2024 11:29:38 +0700 Subject: [PATCH 1/4] msvidc32/tests: Add MS Video-1 decoder tests. --- configure | 1 + configure.ac | 1 + dlls/msvidc32/tests/Makefile.in | 5 + dlls/msvidc32/tests/msvidc32.c | 416 ++++++++++++++++++++++++++++++++ 4 files changed, 423 insertions(+) create mode 100644 dlls/msvidc32/tests/Makefile.in create mode 100644 dlls/msvidc32/tests/msvidc32.c diff --git a/configure b/configure index bf0f6e8903b..4473ff55df8 100755 --- a/configure +++ b/configure @@ -22332,6 +22332,7 @@ wine_fn_config_makefile dlls/msvcrtd/tests enable_tests wine_fn_config_makefile dlls/msvfw32 enable_msvfw32 wine_fn_config_makefile dlls/msvfw32/tests enable_tests wine_fn_config_makefile dlls/msvidc32 enable_msvidc32 +wine_fn_config_makefile dlls/msvidc32/tests enable_tests wine_fn_config_makefile dlls/msvideo.dll16 enable_win16 wine_fn_config_makefile dlls/msvproc enable_msvproc wine_fn_config_makefile dlls/mswsock enable_mswsock diff --git a/configure.ac b/configure.ac index 8edfce44d6e..01ac06970c1 100644 --- a/configure.ac +++ b/configure.ac @@ -2909,6 +2909,7 @@ WINE_CONFIG_MAKEFILE(dlls/msvcrtd/tests) WINE_CONFIG_MAKEFILE(dlls/msvfw32) WINE_CONFIG_MAKEFILE(dlls/msvfw32/tests) WINE_CONFIG_MAKEFILE(dlls/msvidc32) +WINE_CONFIG_MAKEFILE(dlls/msvidc32/tests) WINE_CONFIG_MAKEFILE(dlls/msvideo.dll16,enable_win16) WINE_CONFIG_MAKEFILE(dlls/msvproc) WINE_CONFIG_MAKEFILE(dlls/mswsock) diff --git a/dlls/msvidc32/tests/Makefile.in b/dlls/msvidc32/tests/Makefile.in new file mode 100644 index 00000000000..64d847d2a25 --- /dev/null +++ b/dlls/msvidc32/tests/Makefile.in @@ -0,0 +1,5 @@ +TESTDLL = msvidc32.dll +IMPORTS = msvfw32 + +SOURCES = \ + msvidc32.c diff --git a/dlls/msvidc32/tests/msvidc32.c b/dlls/msvidc32/tests/msvidc32.c new file mode 100644 index 00000000000..542617e84f7 --- /dev/null +++ b/dlls/msvidc32/tests/msvidc32.c @@ -0,0 +1,416 @@ +/* + * Microsoft Video-1 Decoder unit tests + * + * Copyright 2024 Anton Baskanov + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define WIN32_LEAN_AND_MEAN +#include +#include + +#include "wine/test.h" + +struct bitmap_info +{ + BITMAPINFOHEADER header; + union + { + RGBQUAD colors[256]; + DWORD color_masks[3]; + }; +}; + +typedef void check_pixel_t(int line, int frame, int row, int col, BYTE *data, BYTE *expected_data); + +static const struct bitmap_info format_cram8 = +{ + .header = + { + .biSize = sizeof(BITMAPINFOHEADER), + .biWidth = 4, + .biHeight = 16, + .biPlanes = 1, + .biBitCount = 8, + .biCompression = mmioFOURCC('C','R','A','M'), + }, +}; + +static const struct bitmap_info format_cram16 = +{ + .header = + { + .biSize = sizeof(BITMAPINFOHEADER), + .biWidth = 4, + .biHeight = 16, + .biPlanes = 1, + .biBitCount = 16, + .biCompression = mmioFOURCC('C','R','A','M'), + }, +}; + +static const struct bitmap_info format_rgb8 = +{ + .header = + { + .biSize = sizeof(BITMAPINFOHEADER), + .biWidth = 4, + .biHeight = 16, + .biPlanes = 1, + .biBitCount = 8, + .biCompression = BI_RGB, + .biSizeImage = 16 * 4, + }, +}; + +static const struct bitmap_info format_rgb555 = +{ + .header = + { + .biSize = sizeof(BITMAPINFOHEADER), + .biWidth = 4, + .biHeight = 16, + .biPlanes = 1, + .biBitCount = 16, + .biCompression = BI_RGB, + .biSizeImage = 16 * 4 * 2, + }, +}; + +static const struct bitmap_info format_rgb565 = +{ + .header = + { + .biSize = sizeof(BITMAPINFOHEADER), + .biWidth = 4, + .biHeight = 16, + .biPlanes = 1, + .biBitCount = 16, + .biCompression = BI_BITFIELDS, + .biSizeImage = 16 * 4 * 2, + }, + .color_masks = + { + 0xf800, + 0x07e0, + 0x001f, + }, +}; + +static const struct bitmap_info format_rgb24 = +{ + .header = + { + .biSize = sizeof(BITMAPINFOHEADER), + .biWidth = 4, + .biHeight = 16, + .biPlanes = 1, + .biBitCount = 24, + .biCompression = BI_RGB, + .biSizeImage = 16 * 4 * 3, + }, +}; + +static const struct bitmap_info format_yvuv = +{ + .header = + { + .biSize = sizeof(BITMAPINFOHEADER), + .biWidth = 4, + .biHeight = 16, + .biPlanes = 1, + .biBitCount = 16, + .biCompression = mmioFOURCC('Y','V','U','V'), + .biSizeImage = 16 * 4 * 2, + }, +}; + +static void check_image(int line, int frame, check_pixel_t *check_pixel, + const struct bitmap_info *out_format, BYTE *image, BYTE *expected_image) +{ + int stride = ((out_format->header.biWidth * out_format->header.biBitCount + 31) >> 3) & ~3; + int step = out_format->header.biBitCount >> 3; + int row, col; + + for (row = 0; row < out_format->header.biHeight; ++row) + { + for (col = 0; col < out_format->header.biWidth; ++col) + { + BYTE *pixel = image + row * stride + col * step; + BYTE *expected_pixel = expected_image + row * stride + col * step; + check_pixel(line, frame, row, col, pixel, expected_pixel); + } + } +} + +static void check_pixel_rgb8(int line, int frame, int row, int col, BYTE *pixel, + BYTE *expected_pixel) +{ + ok_(__FILE__, line)(*pixel == *expected_pixel, "got frame %d image[%d][%d] 0x%02x.\n", frame, + row, col, *pixel); +} + +static void check_pixel_rgb555(int line, int frame, int row, int col, BYTE *pixel, + BYTE *expected_pixel) +{ + /* Native sets the MSB inconsistently so ignore it. */ + ok_(__FILE__, line)((*(WORD *)pixel & 0x7fff) == (*(WORD *)expected_pixel & 0x7fff), + "got frame %d image[%d][%d] 0x%02x.\n", frame, row, col, *pixel); +} + +static void check_pixel_rgb565(int line, int frame, int row, int col, BYTE *pixel, + BYTE *expected_pixel) +{ + todo_wine_if(*(WORD *)pixel != *(WORD *)expected_pixel) + ok_(__FILE__, line)(*(WORD *)pixel == *(WORD *)expected_pixel, + "got frame %d image[%d][%d] 0x%02x.\n", frame, row, col, *pixel); +} + +static void check_pixel_rgb24(int line, int frame, int row, int col, BYTE *pixel, + BYTE *expected_pixel) +{ + int i; + + for (i = 0; i < 3; ++i) + { + todo_wine_if(pixel[i] != expected_pixel[i]) + ok_(__FILE__, line)(pixel[i] == expected_pixel[i], + "got frame %d image[%d][%d][%d] 0x%02x.\n", frame, row, col, i, pixel[i]); + } +} + +static void test_ICDecompressQuery(void) +{ + LRESULT lr; + HIC hic; + + hic = ICOpen(mmioFOURCC('V','I','D','C'), mmioFOURCC('M','S','V','C'), ICMODE_DECOMPRESS); + ok(!!hic, "got hic %p.\n", hic); + + lr = ICDecompressQuery(hic, &format_cram8, &format_rgb8); + ok(lr == ICERR_OK, "got lr %Id.\n", lr); + + lr = ICDecompressQuery(hic, &format_cram16, &format_rgb555); + ok(lr == ICERR_OK, "got lr %Id.\n", lr); + + lr = ICDecompressQuery(hic, &format_cram16, &format_rgb565); + ok(lr == ICERR_OK, "got lr %Id.\n", lr); + + lr = ICDecompressQuery(hic, &format_cram16, &format_rgb24); + ok(lr == ICERR_OK, "got lr %Id.\n", lr); + + lr = ICDecompressQuery(hic, &format_cram16, &format_yvuv); + todo_wine ok(lr == ICERR_BADFORMAT, "got lr %Id.\n", lr); + + ICClose(hic); +} + +#define check_ICDecompress(check_pixel, in_format, out_format, data0, data0_size, data1, data1_size, expected_data) \ + check_ICDecompress_(__LINE__, check_pixel, in_format, out_format, data0, data0_size, data1, data1_size, expected_data) +static void check_ICDecompress_(int line, check_pixel_t *check_pixel, + const struct bitmap_info *in_format, const struct bitmap_info *out_format, BYTE *data0, + DWORD data0_size, BYTE *data1, DWORD data1_size, BYTE *expected_data) +{ + struct bitmap_info format; + BYTE data[1024]; + LRESULT lr; + HIC hic; + + hic = ICOpen(mmioFOURCC('V','I','D','C'), mmioFOURCC('M','S','V','C'), ICMODE_DECOMPRESS); + ok_(__FILE__, line)(!!hic, "got hic %p.\n", hic); + + format = *in_format; + format.header.biSizeImage = data0_size; + lr = ICDecompressBegin(hic, &format, out_format); + ok_(__FILE__, line)(lr == ICERR_OK, "got lr %Id.\n", lr); + + format = *in_format; + format.header.biSizeImage = data0_size; + memset(data, 0, sizeof(data)); + lr = ICDecompress(hic, 0, &format.header, data0, (BITMAPINFOHEADER *)&out_format->header, data); + ok_(__FILE__, line)(lr == ICERR_OK, "got lr %Id.\n", lr); + + check_image(line, 0, check_pixel, out_format, data, expected_data); + + format = *in_format; + format.header.biSizeImage = data1_size; + lr = ICDecompress(hic, 0, &format.header, data1, (BITMAPINFOHEADER *)&out_format->header, data); + ok_(__FILE__, line)(lr == ICERR_OK, "got lr %Id.\n", lr); + + check_image(line, 1, check_pixel, out_format, data, expected_data); + + ICDecompressEnd(hic); + ICClose(hic); +} + +static void test_ICDecompress(void) +{ + BYTE frame0_data8[] = + { + /* Skip 1 block. */ + 0x01, 0x84, + /* 8-color block. */ + 0x55, 0xaa, + 0x01, + 0x02, + 0x04, + 0x08, + 0x10, + 0x20, + 0x40, + 0x80, + /* 2-color block. */ + 0xaa, 0x55, + 0x00, + 0xff, + /* 1-color block. */ + 0xff, 0x80, + }; + BYTE frame1_data8[] = + { + /* Skip 4 blocks. */ + 0x04, 0x84, + }; + BYTE frame0_data16[] = + { + /* Skip 1 block. */ + 0x01, 0x84, + /* 8-color block. */ + 0xaa, 0x55, + 0x01, 0x80, + 0x10, 0x00, + 0x20, 0x00, + 0x00, 0x02, + 0x00, 0x04, + 0x00, 0x40, + 0x00, 0x00, + 0xff, 0x7f, + /* 2-color block. */ + 0xaa, 0x55, + 0x00, 0x00, + 0xff, 0x7f, + /* 1-color block. */ + 0xff, 0xff, + }; + BYTE frame1_data16[] = + { + /* Skip 4 blocks. */ + 0x04, 0x84, + }; + BYTE expected_data8[] = + { + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x01, 0x02, 0x04, 0x08, + 0x01, 0x02, 0x04, 0x08, + 0x20, 0x10, 0x80, 0x40, + 0x20, 0x10, 0x80, 0x40, + + 0xff, 0x00, 0xff, 0x00, + 0xff, 0x00, 0xff, 0x00, + 0x00, 0xff, 0x00, 0xff, + 0x00, 0xff, 0x00, 0xff, + + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + }; + BYTE expected_data555[] = + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0x10, 0x00, 0x01, 0x80, 0x00, 0x02, 0x20, 0x00, + 0x10, 0x00, 0x01, 0x80, 0x00, 0x02, 0x20, 0x00, + 0x00, 0x04, 0x00, 0x40, 0x00, 0x00, 0xff, 0x7f, + 0x00, 0x04, 0x00, 0x40, 0x00, 0x00, 0xff, 0x7f, + + 0xff, 0x7f, 0x00, 0x00, 0xff, 0x7f, 0x00, 0x00, + 0xff, 0x7f, 0x00, 0x00, 0xff, 0x7f, 0x00, 0x00, + 0x00, 0x00, 0xff, 0x7f, 0x00, 0x00, 0xff, 0x7f, + 0x00, 0x00, 0xff, 0x7f, 0x00, 0x00, 0xff, 0x7f, + + 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, + 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, + 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, + 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, + }; + BYTE expected_data565[] = + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0x10, 0x00, 0x01, 0x00, 0x00, 0x04, 0x40, 0x00, + 0x10, 0x00, 0x01, 0x00, 0x00, 0x04, 0x40, 0x00, + 0x00, 0x08, 0x00, 0x80, 0x00, 0x00, 0xdf, 0xff, + 0x00, 0x08, 0x00, 0x80, 0x00, 0x00, 0xdf, 0xff, + + 0xdf, 0xff, 0x00, 0x00, 0xdf, 0xff, 0x00, 0x00, + 0xdf, 0xff, 0x00, 0x00, 0xdf, 0xff, 0x00, 0x00, + 0x00, 0x00, 0xdf, 0xff, 0x00, 0x00, 0xdf, 0xff, + 0x00, 0x00, 0xdf, 0xff, 0x00, 0x00, 0xdf, 0xff, + + 0xdf, 0xff, 0xdf, 0xff, 0xdf, 0xff, 0xdf, 0xff, + 0xdf, 0xff, 0xdf, 0xff, 0xdf, 0xff, 0xdf, 0xff, + 0xdf, 0xff, 0xdf, 0xff, 0xdf, 0xff, 0xdf, 0xff, + 0xdf, 0xff, 0xdf, 0xff, 0xdf, 0xff, 0xdf, 0xff, + }; + BYTE expected_data24[] = + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0x80, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x08, 0x00, + 0x80, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xf8, 0xf8, 0xf8, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xf8, 0xf8, 0xf8, + + 0xf8, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0xf8, 0xf8, 0xf8, 0x00, 0x00, 0x00, + 0xf8, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0xf8, 0xf8, 0xf8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xf8, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0xf8, 0xf8, 0xf8, + 0x00, 0x00, 0x00, 0xf8, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0xf8, 0xf8, 0xf8, + + 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, + 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, + 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, + 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, + }; + + check_ICDecompress(check_pixel_rgb8, &format_cram8, &format_rgb8, frame0_data8, + sizeof(frame0_data8), frame1_data8, sizeof(frame1_data8), expected_data8); + check_ICDecompress(check_pixel_rgb555, &format_cram16, &format_rgb555, frame0_data16, + sizeof(frame0_data16), frame1_data16, sizeof(frame1_data16), expected_data555); + check_ICDecompress(check_pixel_rgb565, &format_cram16, &format_rgb565, frame0_data16, + sizeof(frame0_data16), frame1_data16, sizeof(frame1_data16), expected_data565); + check_ICDecompress(check_pixel_rgb24, &format_cram16, &format_rgb24, frame0_data16, + sizeof(frame0_data16), frame1_data16, sizeof(frame1_data16), expected_data24); +} + +START_TEST(msvidc32) +{ + test_ICDecompressQuery(); + test_ICDecompress(); +} From bb4e050f663641901f29a700b4bc89b67ac50278 Mon Sep 17 00:00:00 2001 From: Anton Baskanov Date: Wed, 30 Oct 2024 17:09:54 +0700 Subject: [PATCH 2/4] msvidc32: Reject incompatible output compression. --- dlls/msvidc32/msvideo1.c | 7 +++++++ dlls/msvidc32/tests/msvidc32.c | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/dlls/msvidc32/msvideo1.c b/dlls/msvidc32/msvideo1.c index 327882f68f2..02427d98fa3 100644 --- a/dlls/msvidc32/msvideo1.c +++ b/dlls/msvidc32/msvideo1.c @@ -333,6 +333,13 @@ CRAM_DecompressQuery( Msvideo1Context *info, LPBITMAPINFO in, LPBITMAPINFO out ) TRACE("out->height = %ld\n", out->bmiHeader.biHeight ); TRACE("out->width = %ld\n", out->bmiHeader.biWidth ); + if ((out->bmiHeader.biCompression != BI_RGB) && + (out->bmiHeader.biCompression != BI_BITFIELDS)) + { + TRACE("incompatible compression requested\n"); + return ICERR_BADFORMAT; + } + if ((in->bmiHeader.biBitCount != out->bmiHeader.biBitCount) && (in->bmiHeader.biBitCount != 16 || out->bmiHeader.biBitCount != 24)) { diff --git a/dlls/msvidc32/tests/msvidc32.c b/dlls/msvidc32/tests/msvidc32.c index 542617e84f7..f6a5eb77449 100644 --- a/dlls/msvidc32/tests/msvidc32.c +++ b/dlls/msvidc32/tests/msvidc32.c @@ -213,7 +213,7 @@ static void test_ICDecompressQuery(void) ok(lr == ICERR_OK, "got lr %Id.\n", lr); lr = ICDecompressQuery(hic, &format_cram16, &format_yvuv); - todo_wine ok(lr == ICERR_BADFORMAT, "got lr %Id.\n", lr); + ok(lr == ICERR_BADFORMAT, "got lr %Id.\n", lr); ICClose(hic); } From 622e9773469fc61ca072a2a5e71117ac2f88ee55 Mon Sep 17 00:00:00 2001 From: Anton Baskanov Date: Tue, 5 Nov 2024 13:59:07 +0700 Subject: [PATCH 3/4] msvidc32: Convert to RGB24 by simple bit shifts. --- dlls/msvidc32/msvideo1.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/dlls/msvidc32/msvideo1.c b/dlls/msvidc32/msvideo1.c index 02427d98fa3..c7ac025bf83 100644 --- a/dlls/msvidc32/msvideo1.c +++ b/dlls/msvidc32/msvideo1.c @@ -420,14 +420,6 @@ static void convert_depth(char *input, int depth_in, char *output, BITMAPINFOHEA 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, - }; - for (y = 0; y < out_hdr->biHeight; y++) { WORD *src_row = (WORD *)(input + y * stride_in); @@ -436,9 +428,9 @@ static void convert_depth(char *input, int depth_in, char *output, BITMAPINFOHEA for (x = 0; x < out_hdr->biWidth; x++) { WORD pixel = *src_row++; - *out_row++ = convert_5to8[(pixel & 0x7c00u) >> 10]; - *out_row++ = convert_5to8[(pixel & 0x03e0u) >> 5]; - *out_row++ = convert_5to8[(pixel & 0x001fu)]; + *out_row++ = (pixel >> 7) & 0xf8; + *out_row++ = (pixel >> 2) & 0xf8; + *out_row++ = (pixel << 3) & 0xf8; } } } From 08fb8a10ffd26002f22686c3426dd20cfe6fe828 Mon Sep 17 00:00:00 2001 From: Anton Baskanov Date: Tue, 5 Nov 2024 13:59:51 +0700 Subject: [PATCH 4/4] msvidc32: Use the correct channel order for RGB24. --- dlls/msvidc32/msvideo1.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dlls/msvidc32/msvideo1.c b/dlls/msvidc32/msvideo1.c index c7ac025bf83..358948e1201 100644 --- a/dlls/msvidc32/msvideo1.c +++ b/dlls/msvidc32/msvideo1.c @@ -428,9 +428,9 @@ static void convert_depth(char *input, int depth_in, char *output, BITMAPINFOHEA for (x = 0; x < out_hdr->biWidth; x++) { WORD pixel = *src_row++; - *out_row++ = (pixel >> 7) & 0xf8; - *out_row++ = (pixel >> 2) & 0xf8; *out_row++ = (pixel << 3) & 0xf8; + *out_row++ = (pixel >> 2) & 0xf8; + *out_row++ = (pixel >> 7) & 0xf8; } } }