]> git.imager.perl.org - imager.git/blobdiff - GIF/imgif.c
typo fixes in the sources of APIRef.pod
[imager.git] / GIF / imgif.c
index 506e10054ae1fbf6744d82a1e9e8d7d8f0c3817a..44833ff1357278e92d2a0d9669c92f0b69a48120 100644 (file)
@@ -60,15 +60,16 @@ functionality with giflib3.
 */
 
 #if defined(GIFLIB_MAJOR) && GIFLIB_MAJOR >= 5
+#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()
-#define gif_mutex_unlock()
+#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);
@@ -86,10 +87,9 @@ myEGifOpen(void *userPtr, OutputFunc outputFunc, int *error) {
   return result;
 }
 #define myGifError(gif) GifLastError()
+#define gif_mutex_lock(mutex) i_mutex_lock(mutex)
+#define gif_mutex_unlock(mutex) i_mutex_unlock(mutex)
 
-#define gif_mutex_lock() i_mutex_lock(mutex)
-#define gif_mutex_unlock() i_mutex_unlock(mutex)
-#define NEED_MUTEX
 #endif
 
 static char const *gif_error_msg(int code);
@@ -101,25 +101,13 @@ static const int
   InterlacedOffset[] = { 0, 4, 2, 1 }, /* The way Interlaced image should. */
   InterlacedJumps[] = { 8, 8, 4, 2 };    /* be read - offsets and jumps... */
 
-
-#ifdef NEED_MUTEX
+#if !defined(GIFLIB_MAJOR) || GIFLIB_MAJOR < 5
 static i_mutex_t mutex;
 #endif
 
-/*
-=item i_init_gif()
-
-Initialize GIF support.
-
-For versions of giflib that require it, create a mutex to avoid
-reentrancy.
-
-=cut
-*/
-
 void
 i_init_gif(void) {
-#ifdef NEED_MUTEX
+#if !defined(GIFLIB_MAJOR) || GIFLIB_MAJOR < 5
   mutex = i_mutex_new();
 #endif
 }
@@ -185,7 +173,7 @@ i_img *
 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;
@@ -203,11 +191,9 @@ i_readgif_low(GifFileType *GifFile, int **colour_table, int *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++;
   }
@@ -270,7 +256,6 @@ i_readgif_low(GifFileType *GifFile, int **colour_table, int *colours) {
 
       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++;
@@ -516,7 +501,7 @@ i_img **
 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;
@@ -544,8 +529,6 @@ i_readgif_multi_low(GifFileType *GifFile, int *count, int page) {
 
   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);
@@ -902,10 +885,10 @@ static int io_glue_read_cb(GifFileType *gft, GifByteType *buf, int length);
 i_img **
 i_readgif_multi_wiol(io_glue *ig, int *count) {
   GifFileType *GifFile;
-  i_img **result;
   int gif_error;
+  i_img **result;
 
-  gif_mutex_lock();
+  gif_mutex_lock(mutex);
 
   i_clear_error();
   
@@ -913,13 +896,13 @@ i_readgif_multi_wiol(io_glue *ig, int *count) {
     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();
+    gif_mutex_unlock(mutex);
     return NULL;
   }
     
   result = i_readgif_multi_low(GifFile, count, -1);
 
-  gif_mutex_unlock();
+  gif_mutex_unlock(mutex);
 
   return result;
 }
@@ -934,10 +917,10 @@ io_glue_read_cb(GifFileType *gft, GifByteType *buf, int length) {
 i_img *
 i_readgif_wiol(io_glue *ig, int **color_table, int *colors) {
   GifFileType *GifFile;
-  i_img *result;
   int gif_error;
+  i_img *result;
 
-  gif_mutex_lock();
+  gif_mutex_lock(mutex);
 
   i_clear_error();
 
@@ -945,13 +928,13 @@ i_readgif_wiol(io_glue *ig, int **color_table, int *colors) {
     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();
+    gif_mutex_unlock(mutex);
     return NULL;
   }
     
   result = i_readgif_low(GifFile, color_table, colors);
 
-  gif_mutex_unlock();
+  gif_mutex_unlock(mutex);
 
   return result;
 }
@@ -998,8 +981,8 @@ Returns NULL if the page isn't found.
 i_img *
 i_readgif_single_wiol(io_glue *ig, int page) {
   GifFileType *GifFile;
-  i_img *result;
   int gif_error;
+  i_img *result;
 
   i_clear_error();
   if (page < 0) {
@@ -1007,19 +990,19 @@ i_readgif_single_wiol(io_glue *ig, int page) {
     return NULL;
   }
 
-  gif_mutex_lock();
+  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();
+    gif_mutex_unlock(mutex);
     return NULL;
   }
     
   result = i_readgif_single_low(GifFile, page);
 
-  gif_mutex_unlock();
+  gif_mutex_unlock(mutex);
 
   return result;
 }
@@ -1259,78 +1242,52 @@ make_gif_map(i_quantize *quant, i_img *img, int want_trans) {
     i_push_error(0, "Could not create color map object");
     return NULL;
   }
+#if defined GIFLIB_MAJOR && GIFLIB_MAJOR >= 5
+  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.
-
-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.:
+=item need_version_89a(i_quantize *quant, i_img *imgs, int count)
 
-  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 
@@ -1902,26 +1859,32 @@ undef_int
 i_writegif_wiol(io_glue *ig, i_quantize *quant, i_img **imgs,
                 int count) {
   GifFileType *GifFile;
-  int result;
   int gif_error;
+  int result;
 
-  gif_mutex_lock();
+  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();
+    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();
+  gif_mutex_unlock(mutex);
 
   if (i_io_close(ig))
     return 0;