summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKim Woelders <kim@woelders.dk>2021-12-05 11:15:58 +0100
committerKim Woelders <kim@woelders.dk>2021-12-19 14:58:43 +0100
commitbdfcc554edf8f1c5ad34edf25bb3ebff2f53b4fd (patch)
tree78232b1a6c3148e8e8ce54a2b3a89f688a35f56d
parent7a0022684d3d385bf5e8cdd55efe2bd3dd3cb6c4 (diff)
downloadimlib2-bdfcc554edf8f1c5ad34edf25bb3ebff2f53b4fd.tar.gz
GIF loader: Some refactoring, add debug
-rw-r--r--src/modules/loaders/loader_gif.c129
1 files changed, 87 insertions, 42 deletions
diff --git a/src/modules/loaders/loader_gif.c b/src/modules/loaders/loader_gif.c
index b5bfe9c..f0489ff 100644
--- a/src/modules/loaders/loader_gif.c
+++ b/src/modules/loaders/loader_gif.c
@@ -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 == TERMINATE_RECORD_TYPE)
+ {
+ DL(" TERMINATE_RECORD_TYPE(%d)\n", rec);
+ break;
}
- if ((rec == IMAGE_DESC_RECORD_TYPE) && (!done))
+ 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);
}