[PATCH 7/9] gdiplus: Implement GdipInitializePalette.

Dmitry Timoshkov dmitry at baikal.ru
Fri Dec 7 04:06:32 CST 2018


Signed-off-by: Dmitry Timoshkov <dmitry at baikal.ru>
---
 dlls/gdiplus/gdiplus.spec |   2 +-
 dlls/gdiplus/image.c      | 108 ++++++++++++++++++++++++++++++++++++++
 include/gdiplusflat.h     |   1 +
 3 files changed, 110 insertions(+), 1 deletion(-)

diff --git a/dlls/gdiplus/gdiplus.spec b/dlls/gdiplus/gdiplus.spec
index e0cf6d5d34..ed9d50c058 100644
--- a/dlls/gdiplus/gdiplus.spec
+++ b/dlls/gdiplus/gdiplus.spec
@@ -615,7 +615,7 @@
 615 stub GdipGetEffectParameterSize
 616 stub GdipGetEffectParameters
 617 stdcall GdipSetEffectParameters(ptr ptr long)
-618 stub GdipInitializePalette
+618 stdcall GdipInitializePalette(ptr long long long ptr)
 619 stdcall GdipBitmapCreateApplyEffect(ptr long ptr ptr ptr ptr long ptr ptr)
 620 stdcall GdipBitmapApplyEffect(ptr ptr ptr long ptr ptr)
 621 stdcall GdipBitmapGetHistogram(ptr long long ptr ptr ptr ptr)
diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c
index 2e844cfcc5..8bd723f031 100644
--- a/dlls/gdiplus/image.c
+++ b/dlls/gdiplus/image.c
@@ -5636,3 +5636,111 @@ GpStatus WINGDIPAPI GdipBitmapGetHistogramSize(HistogramFormat format, UINT *num
     *num_of_entries = 256;
     return Ok;
 }
+
+static GpStatus create_optimal_palette(ColorPalette *palette, INT desired,
+    BOOL transparent, GpBitmap *bitmap)
+{
+    GpStatus status;
+    BitmapData data;
+    HRESULT hr;
+    IWICImagingFactory *factory;
+    IWICPalette *wic_palette;
+
+    if (!bitmap) return InvalidParameter;
+    if (palette->Count < desired) return GenericError;
+
+    status = GdipBitmapLockBits(bitmap, NULL, ImageLockModeRead, PixelFormat24bppRGB, &data);
+    if (status != Ok) return status;
+
+    hr = WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION, &factory);
+    if (hr != S_OK)
+    {
+        GdipBitmapUnlockBits(bitmap, &data);
+        return hresult_to_status(hr);
+    }
+
+    hr = IWICImagingFactory_CreatePalette(factory, &wic_palette);
+    if (hr == S_OK)
+    {
+        IWICBitmap *bitmap;
+
+        /* PixelFormat24bppRGB actually stores the bitmap bits as BGR. */
+        hr = IWICImagingFactory_CreateBitmapFromMemory(factory, data.Width, data.Height,
+                &GUID_WICPixelFormat24bppBGR, data.Stride, data.Stride * data.Width, data.Scan0, &bitmap);
+        if (hr == S_OK)
+        {
+            hr = IWICPalette_InitializeFromBitmap(wic_palette, (IWICBitmapSource *)bitmap, desired, transparent);
+            if (hr == S_OK)
+            {
+                palette->Flags = 0;
+                IWICPalette_GetColorCount(wic_palette, &palette->Count);
+                IWICPalette_GetColors(wic_palette, palette->Count, palette->Entries, &palette->Count);
+            }
+
+            IWICBitmap_Release(bitmap);
+        }
+
+        IWICPalette_Release(wic_palette);
+    }
+
+    IWICImagingFactory_Release(factory);
+    GdipBitmapUnlockBits(bitmap, &data);
+
+    return hresult_to_status(hr);
+}
+
+/*****************************************************************************
+ * GdipInitializePalette [GDIPLUS.@]
+ */
+GpStatus WINGDIPAPI GdipInitializePalette(ColorPalette *palette,
+    PaletteType type, INT desired, BOOL transparent, GpBitmap *bitmap)
+{
+    TRACE("(%p,%d,%d,%d,%p)\n", palette, type, desired, transparent, bitmap);
+
+    if (!palette) return InvalidParameter;
+
+    switch (type)
+    {
+    case PaletteTypeCustom:
+        return Ok;
+
+    case PaletteTypeOptimal:
+        return create_optimal_palette(palette, desired, transparent, bitmap);
+
+    /* WIC palette type enumeration matches these gdiplus enums */
+    case PaletteTypeFixedBW:
+    case PaletteTypeFixedHalftone8:
+    case PaletteTypeFixedHalftone27:
+    case PaletteTypeFixedHalftone64:
+    case PaletteTypeFixedHalftone125:
+    case PaletteTypeFixedHalftone216:
+    case PaletteTypeFixedHalftone252:
+    case PaletteTypeFixedHalftone256:
+    {
+        ColorPalette *wic_palette;
+        GpStatus status = Ok;
+
+        wic_palette = get_palette(NULL, type);
+        if (!wic_palette) return OutOfMemory;
+
+        if (palette->Count >= wic_palette->Count)
+        {
+            palette->Flags = wic_palette->Flags;
+            palette->Count = wic_palette->Count;
+            memcpy(palette->Entries, wic_palette->Entries, wic_palette->Count * sizeof(wic_palette->Entries[0]));
+        }
+        else
+            status = GenericError;
+
+        heap_free(wic_palette);
+
+        return status;
+    }
+
+    default:
+        FIXME("unknown palette type %d\n", type);
+        break;
+    }
+
+    return InvalidParameter;
+}
diff --git a/include/gdiplusflat.h b/include/gdiplusflat.h
index ad944d6a34..57fa6c64f2 100644
--- a/include/gdiplusflat.h
+++ b/include/gdiplusflat.h
@@ -266,6 +266,7 @@ GpStatus WINGDIPAPI GdipGraphicsClear(GpGraphics*,ARGB);
 GpStatus WINGDIPAPI GdipGraphicsSetAbort(GpGraphics*,GdiplusAbort*);
 GpStatus WINGDIPAPI GdipGetVisibleClipBounds(GpGraphics*,GpRectF*);
 GpStatus WINGDIPAPI GdipGetVisibleClipBoundsI(GpGraphics*,GpRect*);
+GpStatus WINGDIPAPI GdipInitializePalette(ColorPalette*,PaletteType,INT,BOOL,GpBitmap*);
 GpStatus WINGDIPAPI GdipIsClipEmpty(GpGraphics*, BOOL*);
 GpStatus WINGDIPAPI GdipIsVisiblePoint(GpGraphics*,REAL,REAL,BOOL*);
 GpStatus WINGDIPAPI GdipIsVisiblePointI(GpGraphics*,INT,INT,BOOL*);
-- 
2.19.2




More information about the wine-devel mailing list