diff --git a/dlls/windowscodecs/gifformat.c b/dlls/windowscodecs/gifformat.c index 11b2ccf6aea..152c51eac76 100644 --- a/dlls/windowscodecs/gifformat.c +++ b/dlls/windowscodecs/gifformat.c @@ -743,20 +743,27 @@ static HRESULT WINAPI GifFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface, GifFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); WICColor colors[256]; ColorMapObject *cm = This->frame->ImageDesc.ColorMap; + int count; TRACE("(%p,%p)\n", iface, pIPalette); - if (!cm) cm = This->parent->gif->SColorMap; - - if (cm->ColorCount > 256) + if (cm) + count = cm->ColorCount; + else { - ERR("GIF contains %i colors???\n", cm->ColorCount); + cm = This->parent->gif->SColorMap; + count = This->parent->gif->SColorTableSize; + } + + if (count > 256) + { + ERR("GIF contains %i colors???\n", count); return E_FAIL; } - copy_palette(cm, &This->frame->Extensions, cm->ColorCount, colors); + copy_palette(cm, &This->frame->Extensions, count, colors); - return IWICPalette_InitializeCustom(pIPalette, colors, cm->ColorCount); + return IWICPalette_InitializeCustom(pIPalette, colors, count); } static HRESULT copy_interlaced_pixels(const BYTE *srcbuffer, @@ -1196,18 +1203,13 @@ static HRESULT WINAPI GifDecoder_CopyPalette(IWICBitmapDecoder *iface, IWICPalet return WINCODEC_ERR_WRONGSTATE; cm = This->gif->SColorMap; - if (cm) - { - if (cm->ColorCount > 256) - { - ERR("GIF contains invalid number of colors: %d\n", cm->ColorCount); - return E_FAIL; - } + count = This->gif->SColorTableSize; - count = cm->ColorCount; + if (count > 256) + { + ERR("GIF contains invalid number of colors: %d\n", count); + return E_FAIL; } - else - count = 256; copy_palette(cm, &This->gif->SavedImages[This->current_frame].Extensions, count, colors); diff --git a/dlls/windowscodecs/tests/gifformat.c b/dlls/windowscodecs/tests/gifformat.c index 8488f486a11..08f8ba1c12b 100644 --- a/dlls/windowscodecs/tests/gifformat.c +++ b/dlls/windowscodecs/tests/gifformat.c @@ -57,6 +57,13 @@ static const char gif_local_palette[] = { 0x02,0x02,0x44,0x01,0x00,0x3b }; +static const char gif_no_palette[] = { +/* LSD */'G','I','F','8','7','a',0x01,0x00,0x01,0x00,0x21,0x02,0x00, +/* GCE */0x21,0xf9,0x04,0x01,0x05,0x00,0x01,0x00, /* index 1 */ +/* IMD */0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00, +0x02,0x02,0x44,0x01,0x00,0x3b +}; + /* Generated with ImageMagick: * convert -delay 100 -size 2x2 xc:red \ * -dispose none -page +0+0 -size 2x1 xc:white \ @@ -364,6 +371,67 @@ static void test_local_gif_palette(void) IWICBitmapDecoder_Release(decoder); } +static void test_no_gif_palette(void) +{ + HRESULT hr; + IWICBitmapDecoder *decoder; + IWICBitmapFrameDecode *frame; + IWICPalette *palette; + GUID format; + UINT count, ret; + WICColor color[256]; + + decoder = create_decoder(gif_no_palette, sizeof(gif_no_palette)); + ok(decoder != 0, "Failed to load GIF image data\n"); + + hr = IWICImagingFactory_CreatePalette(factory, &palette); + ok(hr == S_OK, "CreatePalette error %#lx\n", hr); + + /* global palette */ + hr = IWICBitmapDecoder_CopyPalette(decoder, palette); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); + + hr = IWICPalette_GetColorCount(palette, &count); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); + ok(count == 4, "expected 4, got %u\n", count); + + hr = IWICPalette_GetColors(palette, count, color, &ret); + ok(hr == S_OK, "GetColors error %#lx\n", hr); + ok(ret == count, "expected %u, got %u\n", count, ret); + ok(color[0] == 0xff000000, "expected 0xff000000, got %#x\n", color[0]); + ok(color[1] == 0x00ffffff, "expected 0x00ffffff, got %#x\n", color[1]); + ok(color[2] == 0xff000000, "expected 0xff000000, got %#x\n", color[2]); + ok(color[3] == 0xff000000, "expected 0xff000000, got %#x\n", color[3]); + + /* frame palette */ + hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); + + hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); + ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed), + "wrong pixel format %s\n", wine_dbgstr_guid(&format)); + + hr = IWICBitmapFrameDecode_CopyPalette(frame, palette); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); + + hr = IWICPalette_GetColorCount(palette, &count); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); + ok(count == 4, "expected 4, got %u\n", count); + + hr = IWICPalette_GetColors(palette, count, color, &ret); + ok(hr == S_OK, "GetColors error %#lx\n", hr); + ok(ret == count, "expected %u, got %u\n", count, ret); + ok(color[0] == 0xff000000, "expected 0xff000000, got %#x\n", color[0]); + ok(color[1] == 0x00ffffff, "expected 0x00ffffff, got %#x\n", color[1]); + ok(color[2] == 0xff000000, "expected 0xff000000, got %#x\n", color[2]); + ok(color[3] == 0xff000000, "expected 0xff000000, got %#x\n", color[3]); + + IWICPalette_Release(palette); + IWICBitmapFrameDecode_Release(frame); + IWICBitmapDecoder_Release(decoder); +} + static void test_gif_frame_sizes(void) { static const BYTE frame0[] = {0, 1, 0xfe, 0xfe, 2, 3, 0xfe, 0xfe}; @@ -577,6 +645,7 @@ START_TEST(gifformat) test_global_gif_palette(); test_global_gif_palette_2frames(); test_local_gif_palette(); + test_no_gif_palette(); test_gif_frame_sizes(); test_gif_notrailer(); @@ -590,6 +659,7 @@ START_TEST(gifformat) test_global_gif_palette(); test_global_gif_palette_2frames(); test_local_gif_palette(); + test_no_gif_palette(); test_gif_frame_sizes(); test_truncated_gif(); diff --git a/dlls/windowscodecs/ungif.c b/dlls/windowscodecs/ungif.c index 0f5ed6e25d5..1fb16e52f15 100644 --- a/dlls/windowscodecs/ungif.c +++ b/dlls/windowscodecs/ungif.c @@ -320,6 +320,7 @@ DGifGetScreenDesc(GifFileType * GifFile) { GifFile->SColorResolution = (((Buf[0] & 0x70) + 1) >> 4) + 1; SortFlag = (Buf[0] & 0x08) != 0; BitsPerPixel = (Buf[0] & 0x07) + 1; + GifFile->SColorTableSize = 1 << BitsPerPixel; GifFile->SBackGroundColor = Buf[1]; GifFile->SAspectRatio = Buf[2]; if (Buf[0] & 0x80) { /* Do we have global color map? */ diff --git a/dlls/windowscodecs/ungif.h b/dlls/windowscodecs/ungif.h index ae8269226df..f61a7eb1e16 100644 --- a/dlls/windowscodecs/ungif.h +++ b/dlls/windowscodecs/ungif.h @@ -114,6 +114,7 @@ typedef struct { typedef struct GifFileType { GifWord SWidth, SHeight, /* Screen dimensions. */ SColorResolution, /* How many colors can we generate? */ + SColorTableSize, /* Calculated color table size, even if not present */ SBackGroundColor, /* I hope you understand this one... */ SAspectRatio; /* Pixel aspect ratio, in 1/64 units, starting at 1:4. */ ColorMapObject *SColorMap; /* NULL if not exists. */