From cbc486aca1c0691df09801f5dc3ef039272a66a7 Mon Sep 17 00:00:00 2001 From: Dmitry Timoshkov Date: Thu, 31 Jan 2019 09:56:03 +0800 Subject: [PATCH] gdiplus: Implement GdipInitializePalette. Signed-off-by: Dmitry Timoshkov Signed-off-by: Vincent Povirk Signed-off-by: Alexandre Julliard --- 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 e0cf6d5d341..ed9d50c058d 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 8a136eff091..1966401507c 100644 --- a/dlls/gdiplus/image.c +++ b/dlls/gdiplus/image.c @@ -5640,3 +5640,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 ad944d6a345..57fa6c64f22 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*);