From cfaeaaa993d55a72e6925236355ef4ce9eca0063 Mon Sep 17 00:00:00 2001 From: Thomas Csovcsity <46087964+thc13@users.noreply.github.com> Date: Thu, 6 Jan 2022 01:56:45 +0100 Subject: [PATCH] [WINDOWSCODECS] Add converter for WICPixelFormat32bppRGBA (#4239) This fixes CORE-15708 "PdfSam 3.3.5 setup can not decode bmp" https://jira.reactos.org/browse/CORE-15708 Wine does not have this issue, but it did not have it back when last sync to WineStaging-4.18 was done. This commit is as near as possible to actual wine-7.0-rc3 version. This wine code uses reverse_bgr8 instead of own convert_rgba_to_bgra, but it leads to wrong colors. --- dll/win32/windowscodecs/bmpdecode.c | 1 + dll/win32/windowscodecs/converter.c | 52 +++++++++++++++++---- dll/win32/windowscodecs/main.c | 21 +++++++++ dll/win32/windowscodecs/wincodecs_private.h | 1 + 4 files changed, 65 insertions(+), 10 deletions(-) diff --git a/dll/win32/windowscodecs/bmpdecode.c b/dll/win32/windowscodecs/bmpdecode.c index f5a2589d68a..5ee4ac38ccb 100644 --- a/dll/win32/windowscodecs/bmpdecode.c +++ b/dll/win32/windowscodecs/bmpdecode.c @@ -744,6 +744,7 @@ static const struct bitfields_format bitfields_formats[] = { {16,0xf800,0x7e0,0x1f,0,&GUID_WICPixelFormat16bppBGR565,BmpFrameDecode_ReadUncompressed}, {32,0xff0000,0xff00,0xff,0,&GUID_WICPixelFormat32bppBGR,BmpFrameDecode_ReadUncompressed}, {32,0xff0000,0xff00,0xff,0xff000000,&GUID_WICPixelFormat32bppBGRA,BmpFrameDecode_ReadUncompressed}, + {32,0xff000000,0xff0000,0xff00,0xff,&GUID_WICPixelFormat32bppRGBA,BmpFrameDecode_ReadUncompressed}, {32,0xff,0xff00,0xff0000,0,&GUID_WICPixelFormat32bppBGR,BmpFrameDecode_ReadRGB8}, {0} }; diff --git a/dll/win32/windowscodecs/converter.c b/dll/win32/windowscodecs/converter.c index dcc2f05693f..cac2ac1aa5a 100644 --- a/dll/win32/windowscodecs/converter.c +++ b/dll/win32/windowscodecs/converter.c @@ -722,6 +722,15 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe pbBuffer[cbStride*y+4*x+3] = 0xff; } return S_OK; + case format_32bppRGBA: + if (prc) + { + HRESULT res; + res = IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer); + if (FAILED(res)) return res; + convert_rgba_to_bgra(4, pbBuffer, prc->Width, prc->Height, cbStride); + } + return S_OK; case format_32bppBGRA: if (prc) return IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer); @@ -859,6 +868,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe } return S_OK; default: + FIXME("Unimplemented conversion path!\n"); return WINCODEC_ERR_UNSUPPORTEDOPERATION; } } @@ -1038,6 +1048,7 @@ static HRESULT copypixels_to_24bppBGR(struct FormatConverter *This, const WICRec case format_32bppBGR: case format_32bppBGRA: case format_32bppPBGRA: + case format_32bppRGBA: if (prc) { HRESULT res; @@ -1061,17 +1072,38 @@ static HRESULT copypixels_to_24bppBGR(struct FormatConverter *This, const WICRec { srcrow = srcdata; dstrow = pbBuffer; - for (y=0; yHeight; y++) { - srcpixel=srcrow; - dstpixel=dstrow; - for (x=0; xWidth; x++) { - *dstpixel++=*srcpixel++; /* blue */ - *dstpixel++=*srcpixel++; /* green */ - *dstpixel++=*srcpixel++; /* red */ - srcpixel++; /* alpha */ + + if (source_format == format_32bppRGBA) + { + for (y = 0; y < prc->Height; y++) + { + srcpixel = srcrow; + dstpixel = dstrow; + for (x = 0; x < prc->Width; x++) { + *dstpixel++ = srcpixel[2]; /* blue */ + *dstpixel++ = srcpixel[1]; /* green */ + *dstpixel++ = srcpixel[0]; /* red */ + srcpixel += 4; + } + srcrow += srcstride; + dstrow += cbStride; + } + } + else + { + for (y = 0; y < prc->Height; y++) + { + srcpixel = srcrow; + dstpixel = dstrow; + for (x = 0; x < prc->Width; x++) { + *dstpixel++ = *srcpixel++; /* blue */ + *dstpixel++ = *srcpixel++; /* green */ + *dstpixel++ = *srcpixel++; /* red */ + srcpixel++; /* alpha */ + } + srcrow += srcstride; + dstrow += cbStride; } - srcrow += srcstride; - dstrow += cbStride; } } diff --git a/dll/win32/windowscodecs/main.c b/dll/win32/windowscodecs/main.c index 78281519b81..751f4625133 100644 --- a/dll/win32/windowscodecs/main.c +++ b/dll/win32/windowscodecs/main.c @@ -228,6 +228,27 @@ void reverse_bgr8(UINT bytesperpixel, LPBYTE bits, UINT width, UINT height, INT } } +void convert_rgba_to_bgra(UINT bytesperpixel, LPBYTE bits, UINT width, UINT height, INT stride) +{ + UINT x, y; + BYTE *pixel, temp; + + for (y=0; y