GIF loader: Some refactoring, add debug

This commit is contained in:
Kim Woelders 2021-12-05 11:15:58 +01:00
parent 7a0022684d
commit bdfcc554ed
1 changed files with 87 additions and 42 deletions

View File

@ -2,18 +2,40 @@
#include <gif_lib.h>
#define DBG_PFX "LDR-gif"
static void
make_colormap(DATA32 * cmi, ColorMapObject * cmg, int bg, int tr)
{
int i, r, g, b;
memset(cmi, 0, 256 * sizeof(DATA32));
if (!cmg)
return;
for (i = cmg->ColorCount > 256 ? 256 : cmg->ColorCount; i-- > 0;)
{
r = cmg->Colors[i].Red;
g = cmg->Colors[i].Green;
b = cmg->Colors[i].Blue;
cmi[i] = PIXEL_ARGB(0xff, r, g, b);
}
/* if bg > cmg->ColorCount, it is transparent black already */
if (tr >= 0 && tr < 256)
cmi[tr] = bg >= 0 && bg < 256 ? cmi[bg] & 0x00ffffff : 0x00000000;
}
int
load2(ImlibImage * im, int load_data)
{
static const int intoffset[] = { 0, 4, 2, 1 };
static const int intjump[] = { 8, 8, 4, 2 };
int rc;
DATA32 *ptr;
GifFileType *gif;
GifRowType *rows;
GifRecordType rec;
ColorMapObject *cmap;
int i, j, done, bg, r, g, b, w = 0, h = 0;
int i, j, bg, bits, done;
int transp;
int fd;
DATA32 colormap[256];
@ -33,57 +55,86 @@ load2(ImlibImage * im, int load_data)
rows = NULL;
transp = -1;
do
bg = gif->SBackGroundColor;
cmap = gif->SColorMap;
for (;;)
{
if (DGifGetRecordType(gif, &rec) == GIF_ERROR)
{
/* PrintGifError(); */
rec = TERMINATE_RECORD_TYPE;
DL("err1\n");
break;
}
if ((rec == IMAGE_DESC_RECORD_TYPE) && (!done))
if (rec == TERMINATE_RECORD_TYPE)
{
DL(" TERMINATE_RECORD_TYPE(%d)\n", rec);
break;
}
if (rec == IMAGE_DESC_RECORD_TYPE)
{
if (DGifGetImageDesc(gif) == GIF_ERROR)
{
/* PrintGifError(); */
rec = TERMINATE_RECORD_TYPE;
DL("err2\n");
break;
}
im->w = w = gif->Image.Width;
im->h = h = gif->Image.Height;
if (!IMAGE_DIMENSIONS_OK(w, h))
DL(" IMAGE_DESC_RECORD_TYPE(%d): ic=%d x,y=%d,%d wxh=%dx%d\n",
rec, gif->ImageCount, gif->Image.Left, gif->Image.Top,
gif->Image.Width, gif->Image.Height);
if (done)
continue;
im->w = gif->Image.Width;
im->h = gif->Image.Height;
if (!IMAGE_DIMENSIONS_OK(im->w, im->h))
goto quit;
rows = calloc(h, sizeof(GifRowType));
D(" Frame %d: x,y=%d,%d wxh=%dx%d\n", gif->ImageCount,
gif->Image.Left, gif->Image.Top, im->w, im->h);
DL(" CM S=%p I=%p\n", cmap, gif->Image.ColorMap);
if (gif->Image.ColorMap)
cmap = gif->Image.ColorMap;
if (load_data)
make_colormap(colormap, cmap, bg, transp);
rows = calloc(im->h, sizeof(GifRowType));
if (!rows)
goto quit;
for (i = 0; i < h; i++)
for (i = 0; i < im->h; i++)
{
rows[i] = calloc(w, sizeof(GifPixelType));
rows[i] = calloc(im->w, sizeof(GifPixelType));
if (!rows[i])
goto quit;
}
if (gif->Image.Interlace)
{
static const int intoffset[] = { 0, 4, 2, 1 };
static const int intjump[] = { 8, 8, 4, 2 };
for (i = 0; i < 4; i++)
{
for (j = intoffset[i]; j < h; j += intjump[i])
for (j = intoffset[i]; j < im->h; j += intjump[i])
{
DGifGetLine(gif, rows[j], w);
DGifGetLine(gif, rows[j], im->w);
}
}
}
else
{
for (i = 0; i < h; i++)
for (i = 0; i < im->h; i++)
{
DGifGetLine(gif, rows[i], w);
DGifGetLine(gif, rows[i], im->w);
}
}
done = 1;
break;
}
else if (rec == EXTENSION_RECORD_TYPE)
{
@ -94,16 +145,28 @@ load2(ImlibImage * im, int load_data)
DGifGetExtension(gif, &ext_code, &ext);
while (ext)
{
if ((ext_code == 0xf9) && (ext[1] & 1) && (transp < 0))
DL(" EXTENSION_RECORD_TYPE(%d): ic=%d: ext_code=%02x: %02x %02x %02x %02x %02x\n", //
rec, gif->ImageCount, ext_code,
ext[0], ext[1], ext[2], ext[3], ext[4]);
if (ext_code == GRAPHICS_EXT_FUNC_CODE
&& gif->ImageCount == 0)
{
transp = (int)ext[4];
bits = ext[1];
if (bits & 1)
transp = ext[4];
D(" Frame %d: disp=%d ui=%d tr=%d, transp = #%02x\n",
gif->ImageCount + 1,
(bits >> 2) & 0x7, (bits >> 1) & 1, bits & 1, transp);
}
ext = NULL;
DGifGetExtensionNext(gif, &ext);
}
}
else
{
DL(" Unknown record type(%d)\n", rec);
}
}
while (rec != TERMINATE_RECORD_TYPE);
UPDATE_FLAG(im->flags, F_HAS_ALPHA, transp >= 0);
@ -118,31 +181,13 @@ load2(ImlibImage * im, int load_data)
/* Load data */
bg = gif->SBackGroundColor;
cmap = (gif->Image.ColorMap ? gif->Image.ColorMap : gif->SColorMap);
memset(colormap, 0, sizeof(colormap));
if (cmap != NULL)
{
for (i = cmap->ColorCount > 256 ? 256 : cmap->ColorCount; i-- > 0;)
{
r = cmap->Colors[i].Red;
g = cmap->Colors[i].Green;
b = cmap->Colors[i].Blue;
colormap[i] = PIXEL_ARGB(0xff, r, g, b);
}
/* if bg > cmap->ColorCount, it is transparent black already */
if (transp >= 0 && transp < 256)
colormap[transp] = bg >= 0 && bg < 256 ?
colormap[bg] & 0x00ffffff : 0x00000000;
}
ptr = __imlib_AllocateData(im);
if (!ptr)
goto quit;
for (i = 0; i < h; i++)
for (i = 0; i < im->h; i++)
{
for (j = 0; j < w; j++)
for (j = 0; j < im->w; j++)
{
*ptr++ = colormap[rows[i][j]];
}
@ -159,7 +204,7 @@ load2(ImlibImage * im, int load_data)
quit:
if (rows)
{
for (i = 0; i < h; i++)
for (i = 0; i < im->h; i++)
free(rows[i]);
free(rows);
}