diff --git a/dlls/windowscodecs/converter.c b/dlls/windowscodecs/converter.c index 4720a360feb..b1ee044d718 100644 --- a/dlls/windowscodecs/converter.c +++ b/dlls/windowscodecs/converter.c @@ -1555,6 +1555,66 @@ static HRESULT copypixels_to_16bppBGRA5551(struct FormatConverter *This, const W } } +static HRESULT copypixels_to_64bppRGBA(struct FormatConverter *This, const WICRect *prc, + UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format) +{ + HRESULT hr; + + switch (source_format) + { + case format_64bppRGBA: + if (prc) + return IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer); + return S_OK; + + case format_48bppRGB: + { + UINT srcstride, srcdatasize; + const USHORT *srcpixel; + const BYTE *srcrow; + USHORT *dstpixel; + BYTE *srcdata; + BYTE *dstrow; + INT x, y; + + if (!prc) + return S_OK; + + srcstride = 6 * prc->Width; + srcdatasize = srcstride * prc->Height; + + srcdata = malloc(srcdatasize); + if (!srcdata) return E_OUTOFMEMORY; + + hr = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); + if (SUCCEEDED(hr)) + { + srcrow = srcdata; + dstrow = pbBuffer; + for (y = 0; y < prc->Height; y++) + { + srcpixel = (USHORT *)srcrow; + dstpixel= (USHORT *)dstrow; + for (x = 0; x < prc->Width; x++) + { + *dstpixel++ = *srcpixel++; + *dstpixel++ = *srcpixel++; + *dstpixel++ = *srcpixel++; + *dstpixel++ = 65535; + } + srcrow += srcstride; + dstrow += cbStride; + } + } + free(srcdata); + return hr; + } + default: + FIXME("Unimplemented conversion path %d.\n", source_format); + return WINCODEC_ERR_UNSUPPORTEDOPERATION; + } +} + static const struct pixelformatinfo supported_formats[] = { {format_1bppIndexed, &GUID_WICPixelFormat1bppIndexed, NULL, TRUE}, {format_2bppIndexed, &GUID_WICPixelFormat2bppIndexed, NULL, TRUE}, @@ -1578,7 +1638,7 @@ static const struct pixelformatinfo supported_formats[] = { {format_32bppPBGRA, &GUID_WICPixelFormat32bppPBGRA, copypixels_to_32bppPBGRA}, {format_32bppPRGBA, &GUID_WICPixelFormat32bppPRGBA, copypixels_to_32bppPRGBA}, {format_48bppRGB, &GUID_WICPixelFormat48bppRGB, NULL}, - {format_64bppRGBA, &GUID_WICPixelFormat64bppRGBA, NULL}, + {format_64bppRGBA, &GUID_WICPixelFormat64bppRGBA, copypixels_to_64bppRGBA}, {format_32bppCMYK, &GUID_WICPixelFormat32bppCMYK, NULL}, {0} }; diff --git a/dlls/windowscodecs/tests/converter.c b/dlls/windowscodecs/tests/converter.c index ff2a1e0a067..fd617a1feb7 100644 --- a/dlls/windowscodecs/tests/converter.c +++ b/dlls/windowscodecs/tests/converter.c @@ -622,6 +622,20 @@ static const WORD bits_16bppBGRA5551[] = { static const struct bitmap_data testdata_16bppBGRA5551 = { &GUID_WICPixelFormat16bppBGRA5551, 16, (BYTE*)bits_16bppBGRA5551, 32, 2, 96.0, 96.0}; +static const WORD bits_48bppRGB[] = { + 0,0,0, 0,65535,0, 32767,32768,32767, + 65535,65535,65535, 10,10,10, 0,0,10}; + +static const struct bitmap_data testdata_48bppRGB = { + &GUID_WICPixelFormat48bppRGB, 48, (BYTE*)bits_48bppRGB, 3, 2, 96.0, 96.0}; + +static const WORD bits_64bppRGBA_2[] = { + 0,0,0,65535, 0,65535,0,65535, 32767,32768,32767,65535, + 65535,65535,65535,65535, 10,10,10,65535, 0,0,10,65535,}; + +static const struct bitmap_data testdata_64bppRGBA_2 = { + &GUID_WICPixelFormat64bppRGBA, 64, (BYTE*)bits_64bppRGBA_2, 3, 2, 96.0, 96.0}; + static void test_conversion(const struct bitmap_data *src, const struct bitmap_data *dst, const char *name, BOOL todo) { BitmapTestSrc *src_obj; @@ -2075,6 +2089,7 @@ START_TEST(converter) test_conversion(&testdata_32bppGrayFloat, &testdata_24bppBGR_gray, "32bppGrayFloat -> 24bppBGR gray", FALSE); test_conversion(&testdata_32bppGrayFloat, &testdata_8bppGray, "32bppGrayFloat -> 8bppGray", FALSE); test_conversion(&testdata_32bppBGRA, &testdata_16bppBGRA5551, "32bppBGRA -> 16bppBGRA5551", FALSE); + test_conversion(&testdata_48bppRGB, &testdata_64bppRGBA_2, "48bppRGB -> 64bppRGBA", FALSE); test_invalid_conversion(); test_default_converter();