-#include "image.h"
+#include "imageri.h"
#include <gif_lib.h>
-#ifdef _MSCVER
+#ifdef _MSC_VER
#include <io.h>
#else
#include <unistd.h>
cmapcnt++;
}
+ if (!i_int_check_image_file_limits(GifFile->SWidth, GifFile->SHeight, 3, sizeof(i_sample_t))) {
+ if (colour_table && *colour_table) {
+ myfree(*colour_table);
+ *colour_table = NULL;
+ }
+ DGifCloseFile(GifFile);
+ mm_log((1, "i_readgif: image size exceeds limits\n"));
+ return NULL;
+ }
im = i_img_empty_ch(NULL, GifFile->SWidth, GifFile->SHeight, 3);
+ if (!im) {
+ if (colour_table && *colour_table) {
+ myfree(*colour_table);
+ *colour_table = NULL;
+ }
+ DGifCloseFile(GifFile);
+ return NULL;
+ }
Size = GifFile->SWidth * sizeof(GifPixelType);
i_img_destroy(im);
return NULL;
}
+
+ i_tags_add(&im->tags, "i_format", 0, "gif", -1, 0);
+
return im;
}
*/
static void free_images(i_img **imgs, int count) {
int i;
- for (i = 0; i < count; ++i)
- i_img_destroy(imgs[i]);
- myfree(imgs);
+
+ if (count) {
+ for (i = 0; i < count; ++i)
+ i_img_destroy(imgs[i]);
+ myfree(imgs);
+ }
}
/*
-=item i_readgif_multi_low(GifFileType *gf, int *count)
+=item i_readgif_multi_low(GifFileType *gf, int *count, int page)
Reads one of more gif images from the given GIF file.
Returns a pointer to an array of i_img *, and puts the count into
*count.
+If page is not -1 then the given image _only_ is returned from the
+file, where the first image is 0, the second 1 and so on.
+
Unlike the normal i_readgif*() functions the images are paletted
images rather than a combined RGB image.
=cut
*/
-i_img **i_readgif_multi_low(GifFileType *GifFile, int *count) {
+i_img **i_readgif_multi_low(GifFileType *GifFile, int *count, int page) {
i_img *img;
- int i, j, Size, Width, Height, ExtCode, Count, x;
+ int i, j, Size, Width, Height, ExtCode, Count;
int ImageNum = 0, BackGround = 0, ColorMapSize = 0;
ColorMapObject *ColorMap;
GifRowType GifRow;
int got_gce = 0;
- int trans_index; /* transparent index if we see a GCE */
- int gif_delay; /* delay from a GCE */
- int user_input; /* user input flag from a GCE */
- int disposal; /* disposal method from a GCE */
+ int trans_index = 0; /* transparent index if we see a GCE */
+ int gif_delay = 0; /* delay from a GCE */
+ int user_input = 0; /* user input flag from a GCE */
+ int disposal = 0; /* disposal method from a GCE */
int got_ns_loop = 0;
- int ns_loop;
+ int ns_loop = 0;
char *comment = NULL; /* a comment */
i_img **results = NULL;
int result_alloc = 0;
int channels;
+ int image_colors = 0;
+ i_color black; /* used to expand the palette if needed */
+
+ for (i = 0; i < MAXCHANNELS; ++i)
+ black.channel[i] = 0;
*count = 0;
Size = GifFile->SWidth * sizeof(GifPixelType);
if ((GifRow = (GifRowType) mymalloc(Size)) == NULL)
- m_fatal(0,"Failed to allocate memory required, aborted."); /* First row. */
+ i_fatal(0,"Failed to allocate memory required, aborted."); /* First row. */
/* Scan the content of the GIF file and load the image(s) in: */
do {
i_push_error(0, "Unable to get record type");
free_images(results, *count);
DGifCloseFile(GifFile);
+ myfree(GifRow);
return NULL;
}
i_push_error(0, "Unable to get image descriptor");
free_images(results, *count);
DGifCloseFile(GifFile);
+ myfree(GifRow);
return NULL;
}
- if (( ColorMap = (GifFile->Image.ColorMap ? GifFile->Image.ColorMap : GifFile->SColorMap) )) {
- mm_log((1, "Adding local colormap\n"));
- ColorMapSize = ColorMap->ColorCount;
- } else {
- /* No colormap and we are about to read in the image -
- abandon for now */
- mm_log((1, "Going in with no colormap\n"));
- i_push_error(0, "Image does not have a local or a global color map");
- free_images(results, *count);
- DGifCloseFile(GifFile);
- return NULL;
- }
-
Width = GifFile->Image.Width;
Height = GifFile->Image.Height;
- channels = 3;
- if (got_gce && trans_index >= 0)
- 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;
- col.rgba.g = ColorMap->Colors[i].Green;
- col.rgba.b = ColorMap->Colors[i].Blue;
- if (channels == 4 && trans_index == i)
- col.rgba.a = 0;
- else
- col.rgba.a = 255;
-
- i_addcolors(img, &col, 1);
- }
- ++*count;
- if (*count > result_alloc) {
- if (result_alloc == 0) {
- result_alloc = 5;
- results = mymalloc(result_alloc * sizeof(i_img *));
- }
- else {
- /* myrealloc never fails (it just dies if it can't allocate) */
- result_alloc *= 2;
- results = myrealloc(results, result_alloc * sizeof(i_img *));
- }
- }
- results[*count-1] = img;
- i_tags_addn(&img->tags, "gif_left", 0, GifFile->Image.Left);
- /**(char *)0 = 1;*/
- i_tags_addn(&img->tags, "gif_top", 0, GifFile->Image.Top);
- i_tags_addn(&img->tags, "gif_interlace", 0, GifFile->Image.Interlace);
- i_tags_addn(&img->tags, "gif_screen_width", 0, GifFile->SWidth);
- i_tags_addn(&img->tags, "gif_screen_height", 0, GifFile->SHeight);
- if (GifFile->SColorMap && !GifFile->Image.ColorMap) {
- i_tags_addn(&img->tags, "gif_background", 0,
- GifFile->SBackGroundColor);
- }
- if (GifFile->Image.ColorMap) {
- i_tags_addn(&img->tags, "gif_localmap", 0, 1);
- }
- if (got_gce) {
- if (trans_index >= 0) {
- i_color trans;
- i_tags_addn(&img->tags, "gif_trans_index", 0, trans_index);
- i_getcolors(img, trans_index, &trans, 1);
- i_tags_set_color(&img->tags, "gif_trans_color", 0, &trans);
- }
- i_tags_addn(&img->tags, "gif_delay", 0, gif_delay);
- i_tags_addn(&img->tags, "gif_user_input", 0, user_input);
- i_tags_addn(&img->tags, "gif_disposal", 0, disposal);
- }
- got_gce = 0;
- if (got_ns_loop)
- i_tags_addn(&img->tags, "gif_loop", 0, ns_loop);
- if (comment) {
- i_tags_add(&img->tags, "gif_comment", 0, comment, strlen(comment), 0);
- myfree(comment);
- comment = NULL;
- }
+ if (page == -1 || page == ImageNum) {
+ if (( ColorMap = (GifFile->Image.ColorMap ? GifFile->Image.ColorMap : GifFile->SColorMap) )) {
+ mm_log((1, "Adding local colormap\n"));
+ ColorMapSize = ColorMap->ColorCount;
+ } else {
+ /* No colormap and we are about to read in the image -
+ abandon for now */
+ mm_log((1, "Going in with no colormap\n"));
+ i_push_error(0, "Image does not have a local or a global color map");
+ free_images(results, *count);
+ DGifCloseFile(GifFile);
+ myfree(GifRow);
+ return NULL;
+ }
+
+ channels = 3;
+ if (got_gce && trans_index >= 0)
+ channels = 4;
+ if (!i_int_check_image_file_limits(Width, Height, channels, sizeof(i_sample_t))) {
+ free_images(results, *count);
+ mm_log((1, "i_readgif: image size exceeds limits\n"));
+ DGifCloseFile(GifFile);
+ myfree(GifRow);
+ return NULL;
+ }
+ img = i_img_pal_new(Width, Height, channels, 256);
+ if (!img) {
+ free_images(results, *count);
+ DGifCloseFile(GifFile);
+ return NULL;
+ }
+ /* 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;
+ col.rgba.g = ColorMap->Colors[i].Green;
+ col.rgba.b = ColorMap->Colors[i].Blue;
+ if (channels == 4 && trans_index == i)
+ col.rgba.a = 0;
+ else
+ col.rgba.a = 255;
+
+ i_addcolors(img, &col, 1);
+ }
+ image_colors = ColorMapSize;
+ ++*count;
+ if (*count > result_alloc) {
+ if (result_alloc == 0) {
+ result_alloc = 5;
+ results = mymalloc(result_alloc * sizeof(i_img *));
+ }
+ else {
+ /* myrealloc never fails (it just dies if it can't allocate) */
+ result_alloc *= 2;
+ results = myrealloc(results, result_alloc * sizeof(i_img *));
+ }
+ }
+ results[*count-1] = img;
+ i_tags_add(&img->tags, "i_format", 0, "gif", -1, 0);
+ i_tags_addn(&img->tags, "gif_left", 0, GifFile->Image.Left);
+ /**(char *)0 = 1;*/
+ i_tags_addn(&img->tags, "gif_top", 0, GifFile->Image.Top);
+ i_tags_addn(&img->tags, "gif_interlace", 0, GifFile->Image.Interlace);
+ i_tags_addn(&img->tags, "gif_screen_width", 0, GifFile->SWidth);
+ i_tags_addn(&img->tags, "gif_screen_height", 0, GifFile->SHeight);
+ i_tags_addn(&img->tags, "gif_colormap_size", 0, ColorMapSize);
+ if (GifFile->SColorMap && !GifFile->Image.ColorMap) {
+ i_tags_addn(&img->tags, "gif_background", 0,
+ GifFile->SBackGroundColor);
+ }
+ if (GifFile->Image.ColorMap) {
+ i_tags_addn(&img->tags, "gif_localmap", 0, 1);
+ }
+ if (got_gce) {
+ if (trans_index >= 0) {
+ i_color trans;
+ i_tags_addn(&img->tags, "gif_trans_index", 0, trans_index);
+ i_getcolors(img, trans_index, &trans, 1);
+ i_tags_set_color(&img->tags, "gif_trans_color", 0, &trans);
+ }
+ i_tags_addn(&img->tags, "gif_delay", 0, gif_delay);
+ i_tags_addn(&img->tags, "gif_user_input", 0, user_input);
+ i_tags_addn(&img->tags, "gif_disposal", 0, disposal);
+ }
+ got_gce = 0;
+ if (got_ns_loop)
+ i_tags_addn(&img->tags, "gif_loop", 0, ns_loop);
+ if (comment) {
+ i_tags_add(&img->tags, "gif_comment", 0, comment, strlen(comment), 0);
+ myfree(comment);
+ comment = NULL;
+ }
+
+ 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) {
+ i_push_errorf(0, "Image %d is not confined to screen dimension, aborted.\n",ImageNum);
+ free_images(results, *count);
+ DGifCloseFile(GifFile);
+ myfree(GifRow);
+ return(0);
+ }
+
+ if (GifFile->Image.Interlace) {
+ for (Count = i = 0; i < 4; i++) {
+ for (j = InterlacedOffset[i]; j < Height;
+ j += InterlacedJumps[i]) {
+ Count++;
+ if (DGifGetLine(GifFile, GifRow, Width) == GIF_ERROR) {
+ gif_push_error();
+ i_push_error(0, "Reading GIF line");
+ free_images(results, *count);
+ DGifCloseFile(GifFile);
+ myfree(GifRow);
+ return NULL;
+ }
+
+ /* range check the scanline if needed */
+ if (image_colors != 256) {
+ int x;
+ for (x = 0; x < Width; ++x) {
+ while (GifRow[x] >= image_colors) {
+ /* expand the palette since a palette index is too big */
+ i_addcolors(img, &black, 1);
+ ++image_colors;
+ }
+ }
+ }
+
+ i_ppal(img, 0, Width, j, GifRow);
+ }
+ }
+ }
+ else {
+ for (i = 0; i < Height; i++) {
+ if (DGifGetLine(GifFile, GifRow, Width) == GIF_ERROR) {
+ gif_push_error();
+ i_push_error(0, "Reading GIF line");
+ free_images(results, *count);
+ DGifCloseFile(GifFile);
+ myfree(GifRow);
+ return NULL;
+ }
+
+ /* range check the scanline if needed */
+ if (image_colors != 256) {
+ int x;
+ for (x = 0; x < Width; ++x) {
+ while (GifRow[x] >= image_colors) {
+ /* expand the palette since a palette index is too big */
+ i_addcolors(img, &black, 1);
+ ++image_colors;
+ }
+ }
+ }
- ImageNum++;
- mm_log((1,"i_readgif_multi_low: Image %d at (%d, %d) [%dx%d]: \n",
- ImageNum, GifFile->Image.Left, GifFile->Image.Top, Width, Height));
+ i_ppal(img, 0, Width, i, GifRow);
+ }
+ }
- if (GifFile->Image.Left + GifFile->Image.Width > GifFile->SWidth ||
- GifFile->Image.Top + GifFile->Image.Height > GifFile->SHeight) {
- i_push_errorf(0, "Image %d is not confined to screen dimension, aborted.\n",ImageNum);
- free_images(results, *count);
- DGifCloseFile(GifFile);
- return(0);
- }
-
- if (GifFile->Image.Interlace) {
- for (Count = i = 0; i < 4; i++) {
- for (j = InterlacedOffset[i]; j < Height;
- j += InterlacedJumps[i]) {
- Count++;
- if (DGifGetLine(GifFile, GifRow, Width) == GIF_ERROR) {
- gif_push_error();
- i_push_error(0, "Reading GIF line");
- free_images(results, *count);
- DGifCloseFile(GifFile);
- return NULL;
- }
-
- i_ppal(img, 0, Width, j, GifRow);
- }
+ /* must be only one image wanted and that was it */
+ if (page != -1) {
+ myfree(GifRow);
+ DGifCloseFile(GifFile);
+ return results;
}
}
else {
+ /* skip the image */
+ /* whether interlaced or not, it has the same number of lines */
+ /* giflib does't have an interface to skip the image data */
for (i = 0; i < Height; i++) {
if (DGifGetLine(GifFile, GifRow, Width) == GIF_ERROR) {
gif_push_error();
i_push_error(0, "Reading GIF line");
- free_images(results, *count);
+ free_images(results, *count);
+ myfree(GifRow);
DGifCloseFile(GifFile);
return NULL;
}
+ }
- i_ppal(img, 0, Width, i, GifRow);
+ /* kill the comment so we get the right comment for the page */
+ if (comment) {
+ myfree(comment);
+ comment = NULL;
}
}
+ ImageNum++;
break;
case EXTENSION_RECORD_TYPE:
/* Skip any extension blocks in file: */
else
trans_index = -1;
gif_delay = Extension[2] + 256 * Extension[3];
- user_input = (Extension[0] & 2) != 0;
- disposal = (Extension[0] >> 2) & 3;
+ user_input = (Extension[1] & 2) != 0;
+ disposal = (Extension[1] >> 2) & 7;
}
if (ExtCode == 0xFF && *Extension == 11) {
if (memcmp(Extension+1, "NETSCAPE2.0", 11) == 0) {
return NULL;
}
+ if (ImageNum && page != -1) {
+ /* there were images, but the page selected wasn't found */
+ i_push_errorf(0, "page %d not found (%d total)", page, ImageNum);
+ free_images(results, *count);
+ return NULL;
+ }
+
return results;
}
return NULL;
}
- return i_readgif_multi_low(GifFile, count);
+ return i_readgif_multi_low(GifFile, count, -1);
#else
i_clear_error();
i_push_error(0, "callbacks not supported with giflib3");
return NULL;
}
- return i_readgif_multi_low(GifFile, count);
+ return i_readgif_multi_low(GifFile, count, -1);
}
/*
return NULL;
}
- return i_readgif_multi_low(GifFile, count);
+ return i_readgif_multi_low(GifFile, count, -1);
#else
return NULL;
#endif
return NULL;
}
- result = i_readgif_multi_low(GifFile, count);
- free_gen_read_data(gci);
+ result = i_readgif_multi_low(GifFile, count, -1);
+ i_free_gen_read_data(gci);
return result;
#else
}
result = i_readgif_low(GifFile, colour_table, colours);
- free_gen_read_data(gci);
+ i_free_gen_read_data(gci);
return result;
#else
}
}
+/*
+=item i_readgif_single_low(GifFile, page)
+
+Lower level function to read a single image from a GIF.
+
+page must be non-negative.
+
+=cut
+*/
+static i_img *
+i_readgif_single_low(GifFileType *GifFile, int page) {
+ int count = 0;
+ i_img **imgs;
+
+ imgs = i_readgif_multi_low(GifFile, &count, page);
+
+ if (imgs && count) {
+ i_img *result = imgs[0];
+
+ myfree(imgs);
+ return result;
+ }
+ else {
+ /* i_readgif_multi_low() handles the errors appropriately */
+ return NULL;
+ }
+}
+
+/*
+=item i_readgif_single_wiol(ig, page)
+
+Read a single page from a GIF image file, where the page is indexed
+from 0.
+
+Returns NULL if the page isn't found.
+
+=cut
+*/
+
+i_img *
+i_readgif_single_wiol(io_glue *ig, int page) {
+ io_glue_commit_types(ig);
+
+ i_clear_error();
+
+ if (page < 0) {
+ i_push_error(0, "page must be non-negative");
+ return NULL;
+ }
+
+ if (ig->source.type == FDSEEK || ig->source.type == FDNOSEEK) {
+ GifFileType *GifFile;
+ int fd = dup(ig->source.fdseek.fd);
+ if (fd < 0) {
+ i_push_error(errno, "dup() failed");
+ return NULL;
+ }
+ if ((GifFile = DGifOpenFileHandle(fd)) == NULL) {
+ gif_push_error();
+ i_push_error(0, "Cannot create giflib file object");
+ mm_log((1,"i_readgif: Unable to open file\n"));
+ return NULL;
+ }
+ return i_readgif_single_low(GifFile, page);
+ }
+ else {
+#if IM_GIFMAJOR >= 4
+ GifFileType *GifFile;
+
+ if ((GifFile = DGifOpen((void *)ig, io_glue_read_cb )) == NULL) {
+ gif_push_error();
+ i_push_error(0, "Cannot create giflib callback object");
+ mm_log((1,"i_readgif_wiol: Unable to open callback datasource.\n"));
+ return NULL;
+ }
+
+ return i_readgif_single_low(GifFile, page);
+#else
+ i_push_error(0, "callbacks not supported with giflib3");
+
+ return NULL;
+#endif
+ }
+}
+
/*
=item do_write(GifFileType *gf, i_gif_opts *opts, i_img *img, i_palidx *data)
Internal. Add the Netscape2.0 loop extension block, if requested.
-The code for this function is currently "#if 0"ed out since the giflib
-extension writing code currently doesn't seem to support writing
-application extension blocks.
+Giflib/libungif prior to 4.1.1 didn't support writing application
+extension blocks, so we don't attempt to write them for older versions.
+
+Giflib/libungif prior to 4.1.3 used the wrong write mechanism when
+writing extension blocks so that they could only be written to files.
=cut
*/
If giflib's callback interface wasn't broken by default, I'd
force file writes to use callbacks, but it is broken by default.
*/
-#if 0
/* yes this was another attempt at supporting the loop extension */
+#if IM_GIFMAJOR == 4 && IM_GIFMINOR >= 1
int loop_count;
if (i_tags_get_int(&img->tags, "gif_loop", 0, &loop_count)) {
unsigned char nsle[12] = "NETSCAPE2.0";
unsigned char subblock[3];
- if (EGifPutExtension(gf, 0xFF, 11, nsle) == GIF_ERROR) {
+ if (EGifPutExtensionFirst(gf, APPLICATION_EXT_FUNC_CODE, 11, nsle) == GIF_ERROR) {
gif_push_error();
i_push_error(0, "writing loop extension");
return 0;
subblock[0] = 1;
subblock[1] = loop_count % 256;
subblock[2] = loop_count / 256;
- if (EGifPutExtension(gf, 0, 3, subblock) == GIF_ERROR) {
+ if (EGifPutExtensionLast(gf, APPLICATION_EXT_FUNC_CODE, 3, subblock) == GIF_ERROR) {
gif_push_error();
i_push_error(0, "writing loop extention sub-block");
return 0;
}
- if (EGifPutExtension(gf, 0, 0, subblock) == GIF_ERROR) {
- gif_push_error();
- i_push_error(0, "writing loop extension terminator");
- return 0;
- }
}
#endif
+
return 1;
}
Failing to set the correct GIF version doesn't seem to cause a problem
with readers.
+Modern versions (4.1.4 anyway) of giflib/libungif handle
+EGifSetGifVersion correctly.
+
+If t/t105gif.t crashes here then run Makefile.PL with
+--nogifsetversion, eg.:
+
+ perl Makefile.PL --nogifsetversion
+
+or install a less buggy giflib.
+
=cut
*/
static void gif_set_version(i_quantize *quant, i_img **imgs, int count) {
- /* the following crashed giflib
- the EGifSetGifVersion() is seriously borked in giflib
- it's less borked in the ungiflib beta, but we don't have a mechanism
- to distinguish them
- Needs to be updated to support tags.
- if (opts->delay_count
- || opts->user_input_count
- || opts->disposal_count
- || opts->loop_count
- || quant->transp != tr_none)
+#if (IM_GIFMAJOR >= 4 || IM_GIFMAJOR == 4 && IM_GIFMINOR >= 1) \
+ && !defined(IM_NO_SET_GIF_VERSION)
+ int need_89a = 0;
+ int temp;
+ int i;
+
+ if (quant->transp != tr_none)
+ need_89a = 1;
+ else {
+ for (i = 0; i < count; ++i) {
+ if (i_tags_get_int(&imgs[i]->tags, "gif_delay", 0, &temp)) {
+ need_89a = 1;
+ break;
+ }
+ if (i_tags_get_int(&imgs[i]->tags, "gif_user_input", 0, &temp) && temp) {
+ need_89a = 1;
+ break;
+ }
+ if (i_tags_get_int(&imgs[i]->tags, "gif_disposal", 0, &temp)) {
+ need_89a = 1;
+ break;
+ }
+ if (i_tags_get_int(&imgs[i]->tags, "gif_loop", 0, &temp)) {
+ need_89a = 1;
+ break;
+ }
+ }
+ }
+ if (need_89a)
EGifSetGifVersion("89a");
- else
+ else
EGifSetGifVersion("87a");
- */
+#endif
}
static int
has_common_palette(i_img **imgs, int count, i_quantize *quant,
int want_trans) {
int size = quant->mc_count;
- int i, j;
+ int i;
int imgn;
- int x, y;
char used[256];
/* we try to build a common palette here, if we can manage that, then
static undef_int
i_writegif_low(i_quantize *quant, GifFileType *gf, i_img **imgs, int count) {
- unsigned char *result;
+ unsigned char *result = NULL;
int color_bits;
ColorMapObject *map;
int scrw = 0, scrh = 0;
int imgn, orig_count, orig_size;
int posx, posy;
- int trans_index;
+ int trans_index = -1;
i_mempool mp;
int *localmaps;
int anylocal;
int glob_img_count;
i_color *orig_colors = quant->mc_colors;
i_color *glob_colors = NULL;
- int glob_color_count;
- int glob_map_size;
+ int glob_color_count = 0;
int glob_want_trans;
- int glob_paletted; /* the global map was made from the image palettes */
- int colors_paletted;
- int want_trans;
+ int glob_paletted = 0; /* the global map was made from the image palettes */
+ int colors_paletted = 0;
+ int want_trans = 0;
int interlace;
int gif_background;
if (!i_tags_get_int(&imgs[0]->tags, "gif_screen_width", 0, &scrw))
scrw = 0;
- if (!i_tags_get_int(&imgs[0]->tags, "gif_screen_height", 0, &scrw))
+ if (!i_tags_get_int(&imgs[0]->tags, "gif_screen_height", 0, &scrh))
scrw = 0;
anylocal = 0;
}
else {
glob_paletted = 0;
- quant_makemap(quant, glob_imgs, glob_img_count);
+ i_quant_makemap(quant, glob_imgs, glob_img_count);
}
glob_color_count = quant->mc_count;
quant->mc_colors = orig_colors;
}
else {
colors_paletted = 0;
- quant_makemap(quant, imgs, 1);
+ i_quant_makemap(quant, imgs, 1);
}
}
if ((map = make_gif_map(quant, imgs[0], want_trans)) == NULL) {
}
else {
colors_paletted = 0;
- quant_makemap(quant, imgs, 1);
+ i_quant_makemap(quant, imgs, 1);
}
if ((map = make_gif_map(quant, imgs[0], want_trans)) == NULL) {
i_mempool_destroy(&mp);
EGifCloseFile(gf);
+ quant->mc_colors = orig_colors;
mm_log((1, "Error in MakeMapObject"));
return 0;
}
if (colors_paletted)
result = quant_paletted(quant, imgs[0]);
else
- result = quant_translate(quant, imgs[0]);
+ result = i_quant_translate(quant, imgs[0]);
+ if (!result) {
+ i_mempool_destroy(&mp);
+ quant->mc_colors = orig_colors;
+ EGifCloseFile(gf);
+ return 0;
+ }
if (want_trans) {
- quant_transparent(quant, result, imgs[0], quant->mc_count);
+ i_quant_transparent(quant, result, imgs[0], quant->mc_count);
trans_index = quant->mc_count;
}
result = quant_paletted(quant, imgs[imgn]);
}
else {
- quant_makemap(quant, imgs+imgn, 1);
- result = quant_translate(quant, imgs[imgn]);
+ i_quant_makemap(quant, imgs+imgn, 1);
+ result = i_quant_translate(quant, imgs[imgn]);
+ }
+ if (!result) {
+ i_mempool_destroy(&mp);
+ quant->mc_colors = orig_colors;
+ EGifCloseFile(gf);
+ mm_log((1, "error in i_quant_translate()"));
+ return 0;
}
if (want_trans) {
- quant_transparent(quant, result, imgs[imgn], quant->mc_count);
+ i_quant_transparent(quant, result, imgs[imgn], quant->mc_count);
trans_index = quant->mc_count;
}
if (glob_paletted)
result = quant_paletted(quant, imgs[imgn]);
else
- result = quant_translate(quant, imgs[imgn]);
+ result = i_quant_translate(quant, imgs[imgn]);
want_trans = glob_want_trans && imgs[imgn]->channels == 4;
if (want_trans) {
- quant_transparent(quant, result, imgs[imgn], quant->mc_count);
+ i_quant_transparent(quant, result, imgs[imgn], quant->mc_count);
trans_index = quant->mc_count;
}
map = NULL;
mm_log((1, "Error in EGifCloseFile\n"));
return 0;
}
+ if (glob_colors) {
+ int i;
+ for (i = 0; i < glob_color_count; ++i)
+ orig_colors[i] = glob_colors[i];
+ }
+
i_mempool_destroy(&mp);
quant->mc_colors = orig_colors;
gif_push_error();
i_push_error(0, "Cannot create GIF file object");
mm_log((1, "Error in EGifOpenFileHandle, unable to write image.\n"));
- free_gen_write_data(gwd, 0);
+ i_free_gen_write_data(gwd, 0);
return 0;
}
result = i_writegif_low(quant, gf, imgs, count);
- return free_gen_write_data(gwd, result);
+ return i_free_gen_write_data(gwd, result);
#else
i_clear_error();
i_push_error(0, "callbacks not supported with giflib3");