Size = GifFile->SWidth * sizeof(GifPixelType);
- GifRow = (GifRowType) mymalloc(Size);
+ GifRow = mymalloc(Size);
for (i = 0; i < GifFile->SWidth; i++) GifRow[i] = GifFile->SBackGroundColor;
myfree(*colour_table);
*colour_table = NULL;
}
+ myfree(GifRow);
i_img_destroy(im);
DGifCloseFile(GifFile);
return NULL;
myfree(*colour_table);
*colour_table = NULL;
}
+ myfree(GifRow);
i_img_destroy(im);
DGifCloseFile(GifFile);
return NULL;
mm_log((1, "Going in with no colormap\n"));
i_push_error(0, "Image does not have a local or a global color map");
/* we can't have allocated a colour table here */
+ myfree(GifRow);
i_img_destroy(im);
DGifCloseFile(GifFile);
return NULL;
myfree(*colour_table);
*colour_table = NULL;
}
+ myfree(GifRow);
i_img_destroy(im);
DGifCloseFile(GifFile);
- return(0);
+ return NULL;
}
if (GifFile->Image.Interlace) {
myfree(*colour_table);
*colour_table = NULL;
}
+ myfree(GifRow);
i_img_destroy(im);
DGifCloseFile(GifFile);
return NULL;
myfree(*colour_table);
*colour_table = NULL;
}
+ myfree(GifRow);
i_img_destroy(im);
DGifCloseFile(GifFile);
return NULL;
myfree(*colour_table);
*colour_table = NULL;
}
+ myfree(GifRow);
i_img_destroy(im);
DGifCloseFile(GifFile);
return NULL;
myfree(*colour_table);
*colour_table = NULL;
}
+ myfree(GifRow);
i_img_destroy(im);
DGifCloseFile(GifFile);
return NULL;
i_img **i_readgif_multi_low(GifFileType *GifFile, int *count) {
i_img *img;
- int i, j, Size, Row, Col, Width, Height, ExtCode, Count, x;
+ int i, j, Size, Width, Height, ExtCode, Count, x;
int ImageNum = 0, BackGround = 0, ColorMapSize = 0;
ColorMapObject *ColorMap;
channels = 4;
img = i_img_pal_new(Width, Height, channels, 256);
/* populate the palette of the new image */
+ mm_log((1, "ColorMapSize %d\n", ColorMapSize));
for (i = 0; i < ColorMapSize; ++i) {
i_color col;
col.rgba.r = ColorMap->Colors[i].Red;
if (GifFile->Image.ColorMap) {
i_tags_addn(&img->tags, "gif_localmap", 0, 1);
}
-
if (got_gce) {
if (trans_index >= 0)
i_tags_addn(&img->tags, "gif_trans_index", 0, trans_index);
}
ImageNum++;
- mm_log((1,"i_readgif_multi: Image %d at (%d, %d) [%dx%d]: \n",ImageNum, Col, Row, Width, Height));
+ mm_log((1,"i_readgif_multi_low: Image %d at (%d, %d) [%dx%d]: \n",
+ ImageNum, GifFile->Image.Left, GifFile->Image.Top, Width, Height));
if (GifFile->Image.Left + GifFile->Image.Width > GifFile->SWidth ||
GifFile->Image.Top + GifFile->Image.Height > GifFile->SHeight) {
DGifCloseFile(GifFile);
return(0);
}
+
if (GifFile->Image.Interlace) {
for (Count = i = 0; i < 4; i++) {
for (j = InterlacedOffset[i]; j < Height;
static int
gif_read_callback(GifFileType *gft, GifByteType *buf, int length) {
- return i_gen_reader((i_gen_read_data *)gft->UserData, buf, length);
+ return i_gen_reader((i_gen_read_data *)gft->UserData, (char*)buf, length);
}
#endif
*/
}
+static int
+in_palette(i_color *c, i_quantize *quant, int size) {
+ int i;
+
+ for (i = 0; i < size; ++i) {
+ if (c->channel[0] == quant->mc_colors[i].channel[0]
+ && c->channel[1] == quant->mc_colors[i].channel[1]
+ && c->channel[2] == quant->mc_colors[i].channel[2]) {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+/*
+=item has_common_palette(imgs, count, quant, want_trans)
+
+Tests if all the given images are paletted and have a common palette,
+if they do it builds that palette.
+
+A possible improvement might be to eliminate unused colors in the
+images palettes.
+
+=cut */
+static int
+has_common_palette(i_img **imgs, int count, i_quantize *quant, int want_trans,
+ i_gif_opts *opts) {
+ int size = quant->mc_count;
+ int i, j;
+ int imgn;
+ int x, y;
+ char used[256];
+
+ /* we try to build a common palette here, if we can manage that, then
+ that's the palette we use */
+ for (imgn = 0; imgn < count; ++imgn) {
+ if (imgs[imgn]->type != i_palette_type)
+ return 0;
+
+ if (opts->eliminate_unused) {
+ i_palidx *line = mymalloc(sizeof(i_palidx) * imgs[imgn]->xsize);
+ int x, y;
+ memset(used, 0, sizeof(used));
+
+ for (y = 0; y < imgs[imgn]->ysize; ++y) {
+ i_gpal(imgs[imgn], 0, imgs[imgn]->xsize, y, line);
+ for (x = 0; x < imgs[imgn]->xsize; ++x)
+ used[line[x]] = 1;
+ }
+
+ myfree(line);
+ }
+ else {
+ /* assume all are in use */
+ memset(used, 1, sizeof(used));
+ }
+
+ for (i = 0; i < i_colorcount(imgs[imgn]); ++i) {
+ i_color c;
+
+ i_getcolors(imgs[imgn], i, &c, 1);
+ if (used[i]) {
+ if (in_palette(&c, quant, size) < 0) {
+ if (size < quant->mc_size) {
+ quant->mc_colors[size++] = c;
+ }
+ else {
+ /* oops, too many colors */
+ return 0;
+ }
+ }
+ }
+ }
+ }
+
+ quant->mc_count = size;
+
+ return 1;
+}
+
+static i_palidx *
+quant_paletted(i_quantize *quant, i_img *img) {
+ i_palidx *data = mymalloc(sizeof(i_palidx) * img->xsize * img->ysize);
+ i_palidx *p = data;
+ i_palidx trans[256];
+ int i;
+ int x, y;
+
+ /* build a translation table */
+ for (i = 0; i < i_colorcount(img); ++i) {
+ i_color c;
+ i_getcolors(img, i, &c, 1);
+ trans[i] = in_palette(&c, quant, quant->mc_count);
+ }
+
+ for (y = 0; y < img->ysize; ++y) {
+ i_gpal(img, 0, img->xsize, y, data+img->xsize * y);
+ for (x = 0; x < img->xsize; ++x) {
+ *p = trans[*p];
+ ++p;
+ }
+ }
+
+ return data;
+}
+
/*
=item i_writegif_low(i_quantize *quant, GifFileType *gf, i_img **imgs, int count, i_gif_opts *opts)
int scrw = 0, scrh = 0;
int imgn, orig_count, orig_size;
int posx, posy;
+ int trans_index;
mm_log((1, "i_writegif_low(quant %p, gf %p, imgs %p, count %d, opts %p)\n",
quant, gf, imgs, count, opts));
if (imgn < opts->position_count) {
if (imgs[imgn]->xsize + opts->positions[imgn].x > scrw)
scrw = imgs[imgn]->xsize + opts->positions[imgn].x;
- if (imgs[imgn]->ysize + opts->positions[imgn].y > scrw)
+ if (imgs[imgn]->ysize + opts->positions[imgn].y > scrh)
scrh = imgs[imgn]->ysize + opts->positions[imgn].y;
}
else {
/* we always generate a global palette - this lets systems with a
broken giflib work */
- quant_makemap(quant, imgs, 1);
- result = quant_translate(quant, imgs[0]);
+ if (has_common_palette(imgs, 1, quant, want_trans, opts)) {
+ result = quant_paletted(quant, imgs[0]);
+ }
+ else {
+ quant_makemap(quant, imgs, 1);
+ result = quant_translate(quant, imgs[0]);
+ }
+ if (want_trans) {
+ trans_index = quant->mc_count;
+ quant_transparent(quant, result, imgs[0], trans_index);
+ }
- if (want_trans)
- quant_transparent(quant, result, imgs[0], quant->mc_count);
-
if ((map = make_gif_map(quant, opts, want_trans)) == NULL) {
myfree(result);
EGifCloseFile(gf);
if (!do_ns_loop(gf, opts))
return 0;
- if (!do_gce(gf, 0, opts, want_trans, quant->mc_count)) {
+ if (!do_gce(gf, 0, opts, want_trans, trans_index)) {
myfree(result);
EGifCloseFile(gf);
return 0;
myfree(result);
return 0;
}
+ myfree(result);
for (imgn = 1; imgn < count; ++imgn) {
quant->mc_count = orig_count;
quant->mc_size = orig_size;
if (want_trans && quant->mc_size == 256)
--quant->mc_size;
- quant_makemap(quant, imgs+imgn, 1);
- result = quant_translate(quant, imgs[imgn]);
- if (want_trans)
- quant_transparent(quant, result, imgs[imgn], quant->mc_count);
-
+ if (has_common_palette(imgs+imgn, 1, quant, want_trans, opts)) {
+ result = quant_paletted(quant, imgs[imgn]);
+ }
+ else {
+ quant_makemap(quant, imgs+imgn, 1);
+ result = quant_translate(quant, imgs[imgn]);
+ }
+ if (want_trans) {
+ quant_transparent(quant, result, imgs[imgn], quant->mc_count);
+ trans_index = quant->mc_count;
+ }
+
if (!do_gce(gf, imgn, opts, want_trans, quant->mc_count)) {
myfree(result);
EGifCloseFile(gf);
}
else {
int want_trans;
+ int do_quant_paletted = 0;
/* get a palette entry for the transparency iff we have an image
with an alpha channel */
the colormap. */
/* produce a colour map */
- quant_makemap(quant, imgs, count);
- result = quant_translate(quant, imgs[0]);
+ if (has_common_palette(imgs, count, quant, want_trans, opts)) {
+ result = quant_paletted(quant, imgs[0]);
+ ++do_quant_paletted;
+ }
+ else {
+ quant_makemap(quant, imgs, count);
+ result = quant_translate(quant, imgs[0]);
+ }
if ((map = make_gif_map(quant, opts, want_trans)) == NULL) {
myfree(result);
for (imgn = 1; imgn < count; ++imgn) {
int local_trans;
- result = quant_translate(quant, imgs[imgn]);
+ if (do_quant_paletted)
+ result = quant_paletted(quant, imgs[imgn]);
+ else
+ result = quant_translate(quant, imgs[imgn]);
local_trans = want_trans && imgs[imgn]->channels == 4;
if (local_trans)
quant_transparent(quant, result, imgs[imgn], quant->mc_count);
{
i_gen_write_data *gwd = (i_gen_write_data *)gf->UserData;
- return i_gen_writer(gwd, data, size) ? size : 0;
+ return i_gen_writer(gwd, (char*)data, size) ? size : 0;
}
#endif