From eec7fc946887f9f93de2bc2c00cb171f0de5bb53 Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Mon, 7 Mar 2016 17:22:55 +0800
Subject: windowscodecs: Add support for converting 32bpp grayscale float to
 24bpp BGR format.

---
 dlls/windowscodecs/converter.c       | 43 ++++++++++++++++++++++++++++++++++++
 dlls/windowscodecs/tests/converter.c |  7 ++++++
 2 files changed, 50 insertions(+)

diff --git a/dlls/windowscodecs/converter.c b/dlls/windowscodecs/converter.c
index 7fc8a9c..322b2d1 100644
--- a/dlls/windowscodecs/converter.c
+++ b/dlls/windowscodecs/converter.c
@@ -970,6 +970,49 @@ static HRESULT copypixels_to_24bppBGR(struct FormatConverter *This, const WICRec
             return res;
         }
         return S_OK;
+
+    case format_32bppGrayFloat:
+        if (prc)
+        {
+            BYTE *srcdata;
+            UINT srcstride, srcdatasize;
+
+            srcstride = 4 * prc->Width;
+            srcdatasize = srcstride * prc->Height;
+
+            srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize);
+            if (!srcdata) return E_OUTOFMEMORY;
+
+            hr = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata);
+
+            if (SUCCEEDED(hr))
+            {
+                INT x, y;
+                BYTE *src = srcdata, *dst = pbBuffer;
+
+                for (y = 0; y < prc->Height; y++)
+                {
+                    float *gray_float = (float *)src;
+                    BYTE *bgr = dst;
+
+                    for (x = 0; x < prc->Width; x++)
+                    {
+                        BYTE gray = (BYTE)floorf(to_sRGB_component(gray_float[x]) * 255.0f + 0.51f);
+                        *bgr++ = gray;
+                        *bgr++ = gray;
+                        *bgr++ = gray;
+                    }
+                    src += srcstride;
+                    dst += cbStride;
+                }
+            }
+
+            HeapFree(GetProcessHeap(), 0, srcdata);
+
+            return hr;
+        }
+        return S_OK;
+
     default:
         FIXME("Unimplemented conversion path!\n");
         return WINCODEC_ERR_UNSUPPORTEDOPERATION;
diff --git a/dlls/windowscodecs/tests/converter.c b/dlls/windowscodecs/tests/converter.c
index a0a5d31..9dd77a5 100644
--- a/dlls/windowscodecs/tests/converter.c
+++ b/dlls/windowscodecs/tests/converter.c
@@ -374,6 +374,12 @@ static const BYTE bits_8bppGray[] = {
 static const struct bitmap_data testdata_8bppGray = {
     &GUID_WICPixelFormat8bppGray, 8, bits_8bppGray, 4, 2, 96.0, 96.0};
 
+static const BYTE bits_24bppBGR_gray[] = {
+    76,76,76, 220,220,220, 127,127,127, 0,0,0,
+    247,247,247, 145,145,145, 230,230,230, 255,255,255};
+static const struct bitmap_data testdata_24bppBGR_gray = {
+    &GUID_WICPixelFormat24bppBGR, 24, bits_24bppBGR_gray, 4, 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;
@@ -818,6 +824,7 @@ START_TEST(converter)
 
     test_conversion(&testdata_24bppBGR, &testdata_8bppGray, "24bppBGR -> 8bppGray", FALSE);
     test_conversion(&testdata_32bppBGR, &testdata_8bppGray, "32bppBGR -> 8bppGray", FALSE);
+    test_conversion(&testdata_32bppGrayFloat, &testdata_24bppBGR_gray, "32bppGrayFloat -> 24bppBGR gray", FALSE);
 
     test_invalid_conversion();
     test_default_converter();
-- 
2.7.1

