=cut
*/
-#if defined(GIFLIB_MAJOR) && GIFLIB_MAJOR >= 5
+#ifdef GIFLIB_MAJOR
+#define IMGIFLIB_API_VERSION (GIFLIB_MAJOR * 100 + GIFLIB_MINOR)
+#else
+/* only matters for pre-5.0 which we either reject, or which contains
+ no significant API changes */
+#define IMGIFLIB_API_VERSION 0
+#endif
+
+#if IMGIFLIB_API_VERSION >= 500
+#define POST_SET_VERSION
#define myDGifOpen(userPtr, readFunc, Error) DGifOpen((userPtr), (readFunc), (Error))
#define myEGifOpen(userPtr, readFunc, Error) EGifOpen((userPtr), (readFunc), (Error))
#define myGifError(gif) ((gif)->Error)
#define MakeMapObject GifMakeMapObject
#define FreeMapObject GifFreeMapObject
-
+#define gif_mutex_lock(mutex)
+#define gif_mutex_unlock(mutex)
#else
+#define PRE_SET_VERSION
static GifFileType *
myDGifOpen(void *userPtr, InputFunc readFunc, int *error) {
GifFileType *result = DGifOpen(userPtr, readFunc);
return result;
}
#define myGifError(gif) GifLastError()
+#define gif_mutex_lock(mutex) i_mutex_lock(mutex)
+#define gif_mutex_unlock(mutex) i_mutex_unlock(mutex)
+
+#endif
+
+#if IMGIFLIB_API_VERSION >= 501
+#define myDGifCloseFile(gif, perror) (DGifCloseFile((gif), (perror)))
+#define myEGifCloseFile(gif, perror) (EGifCloseFile((gif), (perror)))
+#else
+static int
+myDGifCloseFile(GifFileType *GifFile, int *ErrorCode) {
+ int result = DGifCloseFile(GifFile);
+ if (result == GIF_ERROR) {
+ if (ErrorCode)
+ *ErrorCode = myGifError(GifFile);
+ free(GifFile->Private);
+ free(GifFile);
+ }
+
+ return result;
+}
+
+static int
+myEGifCloseFile(GifFileType *GifFile, int *ErrorCode) {
+ int result = EGifCloseFile(GifFile);
+ if (result == GIF_ERROR) {
+ if (ErrorCode)
+ *ErrorCode = myGifError(GifFile);
+ free(GifFile->Private);
+ free(GifFile);
+ }
+ return result;
+}
#endif
static char const *gif_error_msg(int code);
InterlacedOffset[] = { 0, 4, 2, 1 }, /* The way Interlaced image should. */
InterlacedJumps[] = { 8, 8, 4, 2 }; /* be read - offsets and jumps... */
+#if IMGIFLIB_API_VERSION < 500
+static i_mutex_t mutex;
+#endif
+
+void
+i_init_gif(void) {
+#if IMGIFLIB_API_VERSION < 500
+ mutex = i_mutex_new();
+#endif
+}
+
static
void
i_colortable_copy(int **colour_table, int *colours, ColorMapObject *colourmap) {
i_readgif_low(GifFileType *GifFile, int **colour_table, int *colours) {
i_img *im;
int i, j, Size, Row, Col, Width, Height, ExtCode, Count, x;
- int cmapcnt = 0, ImageNum = 0, BackGround = 0, ColorMapSize = 0;
+ int cmapcnt = 0, ImageNum = 0;
ColorMapObject *ColorMap;
GifRecordType RecordType;
GifRowType GifRow;
GifColorType *ColorMapEntry;
i_color col;
+ int error;
mm_log((1,"i_readgif_low(GifFile %p, colour_table %p, colours %p)\n", GifFile, colour_table, colours));
*/
if (colour_table) *colour_table = NULL;
- BackGround = GifFile->SBackGroundColor;
ColorMap = (GifFile->Image.ColorMap ? GifFile->Image.ColorMap : GifFile->SColorMap);
if (ColorMap) {
- ColorMapSize = ColorMap->ColorCount;
i_colortable_copy(colour_table, colours, ColorMap);
cmapcnt++;
}
myfree(*colour_table);
*colour_table = NULL;
}
- DGifCloseFile(GifFile);
+ (void)myDGifCloseFile(GifFile, NULL);
mm_log((1, "i_readgif: image size exceeds limits\n"));
return NULL;
}
myfree(*colour_table);
*colour_table = NULL;
}
- DGifCloseFile(GifFile);
+ (void)myDGifCloseFile(GifFile, NULL);
return NULL;
}
}
myfree(GifRow);
i_img_destroy(im);
- DGifCloseFile(GifFile);
+ (void)myDGifCloseFile(GifFile, NULL);
return NULL;
}
}
myfree(GifRow);
i_img_destroy(im);
- DGifCloseFile(GifFile);
+ (void)myDGifCloseFile(GifFile, NULL);
return NULL;
}
if (( ColorMap = (GifFile->Image.ColorMap ? GifFile->Image.ColorMap : GifFile->SColorMap) )) {
mm_log((1, "Adding local colormap\n"));
- ColorMapSize = ColorMap->ColorCount;
if ( cmapcnt == 0) {
i_colortable_copy(colour_table, colours, ColorMap);
cmapcnt++;
/* we can't have allocated a colour table here */
myfree(GifRow);
i_img_destroy(im);
- DGifCloseFile(GifFile);
+ (void)myDGifCloseFile(GifFile, NULL);
return NULL;
}
}
myfree(GifRow);
i_img_destroy(im);
- DGifCloseFile(GifFile);
+ (void)myDGifCloseFile(GifFile, NULL);
return NULL;
}
if (GifFile->Image.Interlace) {
}
myfree(GifRow);
i_img_destroy(im);
- DGifCloseFile(GifFile);
+ (void)myDGifCloseFile(GifFile, NULL);
return NULL;
}
}
myfree(GifRow);
i_img_destroy(im);
- DGifCloseFile(GifFile);
+ (void)myDGifCloseFile(GifFile, NULL);
return NULL;
}
}
myfree(GifRow);
i_img_destroy(im);
- DGifCloseFile(GifFile);
+ (void)myDGifCloseFile(GifFile, NULL);
return NULL;
}
while (Extension != NULL) {
}
myfree(GifRow);
i_img_destroy(im);
- DGifCloseFile(GifFile);
+ (void)myDGifCloseFile(GifFile, NULL);
return NULL;
}
}
myfree(GifRow);
- if (DGifCloseFile(GifFile) == GIF_ERROR) {
- gif_push_error(myGifError(GifFile));
+ if (myDGifCloseFile(GifFile, &error) == GIF_ERROR) {
+ gif_push_error(error);
i_push_error(0, "Closing GIF file object");
if (colour_table && *colour_table) {
myfree(*colour_table);
i_readgif_multi_low(GifFileType *GifFile, int *count, int page) {
i_img *img;
int i, j, Size, Width, Height, ExtCode, Count;
- int ImageNum = 0, BackGround = 0, ColorMapSize = 0;
+ int ImageNum = 0, ColorMapSize = 0;
ColorMapObject *ColorMap;
GifRecordType RecordType;
int channels;
int image_colors = 0;
i_color black; /* used to expand the palette if needed */
+ int error;
for (i = 0; i < MAXCHANNELS; ++i)
black.channel[i] = 0;
mm_log((1,"i_readgif_multi_low(GifFile %p, , count %p)\n", GifFile, count));
- BackGround = GifFile->SBackGroundColor;
-
Size = GifFile->SWidth * sizeof(GifPixelType);
GifRow = (GifRowType) mymalloc(Size);
gif_push_error(myGifError(GifFile));
i_push_error(0, "Unable to get record type");
free_images(results, *count);
- DGifCloseFile(GifFile);
+ (void)myDGifCloseFile(GifFile, NULL);
myfree(GifRow);
if (comment)
myfree(comment);
gif_push_error(myGifError(GifFile));
i_push_error(0, "Unable to get image descriptor");
free_images(results, *count);
- DGifCloseFile(GifFile);
+ (void)myDGifCloseFile(GifFile, NULL);
myfree(GifRow);
if (comment)
myfree(comment);
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);
+ (void)myDGifCloseFile(GifFile, NULL);
myfree(GifRow);
if (comment)
myfree(comment);
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);
+ (void)myDGifCloseFile(GifFile, NULL);
myfree(GifRow);
if (comment)
myfree(comment);
img = i_img_pal_new(Width, Height, channels, 256);
if (!img) {
free_images(results, *count);
- DGifCloseFile(GifFile);
+ (void)myDGifCloseFile(GifFile, NULL);
if (comment)
myfree(comment);
myfree(GifRow);
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);
+ (void)myDGifCloseFile(GifFile, NULL);
myfree(GifRow);
if (comment)
myfree(comment);
gif_push_error(myGifError(GifFile));
i_push_error(0, "Reading GIF line");
free_images(results, *count);
- DGifCloseFile(GifFile);
+ (void)myDGifCloseFile(GifFile, NULL);
myfree(GifRow);
if (comment)
myfree(comment);
gif_push_error(myGifError(GifFile));
i_push_error(0, "Reading GIF line");
free_images(results, *count);
- DGifCloseFile(GifFile);
+ (void)myDGifCloseFile(GifFile, NULL);
myfree(GifRow);
if (comment)
myfree(comment);
/* must be only one image wanted and that was it */
if (page != -1) {
myfree(GifRow);
- DGifCloseFile(GifFile);
+ (void)myDGifCloseFile(GifFile, NULL);
if (comment)
myfree(comment);
return results;
i_push_error(0, "Reading GIF line");
free_images(results, *count);
myfree(GifRow);
- DGifCloseFile(GifFile);
+ (void)myDGifCloseFile(GifFile, NULL);
if (comment)
myfree(comment);
return NULL;
i_push_error(0, "Reading extension record");
free_images(results, *count);
myfree(GifRow);
- DGifCloseFile(GifFile);
+ (void)myDGifCloseFile(GifFile, NULL);
if (comment)
myfree(comment);
return NULL;
i_push_error(0, "reading loop extension");
free_images(results, *count);
myfree(GifRow);
- DGifCloseFile(GifFile);
+ (void)myDGifCloseFile(GifFile, NULL);
if (comment)
myfree(comment);
return NULL;
i_push_error(0, "reading next block of extension");
free_images(results, *count);
myfree(GifRow);
- DGifCloseFile(GifFile);
+ (void)myDGifCloseFile(GifFile, NULL);
if (comment)
myfree(comment);
return NULL;
myfree(GifRow);
- if (DGifCloseFile(GifFile) == GIF_ERROR) {
- gif_push_error(myGifError(GifFile));
+ if (myDGifCloseFile(GifFile, &error) == GIF_ERROR) {
+ gif_push_error(error);
i_push_error(0, "Closing GIF file object");
free_images(results, *count);
return NULL;
i_readgif_multi_wiol(io_glue *ig, int *count) {
GifFileType *GifFile;
int gif_error;
+ i_img **result;
+
+ gif_mutex_lock(mutex);
i_clear_error();
gif_push_error(gif_error);
i_push_error(0, "Cannot create giflib callback object");
mm_log((1,"i_readgif_multi_wiol: Unable to open callback datasource.\n"));
+ gif_mutex_unlock(mutex);
return NULL;
}
- return i_readgif_multi_low(GifFile, count, -1);
+ result = i_readgif_multi_low(GifFile, count, -1);
+
+ gif_mutex_unlock(mutex);
+
+ return result;
}
static int
i_readgif_wiol(io_glue *ig, int **color_table, int *colors) {
GifFileType *GifFile;
int gif_error;
+ i_img *result;
+
+ gif_mutex_lock(mutex);
i_clear_error();
gif_push_error(gif_error);
i_push_error(0, "Cannot create giflib callback object");
mm_log((1,"i_readgif_wiol: Unable to open callback datasource.\n"));
+ gif_mutex_unlock(mutex);
return NULL;
}
- return i_readgif_low(GifFile, color_table, colors);
+ result = i_readgif_low(GifFile, color_table, colors);
+
+ gif_mutex_unlock(mutex);
+
+ return result;
}
/*
i_readgif_single_wiol(io_glue *ig, int page) {
GifFileType *GifFile;
int gif_error;
+ i_img *result;
i_clear_error();
if (page < 0) {
return NULL;
}
+ gif_mutex_lock(mutex);
if ((GifFile = myDGifOpen((void *)ig, io_glue_read_cb, &gif_error )) == NULL) {
gif_push_error(gif_error);
i_push_error(0, "Cannot create giflib callback object");
mm_log((1,"i_readgif_wiol: Unable to open callback datasource.\n"));
+ gif_mutex_unlock(mutex);
return NULL;
}
- return i_readgif_single_low(GifFile, page);
+ result = i_readgif_single_low(GifFile, page);
+
+ gif_mutex_unlock(mutex);
+
+ return result;
}
/*
gif_push_error(myGifError(gf));
i_push_error(0, "Could not save image data:");
mm_log((1, "Error in EGifPutLine\n"));
- EGifCloseFile(gf);
return 0;
}
}
gif_push_error(myGifError(gf));
i_push_error(0, "Could not save image data:");
mm_log((1, "Error in EGifPutLine\n"));
- EGifCloseFile(gf);
return 0;
}
data += img->xsize;
subblock[1] = loop_count % 256;
subblock[2] = loop_count / 256;
-#if defined(GIFLIB_MAJOR) && GIFLIB_MAJOR >= 5
+#if IMGIFLIB_API_VERSION >= 500
if (EGifPutExtensionLeader(gf, APPLICATION_EXT_FUNC_CODE) == GIF_ERROR
|| EGifPutExtensionBlock(gf, 11, nsle) == GIF_ERROR
|| EGifPutExtensionBlock(gf, 3, subblock) == GIF_ERROR
}
map = MakeMapObject(map_size, colors);
- mm_log((1, "XXX map is at %p and colors at %p\n", map, map->Colors));
if (!map) {
i_push_error(0, "Could not create color map object");
return NULL;
}
+ mm_log((1, "XXX map is at %p and colors at %p\n", map, map->Colors));
+#if IMGIFLIB_API_VERSION >= 500
+ map->SortFlag = 0;
+#endif
return map;
}
/*
-=item gif_set_version(i_quantize *quant, i_img *imgs, int count)
-
-We need to call EGifSetGifVersion() before opening the file - put that
-common code here.
-
-Unfortunately giflib 4.1.0 crashes when we use this. Internally
-giflib 4.1.0 has code:
-
- static char *GifVersionPrefix = GIF87_STAMP;
-
-and the code that sets the version internally does:
-
- strncpy(&GifVersionPrefix[3], Version, 3);
-
-which is very broken.
+=item need_version_89a(i_quantize *quant, i_img *imgs, int count)
-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.
-
-This code is completely unnecessary in giflib 5
+Return true if the file we're creating on these images needs a GIF89a
+header.
=cut
*/
-static void
-gif_set_version(i_quantize *quant, i_img **imgs, int count) {
-#if !defined(GIFLIB_MAJOR) || GIFLIB_MAJOR < 5
+static int
+need_version_89a(i_quantize *quant, i_img **imgs, int count) {
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;
- }
+ for (i = 0; i < count; ++i) {
+ if (quant->transp != tr_none &&
+ (imgs[i]->channels == 2 || imgs[i]->channels == 4)) {
+ need_89a = 1;
+ break;
+ }
+ 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
- EGifSetGifVersion("87a");
-#endif
+
+ return need_89a;
}
static int
int imgn, orig_count, orig_size;
int posx, posy;
int trans_index = -1;
- int *localmaps;
+ int *localmaps = NULL;
int anylocal;
- i_img **glob_imgs; /* images that will use the global color map */
+ i_img **glob_imgs = NULL; /* images that will use the global color map */
int glob_img_count;
i_color *orig_colors = quant->mc_colors;
i_color *glob_colors = NULL;
int want_trans = 0;
int interlace;
int gif_background;
+ int error;
mm_log((1, "i_writegif_low(quant %p, gf %p, imgs %p, count %d)\n",
quant, gf, imgs, count));
if (count <= 0) {
i_push_error(0, "No images provided to write");
- return 0; /* what are you smoking? */
+ goto fail_cleanup;
}
/* sanity is nice */
i_img *im = imgs[imgn];
if (im->xsize > 0xFFFF || im->ysize > 0xFFFF) {
i_push_error(0, "image too large for GIF");
- return 0;
+ goto fail_cleanup;
}
posx = posy = 0;
if (scrw > 0xFFFF || scrh > 0xFFFF) {
i_push_error(0, "screen size too large for GIF");
- return 0;
+ goto fail_cleanup;
}
orig_count = quant->mc_count;
}
if ((map = make_gif_map(quant, imgs[0], want_trans)) == NULL) {
- myfree(glob_colors);
- myfree(localmaps);
- myfree(glob_imgs);
- quant->mc_colors = orig_colors;
- EGifCloseFile(gf);
mm_log((1, "Error in MakeMapObject"));
- return 0;
+ goto fail_cleanup;
}
color_bits = 1;
if (anylocal) {
if (EGifPutScreenDesc(gf, scrw, scrh, color_bits,
gif_background, map) == GIF_ERROR) {
- myfree(glob_colors);
- myfree(localmaps);
- myfree(glob_imgs);
- quant->mc_colors = orig_colors;
gif_push_error(myGifError(gf));
i_push_error(0, "Could not save screen descriptor");
FreeMapObject(map);
- myfree(result);
- EGifCloseFile(gf);
mm_log((1, "Error in EGifPutScreenDesc."));
- return 0;
+ goto fail_cleanup;
}
FreeMapObject(map);
i_quant_makemap(quant, imgs, 1);
colors_paletted = has_common_palette(imgs, 1, quant);
if ((map = make_gif_map(quant, imgs[0], want_trans)) == NULL) {
- myfree(glob_colors);
- myfree(localmaps);
- myfree(glob_imgs);
- EGifCloseFile(gf);
- quant->mc_colors = orig_colors;
mm_log((1, "Error in MakeMapObject"));
- return 0;
+ goto fail_cleanup;
}
}
else {
else
result = i_quant_translate(quant, imgs[0]);
if (!result) {
- myfree(glob_colors);
- myfree(localmaps);
- myfree(glob_imgs);
- quant->mc_colors = orig_colors;
- EGifCloseFile(gf);
- return 0;
+ goto fail_cleanup;
}
if (want_trans) {
i_quant_transparent(quant, result, imgs[0], quant->mc_count);
}
if (!do_ns_loop(gf, imgs[0])) {
- myfree(glob_colors);
- myfree(localmaps);
- myfree(glob_imgs);
- quant->mc_colors = orig_colors;
- return 0;
+ goto fail_cleanup;
}
if (!do_gce(gf, imgs[0], want_trans, trans_index)) {
- myfree(glob_colors);
- myfree(localmaps);
- myfree(glob_imgs);
- quant->mc_colors = orig_colors;
- myfree(result);
- EGifCloseFile(gf);
- return 0;
+ goto fail_cleanup;
}
if (!do_comments(gf, imgs[0])) {
- myfree(glob_colors);
- myfree(localmaps);
- myfree(glob_imgs);
- quant->mc_colors = orig_colors;
- myfree(result);
- EGifCloseFile(gf);
- return 0;
+ goto fail_cleanup;
}
if (!i_tags_get_int(&imgs[0]->tags, "gif_interlace", 0, &interlace))
interlace = 0;
if (EGifPutImageDesc(gf, posx, posy, imgs[0]->xsize, imgs[0]->ysize,
interlace, map) == GIF_ERROR) {
- myfree(glob_colors);
- myfree(localmaps);
- myfree(glob_imgs);
- quant->mc_colors = orig_colors;
+ if (map)
+ FreeMapObject(map);
gif_push_error(myGifError(gf));
i_push_error(0, "Could not save image descriptor");
- EGifCloseFile(gf);
mm_log((1, "Error in EGifPutImageDesc."));
- return 0;
+ goto fail_cleanup;
}
if (map)
FreeMapObject(map);
if (!do_write(gf, interlace, imgs[0], result)) {
- myfree(glob_colors);
- myfree(localmaps);
- myfree(glob_imgs);
- quant->mc_colors = orig_colors;
- EGifCloseFile(gf);
- myfree(result);
- return 0;
+ goto fail_cleanup;
}
myfree(result);
+ result = NULL;
/* that first awful image is out of the way, do the rest */
for (imgn = 1; imgn < count; ++imgn) {
result = i_quant_translate(quant, imgs[imgn]);
}
if (!result) {
- myfree(glob_colors);
- myfree(localmaps);
- myfree(glob_imgs);
- quant->mc_colors = orig_colors;
- EGifCloseFile(gf);
mm_log((1, "error in i_quant_translate()"));
- return 0;
+ goto fail_cleanup;
}
if (want_trans) {
i_quant_transparent(quant, result, imgs[imgn], quant->mc_count);
}
if ((map = make_gif_map(quant, imgs[imgn], want_trans)) == NULL) {
- myfree(glob_colors);
- myfree(localmaps);
- myfree(glob_imgs);
- quant->mc_colors = orig_colors;
- myfree(result);
- EGifCloseFile(gf);
mm_log((1, "Error in MakeMapObject."));
- return 0;
+ goto fail_cleanup;
}
}
else {
}
if (!do_gce(gf, imgs[imgn], want_trans, trans_index)) {
- myfree(glob_colors);
- myfree(localmaps);
- myfree(glob_imgs);
- quant->mc_colors = orig_colors;
- myfree(result);
- EGifCloseFile(gf);
- return 0;
+ goto fail_cleanup;
}
if (!do_comments(gf, imgs[imgn])) {
- myfree(glob_colors);
- myfree(localmaps);
- myfree(glob_imgs);
- quant->mc_colors = orig_colors;
- myfree(result);
- EGifCloseFile(gf);
- return 0;
+ goto fail_cleanup;
}
if (!i_tags_get_int(&imgs[imgn]->tags, "gif_left", 0, &posx))
interlace = 0;
if (EGifPutImageDesc(gf, posx, posy, imgs[imgn]->xsize,
imgs[imgn]->ysize, interlace, map) == GIF_ERROR) {
- myfree(glob_colors);
- myfree(localmaps);
- myfree(glob_imgs);
- quant->mc_colors = orig_colors;
gif_push_error(myGifError(gf));
i_push_error(0, "Could not save image descriptor");
- myfree(result);
if (map)
FreeMapObject(map);
- EGifCloseFile(gf);
mm_log((1, "Error in EGifPutImageDesc."));
- return 0;
+ goto fail_cleanup;
}
if (map)
FreeMapObject(map);
if (!do_write(gf, interlace, imgs[imgn], result)) {
- myfree(glob_colors);
- myfree(localmaps);
- myfree(glob_imgs);
- quant->mc_colors = orig_colors;
- EGifCloseFile(gf);
- myfree(result);
- return 0;
+ goto fail_cleanup;
}
myfree(result);
+ result = NULL;
}
- if (EGifCloseFile(gf) == GIF_ERROR) {
- myfree(glob_colors);
- myfree(localmaps);
- myfree(glob_imgs);
- gif_push_error(myGifError(gf));
+ if (myEGifCloseFile(gf, &error) == GIF_ERROR) {
+ gif_push_error(error);
i_push_error(0, "Could not close GIF file");
- mm_log((1, "Error in EGifCloseFile\n"));
- return 0;
+ goto fail_cleanup;
}
if (glob_colors) {
int i;
quant->mc_colors = orig_colors;
return 1;
+
+ fail_cleanup:
+ quant->mc_colors = orig_colors;
+ myfree(result);
+ myfree(glob_colors);
+ myfree(localmaps);
+ myfree(glob_imgs);
+ (void)myEGifCloseFile(gf, &error);
+ return 0;
}
static int
int gif_error;
int result;
+ gif_mutex_lock(mutex);
+
i_clear_error();
- gif_set_version(quant, imgs, count);
+#ifdef PRE_SET_VERSION
+ EGifSetGifVersion(need_version_89a(quant, imgs, count) ? "89a" : "87a");
+#endif
if ((GifFile = myEGifOpen((void *)ig, io_glue_write_cb, &gif_error )) == NULL) {
gif_push_error(gif_error);
i_push_error(0, "Cannot create giflib callback object");
mm_log((1,"i_writegif_wiol: Unable to open callback datasource.\n"));
+ gif_mutex_unlock(mutex);
return 0;
}
+#ifdef POST_SET_VERSION
+ EGifSetGifVersion(GifFile, need_version_89a(quant, imgs, count));
+#endif
+
result = i_writegif_low(quant, GifFile, imgs, count);
+ gif_mutex_unlock(mutex);
+
if (i_io_close(ig))
return 0;
static char const *
gif_error_msg(int code) {
-#if defined(GIFLIB_MAJOR) && GIFLIB_MAJOR >= 5
+#if IMGIFLIB_API_VERSION >= 500
return GifErrorString(code);
#else
switch (code) {
Arnar M. Hrafnkelsson, addi@umich.edu
+Tony Cook <tonyc@cpan.org>
+
=head1 SEE ALSO
perl(1), Imager(3)