]> granicus.if.org Git - imagemagick/blobdiff - coders/gif.c
(no commit message)
[imagemagick] / coders / gif.c
index 440d0c7545d34171deb630cbb012d5b7d4b4def4..4d9ce5baeaadf53ce4e719e59edaa61ec828860e 100644 (file)
@@ -17,7 +17,7 @@
 %                                 July 1992                                   %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2009 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization      %
 %  dedicated to making software imaging solutions freely available.           %
 %                                                                             %
 %  You may not use this file except in compliance with the License.  You may  %
 /*
   Include declarations.
 */
-#include "magick/studio.h"
-#include "magick/blob.h"
-#include "magick/blob-private.h"
-#include "magick/cache.h"
-#include "magick/color.h"
-#include "magick/colormap-private.h"
-#include "magick/color-private.h"
-#include "magick/colorspace.h"
-#include "magick/exception.h"
-#include "magick/exception-private.h"
-#include "magick/image.h"
-#include "magick/image-private.h"
-#include "magick/list.h"
-#include "magick/profile.h"
-#include "magick/magick.h"
-#include "magick/memory_.h"
-#include "magick/monitor.h"
-#include "magick/monitor-private.h"
-#include "magick/option.h"
-#include "magick/property.h"
-#include "magick/quantize.h"
-#include "magick/quantum-private.h"
-#include "magick/static.h"
-#include "magick/string_.h"
-#include "magick/module.h"
+#include "MagickCore/studio.h"
+#include "MagickCore/attribute.h"
+#include "MagickCore/blob.h"
+#include "MagickCore/blob-private.h"
+#include "MagickCore/cache.h"
+#include "MagickCore/color.h"
+#include "MagickCore/color-private.h"
+#include "MagickCore/colormap.h"
+#include "MagickCore/colormap-private.h"
+#include "MagickCore/colorspace.h"
+#include "MagickCore/colorspace-private.h"
+#include "MagickCore/exception.h"
+#include "MagickCore/exception-private.h"
+#include "MagickCore/image.h"
+#include "MagickCore/image-private.h"
+#include "MagickCore/list.h"
+#include "MagickCore/profile.h"
+#include "MagickCore/magick.h"
+#include "MagickCore/memory_.h"
+#include "MagickCore/monitor.h"
+#include "MagickCore/monitor-private.h"
+#include "MagickCore/option.h"
+#include "MagickCore/pixel.h"
+#include "MagickCore/pixel-accessor.h"
+#include "MagickCore/property.h"
+#include "MagickCore/quantize.h"
+#include "MagickCore/quantum-private.h"
+#include "MagickCore/static.h"
+#include "MagickCore/string_.h"
+#include "MagickCore/string-private.h"
+#include "MagickCore/module.h"
 \f
 /*
   Define declarations.
@@ -79,7 +85,7 @@ typedef struct _LZWCodeInfo
   unsigned char
     buffer[280];
 
-  unsigned long
+  size_t
     count,
     bit;
 
@@ -89,7 +95,7 @@ typedef struct _LZWCodeInfo
 
 typedef struct _LZWStack
 {
-  unsigned long
+  size_t
     *codes,
     *index,
     *top;
@@ -106,7 +112,7 @@ typedef struct _LZWInfo
   MagickBooleanType
     genesis;
 
-  unsigned long
+  size_t
     data_size,
     maximum_data_value,
     clear_code,
@@ -126,10 +132,10 @@ typedef struct _LZWInfo
   Forward declarations.
 */
 static inline int
-  GetNextLZWCode(LZWInfo *,const unsigned long);
+  GetNextLZWCode(LZWInfo *,const size_t);
 
 static MagickBooleanType
-  WriteGIFImage(const ImageInfo *,Image *);
+  WriteGIFImage(const ImageInfo *,Image *,ExceptionInfo *);
 
 static ssize_t
   ReadBlobBlock(Image *,unsigned char *);
@@ -149,7 +155,7 @@ static ssize_t
 %
 %  The format of the DecodeImage method is:
 %
-%      MagickBooleanType DecodeImage(Image *image,const long opacity)
+%      MagickBooleanType DecodeImage(Image *image,const ssize_t opacity)
 %
 %  A description of each parameter follows:
 %
@@ -161,16 +167,16 @@ static ssize_t
 
 static LZWInfo *RelinquishLZWInfo(LZWInfo *lzw_info)
 {
-  if (lzw_info->table[0] != (unsigned long *) NULL)
-    lzw_info->table[0]=(unsigned long *) RelinquishMagickMemory(
+  if (lzw_info->table[0] != (size_t *) NULL)
+    lzw_info->table[0]=(size_t *) RelinquishMagickMemory(
       lzw_info->table[0]);
-  if (lzw_info->table[1] != (unsigned long *) NULL)
-    lzw_info->table[1]=(unsigned long *) RelinquishMagickMemory(
+  if (lzw_info->table[1] != (size_t *) NULL)
+    lzw_info->table[1]=(size_t *) RelinquishMagickMemory(
       lzw_info->table[1]);
   if (lzw_info->stack != (LZWStack *) NULL)
     {
-      if (lzw_info->stack->codes != (unsigned long *) NULL)
-        lzw_info->stack->codes=(unsigned long *) RelinquishMagickMemory(
+      if (lzw_info->stack->codes != (size_t *) NULL)
+        lzw_info->stack->codes=(size_t *) RelinquishMagickMemory(
           lzw_info->stack->codes);
       lzw_info->stack=(LZWStack *) RelinquishMagickMemory(lzw_info->stack);
     }
@@ -180,43 +186,51 @@ static LZWInfo *RelinquishLZWInfo(LZWInfo *lzw_info)
 
 static inline void ResetLZWInfo(LZWInfo *lzw_info)
 {
+  size_t
+    one;
+
   lzw_info->bits=lzw_info->data_size+1;
-  lzw_info->maximum_code=1UL << lzw_info->bits;
+  one=1;
+  lzw_info->maximum_code=one << lzw_info->bits;
   lzw_info->slot=lzw_info->maximum_data_value+3;
   lzw_info->genesis=MagickTrue;
 }
 
-static LZWInfo *AcquireLZWInfo(Image *image,const unsigned long data_size)
+static LZWInfo *AcquireLZWInfo(Image *image,const size_t data_size)
 {
   LZWInfo
     *lzw_info;
 
-  register long
+  register ssize_t
     i;
 
+  size_t
+    one;
+
   lzw_info=(LZWInfo *) AcquireMagickMemory(sizeof(*lzw_info));
   if (lzw_info == (LZWInfo *) NULL)
     return((LZWInfo *) NULL);
   (void) ResetMagickMemory(lzw_info,0,sizeof(*lzw_info));
   lzw_info->image=image;
   lzw_info->data_size=data_size;
-  lzw_info->maximum_data_value=(1UL << data_size)-1;
+  one=1;
+  lzw_info->maximum_data_value=(one << data_size)-1;
   lzw_info->clear_code=lzw_info->maximum_data_value+1;
   lzw_info->end_code=lzw_info->maximum_data_value+2;
-  lzw_info->table[0]=(unsigned long *) AcquireQuantumMemory(MaximumLZWCode,
+  lzw_info->table[0]=(size_t *) AcquireQuantumMemory(MaximumLZWCode,
     sizeof(*lzw_info->table));
-  lzw_info->table[1]=(unsigned long *) AcquireQuantumMemory(MaximumLZWCode,
+  lzw_info->table[1]=(size_t *) AcquireQuantumMemory(MaximumLZWCode,
     sizeof(*lzw_info->table));
-  if ((lzw_info->table[0] == (unsigned long *) NULL) ||
-      (lzw_info->table[1] == (unsigned long *) NULL))
+  if ((lzw_info->table[0] == (size_t *) NULL) ||
+      (lzw_info->table[1] == (size_t *) NULL))
     {
       lzw_info=RelinquishLZWInfo(lzw_info);
       return((LZWInfo *) NULL);
     }
-  for (i=0; i <= (long) lzw_info->maximum_data_value; i++)
+  for (i=0; i <= (ssize_t) lzw_info->maximum_data_value; i++)
   {
     lzw_info->table[0][i]=0;
-    lzw_info->table[1][i]=(unsigned long) i;
+    lzw_info->table[1][i]=(size_t) i;
   }
   ResetLZWInfo(lzw_info);
   lzw_info->code_info.buffer[0]='\0';
@@ -231,9 +245,9 @@ static LZWInfo *AcquireLZWInfo(Image *image,const unsigned long data_size)
       lzw_info=RelinquishLZWInfo(lzw_info);
       return((LZWInfo *) NULL);
     }
-  lzw_info->stack->codes=(unsigned long *) AcquireQuantumMemory(2UL*
+  lzw_info->stack->codes=(size_t *) AcquireQuantumMemory(2UL*
     MaximumLZWCode,sizeof(*lzw_info->stack->codes));
-  if (lzw_info->stack->codes == (unsigned long *) NULL)
+  if (lzw_info->stack->codes == (size_t *) NULL)
     {
       lzw_info=RelinquishLZWInfo(lzw_info);
       return((LZWInfo *) NULL);
@@ -243,14 +257,17 @@ static LZWInfo *AcquireLZWInfo(Image *image,const unsigned long data_size)
   return(lzw_info);
 }
 
-static inline int GetNextLZWCode(LZWInfo *lzw_info,const unsigned long bits)
+static inline int GetNextLZWCode(LZWInfo *lzw_info,const size_t bits)
 {
   int
     code;
 
-  register long
+  register ssize_t
     i;
 
+  size_t
+    one;
+
   while (((lzw_info->code_info.bit+bits) > (8*lzw_info->code_info.count)) &&
          (lzw_info->code_info.eof == MagickFalse))
   {
@@ -273,24 +290,25 @@ static inline int GetNextLZWCode(LZWInfo *lzw_info,const unsigned long bits)
   if ((lzw_info->code_info.bit+bits) > (8*lzw_info->code_info.count))
     return(-1);
   code=0;
-  for (i=0; i < (long) bits; i++)
+  one=1;
+  for (i=0; i < (ssize_t) bits; i++)
   {
     code|=((lzw_info->code_info.buffer[lzw_info->code_info.bit/8] &
-      (1UL << (lzw_info->code_info.bit % 8))) != 0) << i;
+      (one << (lzw_info->code_info.bit % 8))) != 0) << i;
     lzw_info->code_info.bit++;
   }
   return(code);
 }
 
-static inline long PopLZWStack(LZWStack *stack_info)
+static inline int PopLZWStack(LZWStack *stack_info)
 {
   if (stack_info->index <= stack_info->codes)
     return(-1);
   stack_info->index--;
-  return((long) *stack_info->index);
+  return((int) *stack_info->index);
 }
 
-static inline void PushLZWStack(LZWStack *stack_info,const unsigned long value)
+static inline void PushLZWStack(LZWStack *stack_info,const size_t value)
 {
   if (stack_info->index >= stack_info->top)
     return;
@@ -306,7 +324,8 @@ static int ReadBlobLZWByte(LZWInfo *lzw_info)
   ssize_t
     count;
 
-  unsigned long
+  size_t
+    one,
     value;
 
   if (lzw_info->stack->index != lzw_info->stack->codes)
@@ -316,7 +335,7 @@ static int ReadBlobLZWByte(LZWInfo *lzw_info)
       lzw_info->genesis=MagickFalse;
       do
       {
-        lzw_info->first_code=(unsigned long) GetNextLZWCode(lzw_info,
+        lzw_info->first_code=(size_t) GetNextLZWCode(lzw_info,
           lzw_info->bits);
         lzw_info->last_code=lzw_info->first_code;
       } while (lzw_info->first_code == lzw_info->clear_code);
@@ -325,15 +344,15 @@ static int ReadBlobLZWByte(LZWInfo *lzw_info)
   code=GetNextLZWCode(lzw_info,lzw_info->bits);
   if (code < 0)
     return(code);
-  if ((unsigned long) code == lzw_info->clear_code)
+  if ((size_t) code == lzw_info->clear_code)
     {
       ResetLZWInfo(lzw_info);
       return(ReadBlobLZWByte(lzw_info));
     }
-  if ((unsigned long) code == lzw_info->end_code)
+  if ((size_t) code == lzw_info->end_code)
     return(-1);
-  if ((unsigned long) code < lzw_info->slot)
-    value=(unsigned long) code;
+  if ((size_t) code < lzw_info->slot)
+    value=(size_t) code;
   else
     {
       PushLZWStack(lzw_info->stack,lzw_info->first_code);
@@ -352,6 +371,7 @@ static int ReadBlobLZWByte(LZWInfo *lzw_info)
   }
   lzw_info->first_code=lzw_info->table[1][value];
   PushLZWStack(lzw_info->stack,lzw_info->first_code);
+  one=1;
   if (lzw_info->slot < MaximumLZWCode)
     {
       lzw_info->table[0][lzw_info->slot]=lzw_info->last_code;
@@ -361,37 +381,35 @@ static int ReadBlobLZWByte(LZWInfo *lzw_info)
           (lzw_info->bits < MaximumLZWBits))
         {
           lzw_info->bits++;
-          lzw_info->maximum_code=1UL << lzw_info->bits;
+          lzw_info->maximum_code=one << lzw_info->bits;
         }
     }
-  lzw_info->last_code=(unsigned long) code;
+  lzw_info->last_code=(size_t) code;
   return(PopLZWStack(lzw_info->stack));
 }
 
-static MagickBooleanType DecodeImage(Image *image,const long opacity)
+static MagickBooleanType DecodeImage(Image *image,const ssize_t opacity,
+  ExceptionInfo *exception)
 {
-  ExceptionInfo
-    *exception;
+  int
+    c;
+
+  LZWInfo
+    *lzw_info;
 
-  IndexPacket
+  Quantum
     index;
 
-  int
-    c;
+  size_t
+    pass;
 
-  long
+  ssize_t
     offset,
     y;
 
-  LZWInfo
-    *lzw_info;
-
   unsigned char
     data_size;
 
-  unsigned long
-    pass;
-
   /*
     Allocate decoder tables.
   */
@@ -406,40 +424,33 @@ static MagickBooleanType DecodeImage(Image *image,const long opacity)
   if (lzw_info == (LZWInfo *) NULL)
     ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
       image->filename);
-  exception=(&image->exception);
   pass=0;
   offset=0;
-  for (y=0; y < (long) image->rows; y++)
+  for (y=0; y < (ssize_t) image->rows; y++)
   {
-    register IndexPacket
-      *__restrict indexes;
-
-    register long
+    register ssize_t
       x;
 
-    register PixelPacket
-      *__restrict q;
+    register Quantum
+      *restrict q;
 
     q=GetAuthenticPixels(image,0,offset,image->columns,1,exception);
-    if (q == (PixelPacket *) NULL)
+    if (q == (Quantum *) NULL)
       break;
-    indexes=GetAuthenticIndexQueue(image);
-    for (x=0; x < (long) image->columns; )
+    for (x=0; x < (ssize_t) image->columns; )
     {
       c=ReadBlobLZWByte(lzw_info);
       if (c < 0)
         break;
-      index=ConstrainColormapIndex(image,(unsigned long) c);
-      q->red=image->colormap[(long) index].red;
-      q->green=image->colormap[(long) index].green;
-      q->blue=image->colormap[(long) index].blue;
-      q->opacity=(long) index == opacity ? (Quantum) TransparentOpacity :
-        (Quantum) OpaqueOpacity;
-      indexes[x]=index;
+      index=ConstrainColormapIndex(image,(size_t) c,exception);
+      SetPixelIndex(image,index,q);
+      SetPixelInfoPixel(image,image->colormap+(ssize_t) index,q);
+      SetPixelAlpha(image,(ssize_t) index == opacity ? TransparentAlpha :
+        OpaqueAlpha,q);
       x++;
-      q++;
+      q+=GetPixelChannels(image);
     }
-    if (x < (long) image->columns)
+    if (x < (ssize_t) image->columns)
       break;
     if (image->interlace == NoInterlace)
       offset++;
@@ -450,7 +461,7 @@ static MagickBooleanType DecodeImage(Image *image,const long opacity)
         default:
         {
           offset+=8;
-          if (offset >= (long) image->rows)
+          if (offset >= (ssize_t) image->rows)
             {
               pass++;
               offset=4;
@@ -460,7 +471,7 @@ static MagickBooleanType DecodeImage(Image *image,const long opacity)
         case 1:
         {
           offset+=8;
-          if (offset >= (long) image->rows)
+          if (offset >= (ssize_t) image->rows)
             {
               pass++;
               offset=2;
@@ -470,7 +481,7 @@ static MagickBooleanType DecodeImage(Image *image,const long opacity)
         case 2:
         {
           offset+=4;
-          if (offset >= (long) image->rows)
+          if (offset >= (ssize_t) image->rows)
             {
               pass++;
               offset=1;
@@ -487,7 +498,7 @@ static MagickBooleanType DecodeImage(Image *image,const long opacity)
       break;
   }
   lzw_info=RelinquishLZWInfo(lzw_info);
-  if (y < (long) image->rows)
+  if (y < (ssize_t) image->rows)
     ThrowBinaryException(CorruptImageError,"CorruptImage",image->filename);
   return(MagickTrue);
 }
@@ -508,7 +519,7 @@ static MagickBooleanType DecodeImage(Image *image,const long opacity)
 %  The format of the EncodeImage method is:
 %
 %      MagickBooleanType EncodeImage(const ImageInfo *image_info,Image *image,
-%        const unsigned long data_size)
+%        const size_t data_size)
 %
 %  A description of each parameter follows:
 %
@@ -520,9 +531,9 @@ static MagickBooleanType DecodeImage(Image *image,const long opacity)
 %
 */
 static MagickBooleanType EncodeImage(const ImageInfo *image_info,Image *image,
-  const unsigned long data_size)
+  const size_t data_size,ExceptionInfo *exception)
 {
-#define MaxCode(number_bits)  ((1UL << (number_bits))-1)
+#define MaxCode(number_bits)  ((one << (number_bits))-1)
 #define MaxHashTable  5003
 #define MaxGIFBits  12UL
 #define MaxGIFTable  (1UL << MaxGIFBits)
@@ -561,45 +572,45 @@ static MagickBooleanType EncodeImage(const ImageInfo *image_info,Image *image,
     } \
 }
 
-  IndexPacket
+  Quantum
     index;
 
-  long
-    displacement,
-    offset,
-    k,
-    y;
-
-  register long
+  register ssize_t
     i;
 
-  size_t
-    length;
-
   short
     *hash_code,
     *hash_prefix,
     waiting_code;
 
-  unsigned char
-    *packet,
-    *hash_suffix;
-
-  unsigned long
+  size_t
     bits,
     clear_code,
     datum,
     end_of_information_code,
     free_code,
+    length,
     max_code,
     next_pixel,
     number_bits,
+    one,
     pass;
 
+  ssize_t
+    displacement,
+    offset,
+    k,
+    y;
+
+  unsigned char
+    *packet,
+    *hash_suffix;
+
   /*
     Allocate encoder tables.
   */
   assert(image != (Image *) NULL);
+  one=1;
   packet=(unsigned char *) AcquireQuantumMemory(256,sizeof(*packet));
   hash_code=(short *) AcquireQuantumMemory(MaxHashTable,sizeof(*hash_code));
   hash_prefix=(short *) AcquireQuantumMemory(MaxHashTable,sizeof(*hash_prefix));
@@ -624,7 +635,7 @@ static MagickBooleanType EncodeImage(const ImageInfo *image_info,Image *image,
   */
   number_bits=data_size;
   max_code=MaxCode(number_bits);
-  clear_code=((short) 1UL << (data_size-1));
+  clear_code=((short) one << (data_size-1));
   end_of_information_code=clear_code+1;
   free_code=clear_code+2;
   length=0;
@@ -639,31 +650,30 @@ static MagickBooleanType EncodeImage(const ImageInfo *image_info,Image *image,
   offset=0;
   pass=0;
   waiting_code=0;
-  for (y=0; y < (long) image->rows; y++)
+  for (y=0; y < (ssize_t) image->rows; y++)
   {
-    register const IndexPacket
-      *__restrict indexes;
-
-    register const PixelPacket
-      *__restrict p;
+    register const Quantum
+      *restrict p;
 
-    register long
+    register ssize_t
       x;
 
-    p=GetVirtualPixels(image,0,offset,image->columns,1,&image->exception);
-    if (p == (const PixelPacket *) NULL)
+    p=GetVirtualPixels(image,0,offset,image->columns,1,exception);
+    if (p == (const Quantum *) NULL)
       break;
-    indexes=GetVirtualIndexQueue(image);
     if (y == 0)
-      waiting_code=(short) (*indexes);
-    for (x=(y == 0) ? 1 : 0; x < (long) image->columns; x++)
+      {
+        waiting_code=(short) GetPixelIndex(image,p);
+        p+=GetPixelChannels(image);
+      }
+    for (x=(ssize_t) (y == 0 ? 1 : 0); x < (ssize_t) image->columns; x++)
     {
       /*
         Probe hash table.
       */
-      index=(IndexPacket) ((unsigned long) indexes[x] & 0xff);
-      p++;
-      k=(long) (((unsigned long) index << (MaxGIFBits-8))+waiting_code);
+      index=(Quantum) ((size_t) GetPixelIndex(image,p) & 0xff);
+      p+=GetPixelChannels(image);
+      k=(ssize_t) (((size_t) index << (MaxGIFBits-8))+waiting_code);
       if (k >= MaxHashTable)
         k-=MaxHashTable;
       next_pixel=MagickFalse;
@@ -696,7 +706,7 @@ static MagickBooleanType EncodeImage(const ImageInfo *image_info,Image *image,
           if (next_pixel == MagickTrue)
             continue;
         }
-      GIFOutputCode((unsigned long) waiting_code);
+      GIFOutputCode((size_t) waiting_code);
       if (free_code < MaxGIFTable)
         {
           hash_code[k]=(short) free_code++;
@@ -729,7 +739,7 @@ static MagickBooleanType EncodeImage(const ImageInfo *image_info,Image *image,
         default:
         {
           offset+=8;
-          if (offset >= (long) image->rows)
+          if (offset >= (ssize_t) image->rows)
             {
               pass++;
               offset=4;
@@ -739,7 +749,7 @@ static MagickBooleanType EncodeImage(const ImageInfo *image_info,Image *image,
         case 1:
         {
           offset+=8;
-          if (offset >= (long) image->rows)
+          if (offset >= (ssize_t) image->rows)
             {
               pass++;
               offset=2;
@@ -749,7 +759,7 @@ static MagickBooleanType EncodeImage(const ImageInfo *image_info,Image *image,
         case 2:
         {
           offset+=4;
-          if (offset >= (long) image->rows)
+          if (offset >= (ssize_t) image->rows)
             {
               pass++;
               offset=1;
@@ -766,7 +776,7 @@ static MagickBooleanType EncodeImage(const ImageInfo *image_info,Image *image,
   /*
     Flush out the buffered code.
   */
-  GIFOutputCode((unsigned long) waiting_code);
+  GIFOutputCode((size_t) waiting_code);
   GIFOutputCode(end_of_information_code);
   if (bits > 0)
     {
@@ -918,7 +928,7 @@ static inline size_t MagickMin(const size_t x,const size_t y)
   return(y);
 }
 
-static MagickBooleanType PingGIFImage(Image *image)
+static MagickBooleanType PingGIFImage(Image *image,ExceptionInfo *exception)
 {
   unsigned char
     buffer[256],
@@ -956,23 +966,29 @@ static Image *ReadGIFImage(const ImageInfo *image_info,ExceptionInfo *exception)
   int
     number_extensionss=0;
 
-  long
-    opacity;
-
   MagickBooleanType
     status;
 
   RectangleInfo
     page;
 
-  register long
+  register ssize_t
     i;
 
   register unsigned char
     *p;
 
+  size_t
+    delay,
+    dispose,
+    global_colors,
+    image_count,
+    iterations,
+    one;
+
   ssize_t
-    count;
+    count,
+    opacity;
 
   unsigned char
     background,
@@ -982,13 +998,6 @@ static Image *ReadGIFImage(const ImageInfo *image_info,ExceptionInfo *exception)
     header[MaxTextExtent],
     magick[12];
 
-  unsigned long
-    delay,
-    dispose,
-    global_colors,
-    image_count,
-    iterations;
-
   /*
     Open image file.
   */
@@ -999,7 +1008,7 @@ static Image *ReadGIFImage(const ImageInfo *image_info,ExceptionInfo *exception)
       image_info->filename);
   assert(exception != (ExceptionInfo *) NULL);
   assert(exception->signature == MagickSignature);
-  image=AcquireImage(image_info);
+  image=AcquireImage(image_info,exception);
   status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
   if (status == MagickFalse)
     {
@@ -1018,7 +1027,8 @@ static Image *ReadGIFImage(const ImageInfo *image_info,ExceptionInfo *exception)
   flag=(unsigned char) ReadBlobByte(image);
   background=(unsigned char) ReadBlobByte(image);
   c=(unsigned char) ReadBlobByte(image);  /* reserved */
-  global_colors=1UL << (((unsigned long) flag & 0x07)+1);
+  one=1;
+  global_colors=one << (((size_t) flag & 0x07)+1);
   global_colormap=(unsigned char *) AcquireQuantumMemory((size_t)
     MagickMax(global_colors,256),3UL*sizeof(*global_colormap));
   if (global_colormap == (unsigned char *) NULL)
@@ -1042,7 +1052,6 @@ static Image *ReadGIFImage(const ImageInfo *image_info,ExceptionInfo *exception)
         /*
           GIF Extension block.
         */
-
         count=ReadBlob(image,1,&c);
         if (count != 1)
           {
@@ -1059,10 +1068,10 @@ static Image *ReadGIFImage(const ImageInfo *image_info,ExceptionInfo *exception)
               Read graphics control extension.
             */
             while (ReadBlobBlock(image,header) != 0) ;
-            dispose=(unsigned long) (header[0] >> 2);
-            delay=(unsigned long) ((header[2] << 8) | header[1]);
-            if ((long) (header[0] & 0x01) == 0x01)
-              opacity=(long) header[3];
+            dispose=(size_t) (header[0] >> 2);
+            delay=(size_t) ((header[2] << 8) | header[1]);
+            if ((ssize_t) (header[0] & 0x01) == 0x01)
+              opacity=(ssize_t) header[3];
             break;
           }
           case 0xfe:
@@ -1070,26 +1079,33 @@ static Image *ReadGIFImage(const ImageInfo *image_info,ExceptionInfo *exception)
             char
               *comments;
 
+            size_t
+              length;
+
             /*
               Read comment extension.
             */
             comments=AcquireString((char *) NULL);
-            for ( ; ; )
+            for (length=0; ; length+=count)
             {
               count=(ssize_t) ReadBlobBlock(image,header);
               if (count == 0)
                 break;
               header[count]='\0';
-              (void) ConcatenateString(&comments,(const char *) header);
+              comments=(char *) ResizeQuantumMemory(comments,length+count,
+                sizeof(*comments));
+              if (comments == (char *) NULL)
+                ThrowReaderException(ResourceLimitError,
+                  "MemoryAllocationFailed");
+              (void) CopyMagickMemory(comments+length,header,(size_t) count);
             }
-            (void) SetImageProperty(image,"comment",comments);
+            comments[length+count]='\0';
+            (void) SetImageProperty(image,"comment",comments,exception);
             comments=DestroyString(comments);
             break;
           }
           case 0xff:
           {
-            /* Read GIF application extension */
-
             MagickBooleanType
               loop;
 
@@ -1103,7 +1119,7 @@ static Image *ReadGIFImage(const ImageInfo *image_info,ExceptionInfo *exception)
             if (loop != MagickFalse)
               {
                 while (ReadBlobBlock(image,header) != 0)
-                  iterations=(unsigned long) ((header[2] << 8) | header[1]);
+                  iterations=(size_t) ((header[2] << 8) | header[1]);
                 break;
               }
             else
@@ -1119,7 +1135,8 @@ static Image *ReadGIFImage(const ImageInfo *image_info,ExceptionInfo *exception)
                 MagickBooleanType
                   i8bim,
                   icc,
-                  iptc;
+                  iptc,
+                  magick;
 
                 StringInfo
                   *profile;
@@ -1130,10 +1147,12 @@ static Image *ReadGIFImage(const ImageInfo *image_info,ExceptionInfo *exception)
                 /*
                   Store GIF application extension as a generic profile.
                 */
-                i8bim=LocaleNCompare((char *) header,"MGK8BIM0000",11) == 0 ?
-                  MagickTrue : MagickFalse;
                 icc=LocaleNCompare((char *) header,"ICCRGBG1012",11) == 0 ?
                   MagickTrue : MagickFalse;
+                magick=LocaleNCompare((char *) header,"ImageMagick",11) == 0 ?
+                  MagickTrue : MagickFalse;
+                i8bim=LocaleNCompare((char *) header,"MGK8BIM0000",11) == 0 ?
+                  MagickTrue : MagickFalse;
                 iptc=LocaleNCompare((char *) header,"MGKIPTC0000",11) == 0 ?
                   MagickTrue : MagickFalse;
                 number_extensionss++;
@@ -1141,6 +1160,9 @@ static Image *ReadGIFImage(const ImageInfo *image_info,ExceptionInfo *exception)
                   "    Reading GIF application extension");
                 info=(unsigned char *) AcquireQuantumMemory(255UL,
                   sizeof(*info));
+                if (info == (unsigned char *) NULL)
+                  ThrowReaderException(ResourceLimitError,
+                    "MemoryAllocationFailed");
                 reserved_length=255;
                 for (info_length=0; ; )
                 {
@@ -1153,23 +1175,32 @@ static Image *ReadGIFImage(const ImageInfo *image_info,ExceptionInfo *exception)
                        reserved_length+=4096;
                        info=(unsigned char *) ResizeQuantumMemory(info,
                          (size_t) reserved_length,sizeof(*info));
+                       if (info == (unsigned char *) NULL)
+                         ThrowReaderException(ResourceLimitError,
+                           "MemoryAllocationFailed");
                     }
                 }
-                info=(unsigned char *) ResizeQuantumMemory(info,(size_t)
-                  (info_length+1),sizeof(*info));
-                profile=AcquireStringInfo((size_t) info_length);
-                SetStringInfoDatum(profile,(const unsigned char *) info);
+                profile=BlobToStringInfo(info,(size_t) info_length);
+                if (profile == (StringInfo *) NULL)
+                  ThrowReaderException(ResourceLimitError,
+                    "MemoryAllocationFailed");
                 if (i8bim == MagickTrue)
                   (void) CopyMagickString(name,"8bim",sizeof(name));
                 else if (icc == MagickTrue)
                   (void) CopyMagickString(name,"icc",sizeof(name));
                 else if (iptc == MagickTrue)
                   (void) CopyMagickString(name,"iptc",sizeof(name));
+                else if (magick == MagickTrue)
+                  {
+                    (void) CopyMagickString(name,"magick",sizeof(name));
+                    image->gamma=StringToDouble((char *) info+6,(char **) NULL);
+                  }
                 else
-                  (void) FormatMagickString(name,sizeof(name),"gif:%.11s",
+                  (void) FormatLocaleString(name,sizeof(name),"gif:%.11s",
                     header);
-                (void) SetImageProfile(image,name,profile);
                 info=(unsigned char *) RelinquishMagickMemory(info);
+                if (magick == MagickFalse)
+                  (void) SetImageProfile(image,name,profile,exception);
                 profile=DestroyStringInfo(profile);
                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                   "      profile name=%s",name);
@@ -1190,7 +1221,7 @@ static Image *ReadGIFImage(const ImageInfo *image_info,ExceptionInfo *exception)
         /*
           Allocate next image structure.
         */
-        AcquireNextImage(image_info,image);
+        AcquireNextImage(image_info,image,exception);
         if (GetNextImageInList(image) == (Image *) NULL)
           {
             image=DestroyImageList(image);
@@ -1206,17 +1237,16 @@ static Image *ReadGIFImage(const ImageInfo *image_info,ExceptionInfo *exception)
     */
     image->storage_class=PseudoClass;
     image->compression=LZWCompression;
-    page.x=(long) ReadBlobLSBShort(image);
-    page.y=(long) ReadBlobLSBShort(image);
+    page.x=(ssize_t) ReadBlobLSBShort(image);
+    page.y=(ssize_t) ReadBlobLSBShort(image);
     image->columns=ReadBlobLSBShort(image);
     image->rows=ReadBlobLSBShort(image);
     image->depth=8;
     flag=(unsigned char) ReadBlobByte(image);
-    image->interlace=BitSet((int) flag,0x40) != 0 ? GIFInterlace :
-      NoInterlace;
-    image->colors=BitSet((int) flag,0x80) == 0 ? global_colors :
-      1UL << ((unsigned long) (flag & 0x07)+1);
-    if (opacity >= (long) image->colors)
+    image->interlace=BitSet((int) flag,0x40) != 0 ? GIFInterlace : NoInterlace;
+    image->colors=BitSet((int) flag,0x80) == 0 ? global_colors : one <<
+      ((size_t) (flag & 0x07)+1);
+    if (opacity >= (ssize_t) image->colors)
       opacity=(-1);
     image->page.width=page.width;
     image->page.height=page.height;
@@ -1239,7 +1269,7 @@ static Image *ReadGIFImage(const ImageInfo *image_info,ExceptionInfo *exception)
     /*
       Inititialize colormap.
     */
-    if (AcquireImageColormap(image,image->colors) == MagickFalse)
+    if (AcquireImageColormap(image,image->colors,exception) == MagickFalse)
       {
         global_colormap=(unsigned char *) RelinquishMagickMemory(
           global_colormap);
@@ -1251,14 +1281,14 @@ static Image *ReadGIFImage(const ImageInfo *image_info,ExceptionInfo *exception)
           Use global colormap.
         */
         p=global_colormap;
-        for (i=0; i < (long) image->colors; i++)
+        for (i=0; i < (ssize_t) image->colors; i++)
         {
-          image->colormap[i].red=ScaleCharToQuantum(*p++);
-          image->colormap[i].green=ScaleCharToQuantum(*p++);
-          image->colormap[i].blue=ScaleCharToQuantum(*p++);
+          image->colormap[i].red=(double) ScaleCharToQuantum(*p++);
+          image->colormap[i].green=(double) ScaleCharToQuantum(*p++);
+          image->colormap[i].blue=(double) ScaleCharToQuantum(*p++);
           if (i == opacity)
             {
-              image->colormap[i].opacity=(Quantum) TransparentOpacity;
+              image->colormap[i].alpha=(double) TransparentAlpha;
               image->transparent_color=image->colormap[opacity];
             }
         }
@@ -1273,8 +1303,8 @@ static Image *ReadGIFImage(const ImageInfo *image_info,ExceptionInfo *exception)
         /*
           Read local colormap.
         */
-        colormap=(unsigned char *) AcquireQuantumMemory(image->colors,
-          3*sizeof(*colormap));
+        colormap=(unsigned char *) AcquireQuantumMemory(image->colors,3*
+          sizeof(*colormap));
         if (colormap == (unsigned char *) NULL)
           {
             global_colormap=(unsigned char *) RelinquishMagickMemory(
@@ -1291,16 +1321,24 @@ static Image *ReadGIFImage(const ImageInfo *image_info,ExceptionInfo *exception)
               "InsufficientImageDataInFile");
           }
         p=colormap;
-        for (i=0; i < (long) image->colors; i++)
+        for (i=0; i < (ssize_t) image->colors; i++)
         {
-          image->colormap[i].red=ScaleCharToQuantum(*p++);
-          image->colormap[i].green=ScaleCharToQuantum(*p++);
-          image->colormap[i].blue=ScaleCharToQuantum(*p++);
+          image->colormap[i].red=(double) ScaleCharToQuantum(*p++);
+          image->colormap[i].green=(double) ScaleCharToQuantum(*p++);
+          image->colormap[i].blue=(double) ScaleCharToQuantum(*p++);
           if (i == opacity)
-            image->colormap[i].opacity=(Quantum) TransparentOpacity;
+            image->colormap[i].alpha=(double) TransparentAlpha;
         }
         colormap=(unsigned char *) RelinquishMagickMemory(colormap);
       }
+    if (image->gamma == 1.0)
+      {
+        for (i=0; i < (ssize_t) image->colors; i++)
+          if (IsPixelInfoGray(image->colormap+i) == MagickFalse)
+            break;
+        (void) SetImageColorspace(image,i == (ssize_t) image->colors ? 
+          GRAYColorspace : RGBColorspace,exception);
+      }
     if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
       if (image->scene >= (image_info->scene+image_info->number_scenes-1))
         break;
@@ -1308,9 +1346,9 @@ static Image *ReadGIFImage(const ImageInfo *image_info,ExceptionInfo *exception)
       Decode image.
     */
     if (image_info->ping != MagickFalse)
-      status=PingGIFImage(image);
+      status=PingGIFImage(image,exception);
     else
-      status=DecodeImage(image,opacity);
+      status=DecodeImage(image,opacity,exception);
     if ((image_info->ping == MagickFalse) && (status == MagickFalse))
       {
         global_colormap=(unsigned char *) RelinquishMagickMemory(
@@ -1353,10 +1391,10 @@ static Image *ReadGIFImage(const ImageInfo *image_info,ExceptionInfo *exception)
 %
 %  The format of the RegisterGIFImage method is:
 %
-%      unsigned long RegisterGIFImage(void)
+%      size_t RegisterGIFImage(void)
 %
 */
-ModuleExport unsigned long RegisterGIFImage(void)
+ModuleExport size_t RegisterGIFImage(void)
 {
   MagickInfo
     *entry;
@@ -1421,7 +1459,8 @@ ModuleExport void UnregisterGIFImage(void)
 %
 %  The format of the WriteGIFImage method is:
 %
-%      MagickBooleanType WriteGIFImage(const ImageInfo *image_info,Image *image)
+%      MagickBooleanType WriteGIFImage(const ImageInfo *image_info,
+%        Image *image,ExceptionInfo *exception)
 %
 %  A description of each parameter follows.
 %
@@ -1429,19 +1468,15 @@ ModuleExport void UnregisterGIFImage(void)
 %
 %    o image:  The image.
 %
+%    o exception: return any errors or warnings in this structure.
+%
 */
-static MagickBooleanType WriteGIFImage(const ImageInfo *image_info,Image *image)
+static MagickBooleanType WriteGIFImage(const ImageInfo *image_info,Image *image,
+  ExceptionInfo *exception)
 {
-  Image
-    *next_image;
-
   int
     c;
 
-  long
-    j,
-    opacity;
-
   ImageInfo
     *write_info;
 
@@ -1457,23 +1492,26 @@ static MagickBooleanType WriteGIFImage(const ImageInfo *image_info,Image *image)
   RectangleInfo
     page;
 
-  register long
+  register ssize_t
     i;
 
   register unsigned char
     *q;
 
   size_t
-    length;
+    bits_per_pixel,
+    delay,
+    length,
+    one;
+
+  ssize_t
+    j,
+    opacity;
 
   unsigned char
     *colormap,
     *global_colormap;
 
-  unsigned long
-    bits_per_pixel,
-    delay;
-
   /*
     Open output image file.
   */
@@ -1483,7 +1521,9 @@ static MagickBooleanType WriteGIFImage(const ImageInfo *image_info,Image *image)
   assert(image->signature == MagickSignature);
   if (image->debug != MagickFalse)
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
-  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+  assert(exception != (ExceptionInfo *) NULL);
+  assert(exception->signature == MagickSignature);
+  status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
   if (status == MagickFalse)
     return(status);
   /*
@@ -1512,24 +1552,13 @@ static MagickBooleanType WriteGIFImage(const ImageInfo *image_info,Image *image)
     Determine image bounding box.
   */
   page.width=image->columns;
+  if (image->page.width > page.width)
+    page.width=image->page.width;
   page.height=image->rows;
-  page.x=0;
-  page.y=0;
-  if (write_info->adjoin != MagickFalse)
-    for (next_image=image; next_image != (Image *) NULL; )
-    {
-      page.x=next_image->page.x;
-      page.y=next_image->page.y;
-      if ((next_image->page.width+page.x) > page.width)
-        page.width=next_image->page.width+page.x;
-      if ((next_image->page.height+page.y) > page.height)
-        page.height=next_image->page.height+page.y;
-      next_image=GetNextImageInList(next_image);
-    }
+  if (image->page.height > page.height)
+    page.height=image->page.height;
   page.x=image->page.x;
   page.y=image->page.y;
-  if ((image->page.width != 0) && (image->page.height != 0))
-    page=image->page;
   (void) WriteBlobLSBShort(image,(unsigned short) page.width);
   (void) WriteBlobLSBShort(image,(unsigned short) page.height);
   /*
@@ -1540,15 +1569,16 @@ static MagickBooleanType WriteGIFImage(const ImageInfo *image_info,Image *image)
       (GetNextImageInList(image) != (Image *) NULL))
     interlace=NoInterlace;
   scene=0;
+  one=1;
   do
   {
-    if (image->colorspace != RGBColorspace)
-      (void) TransformImageColorspace(image,RGBColorspace);
+    if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
+      (void) TransformImageColorspace(image,sRGBColorspace,exception);
     opacity=(-1);
-    if (IsOpaqueImage(image,&image->exception) != MagickFalse)
+    if (IsImageOpaque(image,exception) != MagickFalse)
       {
         if ((image->storage_class == DirectClass) || (image->colors > 256))
-          (void) SetImageType(image,PaletteType);
+          (void) SetImageType(image,PaletteType,exception);
       }
     else
       {
@@ -1560,37 +1590,37 @@ static MagickBooleanType WriteGIFImage(const ImageInfo *image_info,Image *image)
           Identify transparent colormap index.
         */
         if ((image->storage_class == DirectClass) || (image->colors > 256))
-          (void) SetImageType(image,PaletteBilevelMatteType);
-        for (i=0; i < (long) image->colors; i++)
-          if (image->colormap[i].opacity != OpaqueOpacity)
+          (void) SetImageType(image,PaletteBilevelMatteType,exception);
+        for (i=0; i < (ssize_t) image->colors; i++)
+          if (image->colormap[i].alpha != OpaqueAlpha)
             {
               if (opacity < 0)
                 {
                   opacity=i;
                   continue;
                 }
-              alpha=(MagickRealType) TransparentOpacity-(MagickRealType)
-                image->colormap[i].opacity;
-              beta=(MagickRealType) TransparentOpacity-(MagickRealType)
-                image->colormap[opacity].opacity;
+              alpha=(MagickRealType) TransparentAlpha-(MagickRealType)
+                image->colormap[i].alpha;
+              beta=(MagickRealType) TransparentAlpha-(MagickRealType)
+                image->colormap[opacity].alpha;
               if (alpha < beta)
                 opacity=i;
             }
         if (opacity == -1)
           {
-            (void) SetImageType(image,PaletteBilevelMatteType);
-            for (i=0; i < (long) image->colors; i++)
-              if (image->colormap[i].opacity != OpaqueOpacity)
+            (void) SetImageType(image,PaletteBilevelMatteType,exception);
+            for (i=0; i < (ssize_t) image->colors; i++)
+              if (image->colormap[i].alpha != OpaqueAlpha)
                 {
                   if (opacity < 0)
                     {
                       opacity=i;
                       continue;
                     }
-                  alpha=(Quantum) TransparentOpacity-(MagickRealType)
-                    image->colormap[i].opacity;
-                  beta=(Quantum) TransparentOpacity-(MagickRealType)
-                    image->colormap[opacity].opacity;
+                  alpha=(Quantum) TransparentAlpha-(MagickRealType)
+                    image->colormap[i].alpha;
+                  beta=(Quantum) TransparentAlpha-(MagickRealType)
+                    image->colormap[opacity].alpha;
                   if (alpha < beta)
                     opacity=i;
                 }
@@ -1605,16 +1635,16 @@ static MagickBooleanType WriteGIFImage(const ImageInfo *image_info,Image *image)
     if ((image->storage_class == DirectClass) || (image->colors > 256))
       ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
     for (bits_per_pixel=1; bits_per_pixel < 8; bits_per_pixel++)
-      if ((1UL << bits_per_pixel) >= image->colors)
+      if ((one << bits_per_pixel) >= image->colors)
         break;
     q=colormap;
-    for (i=0; i < (long) image->colors; i++)
+    for (i=0; i < (ssize_t) image->colors; i++)
     {
-      *q++=ScaleQuantumToChar(image->colormap[i].red);
-      *q++=ScaleQuantumToChar(image->colormap[i].green);
-      *q++=ScaleQuantumToChar(image->colormap[i].blue);
+      *q++=ScaleQuantumToChar(ClampToQuantum(image->colormap[i].red));
+      *q++=ScaleQuantumToChar(ClampToQuantum(image->colormap[i].green));
+      *q++=ScaleQuantumToChar(ClampToQuantum(image->colormap[i].blue));
     }
-    for ( ; i < (long) (1UL << bits_per_pixel); i++)
+    for ( ; i < (ssize_t) (one << bits_per_pixel); i++)
     {
       *q++=(unsigned char) 0x0;
       *q++=(unsigned char) 0x0;
@@ -1630,13 +1660,13 @@ static MagickBooleanType WriteGIFImage(const ImageInfo *image_info,Image *image)
         c|=(8-1) << 4;  /* color resolution */
         c|=(bits_per_pixel-1);   /* size of global colormap */
         (void) WriteBlobByte(image,(unsigned char) c);
-        for (j=0; j < (long) image->colors; j++)
-          if (IsColorEqual(&image->background_color,image->colormap+j))
+        for (j=0; j < (ssize_t) image->colors; j++)
+          if (IsPixelInfoEquivalent(&image->background_color,image->colormap+j))
             break;
         (void) WriteBlobByte(image,(unsigned char)
-          (j == (long) image->colors ? 0 : j));  /* background color */
+          (j == (ssize_t) image->colors ? 0 : j));  /* background color */
         (void) WriteBlobByte(image,(unsigned char) 0x00);  /* reserved */
-        length=(size_t) (3*(1UL << bits_per_pixel));
+        length=(size_t) (3*(one << bits_per_pixel));
         (void) WriteBlob(image,length,colormap);
         for (j=0; j < 768; j++)
           global_colormap[j]=colormap[j];
@@ -1653,36 +1683,35 @@ static MagickBooleanType WriteGIFImage(const ImageInfo *image_info,Image *image)
         if (opacity >= 0)
           c|=0x01;
         (void) WriteBlobByte(image,(unsigned char) c);
-        delay=(unsigned long) (100*image->delay/MagickMax((size_t)
+        delay=(size_t) (100*image->delay/MagickMax((size_t)
           image->ticks_per_second,1));
         (void) WriteBlobLSBShort(image,(unsigned short) delay);
         (void) WriteBlobByte(image,(unsigned char) (opacity >= 0 ? opacity :
           0));
         (void) WriteBlobByte(image,(unsigned char) 0x00);
         if ((LocaleCompare(write_info->magick,"GIF87") != 0) &&
-            (GetImageProperty(image,"comment") != (const char *) NULL))
+            (GetImageProperty(image,"comment",exception) != (const char *) NULL))
           {
             const char
               *value;
 
-            register const char
+            register const char 
               *p;
 
             size_t
               count;
-
+    
             /*
-              Write Comment extension.
+              Write comment extension.
             */
             (void) WriteBlobByte(image,(unsigned char) 0x21);
             (void) WriteBlobByte(image,(unsigned char) 0xfe);
-            value=GetImageProperty(image,"comment");
-            p=value;
-            while (strlen(p) != 0)
+            value=GetImageProperty(image,"comment",exception);
+            for (p=value; *p != '\0'; )
             {
               count=MagickMin(strlen(p),255);
               (void) WriteBlobByte(image,(unsigned char) count);
-              for (i=0; i < (long) count; i++)
+              for (i=0; i < (ssize_t) count; i++)
                 (void) WriteBlobByte(image,(unsigned char) *p++);
             }
             (void) WriteBlobByte(image,(unsigned char) 0x00);
@@ -1705,6 +1734,29 @@ static MagickBooleanType WriteGIFImage(const ImageInfo *image_info,Image *image)
             (void) WriteBlobLSBShort(image,(unsigned short) image->iterations);
             (void) WriteBlobByte(image,(unsigned char) 0x00);
           }
+        if ((image->gamma != 1.0f/2.2f))
+          {
+            char
+              attributes[MaxTextExtent];
+
+            ssize_t
+              length;
+
+            /*
+              Write ImageMagick extension.
+            */
+            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+               "  Writing GIF Extension %s","ImageMagick");
+            (void) WriteBlobByte(image,(unsigned char) 0x21);
+            (void) WriteBlobByte(image,(unsigned char) 0xff);
+            (void) WriteBlobByte(image,(unsigned char) 0x0b);
+            (void) WriteBlob(image,11,(unsigned char *) "ImageMagick");
+            length=FormatLocaleString(attributes,MaxTextExtent,"gamma=%g",
+              image->gamma);
+            (void) WriteBlobByte(image,(unsigned char) length);
+            (void) WriteBlob(image,length,(unsigned char *) attributes);
+            (void) WriteBlobByte(image,(unsigned char) 0x00);
+          }
         ResetImageProfileIterator(image);
         for ( ; ; )
         {
@@ -1746,7 +1798,7 @@ static MagickBooleanType WriteGIFImage(const ImageInfo *image_info,Image *image)
                    /*
                      Write ICC extension.
                    */
-                   (void) WriteBlob(image,11,(unsigned char *)"ICCRGBG1012");
+                   (void) WriteBlob(image,11,(unsigned char *) "ICCRGBG1012");
                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                        "  Writing GIF Extension %s","ICCRGBG1012");
                  }
@@ -1754,9 +1806,9 @@ static MagickBooleanType WriteGIFImage(const ImageInfo *image_info,Image *image)
                  if ((LocaleCompare(name,"IPTC") == 0))
                    {
                      /*
-                       write IPTC extension.
+                       Write IPTC extension.
                      */
-                     (void) WriteBlob(image,11,(unsigned char *)"MGKIPTC0000");
+                     (void) WriteBlob(image,11,(unsigned char *) "MGKIPTC0000");
                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                          "  Writing GIF Extension %s","MGKIPTC0000");
                    }
@@ -1764,7 +1816,7 @@ static MagickBooleanType WriteGIFImage(const ImageInfo *image_info,Image *image)
                    if ((LocaleCompare(name,"8BIM") == 0))
                      {
                        /*
-                         Write 8BIM extension>
+                         Write 8BIM extension.
                        */
                         (void) WriteBlob(image,11,(unsigned char *)
                           "MGK8BIM0000");
@@ -1776,7 +1828,9 @@ static MagickBooleanType WriteGIFImage(const ImageInfo *image_info,Image *image)
                        char
                          extension[MaxTextExtent];
 
-                       /* write generic extension */
+                       /*
+                         Write generic extension.
+                       */
                        (void) CopyMagickString(extension,name+4,
                          sizeof(extension));
                        (void) WriteBlob(image,11,(unsigned char *) extension);
@@ -1817,17 +1871,17 @@ static MagickBooleanType WriteGIFImage(const ImageInfo *image_info,Image *image)
     c=0x00;
     if (interlace != NoInterlace)
       c|=0x40;  /* pixel data is interlaced */
-    for (j=0; j < (long) (3*image->colors); j++)
+    for (j=0; j < (ssize_t) (3*image->colors); j++)
       if (colormap[j] != global_colormap[j])
         break;
-    if (j == (long) (3*image->colors))
+    if (j == (ssize_t) (3*image->colors))
       (void) WriteBlobByte(image,(unsigned char) c);
     else
       {
         c|=0x80;
         c|=(bits_per_pixel-1);   /* size of local colormap */
         (void) WriteBlobByte(image,(unsigned char) c);
-        length=(size_t) (3*(1UL << bits_per_pixel));
+        length=(size_t) (3*(one << bits_per_pixel));
         (void) WriteBlob(image,length,colormap);
       }
     /*
@@ -1835,8 +1889,8 @@ static MagickBooleanType WriteGIFImage(const ImageInfo *image_info,Image *image)
     */
     c=(int) MagickMax(bits_per_pixel,2);
     (void) WriteBlobByte(image,(unsigned char) c);
-    status=EncodeImage(write_info,image,(unsigned long)
-      MagickMax(bits_per_pixel,2)+1);
+    status=EncodeImage(write_info,image,(size_t) MagickMax(bits_per_pixel,2)+1,
+      exception);
     if (status == MagickFalse)
       {
         global_colormap=(unsigned char *) RelinquishMagickMemory(