update of mat.c to 6.9.9-31's version
Index: ImageMagick-6.8.8-1/coders/mat.c
===================================================================
--- ImageMagick-6.8.8-1.orig/coders/mat.c	2018-01-05 15:02:53.072875559 +0100
+++ ImageMagick-6.8.8-1/coders/mat.c	2018-01-05 15:04:10.394165595 +0100
@@ -48,6 +48,7 @@
   Include declarations.
 */
 #include "magick/studio.h"
+#include "magick/attribute.h"
 #include "magick/blob.h"
 #include "magick/blob-private.h"
 #include "magick/cache.h"
@@ -97,7 +98,7 @@ typedef struct
   unsigned short Version;
   char EndianIndicator[2];
   unsigned long DataType;
-  unsigned long ObjectSize;
+  unsigned int ObjectSize;
   unsigned long unknown1;
   unsigned long unknown2;
 
@@ -118,7 +119,7 @@ MATHeader;
 static const char *MonthsTab[12]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
 static const char *DayOfWTab[7]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
 static const char *OsDesc=
-#ifdef __WIN32__
+#if defined(MAGICKCORE_WINDOWS_SUPPORT)
     "PCWIN";
 #else
  #ifdef __APPLE__
@@ -476,17 +477,20 @@ static void RelinquishZIPMemory(voidpf c
 
 #if defined(MAGICKCORE_ZLIB_DELEGATE)
 /** This procedure decompreses an image block for a new MATLAB format. */
-static Image *DecompressBlock(Image *orig, MagickOffsetType Size, ImageInfo *clone_info, ExceptionInfo *exception)
+static Image *decompress_block(Image *orig, unsigned int *Size, ImageInfo *clone_info, ExceptionInfo *exception)
 {
 
 Image *image2;
-void *CacheBlock, *DecompressBlock;
+void *cache_block, *decompress_block;
 z_stream zip_info;
 FILE *mat_file;
 size_t magick_size;
 size_t extent;
+int file;
 
 int status;
+int zip_status;
+ssize_t TotalSize = 0;
 
   if(clone_info==NULL) return NULL;
   if(clone_info->file)    /* Close file opened from previous transaction. */
@@ -496,56 +500,76 @@ int status;
     (void) remove_utf8(clone_info->filename);
   }
 
-  CacheBlock = AcquireQuantumMemory((size_t)((Size<16384)?Size:16384),sizeof(unsigned char *));
-  if(CacheBlock==NULL) return NULL;
-  DecompressBlock = AcquireQuantumMemory((size_t)(4096),sizeof(unsigned char *));
-  if(DecompressBlock==NULL)
+  cache_block = AcquireQuantumMemory((size_t)(*Size< 16384) ? *Size: 16384,sizeof(unsigned char *));
+  if(cache_block==NULL) return NULL;
+  decompress_block = AcquireQuantumMemory((size_t)(4096),sizeof(unsigned char *));
+  if(decompress_block==NULL)
   {
-    RelinquishMagickMemory(CacheBlock);
+    RelinquishMagickMemory(cache_block);
     return NULL;
   }
 
-  mat_file = fdopen(AcquireUniqueFileResource(clone_info->filename),"w");
+  mat_file=0;
+  file = AcquireUniqueFileResource(clone_info->filename);
+  if (file != -1)
+    mat_file = fdopen(file,"w");
   if(!mat_file)
   {
-    RelinquishMagickMemory(CacheBlock);
-    RelinquishMagickMemory(DecompressBlock);
-    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Gannot create file stream for PS image");
+    RelinquishMagickMemory(cache_block);
+    RelinquishMagickMemory(decompress_block);
+    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Cannot create file stream for decompressed image");
     return NULL;
   }
 
   zip_info.zalloc=AcquireZIPMemory;
   zip_info.zfree=RelinquishZIPMemory;
   zip_info.opaque = (voidpf) NULL;
-  inflateInit(&zip_info);
+  zip_status = inflateInit(&zip_info);
+  if (zip_status != Z_OK)
+    {
+      RelinquishMagickMemory(cache_block);
+      RelinquishMagickMemory(decompress_block);
+      (void) ThrowMagickException(exception,GetMagickModule(),CorruptImageError,
+        "UnableToUncompressImage","`%s'",clone_info->filename);
+      (void) fclose(mat_file);
+      RelinquishUniqueFileResource(clone_info->filename);
+      return NULL;
+    }
   /* zip_info.next_out = 8*4;*/
 
   zip_info.avail_in = 0;
   zip_info.total_out = 0;
-  while(Size>0 && !EOFBlob(orig))
+  while(*Size>0 && !EOFBlob(orig))
   {
-    magick_size = ReadBlob(orig, (Size<16384)?Size:16384, (unsigned char *) CacheBlock);
-    zip_info.next_in = (Bytef *) CacheBlock;
+    magick_size = ReadBlob(orig, (*Size < 16384) ? *Size : 16384, (unsigned char *) cache_block);
+    zip_info.next_in = (Bytef *) cache_block;
     zip_info.avail_in = (uInt) magick_size;
 
     while(zip_info.avail_in>0)
     {
       zip_info.avail_out = 4096;
-      zip_info.next_out = (Bytef *) DecompressBlock;
-      status = inflate(&zip_info,Z_NO_FLUSH);
-      extent=fwrite(DecompressBlock, 4096-zip_info.avail_out, 1, mat_file);
+      zip_info.next_out = (Bytef *) decompress_block;
+      zip_status = inflate(&zip_info,Z_NO_FLUSH);
+			if ((zip_status != Z_OK) && (zip_status != Z_STREAM_END))
+        break;
+      extent=fwrite(decompress_block, 4096-zip_info.avail_out, 1, mat_file);
       (void) extent;
+      TotalSize += 4096-zip_info.avail_out;
 
-      if(status == Z_STREAM_END) goto DblBreak;
+      if(zip_status == Z_STREAM_END) goto DblBreak;
     }
+ 	  if ((zip_status != Z_OK) && (zip_status != Z_STREAM_END))
+      break;
 
-    Size -= magick_size;
+    *Size -= magick_size;
   }
 DblBreak:
 
+  inflateEnd(&zip_info);
   (void)fclose(mat_file);
-  RelinquishMagickMemory(CacheBlock);
-  RelinquishMagickMemory(DecompressBlock);
+  RelinquishMagickMemory(cache_block);
+  RelinquishMagickMemory(decompress_block);
+  *Size = TotalSize;
 
   if((clone_info->file=fopen(clone_info->filename,"rb"))==NULL) goto UnlinkFile;
   if( (image2 = AcquireImage(clone_info))==NULL ) goto EraseFile;
@@ -557,13 +581,243 @@ EraseFile:
     fclose(clone_info->file);
     clone_info->file = NULL;
 UnlinkFile:
-    (void) remove_utf8(clone_info->filename);
+    RelinquishUniqueFileResource(clone_info->filename);
     return NULL;
   }
 
   return image2;
 }
 #endif
+
+static Image *ReadMATImageV4(const ImageInfo *image_info,Image *image,
+  ExceptionInfo *exception)
+{
+  typedef struct {
+    unsigned char Type[4];
+    unsigned int nRows;
+    unsigned int nCols;
+    unsigned int imagf;
+    unsigned int nameLen;
+  } MAT4_HDR;
+
+  long
+    ldblk;
+
+  EndianType
+    endian;
+
+  Image
+    *rotate_image;
+
+  MagickBooleanType
+    status;
+
+  MAT4_HDR
+    HDR;
+
+  QuantumInfo
+    *quantum_info;
+
+  QuantumFormatType
+    format_type;
+
+  register ssize_t
+    i;
+
+  ssize_t
+    count,
+    y;
+
+  unsigned char
+    *pixels;
+
+  unsigned int
+    depth;
+
+  (void) SeekBlob(image,0,SEEK_SET);
+  while (EOFBlob(image) == MagickFalse)
+  {
+    /*
+      Object parser.
+    */
+    ldblk=ReadBlobLSBLong(image);
+    if (EOFBlob(image) != MagickFalse)
+      break;
+    if ((ldblk > 9999) || (ldblk < 0))
+      break;
+    HDR.Type[3]=ldblk % 10; ldblk /= 10;  /* T digit */
+    HDR.Type[2]=ldblk % 10; ldblk /= 10;  /* P digit */
+    HDR.Type[1]=ldblk % 10; ldblk /= 10;  /* O digit */
+    HDR.Type[0]=ldblk;  /* M digit */
+    if (HDR.Type[3] != 0)
+      break;    /* Data format */
+    if (HDR.Type[2] != 0)
+      break;    /* Always 0 */
+    if (HDR.Type[0] == 0)
+      {
+        HDR.nRows=ReadBlobLSBLong(image);
+        HDR.nCols=ReadBlobLSBLong(image);
+        HDR.imagf=ReadBlobLSBLong(image);
+        HDR.nameLen=ReadBlobLSBLong(image);
+        endian=LSBEndian;
+      }
+    else
+      {
+        HDR.nRows=ReadBlobMSBLong(image);
+        HDR.nCols=ReadBlobMSBLong(image);
+        HDR.imagf=ReadBlobMSBLong(image);
+        HDR.nameLen=ReadBlobMSBLong(image);
+        endian=MSBEndian;
+      }
+    if ((HDR.imagf !=0) && (HDR.imagf !=1))
+      break;
+    if (HDR.nameLen > 0xFFFF)
+      break;
+    for (i=0; i < (ssize_t) HDR.nameLen; i++)
+    {
+      int
+        byte;
+
+      /*
+        Skip matrix name.
+      */
+      byte=ReadBlobByte(image);
+      if (byte == EOF)
+        {
+          ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
+            image->filename);
+          break;
+        }
+    }
+    image->columns=(size_t) HDR.nRows;
+    image->rows=(size_t) HDR.nCols;
+    SetImageColorspace(image,GRAYColorspace);
+    if (image_info->ping != MagickFalse)
+      {
+        Swap(image->columns,image->rows);
+        if(HDR.imagf==1) ldblk *= 2;
+        SeekBlob(image, HDR.nCols*ldblk, SEEK_CUR);
+        goto skip_reading_current;
+      }
+    status=SetImageExtent(image,image->columns,image->rows);
+    if (status == MagickFalse)
+      return((Image *) NULL);
+    quantum_info=AcquireQuantumInfo(image_info,image);
+    if (quantum_info == (QuantumInfo *) NULL)
+      return((Image *) NULL);
+    switch(HDR.Type[1])
+    {
+      case 0:
+        format_type=FloatingPointQuantumFormat;
+        depth=64;
+        break;
+      case 1:
+        format_type=FloatingPointQuantumFormat;
+        depth=32;
+        break;
+      case 2:
+        format_type=UnsignedQuantumFormat;
+        depth=16;
+        break;
+      case 3:
+        format_type=SignedQuantumFormat;
+        depth=16;
+        break;
+      case 4:
+        format_type=UnsignedQuantumFormat;
+        depth=8;
+        break;
+      default:
+        format_type=UnsignedQuantumFormat;
+        depth=8;
+        break;
+    }
+    image->depth=depth;
+    if (HDR.Type[0] != 0)
+      SetQuantumEndian(image,quantum_info,MSBEndian);
+    status=SetQuantumFormat(image,quantum_info,format_type);
+    status=SetQuantumDepth(image,quantum_info,depth);
+    status=SetQuantumEndian(image,quantum_info,endian);
+    SetQuantumScale(quantum_info,1.0);
+    pixels=(unsigned char *) GetQuantumPixels(quantum_info);
+    for (y=0; y < (ssize_t) image->rows; y++)
+    {
+      register PixelPacket
+        *restrict q;
+
+      count=ReadBlob(image,depth/8*image->columns,(unsigned char *) pixels);
+      if (count == -1)
+        break;
+      q=QueueAuthenticPixels(image,0,image->rows-y-1,image->columns,1,
+        exception);
+      if (q == (PixelPacket *) NULL)
+        break;
+      (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
+        GrayQuantum,pixels,exception);
+      if ((HDR.Type[1] == 2) || (HDR.Type[1] == 3))
+        FixSignedValues(q,image->columns);
+      if (SyncAuthenticPixels(image,exception) == MagickFalse)
+        break;
+      if (image->previous == (Image *) NULL)
+        {
+          status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
+            image->rows);
+          if (status == MagickFalse)
+            break;
+        }
+    }
+    if (HDR.imagf == 1)
+      for (y=0; y < (ssize_t) image->rows; y++)
+      {
+        /*
+          Read complex pixels.
+        */
+        count=ReadBlob(image,depth/8*image->columns,(unsigned char *) pixels);
+        if (count == -1)
+          break;
+        if (HDR.Type[1] == 0)
+          InsertComplexDoubleRow((double *) pixels,y,image,0,0);
+        else
+          InsertComplexFloatRow((float *) pixels,y,image,0,0);
+      }
+    quantum_info=DestroyQuantumInfo(quantum_info);
+    rotate_image=RotateImage(image,90.0,exception);
+    if (rotate_image != (Image *) NULL)
+      {
+        image=DestroyImage(image);
+        image=rotate_image;
+      }
+    if (EOFBlob(image) != MagickFalse)
+      {
+        ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
+          image->filename);
+        break;
+      }
+    /*
+      Proceed to next image.
+    */
+    if (image_info->number_scenes != 0)
+      if (image->scene >= (image_info->scene+image_info->number_scenes-1))
+        break;
+    /*
+      Allocate next image structure.
+    */
+skip_reading_current:
+    AcquireNextImage(image_info,image);
+    if (GetNextImageInList(image) == (Image *) NULL)
+      {
+        image=DestroyImageList(image);
+        return((Image *) NULL);
+      }
+    image=SyncNextImageInList(image);
+    status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
+      GetBlobSize(image));
+    if (status == MagickFalse)
+      break;
+  }
+  (void) CloseBlob(image);
+  return(GetFirstImageInList(image));
+}
 
 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -595,14 +849,6 @@ UnlinkFile:
 %    o exception: return any errors or warnings in this structure.
 %
 */
-
-static inline size_t MagickMin(const size_t x,const size_t y)
-{
-  if (x < y)
-    return(x);
-  return(y);
-}
-
 static Image *ReadMATImage(const ImageInfo *image_info,ExceptionInfo *exception)
 {
   Image *image, *image2=NULL,
@@ -643,7 +889,9 @@ static Image *ReadMATImage(const ImageIn
   /*
      Open image file.
    */
+  quantum_info=(QuantumInfo *) NULL;
   image = AcquireImage(image_info);
+  image2 = (Image *) NULL;
 
   status = OpenBlob(image_info, image, ReadBinaryBlobMode, exception);
   if (status == MagickFalse)
@@ -654,9 +902,17 @@ static Image *ReadMATImage(const ImageIn
   /*
      Read MATLAB image.
    */
-  clone_info=CloneImageInfo(image_info);
+  clone_info=(ImageInfo *) NULL;
   if(ReadBlob(image,124,(unsigned char *) &MATLAB_HDR.identific) != 124)
     ThrowReaderException(CorruptImageError,"ImproperImageHeader");
+  if (strncmp(MATLAB_HDR.identific,"MATLAB",6) != 0)
+    {
+      image2=ReadMATImageV4(image_info,image,exception);
+      if (image2  == NULL)
+        goto MATLAB_KO;
+      image=image2;
+      goto END_OF_READING;
+    }
   MATLAB_HDR.Version = ReadBlobLSBShort(image);
   if(ReadBlob(image,2,(unsigned char *) &MATLAB_HDR.EndianIndicator) != 2)
     ThrowReaderException(CorruptImageError,"ImproperImageHeader");
@@ -683,7 +939,14 @@ static Image *ReadMATImage(const ImageIn
     goto MATLAB_KO;    /* unsupported endian */
 
   if (strncmp(MATLAB_HDR.identific, "MATLAB", 6))
-MATLAB_KO: ThrowReaderException(CorruptImageError,"ImproperImageHeader");
+    {
+MATLAB_KO:
+      if ((image != image2) && (image2 != (Image *) NULL))
+        image2=DestroyImage(image2);
+      if (clone_info != (ImageInfo *) NULL)
+        clone_info=DestroyImageInfo(clone_info);
+      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
+    }
 
   filepos = TellBlob(image);
   while(!EOFBlob(image)) /* object parser loop */
@@ -696,19 +959,30 @@ MATLAB_KO: ThrowReaderException(CorruptI
     if(EOFBlob(image)) break;
     MATLAB_HDR.ObjectSize = ReadBlobXXXLong(image);
     if(EOFBlob(image)) break;
+    if((MagickSizeType) (MATLAB_HDR.ObjectSize+filepos) > GetBlobSize(image))
+      goto MATLAB_KO;
     filepos += MATLAB_HDR.ObjectSize + 4 + 4;
 
+    if (clone_info != (ImageInfo *) NULL)
+      clone_info=DestroyImageInfo(clone_info);
+    clone_info=CloneImageInfo(image_info);
+    if ((image != image2) && (image2 != (Image *) NULL))
+      image2=DestroyImage(image2);
     image2 = image;
 #if defined(MAGICKCORE_ZLIB_DELEGATE)
     if(MATLAB_HDR.DataType == miCOMPRESSED)
     {
-      image2 = DecompressBlock(image,MATLAB_HDR.ObjectSize,clone_info,exception);
+      image2 = decompress_block(image,&MATLAB_HDR.ObjectSize,clone_info,exception);
       if(image2==NULL) continue;
       MATLAB_HDR.DataType = ReadBlobXXXLong(image2); /* replace compressed object type. */
     }
 #endif
 
-    if(MATLAB_HDR.DataType!=miMATRIX) continue;  /* skip another objects. */
+    if (MATLAB_HDR.DataType!=miMATRIX)
+      {
+        clone_info=DestroyImageInfo(clone_info);
+        continue;  /* skip another objects. */
+      }
 
     MATLAB_HDR.unknown1 = ReadBlobXXXLong(image2);
     MATLAB_HDR.unknown2 = ReadBlobXXXLong(image2);
@@ -732,16 +1006,42 @@ MATLAB_KO: ThrowReaderException(CorruptI
       case 12: z2=z = ReadBlobXXXLong(image2);  /* 3D matrix RGB*/
            Unknown6 = ReadBlobXXXLong(image2);
            (void) Unknown6;
-         if(z!=3) ThrowReaderException(CoderError, "MultidimensionalMatricesAreNotSupported");
+         if(z!=3)
+           {
+             if (clone_info != (ImageInfo *) NULL)
+               clone_info=DestroyImageInfo(clone_info);
+             if ((image != image2) && (image2 != (Image *) NULL))
+               image2=DestroyImage(image2);
+             ThrowReaderException(CoderError,
+               "MultidimensionalMatricesAreNotSupported");
+           }
          break;
       case 16: z2=z = ReadBlobXXXLong(image2);  /* 4D matrix animation */
          if(z!=3 && z!=1)
-           ThrowReaderException(CoderError, "MultidimensionalMatricesAreNotSupported");
-          Frames = ReadBlobXXXLong(image2);
+           {
+             if (clone_info != (ImageInfo *) NULL)
+               clone_info=DestroyImageInfo(clone_info);
+             if ((image != image2) && (image2 != (Image *) NULL))
+               image2=DestroyImage(image2);
+             ThrowReaderException(CoderError,
+               "MultidimensionalMatricesAreNotSupported");
+           }
+         Frames = ReadBlobXXXLong(image2);
          if (Frames == 0)
-           ThrowReaderException(CorruptImageError,"ImproperImageHeader");
+           {
+             if (clone_info != (ImageInfo *) NULL)
+               clone_info=DestroyImageInfo(clone_info);
+             if ((image != image2) && (image2 != (Image *) NULL))
+               image2=DestroyImage(image2);
+             ThrowReaderException(CorruptImageError,"ImproperImageHeader");
+           }
          break;
-      default: ThrowReaderException(CoderError, "MultidimensionalMatricesAreNotSupported");
+      default:
+        if (clone_info != (ImageInfo *) NULL)
+          clone_info=DestroyImageInfo(clone_info);
+        if ((image != image2) && (image2 != (Image *) NULL))
+          image2=DestroyImage(image2);
+        ThrowReaderException(CoderError, "MultidimensionalMatricesAreNotSupported");
     }
 
     MATLAB_HDR.Flag1 = ReadBlobXXXShort(image2);
@@ -760,7 +1060,16 @@ MATLAB_KO: ThrowReaderException(CorruptI
         MATLAB_HDR.StructureClass != mxUINT32_CLASS &&    /* uint32 + uint32 3D */
         MATLAB_HDR.StructureClass != mxINT64_CLASS &&
         MATLAB_HDR.StructureClass != mxUINT64_CLASS)    /* uint64 + uint64 3D */
-      ThrowReaderException(CoderError,"UnsupportedCellTypeInTheMatrix");
+      {
+        if ((image2 != (Image*) NULL) && (image2 != (Image *) image))
+          {
+            CloseBlob(image2);
+            DeleteImageFromList(&image2);
+          }
+        if (clone_info != (ImageInfo *) NULL)
+          DestroyImageInfo(clone_info);
+        ThrowReaderException(CoderError,"UnsupportedCellTypeInTheMatrix");
+      }
 
     switch (MATLAB_HDR.NameFlag)
     {
@@ -839,18 +1148,21 @@ RestoreMSCWarning
         ldblk = (ssize_t) (8 * MATLAB_HDR.SizeX);
         break;
       default:
+        if ((image != image2) && (image2 != (Image *) NULL))
+          image2=DestroyImage(image2);
+        if (clone_info)
+          clone_info=DestroyImageInfo(clone_info);
         ThrowReaderException(CoderError, "UnsupportedCellTypeInTheMatrix");
     }
     (void) sample_size;
     image->columns = MATLAB_HDR.SizeX;
     image->rows = MATLAB_HDR.SizeY;
-    quantum_info=AcquireQuantumInfo(clone_info,image);
-    if (quantum_info == (QuantumInfo *) NULL)
-      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
     one=1;
     image->colors = one << image->depth;
     if (image->columns == 0 || image->rows == 0)
       goto MATLAB_KO;
+    if((unsigned long)ldblk*MATLAB_HDR.SizeY > MATLAB_HDR.ObjectSize)
+      goto MATLAB_KO;
       /* Image is gray when no complex flag is set and 2D Matrix */
     if ((MATLAB_HDR.DimFlag == 8) &&
         ((MATLAB_HDR.StructureFlag & FLAG_COMPLEX) == 0))
@@ -871,6 +1183,17 @@ RestoreMSCWarning
       image->rows = temp;
       goto done_reading; /* !!!!!! BAD  !!!! */
     }
+    status=SetImageExtent(image,image->columns,image->rows);
+    if (status == MagickFalse)
+      {
+        if ((image != image2) && (image2 != (Image *) NULL))
+          image2=DestroyImage(image2);
+        InheritException(exception,&image->exception);
+        return(DestroyImageList(image));
+      }
+    quantum_info=AcquireQuantumInfo(clone_info,image);
+    if (quantum_info == (QuantumInfo *) NULL)
+      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
 
   /* ----- Load raster data ----- */
     BImgBuff = (unsigned char *) AcquireQuantumMemory((size_t) (ldblk),sizeof(double));    /* Ldblk was set in the check phase */
@@ -893,7 +1216,7 @@ RestoreMSCWarning
       for (i = 0; i < (ssize_t) MATLAB_HDR.SizeY; i++)
       {
         q=GetAuthenticPixels(image,0,MATLAB_HDR.SizeY-i-1,image->columns,1,exception);
-        if (q == (PixelPacket *)NULL)
+        if (q == (PixelPacket *) NULL)
   {
     if (logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(),
               "  MAT set image pixels returns unexpected NULL on a row %u.", (unsigned)(MATLAB_HDR.SizeY-i-1));
@@ -1017,6 +1340,8 @@ done_reading:
       /* row scan buffer is no longer needed */
     RelinquishMagickMemory(BImgBuff);
     BImgBuff = NULL;
+    if (quantum_info != (QuantumInfo *) NULL)
+      quantum_info=DestroyQuantumInfo(quantum_info);
 
     if(--Frames>0)
     {
@@ -1040,11 +1365,14 @@ done_reading:
           }
          }
        }
+    if (clone_info)
+      clone_info=DestroyImageInfo(clone_info);
   }
-  clone_info=DestroyImageInfo(clone_info);
 
   RelinquishMagickMemory(BImgBuff);
-  quantum_info=DestroyQuantumInfo(quantum_info);
+  if (quantum_info != (QuantumInfo *) NULL)
+    quantum_info=DestroyQuantumInfo(quantum_info);
+END_OF_READING:
   CloseBlob(image);
 
 
@@ -1057,11 +1385,13 @@ done_reading:
     */
     p=image;
     image=NULL;
-    while (p != (Image *)NULL)
+    while (p != (Image *) NULL)
       {
         Image *tmp=p;
         if ((p->rows == 0) || (p->columns == 0)) {
           p=p->previous;
+          if (tmp == image2)
+            image2=(Image *) NULL;
           DeleteImageFromList(&tmp);
         } else {
           image=p;
@@ -1088,9 +1418,11 @@ done_reading:
     clone_info = NULL;
   }
   if (logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(),"return");
-  if(image==NULL)
-    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
-  return (image);
+  if ((image != image2) && (image2 != (Image *) NULL))
+    image2=DestroyImage(image2);
+  if (image == (Image *) NULL)
+    ThrowReaderException(CorruptImageError,"ImproperImageHeader")
+  return(image);
 }
 
 /*
@@ -1186,28 +1518,23 @@ ModuleExport void UnregisterMATImage(voi
 */
 static MagickBooleanType WriteMATImage(const ImageInfo *image_info,Image *image)
 {
+  char
+    MATLAB_HDR[0x80];
+
   ExceptionInfo
     *exception;
 
-  ssize_t y;
-  unsigned z;
-  const PixelPacket *p;
-
-  unsigned int status;
-  int logging;
-  size_t DataSize;
-  char padding;
-  char MATLAB_HDR[0x80];
-  time_t current_time;
-  struct tm local_time;
-  unsigned char *pixels;
-  int is_gray;
+  MagickBooleanType
+    status;
 
   MagickOffsetType
     scene;
 
-  QuantumInfo
-    *quantum_info;
+  struct tm
+    local_time;
+
+  time_t
+    current_time;
 
   /*
     Open output image file.
@@ -1216,8 +1543,7 @@ static MagickBooleanType WriteMATImage(c
   assert(image_info->signature == MagickSignature);
   assert(image != (Image *) NULL);
   assert(image->signature == MagickSignature);
-  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter MAT");
-  (void) logging;
+  (void) LogMagickEvent(CoderEvent,GetMagickModule(),"enter MAT");
   status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
   if (status == MagickFalse)
     return(MagickFalse);
@@ -1230,7 +1556,8 @@ static MagickBooleanType WriteMATImage(c
   (void) memcpy(&local_time,localtime(&current_time),sizeof(local_time));
 #endif
   (void) memset(MATLAB_HDR,' ',MagickMin(sizeof(MATLAB_HDR),124));
-  FormatLocaleString(MATLAB_HDR,MaxTextExtent,"MATLAB 5.0 MAT-file, Platform: %s, Created on: %s %s %2d %2d:%2d:%2d %d",
+  FormatLocaleString(MATLAB_HDR,sizeof(MATLAB_HDR),
+    "MATLAB 5.0 MAT-file, Platform: %s, Created on: %s %s %2d %2d:%2d:%2d %d",
     OsDesc,DayOfWTab[local_time.tm_wday],MonthsTab[local_time.tm_mon],
     local_time.tm_mday,local_time.tm_hour,local_time.tm_min,
     local_time.tm_sec,local_time.tm_year+1900);
@@ -1242,38 +1569,58 @@ static MagickBooleanType WriteMATImage(c
   scene=0;
   do
   {
+    char
+      padding;
+
+    MagickBooleanType
+      is_gray;
+
+    QuantumInfo
+      *quantum_info;
+
+    size_t
+      data_size;
+
+    unsigned char
+      *pixels;
+
+    unsigned int
+      z;
+
     if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
       (void) TransformImageColorspace(image,sRGBColorspace);
-    is_gray = IsGrayImage(image,&image->exception);
-    z = is_gray ? 0 : 3;
+    is_gray=IsGrayImage(image,&image->exception);
+    z=(is_gray != MagickFalse) ? 0 : 3;
 
     /*
       Store MAT header.
     */
-    DataSize = image->rows /*Y*/ * image->columns /*X*/;
-    if(!is_gray) DataSize *= 3 /*Z*/;
-    padding=((unsigned char)(DataSize-1) & 0x7) ^ 0x7;
-
-    (void) WriteBlobLSBLong(image, miMATRIX);
-    (void) WriteBlobLSBLong(image, (unsigned int) DataSize+padding+(is_gray ? 48 : 56));
-    (void) WriteBlobLSBLong(image, 0x6); /* 0x88 */
-    (void) WriteBlobLSBLong(image, 0x8); /* 0x8C */
-    (void) WriteBlobLSBLong(image, 0x6); /* 0x90 */
-    (void) WriteBlobLSBLong(image, 0);
-    (void) WriteBlobLSBLong(image, 0x5); /* 0x98 */
-    (void) WriteBlobLSBLong(image, is_gray ? 0x8 : 0xC); /* 0x9C - DimFlag */
-    (void) WriteBlobLSBLong(image, (unsigned int) image->rows);    /* x: 0xA0 */
-    (void) WriteBlobLSBLong(image, (unsigned int) image->columns); /* y: 0xA4 */
-    if(!is_gray)
-    {
-      (void) WriteBlobLSBLong(image, 3); /* z: 0xA8 */
-      (void) WriteBlobLSBLong(image, 0);
-    }
-    (void) WriteBlobLSBShort(image, 1);  /* 0xB0 */
-    (void) WriteBlobLSBShort(image, 1);  /* 0xB2 */
-    (void) WriteBlobLSBLong(image, 'M'); /* 0xB4 */
-    (void) WriteBlobLSBLong(image, 0x2); /* 0xB8 */
-    (void) WriteBlobLSBLong(image, (unsigned int) DataSize); /* 0xBC */
+    data_size=image->rows*image->columns;
+    if (is_gray == MagickFalse)
+      data_size*=3;
+    padding=((unsigned char)(data_size-1) & 0x7) ^ 0x7;
+
+    (void) WriteBlobLSBLong(image,miMATRIX);
+    (void) WriteBlobLSBLong(image,(unsigned int) data_size+padding+
+      ((is_gray != MagickFalse) ? 48 : 56));
+    (void) WriteBlobLSBLong(image,0x6); /* 0x88 */
+    (void) WriteBlobLSBLong(image,0x8); /* 0x8C */
+    (void) WriteBlobLSBLong(image,0x6); /* 0x90 */
+    (void) WriteBlobLSBLong(image,0);
+    (void) WriteBlobLSBLong(image,0x5); /* 0x98 */
+    (void) WriteBlobLSBLong(image,(is_gray != MagickFalse) ? 0x8 : 0xC); /* 0x9C - DimFlag */
+    (void) WriteBlobLSBLong(image,(unsigned int) image->rows);    /* x: 0xA0 */
+    (void) WriteBlobLSBLong(image,(unsigned int) image->columns); /* y: 0xA4 */
+    if (is_gray == MagickFalse)
+      {
+        (void) WriteBlobLSBLong(image,3); /* z: 0xA8 */
+        (void) WriteBlobLSBLong(image,0);
+      }
+    (void) WriteBlobLSBShort(image,1);  /* 0xB0 */
+    (void) WriteBlobLSBShort(image,1);  /* 0xB2 */
+    (void) WriteBlobLSBLong(image,'M'); /* 0xB4 */
+    (void) WriteBlobLSBLong(image,0x2); /* 0xB8 */
+    (void) WriteBlobLSBLong(image,(unsigned int) data_size); /* 0xBC */
 
     /*
       Store image data.
@@ -1285,6 +1632,12 @@ static MagickBooleanType WriteMATImage(c
     pixels=GetQuantumPixels(quantum_info);
     do
     {
+      const PixelPacket
+        *p;
+
+      ssize_t
+        y;
+
       for (y=0; y < (ssize_t)image->columns; y++)
       {
         p=GetVirtualPixels(image,y,0,1,image->rows,&image->exception);
@@ -1296,8 +1649,9 @@ static MagickBooleanType WriteMATImage(c
       }
       if (!SyncAuthenticPixels(image,exception))
         break;
-    } while(z-- >= 2);
-    while(padding-->0) (void) WriteBlobByte(image,0);
+    } while (z-- >= 2);
+    while (padding-- > 0)
+      (void) WriteBlobByte(image,0);
     quantum_info=DestroyQuantumInfo(quantum_info);
     if (GetNextImageInList(image) == (Image *) NULL)
       break;
@@ -1308,5 +1662,5 @@ static MagickBooleanType WriteMATImage(c
       break;
   } while (image_info->adjoin != MagickFalse);
   (void) CloseBlob(image);
-  return(MagickTrue);
+  return(status);
 }
