From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/windowscodecs/converter.c | 61 +++++++++++++++++++++++++++- dlls/windowscodecs/regsvr.c | 12 ++++++ dlls/windowscodecs/tests/converter.c | 38 +++++++++++++---- 3 files changed, 102 insertions(+), 9 deletions(-)
diff --git a/dlls/windowscodecs/converter.c b/dlls/windowscodecs/converter.c index b32478d948a..d72f6b2d8d4 100644 --- a/dlls/windowscodecs/converter.c +++ b/dlls/windowscodecs/converter.c @@ -101,13 +101,14 @@ static inline float to_sRGB_component(float f) return 1.055f * powf(f, 1.0f/2.4f) - 0.055f; }
-#if 0 /* FIXME: enable once needed */ static inline float from_sRGB_component(float f) { if (f <= 0.04045f) return f / 12.92f; return powf((f + 0.055f) / 1.055f, 2.4f); }
+#if 0 /* FIXME: enable once needed */ + static void from_sRGB(BYTE *bgr) { float r, g, b; @@ -1687,6 +1688,62 @@ static HRESULT copypixels_to_64bppRGBA(struct FormatConverter *This, const WICRe } }
+static HRESULT copypixels_to_128bppRGBFloat(struct FormatConverter *This, const WICRect *prc, + UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format) +{ + HRESULT hr; + + switch (source_format) + { + case format_48bppRGB: + { + UINT srcstride, srcdatasize; + const USHORT *srcpixel; + const BYTE *srcrow; + float *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= (float *)dstrow; + for (x = 0; x < prc->Width; x++) + { + *dstpixel++ = from_sRGB_component(*srcpixel++ / 65535.0f); + *dstpixel++ = from_sRGB_component(*srcpixel++ / 65535.0f); + *dstpixel++ = from_sRGB_component(*srcpixel++ / 65535.0f); + *dstpixel++ = 1.0f; + } + srcrow += srcstride; + dstrow += cbStride; + } + } + + free(srcdata); + return S_OK; + } + 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}, @@ -1722,7 +1779,7 @@ static const struct pixelformatinfo supported_formats[] = { {format_96bppRGBFloat, &GUID_WICPixelFormat96bppRGBFloat, NULL}, {format_128bppRGBAFloat, &GUID_WICPixelFormat128bppRGBAFloat, NULL}, {format_128bppPRGBAFloat, &GUID_WICPixelFormat128bppPRGBAFloat, NULL}, - {format_128bppRGBFloat, &GUID_WICPixelFormat128bppRGBFloat, NULL}, + {format_128bppRGBFloat, &GUID_WICPixelFormat128bppRGBFloat, copypixels_to_128bppRGBFloat }, {format_32bppR10G10B10A2, &GUID_WICPixelFormat32bppR10G10B10A2, NULL}, {0} }; diff --git a/dlls/windowscodecs/regsvr.c b/dlls/windowscodecs/regsvr.c index 4d27f637f78..59bc8263b7d 100644 --- a/dlls/windowscodecs/regsvr.c +++ b/dlls/windowscodecs/regsvr.c @@ -1683,6 +1683,7 @@ static GUID const * const converter_formats[] = { &GUID_WICPixelFormat48bppRGB, &GUID_WICPixelFormat64bppRGBA, &GUID_WICPixelFormat32bppCMYK, + &GUID_WICPixelFormat128bppRGBFloat, NULL };
@@ -2461,6 +2462,17 @@ static struct regsvr_pixelformat const pixelformat_list[] = { WICPixelFormatNumericRepresentationFloat, 1 }, + { &GUID_WICPixelFormat128bppRGBFloat, + "The Wine Project", + "128bpp RGBFloat", + NULL, /* no version */ + &GUID_VendorMicrosoft, + 128, /* bitsperpixel */ + 3, /* channel count */ + channel_masks_128bit, + WICPixelFormatNumericRepresentationFloat, + 0 + }, { NULL } /* list terminator */ };
diff --git a/dlls/windowscodecs/tests/converter.c b/dlls/windowscodecs/tests/converter.c index bd9a18122d4..1657a8b6abd 100644 --- a/dlls/windowscodecs/tests/converter.c +++ b/dlls/windowscodecs/tests/converter.c @@ -233,7 +233,7 @@ static void DeleteTestBitmap(BitmapTestSrc *This)
static BOOL compare_bits(const struct bitmap_data *expect, UINT buffersize, const BYTE *converted_bits) { - BOOL equal; + BOOL equal, is_float = FALSE;
if (IsEqualGUID(expect->format, &GUID_WICPixelFormat32bppBGR)) { @@ -248,11 +248,13 @@ static BOOL compare_bits(const struct bitmap_data *expect, UINT buffersize, cons break; } } - else if (IsEqualGUID(expect->format, &GUID_WICPixelFormat32bppGrayFloat)) + else if (IsEqualGUID(expect->format, &GUID_WICPixelFormat32bppGrayFloat) + || IsEqualGUID(expect->format, &GUID_WICPixelFormat128bppRGBFloat)) { UINT i; const float *a=(const float*)expect->bits, *b=(const float*)converted_bits; equal=TRUE; + is_float = TRUE; for (i=0; i<(buffersize/4); i++) if (!near_equal(a[i], b[i])) { @@ -297,14 +299,28 @@ static BOOL compare_bits(const struct bitmap_data *expect, UINT buffersize, cons if (!equal && winetest_debug > 1) { UINT i, bps; + bps = expect->bpp / 8; if (!bps) bps = buffersize; printf("converted_bits (%u bytes):\n ", buffersize); - for (i = 0; i < buffersize; i++) + if (is_float) + { + const float *src = (const float *)converted_bits; + for (i = 0; i < buffersize / 4; i++) + { + printf("%f,", src[i]); + if (!((i + 1) % 32)) printf("\n "); + else if (!((i+1) % bps)) printf(" "); + } + } + else { - printf("%u,", converted_bits[i]); - if (!((i + 1) % 32)) printf("\n "); - else if (!((i+1) % bps)) printf(" "); + for (i = 0; i < buffersize; i++) + { + printf("%u,", converted_bits[i]); + if (!((i + 1) % 32)) printf("\n "); + else if (!((i+1) % bps)) printf(" "); + } } printf("\n"); } @@ -649,6 +665,12 @@ static const WORD bits_64bppRGBA_2[] = { static const struct bitmap_data testdata_64bppRGBA_2 = { &GUID_WICPixelFormat64bppRGBA, 64, (BYTE*)bits_64bppRGBA_2, 3, 2, 96.0, 96.0};
+static const float bits_128bppRGBFloat[] = { + 0.0f,0.0f,0.0f,1.0f, 0.0f,1.0f,0.0f,1.0f, 0.214039f,0.214053f,0.214039f,1.0f, + 1.0f,1.0f,1.0f,1.0f, 0.000012f,0.000012f,0.000012f,1.0f, 0.0f,0.0f,0.000012f,1.0f,}; +static const struct bitmap_data testdata_128bppRGBFloat = { + &GUID_WICPixelFormat128bppRGBFloat, 128, (const BYTE *)bits_128bppRGBFloat, 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; @@ -776,7 +798,7 @@ static void test_can_convert(void) {WIC_PIXEL_FORMAT(96bppRGBFloat), TRUE, TRUE, 35, TRUE}, {WIC_PIXEL_FORMAT(128bppRGBAFloat), TRUE, TRUE, 35}, {WIC_PIXEL_FORMAT(128bppPRGBAFloat), TRUE, TRUE, 35}, - {WIC_PIXEL_FORMAT(128bppRGBFloat), TRUE, TRUE, 35}, + {WIC_PIXEL_FORMAT(128bppRGBFloat), TRUE, TRUE, 34},
{WIC_PIXEL_FORMAT(32bppCMYK)},
@@ -2272,6 +2294,8 @@ START_TEST(converter) test_conversion(&testdata_32bppBGRA, &testdata_16bppBGRA5551, "32bppBGRA -> 16bppBGRA5551", FALSE); test_conversion(&testdata_48bppRGB, &testdata_64bppRGBA_2, "48bppRGB -> 64bppRGBA", FALSE);
+ test_conversion(&testdata_48bppRGB, &testdata_128bppRGBFloat, "48bppRGB -> 128bppRGBFloat", FALSE); + test_invalid_conversion(); test_default_converter(); test_can_convert();