]> granicus.if.org Git - imagemagick/blobdiff - coders/miff.c
(no commit message)
[imagemagick] / coders / miff.c
index 61e43211656e291d0ed59d87387a183e79f1acc4..9dba61ad096237c678c1095101fbdce0b3d8abc2 100644 (file)
@@ -17,7 +17,7 @@
 %                                 July 1992                                   %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2014 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2015 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  %
@@ -185,20 +185,6 @@ static voidpf AcquireZIPMemory(voidpf context,unsigned int items,
 }
 #endif
 
-static inline size_t MagickMax(const size_t x,const size_t y)
-{
-  if (x > y)
-    return(x);
-  return(y);
-}
-
-static inline size_t MagickMin(const size_t x,const size_t y)
-{
-  if (x < y)
-    return(x);
-  return(y);
-}
-
 static void PushRunlengthPacket(Image *image,const unsigned char *pixels,
   size_t *length,PixelInfo *pixel,ExceptionInfo *exception)
 {
@@ -243,7 +229,7 @@ static void PushRunlengthPacket(Image *image,const unsigned char *pixels,
           unsigned char
             quantum;
 
-          if (image->alpha_trait == BlendPixelTrait)
+          if (image->alpha_trait != UndefinedPixelTrait)
             {
               p=PushCharPixel(p,&quantum);
               pixel->alpha=ScaleCharToQuantum(quantum);
@@ -255,7 +241,7 @@ static void PushRunlengthPacket(Image *image,const unsigned char *pixels,
           unsigned short
             quantum;
 
-          if (image->alpha_trait == BlendPixelTrait)
+          if (image->alpha_trait != UndefinedPixelTrait)
             {
               p=PushShortPixel(MSBEndian,p,&quantum);
               pixel->alpha=(Quantum) (quantum >> (image->depth-
@@ -268,7 +254,7 @@ static void PushRunlengthPacket(Image *image,const unsigned char *pixels,
           unsigned int
             quantum;
 
-          if (image->alpha_trait == BlendPixelTrait)
+          if (image->alpha_trait != UndefinedPixelTrait)
             {
               p=PushLongPixel(MSBEndian,p,&quantum);
               pixel->alpha=(Quantum) (quantum >> (image->depth-
@@ -306,7 +292,7 @@ static void PushRunlengthPacket(Image *image,const unsigned char *pixels,
           p=PushCharPixel(p,&quantum);
           pixel->black=ScaleCharToQuantum(quantum);
         }
-      if (image->alpha_trait == BlendPixelTrait)
+      if (image->alpha_trait != UndefinedPixelTrait)
         {
           p=PushCharPixel(p,&quantum);
           pixel->alpha=ScaleCharToQuantum(quantum);
@@ -334,7 +320,7 @@ static void PushRunlengthPacket(Image *image,const unsigned char *pixels,
           p=PushShortPixel(MSBEndian,p,&quantum);
           pixel->black=quantum >> (image->depth-MAGICKCORE_QUANTUM_DEPTH);
         }
-      if (image->alpha_trait == BlendPixelTrait)
+      if (image->alpha_trait != UndefinedPixelTrait)
         {
           p=PushShortPixel(MSBEndian,p,&quantum);
           pixel->alpha=quantum >> (image->depth-MAGICKCORE_QUANTUM_DEPTH);
@@ -362,7 +348,7 @@ static void PushRunlengthPacket(Image *image,const unsigned char *pixels,
           p=PushLongPixel(MSBEndian,p,&quantum);
           pixel->black=quantum >> (image->depth-MAGICKCORE_QUANTUM_DEPTH);
         }
-      if (image->alpha_trait == BlendPixelTrait)
+      if (image->alpha_trait != UndefinedPixelTrait)
         {
           p=PushLongPixel(MSBEndian,p,&quantum);
           pixel->alpha=quantum >> (image->depth-MAGICKCORE_QUANTUM_DEPTH);
@@ -466,6 +452,7 @@ static Image *ReadMIFFImage(const ImageInfo *image_info,
     i;
 
   size_t
+    compress_extent,
     length,
     packet_size;
 
@@ -574,6 +561,7 @@ static Image *ReadMIFFImage(const ImageInfo *image_info,
             /*
               Get the keyword.
             */
+            length=MaxTextExtent;
             p=keyword;
             do
             {
@@ -605,9 +593,6 @@ static Image *ReadMIFFImage(const ImageInfo *image_info,
                         break;
                       p=options+strlen(options);
                     }
-                  if (options == (char *) NULL)
-                    ThrowReaderException(ResourceLimitError,
-                      "MemoryAllocationFailed");
                   *p++=(char) c;
                   c=ReadBlobByte(image);
                   if (c == '\\')
@@ -622,7 +607,11 @@ static Image *ReadMIFFImage(const ImageInfo *image_info,
                   if (*options != '{')
                     if (isspace((int) ((unsigned char) c)) != 0)
                       break;
-                } }
+                }
+                if (options == (char *) NULL)
+                  ThrowReaderException(ResourceLimitError,
+                    "MemoryAllocationFailed");
+              }
             *p='\0';
             if (*options == '{')
               (void) CopyMagickString(options,options+1,strlen(options));
@@ -1241,6 +1230,9 @@ static Image *ReadMIFFImage(const ImageInfo *image_info,
     if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
       if (image->scene >= (image_info->scene+image_info->number_scenes-1))
         break;
+    status=SetImageExtent(image,image->columns,image->rows,exception);
+    if (status == MagickFalse)
+      return(DestroyImageList(image));
     /*
       Allocate image pixels.
     */
@@ -1258,17 +1250,16 @@ static Image *ReadMIFFImage(const ImageInfo *image_info,
       packet_size=(size_t) (3*quantum_info->depth/8);
     if (IsGrayColorspace(image->colorspace) != MagickFalse)
       packet_size=quantum_info->depth/8;
-    if (image->alpha_trait == BlendPixelTrait)
+    if (image->alpha_trait != UndefinedPixelTrait)
       packet_size+=quantum_info->depth/8;
     if (image->colorspace == CMYKColorspace)
       packet_size+=quantum_info->depth/8;
     if (image->compression == RLECompression)
       packet_size++;
-    length=image->columns;
-    length=MagickMax(MagickMax(BZipMaxExtent(packet_size*image->columns),
-      LZMAMaxExtent(packet_size*image->columns)),ZipMaxExtent(packet_size*
-      image->columns));
-    compress_pixels=(unsigned char *) AcquireQuantumMemory(length,
+    compress_extent=MagickMax(MagickMax(BZipMaxExtent(packet_size*
+      image->columns),LZMAMaxExtent(packet_size*image->columns)),
+      ZipMaxExtent(packet_size*image->columns));
+    compress_pixels=(unsigned char *) AcquireQuantumMemory(compress_extent,
       sizeof(*compress_pixels));
     if (compress_pixels == (unsigned char *) NULL)
       ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
@@ -1276,24 +1267,24 @@ static Image *ReadMIFFImage(const ImageInfo *image_info,
       Read image pixels.
     */
     quantum_type=RGBQuantum;
-    if (image->alpha_trait == BlendPixelTrait)
+    if (image->alpha_trait != UndefinedPixelTrait)
       quantum_type=RGBAQuantum;
     if (image->colorspace == CMYKColorspace)
       {
         quantum_type=CMYKQuantum;
-        if (image->alpha_trait == BlendPixelTrait)
+        if (image->alpha_trait != UndefinedPixelTrait)
           quantum_type=CMYKAQuantum;
       }
     if (IsGrayColorspace(image->colorspace) != MagickFalse)
       {
         quantum_type=GrayQuantum;
-        if (image->alpha_trait == BlendPixelTrait)
+        if (image->alpha_trait != UndefinedPixelTrait)
           quantum_type=GrayAlphaQuantum;
       }
     if (image->storage_class == PseudoClass)
       {
         quantum_type=IndexQuantum;
-        if (image->alpha_trait == BlendPixelTrait)
+        if (image->alpha_trait != UndefinedPixelTrait)
           quantum_type=IndexAlphaQuantum;
       }
     status=MagickTrue;
@@ -1386,16 +1377,28 @@ static Image *ReadMIFFImage(const ImageInfo *image_info,
           bzip_info.avail_out=(unsigned int) (packet_size*image->columns);
           do
           {
+            int
+              code;
+
             if (bzip_info.avail_in == 0)
               {
                 bzip_info.next_in=(char *) compress_pixels;
                 length=(size_t) BZipMaxExtent(packet_size*image->columns);
                 if (version != 0.0)
                   length=(size_t) ReadBlobMSBLong(image);
+                if (length > compress_extent)
+                  ThrowReaderException(CorruptImageError,
+                    "UnableToReadImageData");
                 bzip_info.avail_in=(unsigned int) ReadBlob(image,length,
                   (unsigned char *) bzip_info.next_in);
               }
-            if (BZ2_bzDecompress(&bzip_info) == BZ_STREAM_END)
+            code=BZ2_bzDecompress(&bzip_info);
+            if (code < 0)
+              {
+                status=MagickFalse;
+                break;
+              }
+            if (code == BZ_STREAM_END)
               break;
           } while (bzip_info.avail_out != 0);
           (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
@@ -1417,6 +1420,9 @@ static Image *ReadMIFFImage(const ImageInfo *image_info,
               {
                 lzma_info.next_in=compress_pixels;
                 length=(size_t) ReadBlobMSBLong(image);
+                if (length > compress_extent)
+                  ThrowReaderException(CorruptImageError,
+                    "UnableToReadImageData");
                 lzma_info.avail_in=(unsigned int) ReadBlob(image,length,
                   (unsigned char *) lzma_info.next_in);
               }
@@ -1442,16 +1448,28 @@ static Image *ReadMIFFImage(const ImageInfo *image_info,
           zip_info.avail_out=(uInt) (packet_size*image->columns);
           do
           {
+            int
+              code;
+
             if (zip_info.avail_in == 0)
               {
                 zip_info.next_in=compress_pixels;
                 length=(size_t) ZipMaxExtent(packet_size*image->columns);
                 if (version != 0.0)
                   length=(size_t) ReadBlobMSBLong(image);
+                if (length > compress_extent)
+                  ThrowReaderException(CorruptImageError,
+                    "UnableToReadImageData");
                 zip_info.avail_in=(unsigned int) ReadBlob(image,length,
                   zip_info.next_in);
               }
-            if (inflate(&zip_info,Z_SYNC_FLUSH) == Z_STREAM_END)
+            code=inflate(&zip_info,Z_SYNC_FLUSH);
+            if (code < 0)
+              {
+                status=MagickFalse;
+                break;
+              }
+            if (code == Z_STREAM_END)
               break;
           } while (zip_info.avail_out != 0);
           (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
@@ -1479,7 +1497,7 @@ static Image *ReadMIFFImage(const ImageInfo *image_info,
                 if (image->colorspace == CMYKColorspace)
                   SetPixelBlack(image,ClampToQuantum(pixel.black),q);
               }
-            if (image->alpha_trait == BlendPixelTrait)
+            if (image->alpha_trait != UndefinedPixelTrait)
               SetPixelAlpha(image,ClampToQuantum(pixel.alpha),q);
             q+=GetPixelChannels(image);
           }
@@ -1650,7 +1668,7 @@ ModuleExport size_t RegisterMIFFImage(void)
   entry->decoder=(DecodeImageHandler *) ReadMIFFImage;
   entry->encoder=(EncodeImageHandler *) WriteMIFFImage;
   entry->magick=(IsImageFormatHandler *) IsMIFF;
-  entry->seekable_stream=MagickTrue;
+  entry->flags|=CoderSeekableStreamFlag;
   entry->description=ConstantString("Magick Image File Format");
   if (*version != '\0')
     entry->version=ConstantString(version);
@@ -1747,7 +1765,7 @@ static unsigned char *PopRunlengthPacket(Image *image,unsigned char *pixels,
           unsigned int
             value;
 
-          if (image->alpha_trait == BlendPixelTrait)
+          if (image->alpha_trait != UndefinedPixelTrait)
             {
               value=ScaleQuantumToLong(ClampToQuantum(pixel->alpha));
               pixels=PopLongPixel(MSBEndian,value,pixels);
@@ -1759,7 +1777,7 @@ static unsigned char *PopRunlengthPacket(Image *image,unsigned char *pixels,
           unsigned short
             value;
 
-          if (image->alpha_trait == BlendPixelTrait)
+          if (image->alpha_trait != UndefinedPixelTrait)
             {
               value=ScaleQuantumToShort(ClampToQuantum(pixel->alpha));
               pixels=PopShortPixel(MSBEndian,value,pixels);
@@ -1771,7 +1789,7 @@ static unsigned char *PopRunlengthPacket(Image *image,unsigned char *pixels,
           unsigned char
             value;
 
-          if (image->alpha_trait == BlendPixelTrait)
+          if (image->alpha_trait != UndefinedPixelTrait)
             {
               value=(unsigned char) ScaleQuantumToChar(ClampToQuantum(
                 pixel->alpha));
@@ -1807,7 +1825,7 @@ static unsigned char *PopRunlengthPacket(Image *image,unsigned char *pixels,
           value=ScaleQuantumToLong(ClampToQuantum(pixel->black));
           pixels=PopLongPixel(MSBEndian,value,pixels);
         }
-      if (image->alpha_trait == BlendPixelTrait)
+      if (image->alpha_trait != UndefinedPixelTrait)
         {
           value=ScaleQuantumToLong(ClampToQuantum(pixel->alpha));
           pixels=PopLongPixel(MSBEndian,value,pixels);
@@ -1833,7 +1851,7 @@ static unsigned char *PopRunlengthPacket(Image *image,unsigned char *pixels,
           value=ScaleQuantumToShort(ClampToQuantum(pixel->black));
           pixels=PopShortPixel(MSBEndian,value,pixels);
         }
-      if (image->alpha_trait == BlendPixelTrait)
+      if (image->alpha_trait != UndefinedPixelTrait)
         {
           value=ScaleQuantumToShort(ClampToQuantum(pixel->alpha));
           pixels=PopShortPixel(MSBEndian,value,pixels);
@@ -1861,7 +1879,7 @@ static unsigned char *PopRunlengthPacket(Image *image,unsigned char *pixels,
             pixel->black));
           pixels=PopCharPixel(value,pixels);
         }
-      if (image->alpha_trait == BlendPixelTrait)
+      if (image->alpha_trait != UndefinedPixelTrait)
         {
           value=(unsigned char) ScaleQuantumToChar(ClampToQuantum(
             pixel->alpha));
@@ -2017,13 +2035,12 @@ static MagickBooleanType WriteMIFFImage(const ImageInfo *image_info,
       packet_size=(size_t) (3*quantum_info->depth/8);
     if (IsGrayColorspace(image->colorspace) != MagickFalse)
       packet_size=(size_t) (quantum_info->depth/8);
-    if (image->alpha_trait == BlendPixelTrait)
+    if (image->alpha_trait != UndefinedPixelTrait)
       packet_size+=quantum_info->depth/8;
     if (image->colorspace == CMYKColorspace)
       packet_size+=quantum_info->depth/8;
     if (compression == RLECompression)
       packet_size++;
-    length=image->columns;
     length=MagickMax(BZipMaxExtent(packet_size*image->columns),ZipMaxExtent(
       packet_size*image->columns));
     if ((compression == BZipCompression) || (compression == ZipCompression))