[PATCH] windowscodecs: Add support for 32bppRGB, 32bppRGBA and 32bppPRGBA to format converter.

Dmitry Timoshkov dmitry at baikal.ru
Thu Feb 14 20:10:44 CST 2019


Signed-off-by: Dmitry Timoshkov <dmitry at baikal.ru>
---
 dlls/windowscodecs/converter.c       | 112 +++++++++++++++++++++++++++
 dlls/windowscodecs/info.c            |   2 +
 dlls/windowscodecs/regsvr.c          |  36 +++++++++
 dlls/windowscodecs/tests/converter.c |  45 ++++++++++-
 4 files changed, 194 insertions(+), 1 deletion(-)

diff --git a/dlls/windowscodecs/converter.c b/dlls/windowscodecs/converter.c
index 83f1339d0c..9083aa04f7 100644
--- a/dlls/windowscodecs/converter.c
+++ b/dlls/windowscodecs/converter.c
@@ -53,8 +53,11 @@ enum pixelformat {
     format_24bppRGB,
     format_32bppGrayFloat,
     format_32bppBGR,
+    format_32bppRGB,
     format_32bppBGRA,
+    format_32bppRGBA,
     format_32bppPBGRA,
+    format_32bppPRGBA,
     format_48bppRGB,
     format_64bppRGBA,
     format_32bppCMYK,
@@ -858,6 +861,63 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe
     }
 }
 
+static HRESULT copypixels_to_32bppRGBA(struct FormatConverter *This, const WICRect *prc,
+    UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
+{
+    HRESULT hr;
+
+    switch (source_format)
+    {
+    case format_32bppRGB:
+        if (prc)
+        {
+            INT x, y;
+
+            hr = IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer);
+            if (FAILED(hr)) return hr;
+
+            /* set all alpha values to 255 */
+            for (y=0; y<prc->Height; y++)
+                for (x=0; x<prc->Width; x++)
+                    pbBuffer[cbStride*y+4*x+3] = 0xff;
+        }
+        return S_OK;
+
+    case format_32bppRGBA:
+        if (prc)
+            return IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer);
+        return S_OK;
+
+    case format_32bppPRGBA:
+        if (prc)
+        {
+            INT x, y;
+
+            hr = IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer);
+            if (FAILED(hr)) return hr;
+
+            for (y=0; y<prc->Height; y++)
+                for (x=0; x<prc->Width; x++)
+                {
+                    BYTE alpha = pbBuffer[cbStride*y+4*x+3];
+                    if (alpha != 0 && alpha != 255)
+                    {
+                        pbBuffer[cbStride*y+4*x] = pbBuffer[cbStride*y+4*x] * 255 / alpha;
+                        pbBuffer[cbStride*y+4*x+1] = pbBuffer[cbStride*y+4*x+1] * 255 / alpha;
+                        pbBuffer[cbStride*y+4*x+2] = pbBuffer[cbStride*y+4*x+2] * 255 / alpha;
+                    }
+                }
+        }
+        return S_OK;
+
+    default:
+        hr = copypixels_to_32bppBGRA(This, prc, cbStride, cbBufferSize, pbBuffer, source_format);
+        if (SUCCEEDED(hr) && prc)
+              reverse_bgr8(4, pbBuffer, prc->Width, prc->Height, cbStride);
+        return hr;
+    }
+}
+
 static HRESULT copypixels_to_32bppBGR(struct FormatConverter *This, const WICRect *prc,
     UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
 {
@@ -874,6 +934,22 @@ static HRESULT copypixels_to_32bppBGR(struct FormatConverter *This, const WICRec
     }
 }
 
+static HRESULT copypixels_to_32bppRGB(struct FormatConverter *This, const WICRect *prc,
+    UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
+{
+    switch (source_format)
+    {
+    case format_32bppRGB:
+    case format_32bppRGBA:
+    case format_32bppPRGBA:
+        if (prc)
+            return IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer);
+        return S_OK;
+    default:
+        return copypixels_to_32bppRGBA(This, prc, cbStride, cbBufferSize, pbBuffer, source_format);
+    }
+}
+
 static HRESULT copypixels_to_32bppPBGRA(struct FormatConverter *This, const WICRect *prc,
     UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
 {
@@ -907,6 +983,39 @@ static HRESULT copypixels_to_32bppPBGRA(struct FormatConverter *This, const WICR
     }
 }
 
+static HRESULT copypixels_to_32bppPRGBA(struct FormatConverter *This, const WICRect *prc,
+    UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
+{
+    HRESULT hr;
+
+    switch (source_format)
+    {
+    case format_32bppPRGBA:
+        if (prc)
+            return IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer);
+        return S_OK;
+    default:
+        hr = copypixels_to_32bppRGBA(This, prc, cbStride, cbBufferSize, pbBuffer, source_format);
+        if (SUCCEEDED(hr) && prc)
+        {
+            INT x, y;
+
+            for (y=0; y<prc->Height; y++)
+                for (x=0; x<prc->Width; x++)
+                {
+                    BYTE alpha = pbBuffer[cbStride*y+4*x+3];
+                    if (alpha != 255)
+                    {
+                        pbBuffer[cbStride*y+4*x] = pbBuffer[cbStride*y+4*x] * alpha / 255;
+                        pbBuffer[cbStride*y+4*x+1] = pbBuffer[cbStride*y+4*x+1] * alpha / 255;
+                        pbBuffer[cbStride*y+4*x+2] = pbBuffer[cbStride*y+4*x+2] * alpha / 255;
+                    }
+                }
+        }
+        return hr;
+    }
+}
+
 static HRESULT copypixels_to_24bppBGR(struct FormatConverter *This, const WICRect *prc,
     UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format)
 {
@@ -1326,8 +1435,11 @@ static const struct pixelformatinfo supported_formats[] = {
     {format_24bppRGB, &GUID_WICPixelFormat24bppRGB, copypixels_to_24bppRGB},
     {format_32bppGrayFloat, &GUID_WICPixelFormat32bppGrayFloat, copypixels_to_32bppGrayFloat},
     {format_32bppBGR, &GUID_WICPixelFormat32bppBGR, copypixels_to_32bppBGR},
+    {format_32bppRGB, &GUID_WICPixelFormat32bppRGB, copypixels_to_32bppRGB},
     {format_32bppBGRA, &GUID_WICPixelFormat32bppBGRA, copypixels_to_32bppBGRA},
+    {format_32bppRGBA, &GUID_WICPixelFormat32bppRGBA, copypixels_to_32bppRGBA},
     {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_32bppCMYK, &GUID_WICPixelFormat32bppCMYK, NULL},
diff --git a/dlls/windowscodecs/info.c b/dlls/windowscodecs/info.c
index 9bec30fcea..0a86266396 100644
--- a/dlls/windowscodecs/info.c
+++ b/dlls/windowscodecs/info.c
@@ -2483,6 +2483,8 @@ HRESULT WINAPI WICConvertBitmapSource(REFWICPixelFormatGUID dstFormat, IWICBitma
     BOOL canconvert;
     ULONG num_fetched;
 
+    TRACE("%s,%p,%p\n", debugstr_guid(dstFormat), pISrc, ppIDst);
+
     res = IWICBitmapSource_GetPixelFormat(pISrc, &srcFormat);
     if (FAILED(res)) return res;
 
diff --git a/dlls/windowscodecs/regsvr.c b/dlls/windowscodecs/regsvr.c
index 9a580c67c5..c8338f1bea 100644
--- a/dlls/windowscodecs/regsvr.c
+++ b/dlls/windowscodecs/regsvr.c
@@ -1463,8 +1463,11 @@ static GUID const * const converter_formats[] = {
     &GUID_WICPixelFormat24bppBGR,
     &GUID_WICPixelFormat24bppRGB,
     &GUID_WICPixelFormat32bppBGR,
+    &GUID_WICPixelFormat32bppRGB,
     &GUID_WICPixelFormat32bppBGRA,
+    &GUID_WICPixelFormat32bppRGBA,
     &GUID_WICPixelFormat32bppPBGRA,
+    &GUID_WICPixelFormat32bppPRGBA,
     &GUID_WICPixelFormat32bppGrayFloat,
     &GUID_WICPixelFormat48bppRGB,
     &GUID_WICPixelFormat64bppRGBA,
@@ -1928,6 +1931,17 @@ static struct regsvr_pixelformat const pixelformat_list[] = {
         WICPixelFormatNumericRepresentationUnsignedInteger,
         0
     },
+    {   &GUID_WICPixelFormat32bppRGB,
+        "The Wine Project",
+        "32bpp RGB",
+        NULL, /* no version */
+        &GUID_VendorMicrosoft,
+        32, /* bitsperpixel */
+        3, /* channel count */
+        channel_masks_8bit,
+        WICPixelFormatNumericRepresentationUnsignedInteger,
+        0
+    },
     {   &GUID_WICPixelFormat32bppBGRA,
         "The Wine Project",
         "32bpp BGRA",
@@ -1939,6 +1953,17 @@ static struct regsvr_pixelformat const pixelformat_list[] = {
         WICPixelFormatNumericRepresentationUnsignedInteger,
         1
     },
+    {   &GUID_WICPixelFormat32bppRGBA,
+        "The Wine Project",
+        "32bpp RGBA",
+        NULL, /* no version */
+        &GUID_VendorMicrosoft,
+        32, /* bitsperpixel */
+        4, /* channel count */
+        channel_masks_8bit,
+        WICPixelFormatNumericRepresentationUnsignedInteger,
+        1
+    },
     {   &GUID_WICPixelFormat32bppPBGRA,
         "The Wine Project",
         "32bpp PBGRA",
@@ -1950,6 +1975,17 @@ static struct regsvr_pixelformat const pixelformat_list[] = {
         WICPixelFormatNumericRepresentationUnsignedInteger,
         1
     },
+    {   &GUID_WICPixelFormat32bppPRGBA,
+        "The Wine Project",
+        "32bpp PRGBA",
+        NULL, /* no version */
+        &GUID_VendorMicrosoft,
+        32, /* bitsperpixel */
+        4, /* channel count */
+        channel_masks_8bit,
+        WICPixelFormatNumericRepresentationUnsignedInteger,
+        1
+    },
     {   &GUID_WICPixelFormat32bppGrayFloat,
         "The Wine Project",
         "32bpp GrayFloat",
diff --git a/dlls/windowscodecs/tests/converter.c b/dlls/windowscodecs/tests/converter.c
index 1cfa29b4df..455c6ae2e6 100644
--- a/dlls/windowscodecs/tests/converter.c
+++ b/dlls/windowscodecs/tests/converter.c
@@ -294,6 +294,21 @@ static BOOL compare_bits(const struct bitmap_data *expect, UINT buffersize, cons
     if (!equal && expect->alt_data)
         equal = compare_bits(expect->alt_data, buffersize, converted_bits);
 
+    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++)
+        {
+            printf("%u,", converted_bits[i]);
+            if (!((i + 1) % 32)) printf("\n    ");
+            else if (!((i+1) % bps)) printf(" ");
+        }
+        printf("\n");
+    }
+
     return equal;
 }
 
@@ -441,6 +456,10 @@ static const BYTE bits_32bppBGR[] = {
     0,255,255,80, 255,0,255,80, 255,255,0,80, 255,255,255,80, 0,255,255,80, 255,0,255,80, 255,255,0,80, 255,255,255,80};
 static const struct bitmap_data testdata_32bppBGR = {
     &GUID_WICPixelFormat32bppBGR, 32, bits_32bppBGR, 32, 2, 96.0, 96.0};
+static const struct bitmap_data testdata_32bppBGRA80 = {
+    &GUID_WICPixelFormat32bppBGRA, 32, bits_32bppBGR, 32, 2, 96.0, 96.0};
+static const struct bitmap_data testdata_32bppRGBA80 = {
+    &GUID_WICPixelFormat32bppRGBA, 32, bits_32bppBGR, 32, 2, 96.0, 96.0};
 
 static const BYTE bits_32bppBGRA[] = {
     255,0,0,255, 0,255,0,255, 0,0,255,255, 0,0,0,255, 255,0,0,255, 0,255,0,255, 0,0,255,255, 0,0,0,255,
@@ -453,6 +472,24 @@ static const BYTE bits_32bppBGRA[] = {
     0,255,255,255, 255,0,255,255, 255,255,0,255, 255,255,255,255, 0,255,255,255, 255,0,255,255, 255,255,0,255, 255,255,255,255};
 static const struct bitmap_data testdata_32bppBGRA = {
     &GUID_WICPixelFormat32bppBGRA, 32, bits_32bppBGRA, 32, 2, 96.0, 96.0};
+static const struct bitmap_data testdata_32bppRGBA = {
+    &GUID_WICPixelFormat32bppRGBA, 32, bits_32bppBGRA, 32, 2, 96.0, 96.0};
+static const struct bitmap_data testdata_32bppRGB = {
+    &GUID_WICPixelFormat32bppRGB, 32, bits_32bppBGRA, 32, 2, 96.0, 96.0};
+
+static const BYTE bits_32bppPBGRA[] = {
+    80,0,0,80, 0,80,0,80, 0,0,80,80, 0,0,0,80, 80,0,0,80, 0,80,0,80, 0,0,80,80, 0,0,0,80,
+    80,0,0,80, 0,80,0,80, 0,0,80,80, 0,0,0,80, 80,0,0,80, 0,80,0,80, 0,0,80,80, 0,0,0,80,
+    80,0,0,80, 0,80,0,80, 0,0,80,80, 0,0,0,80, 80,0,0,80, 0,80,0,80, 0,0,80,80, 0,0,0,80,
+    80,0,0,80, 0,80,0,80, 0,0,80,80, 0,0,0,80, 80,0,0,80, 0,80,0,80, 0,0,80,80, 0,0,0,80,
+    0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80, 0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80,
+    0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80, 0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80,
+    0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80, 0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80,
+    0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80, 0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80};
+static const struct bitmap_data testdata_32bppPBGRA = {
+    &GUID_WICPixelFormat32bppPBGRA, 32, bits_32bppPBGRA, 32, 2, 96.0, 96.0};
+static const struct bitmap_data testdata_32bppPRGBA = {
+    &GUID_WICPixelFormat32bppPRGBA, 32, bits_32bppPBGRA, 32, 2, 96.0, 96.0};
 
 /* XP and 2003 use linear color conversion, later versions use sRGB gamma */
 static const float bits_32bppGrayFloat_xp[] = {
@@ -518,7 +555,7 @@ static void test_conversion(const struct bitmap_data *src, const struct bitmap_d
     hr = WICConvertBitmapSource(dst->format, &src_obj->IWICBitmapSource_iface, &dst_bitmap);
     todo_wine_if (todo)
         ok(hr == S_OK ||
-           broken(hr == E_INVALIDARG) /* XP */, "WICConvertBitmapSource(%s) failed, hr=%x\n", name, hr);
+           broken(hr == E_INVALIDARG || hr == WINCODEC_ERR_COMPONENTNOTFOUND) /* XP */, "WICConvertBitmapSource(%s) failed, hr=%x\n", name, hr);
 
     if (hr == S_OK)
     {
@@ -1751,6 +1788,12 @@ START_TEST(converter)
     test_conversion(&testdata_32bppBGRA, &testdata_32bppBGR, "BGRA -> BGR", FALSE);
     test_conversion(&testdata_32bppBGR, &testdata_32bppBGRA, "BGR -> BGRA", FALSE);
     test_conversion(&testdata_32bppBGRA, &testdata_32bppBGRA, "BGRA -> BGRA", FALSE);
+    test_conversion(&testdata_32bppBGRA80, &testdata_32bppPBGRA, "BGRA -> PBGRA", FALSE);
+
+    test_conversion(&testdata_32bppRGBA, &testdata_32bppRGB, "RGBA -> RGB", FALSE);
+    test_conversion(&testdata_32bppRGB, &testdata_32bppRGBA, "RGB -> RGBA", FALSE);
+    test_conversion(&testdata_32bppRGBA, &testdata_32bppRGBA, "RGBA -> RGBA", FALSE);
+    test_conversion(&testdata_32bppRGBA80, &testdata_32bppPRGBA, "RGBA -> PRGBA", FALSE);
 
     test_conversion(&testdata_24bppBGR, &testdata_24bppBGR, "24bppBGR -> 24bppBGR", FALSE);
     test_conversion(&testdata_24bppBGR, &testdata_24bppRGB, "24bppBGR -> 24bppRGB", FALSE);
-- 
2.20.1




More information about the wine-devel mailing list