From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/windowscodecs/converter.c | 60 +++++++++++++++++++++++++++- dlls/windowscodecs/regsvr.c | 1 + dlls/windowscodecs/tests/converter.c | 18 ++++++++- 3 files changed, 76 insertions(+), 3 deletions(-)
diff --git a/dlls/windowscodecs/converter.c b/dlls/windowscodecs/converter.c index d72f6b2d8d4..65936e6b30a 100644 --- a/dlls/windowscodecs/converter.c +++ b/dlls/windowscodecs/converter.c @@ -1688,6 +1688,64 @@ static HRESULT copypixels_to_64bppRGBA(struct FormatConverter *This, const WICRe } }
+static HRESULT copypixels_to_128bppRGBAFloat(struct FormatConverter *This, const WICRect *prc, + UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format) +{ + HRESULT hr; + + switch (source_format) + { + case format_24bppBGR: + { + UINT srcstride, srcdatasize; + const BYTE *srcpixel; + const BYTE *srcrow; + float *dstpixel; + BYTE *srcdata; + BYTE *dstrow; + INT x, y; + + if (!prc) + return S_OK; + + srcstride = 3 * 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 = srcrow; + dstpixel= (float *)dstrow; + for (x = 0; x < prc->Width; x++) + { + dstpixel[2] = from_sRGB_component(*srcpixel++ / 255.0f); + dstpixel[1] = from_sRGB_component(*srcpixel++ / 255.0f); + dstpixel[0] = from_sRGB_component(*srcpixel++ / 255.0f); + dstpixel[3] = 1.0f; + + dstpixel += 4; + } + srcrow += srcstride; + dstrow += cbStride; + } + } + + free(srcdata); + return S_OK; + } + default: + FIXME("Unimplemented conversion path %d.\n", source_format); + return WINCODEC_ERR_UNSUPPORTEDOPERATION; + } +} + static HRESULT copypixels_to_128bppRGBFloat(struct FormatConverter *This, const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format) { @@ -1777,7 +1835,7 @@ static const struct pixelformatinfo supported_formats[] = { {format_64bppPBGRA, &GUID_WICPixelFormat64bppPBGRA, NULL}, {format_32bppBGR101010, &GUID_WICPixelFormat32bppBGR101010, NULL}, {format_96bppRGBFloat, &GUID_WICPixelFormat96bppRGBFloat, NULL}, - {format_128bppRGBAFloat, &GUID_WICPixelFormat128bppRGBAFloat, NULL}, + {format_128bppRGBAFloat, &GUID_WICPixelFormat128bppRGBAFloat, copypixels_to_128bppRGBAFloat }, {format_128bppPRGBAFloat, &GUID_WICPixelFormat128bppPRGBAFloat, NULL}, {format_128bppRGBFloat, &GUID_WICPixelFormat128bppRGBFloat, copypixels_to_128bppRGBFloat }, {format_32bppR10G10B10A2, &GUID_WICPixelFormat32bppR10G10B10A2, NULL}, diff --git a/dlls/windowscodecs/regsvr.c b/dlls/windowscodecs/regsvr.c index 71c9d3b736c..1cba56c058d 100644 --- a/dlls/windowscodecs/regsvr.c +++ b/dlls/windowscodecs/regsvr.c @@ -1684,6 +1684,7 @@ static GUID const * const converter_formats[] = { &GUID_WICPixelFormat64bppRGBA, &GUID_WICPixelFormat32bppCMYK, &GUID_WICPixelFormat128bppRGBFloat, + &GUID_WICPixelFormat128bppRGBAFloat, NULL };
diff --git a/dlls/windowscodecs/tests/converter.c b/dlls/windowscodecs/tests/converter.c index 3e12326f68e..8122ba51ff5 100644 --- a/dlls/windowscodecs/tests/converter.c +++ b/dlls/windowscodecs/tests/converter.c @@ -249,7 +249,8 @@ static BOOL compare_bits(const struct bitmap_data *expect, UINT buffersize, cons } } else if (IsEqualGUID(expect->format, &GUID_WICPixelFormat32bppGrayFloat) - || IsEqualGUID(expect->format, &GUID_WICPixelFormat128bppRGBFloat)) + || IsEqualGUID(expect->format, &GUID_WICPixelFormat128bppRGBFloat) + || IsEqualGUID(expect->format, &GUID_WICPixelFormat128bppRGBAFloat)) { UINT i; const float *a=(const float*)expect->bits, *b=(const float*)converted_bits; @@ -671,6 +672,18 @@ static const float bits_128bppRGBFloat[] = { static const struct bitmap_data testdata_128bppRGBFloat = { &GUID_WICPixelFormat128bppRGBFloat, 128, (const BYTE *)bits_128bppRGBFloat, 3, 2, 96.0, 96.0};
+static const BYTE bits_24bppBGR_2[] = { + 0,0,0, 0,255,0, 0,0,255, + 255,0,0, 0,125,0, 0,0,125}; +static const struct bitmap_data testdata_24bppBGR_2 = { + &GUID_WICPixelFormat24bppBGR, 24, bits_24bppBGR_2, 3, 2, 96.0, 96.0}; + +static const float bits_128bppRGBAFloat[] = { + 0.0f,0.0f,0.0f,1.0f, 0.0f,1.0f,0.0f,1.0f, 1.0f,0.0f,0.0f,1.0f, + 0.0f,0.0f,1.0f,1.0f, 0.0f,0.205079f,0.0f,1.0f, 0.205079f,0.0f,0.0f,1.0f}; +static const struct bitmap_data testdata_128bppRGBAFloat = { + &GUID_WICPixelFormat128bppRGBAFloat, 128, (const BYTE *)bits_128bppRGBAFloat, 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; @@ -796,7 +809,7 @@ static void test_can_convert(void) {WIC_PIXEL_FORMAT(48bppBGRFixedPoint)}, {WIC_PIXEL_FORMAT(96bppRGBFixedPoint)}, {WIC_PIXEL_FORMAT(96bppRGBFloat), TRUE, TRUE, 35, TRUE}, - {WIC_PIXEL_FORMAT(128bppRGBAFloat), TRUE, TRUE, 35}, + {WIC_PIXEL_FORMAT(128bppRGBAFloat), TRUE, TRUE, 34}, {WIC_PIXEL_FORMAT(128bppPRGBAFloat), TRUE, TRUE, 35}, {WIC_PIXEL_FORMAT(128bppRGBFloat), TRUE, TRUE, 34},
@@ -2306,6 +2319,7 @@ START_TEST(converter) test_conversion(&testdata_48bppRGB, &testdata_64bppRGBA_2, "48bppRGB -> 64bppRGBA", FALSE);
test_conversion(&testdata_48bppRGB, &testdata_128bppRGBFloat, "48bppRGB -> 128bppRGBFloat", FALSE); + test_conversion(&testdata_24bppBGR_2, &testdata_128bppRGBAFloat, "24bppBGR -> 128bppRGBAFloat", FALSE);
test_invalid_conversion(); test_default_converter();