Signed-off-by: Jeff Smith <whydoubt(a)gmail.com>
---
dlls/gdiplus/image.c | 32 +++++++++++++++--
dlls/gdiplus/tests/image.c | 70 ++++++++++++++++++++++++++++++++++++++
2 files changed, 100 insertions(+), 2 deletions(-)
diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c
index f33e2328bf..ace27cd342 100644
--- a/dlls/gdiplus/image.c
+++ b/dlls/gdiplus/image.c
@@ -53,11 +53,11 @@ static const struct
WICBitmapPaletteType palette_type;
} pixel_formats[] =
{
- { &GUID_WICPixelFormatBlackWhite, PixelFormat1bppIndexed, WICBitmapPaletteTypeFixedBW },
{ &GUID_WICPixelFormat1bppIndexed, PixelFormat1bppIndexed, WICBitmapPaletteTypeFixedBW },
+ { &GUID_WICPixelFormatBlackWhite, PixelFormat1bppIndexed, WICBitmapPaletteTypeFixedBW },
{ &GUID_WICPixelFormat4bppIndexed, PixelFormat4bppIndexed, WICBitmapPaletteTypeFixedHalftone8 },
- { &GUID_WICPixelFormat8bppGray, PixelFormat8bppIndexed, WICBitmapPaletteTypeFixedGray256 },
{ &GUID_WICPixelFormat8bppIndexed, PixelFormat8bppIndexed, WICBitmapPaletteTypeFixedHalftone256 },
+ { &GUID_WICPixelFormat8bppGray, PixelFormat8bppIndexed, WICBitmapPaletteTypeFixedGray256 },
{ &GUID_WICPixelFormat16bppBGR555, PixelFormat16bppRGB555, WICBitmapPaletteTypeFixedHalftone256 },
{ &GUID_WICPixelFormat24bppBGR, PixelFormat24bppRGB, WICBitmapPaletteTypeFixedHalftone256 },
{ &GUID_WICPixelFormat32bppBGR, PixelFormat32bppRGB, WICBitmapPaletteTypeFixedHalftone256 },
@@ -126,6 +126,31 @@ static ColorPalette *get_palette(IWICBitmapFrameDecode *frame, WICBitmapPaletteT
return palette;
}
+static HRESULT set_palette(IWICBitmapFrameEncode *frame, ColorPalette *palette)
+{
+ HRESULT hr;
+ IWICImagingFactory *factory;
+ IWICPalette *wic_palette;
+
+ hr = WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION, &factory);
+ if (FAILED(hr))
+ return hr;
+
+ hr = IWICImagingFactory_CreatePalette(factory, &wic_palette);
+ IWICImagingFactory_Release(factory);
+ if (SUCCEEDED(hr))
+ {
+ hr = IWICPalette_InitializeCustom(wic_palette, palette->Entries, palette->Count);
+
+ if (SUCCEEDED(hr))
+ hr = IWICBitmapFrameEncode_SetPalette(frame, wic_palette);
+
+ IWICPalette_Release(wic_palette);
+ }
+
+ return hr;
+}
+
GpStatus WINGDIPAPI GdipBitmapApplyEffect(GpBitmap* bitmap, CGpEffect* effect,
RECT* roi, BOOL useAuxData, VOID** auxData, INT* auxDataSize)
{
@@ -4566,6 +4591,9 @@ static GpStatus encode_frame_wic(IWICBitmapEncoder *encoder, GpImage *image)
}
}
+ if (SUCCEEDED(hr) && IsIndexedPixelFormat(gdipformat))
+ hr = set_palette(frameencode, image->palette);
+
if (SUCCEEDED(hr))
{
stat = GdipBitmapLockBits(bitmap, &rc, ImageLockModeRead, gdipformat,
diff --git a/dlls/gdiplus/tests/image.c b/dlls/gdiplus/tests/image.c
index 145eadbfd3..56727ce63c 100644
--- a/dlls/gdiplus/tests/image.c
+++ b/dlls/gdiplus/tests/image.c
@@ -5622,6 +5622,75 @@ static void test_png_color_formats(void)
#undef PNG_COLOR_TYPE_GRAY_ALPHA
#undef PNG_COLOR_TYPE_RGB_ALPHA
+static void test_png_save_palette(void)
+{
+ GpStatus status;
+ GpBitmap *bitmap;
+ HGLOBAL hglob;
+ BOOL result;
+ IStream *stream;
+ GUID enc_format, clsid;
+ LARGE_INTEGER seek;
+ ULARGE_INTEGER pos;
+ UINT i, ptr;
+ BYTE *data;
+
+ PixelFormat formats[] = {
+ PixelFormat1bppIndexed,
+ PixelFormat4bppIndexed,
+ PixelFormat8bppIndexed,
+ PixelFormat16bppGrayScale,
+ PixelFormat16bppRGB555,
+ PixelFormat16bppRGB565,
+ PixelFormat16bppARGB1555,
+ PixelFormat24bppRGB,
+ PixelFormat32bppRGB,
+ PixelFormat32bppARGB,
+ PixelFormat32bppPARGB,
+ };
+
+ result = get_encoder_clsid(L"image/png", &enc_format, &clsid);
+ ok(result, "getting PNG encoding clsid failed");
+
+ hglob = GlobalAlloc(GMEM_MOVEABLE | GMEM_NODISCARD | GMEM_ZEROINIT, 1024);
+
+ for (i = 0; i < ARRAY_SIZE(formats); i++)
+ {
+ status = GdipCreateBitmapFromScan0(8, 8, 0, formats[i], NULL, &bitmap);
+ ok(status == Ok, "Unexpected return value %d creating bitmap for PixelFormat %#x\n", status, formats[i]);
+
+ CreateStreamOnHGlobal(hglob, FALSE, &stream);
+ status = GdipSaveImageToStream((GpImage *)bitmap, stream, &clsid, NULL);
+ GdipDisposeImage((GpImage*)bitmap);
+
+ todo_wine_if(formats[i] == PixelFormat16bppGrayScale)
+ ok(formats[i] == PixelFormat16bppGrayScale ?
+ (status == GenericError || status == Win32Error) : status == Ok,
+ "Unexpected return value %d saving image for PixelFormat %#x\n", status, formats[i]);
+
+ if (status == Ok)
+ {
+ data = GlobalLock(hglob);
+ seek.QuadPart = 0;
+ IStream_Seek(stream, seek, STREAM_SEEK_CUR, &pos);
+ for (ptr = 0; ptr < pos.QuadPart - 4; ptr++)
+ if (!memcmp(data + ptr, "PLTE", 4))
+ break;
+ memset(data, 0, 1024);
+ GlobalUnlock(hglob);
+
+ if (IsIndexedPixelFormat(formats[i]))
+ ok(ptr < pos.QuadPart - 4, "Expected palette not found for PixelFormat %#x\n", formats[i]);
+ else
+ ok(ptr >= pos.QuadPart - 4, "Unexpected palette found for PixelFormat %#x\n", formats[i]);
+ }
+
+ IStream_Release(stream);
+ }
+
+ GlobalFree(hglob);
+}
+
static void test_GdipLoadImageFromStream(void)
{
IStream *stream;
@@ -5865,6 +5934,7 @@ START_TEST(image)
test_GdipInitializePalette();
test_png_color_formats();
+ test_png_save_palette();
test_supported_encoders();
test_CloneBitmapArea();
test_ARGB_conversion();
--
2.23.0