Commit 224b771c authored by Jeff Smith's avatar Jeff Smith Committed by Alexandre Julliard

windowscodecs: Allow GIF with no color table.

parent 8ff77999
...@@ -743,20 +743,27 @@ static HRESULT WINAPI GifFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface, ...@@ -743,20 +743,27 @@ static HRESULT WINAPI GifFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface,
GifFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); GifFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface);
WICColor colors[256]; WICColor colors[256];
ColorMapObject *cm = This->frame->ImageDesc.ColorMap; ColorMapObject *cm = This->frame->ImageDesc.ColorMap;
int count;
TRACE("(%p,%p)\n", iface, pIPalette); TRACE("(%p,%p)\n", iface, pIPalette);
if (!cm) cm = This->parent->gif->SColorMap; if (cm)
count = cm->ColorCount;
else
{
cm = This->parent->gif->SColorMap;
count = This->parent->gif->SColorTableSize;
}
if (cm->ColorCount > 256) if (count > 256)
{ {
ERR("GIF contains %i colors???\n", cm->ColorCount); ERR("GIF contains %i colors???\n", count);
return E_FAIL; 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, static HRESULT copy_interlaced_pixels(const BYTE *srcbuffer,
...@@ -1196,18 +1203,13 @@ static HRESULT WINAPI GifDecoder_CopyPalette(IWICBitmapDecoder *iface, IWICPalet ...@@ -1196,18 +1203,13 @@ static HRESULT WINAPI GifDecoder_CopyPalette(IWICBitmapDecoder *iface, IWICPalet
return WINCODEC_ERR_WRONGSTATE; return WINCODEC_ERR_WRONGSTATE;
cm = This->gif->SColorMap; cm = This->gif->SColorMap;
if (cm) count = This->gif->SColorTableSize;
{
if (cm->ColorCount > 256)
{
ERR("GIF contains invalid number of colors: %d\n", cm->ColorCount);
return E_FAIL;
}
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); copy_palette(cm, &This->gif->SavedImages[This->current_frame].Extensions, count, colors);
......
...@@ -57,6 +57,13 @@ static const char gif_local_palette[] = { ...@@ -57,6 +57,13 @@ static const char gif_local_palette[] = {
0x02,0x02,0x44,0x01,0x00,0x3b 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: /* Generated with ImageMagick:
* convert -delay 100 -size 2x2 xc:red \ * convert -delay 100 -size 2x2 xc:red \
* -dispose none -page +0+0 -size 2x1 xc:white \ * -dispose none -page +0+0 -size 2x1 xc:white \
...@@ -364,6 +371,67 @@ static void test_local_gif_palette(void) ...@@ -364,6 +371,67 @@ static void test_local_gif_palette(void)
IWICBitmapDecoder_Release(decoder); 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 void test_gif_frame_sizes(void)
{ {
static const BYTE frame0[] = {0, 1, 0xfe, 0xfe, 2, 3, 0xfe, 0xfe}; static const BYTE frame0[] = {0, 1, 0xfe, 0xfe, 2, 3, 0xfe, 0xfe};
...@@ -577,6 +645,7 @@ START_TEST(gifformat) ...@@ -577,6 +645,7 @@ START_TEST(gifformat)
test_global_gif_palette(); test_global_gif_palette();
test_global_gif_palette_2frames(); test_global_gif_palette_2frames();
test_local_gif_palette(); test_local_gif_palette();
test_no_gif_palette();
test_gif_frame_sizes(); test_gif_frame_sizes();
test_gif_notrailer(); test_gif_notrailer();
...@@ -590,6 +659,7 @@ START_TEST(gifformat) ...@@ -590,6 +659,7 @@ START_TEST(gifformat)
test_global_gif_palette(); test_global_gif_palette();
test_global_gif_palette_2frames(); test_global_gif_palette_2frames();
test_local_gif_palette(); test_local_gif_palette();
test_no_gif_palette();
test_gif_frame_sizes(); test_gif_frame_sizes();
test_truncated_gif(); test_truncated_gif();
......
...@@ -320,6 +320,7 @@ DGifGetScreenDesc(GifFileType * GifFile) { ...@@ -320,6 +320,7 @@ DGifGetScreenDesc(GifFileType * GifFile) {
GifFile->SColorResolution = (((Buf[0] & 0x70) + 1) >> 4) + 1; GifFile->SColorResolution = (((Buf[0] & 0x70) + 1) >> 4) + 1;
SortFlag = (Buf[0] & 0x08) != 0; SortFlag = (Buf[0] & 0x08) != 0;
BitsPerPixel = (Buf[0] & 0x07) + 1; BitsPerPixel = (Buf[0] & 0x07) + 1;
GifFile->SColorTableSize = 1 << BitsPerPixel;
GifFile->SBackGroundColor = Buf[1]; GifFile->SBackGroundColor = Buf[1];
GifFile->SAspectRatio = Buf[2]; GifFile->SAspectRatio = Buf[2];
if (Buf[0] & 0x80) { /* Do we have global color map? */ if (Buf[0] & 0x80) { /* Do we have global color map? */
......
...@@ -114,6 +114,7 @@ typedef struct { ...@@ -114,6 +114,7 @@ typedef struct {
typedef struct GifFileType { typedef struct GifFileType {
GifWord SWidth, SHeight, /* Screen dimensions. */ GifWord SWidth, SHeight, /* Screen dimensions. */
SColorResolution, /* How many colors can we generate? */ SColorResolution, /* How many colors can we generate? */
SColorTableSize, /* Calculated color table size, even if not present */
SBackGroundColor, /* I hope you understand this one... */ SBackGroundColor, /* I hope you understand this one... */
SAspectRatio; /* Pixel aspect ratio, in 1/64 units, starting at 1:4. */ SAspectRatio; /* Pixel aspect ratio, in 1/64 units, starting at 1:4. */
ColorMapObject *SColorMap; /* NULL if not exists. */ ColorMapObject *SColorMap; /* NULL if not exists. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment