1
0
mirror of https://github.com/wine-mirror/wine synced 2024-07-05 09:18:56 +00:00

windowscodecs: Allow GIF with no color table.

This commit is contained in:
Jeff Smith 2023-07-16 15:16:57 -05:00 committed by Alexandre Julliard
parent 8ff77999b5
commit 224b771c0d
4 changed files with 90 additions and 16 deletions

View File

@ -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);

View File

@ -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();

View File

@ -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? */

View File

@ -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. */