[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.
This commit is contained in:
Thomas Csovcsity 2022-01-06 01:56:45 +01:00 committed by GitHub
parent 1723c223e3
commit cfaeaaa993
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 65 additions and 10 deletions

View file

@ -744,6 +744,7 @@ static const struct bitfields_format bitfields_formats[] = {
{16,0xf800,0x7e0,0x1f,0,&GUID_WICPixelFormat16bppBGR565,BmpFrameDecode_ReadUncompressed}, {16,0xf800,0x7e0,0x1f,0,&GUID_WICPixelFormat16bppBGR565,BmpFrameDecode_ReadUncompressed},
{32,0xff0000,0xff00,0xff,0,&GUID_WICPixelFormat32bppBGR,BmpFrameDecode_ReadUncompressed}, {32,0xff0000,0xff00,0xff,0,&GUID_WICPixelFormat32bppBGR,BmpFrameDecode_ReadUncompressed},
{32,0xff0000,0xff00,0xff,0xff000000,&GUID_WICPixelFormat32bppBGRA,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}, {32,0xff,0xff00,0xff0000,0,&GUID_WICPixelFormat32bppBGR,BmpFrameDecode_ReadRGB8},
{0} {0}
}; };

View file

@ -722,6 +722,15 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe
pbBuffer[cbStride*y+4*x+3] = 0xff; pbBuffer[cbStride*y+4*x+3] = 0xff;
} }
return S_OK; 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: case format_32bppBGRA:
if (prc) if (prc)
return IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer); 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; return S_OK;
default: default:
FIXME("Unimplemented conversion path!\n");
return WINCODEC_ERR_UNSUPPORTEDOPERATION; return WINCODEC_ERR_UNSUPPORTEDOPERATION;
} }
} }
@ -1038,6 +1048,7 @@ static HRESULT copypixels_to_24bppBGR(struct FormatConverter *This, const WICRec
case format_32bppBGR: case format_32bppBGR:
case format_32bppBGRA: case format_32bppBGRA:
case format_32bppPBGRA: case format_32bppPBGRA:
case format_32bppRGBA:
if (prc) if (prc)
{ {
HRESULT res; HRESULT res;
@ -1061,17 +1072,38 @@ static HRESULT copypixels_to_24bppBGR(struct FormatConverter *This, const WICRec
{ {
srcrow = srcdata; srcrow = srcdata;
dstrow = pbBuffer; dstrow = pbBuffer;
for (y=0; y<prc->Height; y++) {
srcpixel=srcrow; if (source_format == format_32bppRGBA)
dstpixel=dstrow; {
for (x=0; x<prc->Width; x++) { for (y = 0; y < prc->Height; y++)
*dstpixel++=*srcpixel++; /* blue */ {
*dstpixel++=*srcpixel++; /* green */ srcpixel = srcrow;
*dstpixel++=*srcpixel++; /* red */ dstpixel = dstrow;
srcpixel++; /* alpha */ 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;
} }
} }

View file

@ -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 get_pixelformat_bpp(const GUID *pixelformat, UINT *bpp)
{ {
HRESULT hr; HRESULT hr;

View file

@ -184,6 +184,7 @@ extern HRESULT write_source(IWICBitmapFrameEncode *iface,
INT width, INT height) DECLSPEC_HIDDEN; INT width, INT height) DECLSPEC_HIDDEN;
extern void reverse_bgr8(UINT bytesperpixel, LPBYTE bits, UINT width, UINT height, INT stride) 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; extern HRESULT get_pixelformat_bpp(const GUID *pixelformat, UINT *bpp) DECLSPEC_HIDDEN;