https://git.reactos.org/?p=reactos.git;a=commitdiff;h=cfaeaaa993d55a72e69252...
commit cfaeaaa993d55a72e6925236355ef4ce9eca0063 Author: Thomas Csovcsity 46087964+thc13@users.noreply.github.com AuthorDate: Thu Jan 6 01:56:45 2022 +0100 Commit: GitHub noreply@github.com CommitDate: Thu Jan 6 03:56:45 2022 +0300
[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; 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 */ + + 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<height; y++) + { + pixel = bits + stride * y; + + for (x=0; x<width; x++) + { + temp = pixel[3]; + pixel[3] = pixel[0]; + pixel[0] = pixel[1]; + pixel[1] = pixel[2]; + pixel[2] = temp; + pixel += bytesperpixel; + } + } +} + HRESULT get_pixelformat_bpp(const GUID *pixelformat, UINT *bpp) { HRESULT hr; diff --git a/dll/win32/windowscodecs/wincodecs_private.h b/dll/win32/windowscodecs/wincodecs_private.h index ff192c26399..d5172b6befe 100644 --- a/dll/win32/windowscodecs/wincodecs_private.h +++ b/dll/win32/windowscodecs/wincodecs_private.h @@ -184,6 +184,7 @@ extern HRESULT write_source(IWICBitmapFrameEncode *iface, INT width, INT height) DECLSPEC_HIDDEN;
extern void reverse_bgr8(UINT bytesperpixel, LPBYTE bits, UINT width, UINT height, INT stride) DECLSPEC_HIDDEN; +extern void convert_rgba_to_bgra(UINT bytesperpixel, LPBYTE bits, UINT width, UINT height, INT stride) DECLSPEC_HIDDEN;
extern HRESULT get_pixelformat_bpp(const GUID *pixelformat, UINT *bpp) DECLSPEC_HIDDEN;