]> granicus.if.org Git - imagemagick/blobdiff - coders/mat.c
...
[imagemagick] / coders / mat.c
index c7edc46a8f81b9a4d6daa020899e1b81de62e265..0f9a5f44843b50b99372eae1ec798b3e703e4d2c 100644 (file)
@@ -98,20 +98,20 @@ typedef struct
   char identific[124];
   unsigned short Version;
   char EndianIndicator[2];
-  unsigned long DataType;
+  unsigned int DataType;
   unsigned int ObjectSize;
-  unsigned long unknown1;
-  unsigned long unknown2;
+  unsigned int unknown1;
+  unsigned int unknown2;
 
   unsigned short unknown5;
   unsigned char StructureFlag;
   unsigned char StructureClass;
-  unsigned long unknown3;
-  unsigned long unknown4;
-  unsigned long DimFlag;
+  unsigned int unknown3;
+  unsigned int unknown4;
+  unsigned int DimFlag;
 
-  unsigned long SizeX;
-  unsigned long SizeY;
+  unsigned int SizeX;
+  unsigned int SizeY;
   unsigned short Flag1;
   unsigned short NameFlag;
 }
@@ -178,18 +178,16 @@ typedef enum
 
 static const QuantumType z2qtype[4] = {GrayQuantum, BlueQuantum, GreenQuantum, RedQuantum};
 
-
 static void InsertComplexDoubleRow(Image *image,double *p,int y,double MinVal,
   double MaxVal,ExceptionInfo *exception)
 {
-
   double f;
   int x;
   register Quantum *q;
 
-  if (MinVal == 0)
+  if (MinVal >= 0)
     MinVal = -1;
-  if (MaxVal == 0)
+  if (MaxVal <= 0)
     MaxVal = 1;
 
   q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
@@ -198,50 +196,51 @@ static void InsertComplexDoubleRow(Image *image,double *p,int y,double MinVal,
   for (x = 0; x < (ssize_t) image->columns; x++)
   {
     if (*p > 0)
-    {
-      f = (*p / MaxVal) * (QuantumRange-GetPixelRed(image,q));
-      if (f + GetPixelRed(image,q) > QuantumRange)
-        SetPixelRed(image,QuantumRange,q);
-      else
-        SetPixelRed(image,GetPixelRed(image,q)+(int) f,q);
-      if ((int) f / 2.0 > GetPixelGreen(image,q))
-        {
-          SetPixelGreen(image,0,q);
-          SetPixelBlue(image,0,q);
-        }
-      else
-        {
-          SetPixelBlue(image,GetPixelBlue(image,q)-(int) (f/2.0),q);
-          SetPixelGreen(image,GetPixelBlue(image,q),q);
-        }
-    }
+      {
+        f=(*p/MaxVal)*(Quantum) (QuantumRange-GetPixelRed(image,q));
+        if ((f+GetPixelRed(image,q)) >= QuantumRange)
+          SetPixelRed(image,QuantumRange,q);
+        else
+          SetPixelRed(image,GetPixelRed(image,q)+ClampToQuantum(f),q);
+        f=GetPixelGreen(image,q)-f/2.0;
+        if (f <= 0.0)
+          {
+            SetPixelGreen(image,0,q);
+            SetPixelBlue(image,0,q);
+          }
+        else
+          {
+            SetPixelBlue(image,ClampToQuantum(f),q);
+            SetPixelGreen(image,ClampToQuantum(f),q);
+          }
+      }
     if (*p < 0)
-    {
-      f = (*p / MaxVal) * (QuantumRange-GetPixelBlue(image,q));
-      if (f+GetPixelBlue(image,q) > QuantumRange)
-        SetPixelBlue(image,QuantumRange,q);
-      else
-        SetPixelBlue(image,GetPixelBlue(image,q)+(int) f,q);
-      if ((int) f / 2.0 > GetPixelGreen(image,q))
-        {
-          SetPixelRed(image,0,q);
-          SetPixelGreen(image,0,q);
-        }
-      else
-        {
-          SetPixelRed(image,GetPixelRed(image,q)-(int) (f/2.0),q);
-          SetPixelGreen(image,GetPixelRed(image,q),q);
-        }
-    }
+      {
+        f=(*p/MinVal)*(Quantum) (QuantumRange-GetPixelBlue(image,q));
+        if ((f+GetPixelBlue(image,q)) >= QuantumRange)
+          SetPixelBlue(image,QuantumRange,q);
+        else
+          SetPixelBlue(image,GetPixelBlue(image,q)+ClampToQuantum(f),q);
+        f=GetPixelGreen(image,q)-f/2.0;
+        if (f <= 0.0)
+          {
+            SetPixelRed(image,0,q);
+            SetPixelGreen(image,0,q);
+          }
+        else
+          {
+            SetPixelRed(image,ClampToQuantum(f),q);
+            SetPixelGreen(image,ClampToQuantum(f),q);
+          }
+      }
     p++;
-    q+=GetPixelChannels(image);
+    q++;
   }
   if (!SyncAuthenticPixels(image,exception))
     return;
   return;
 }
 
-
 static void InsertComplexFloatRow(Image *image,float *p,int y,double MinVal,
   double MaxVal,ExceptionInfo *exception)
 {
@@ -249,9 +248,9 @@ static void InsertComplexFloatRow(Image *image,float *p,int y,double MinVal,
   int x;
   register Quantum *q;
 
-  if (MinVal == 0)
+  if (MinVal >= 0)
     MinVal = -1;
-  if (MaxVal == 0)
+  if (MaxVal <= 0)
     MaxVal = 1;
 
   q = QueueAuthenticPixels(image, 0, y, image->columns, 1,exception);
@@ -260,42 +259,43 @@ static void InsertComplexFloatRow(Image *image,float *p,int y,double MinVal,
   for (x = 0; x < (ssize_t) image->columns; x++)
   {
     if (*p > 0)
-    {
-      f = (*p / MaxVal) * (QuantumRange-GetPixelRed(image,q));
-      if (f+GetPixelRed(image,q) > QuantumRange)
-        SetPixelRed(image,QuantumRange,q);
-      else
-        SetPixelRed(image,GetPixelRed(image,q)+(int) f,q);
-      if ((int) f / 2.0 > GetPixelGreen(image,q))
-        {
-          SetPixelGreen(image,0,q);
-          SetPixelBlue(image,0,q);
-        }
-      else
-        {
-          SetPixelBlue(image,GetPixelBlue(image,q)-(int) (f/2.0),q);
-          SetPixelGreen(image,GetPixelBlue(image,q),q);
-        }
-    }
+      {
+        f=(*p/MaxVal)*(Quantum) (QuantumRange-GetPixelRed(image,q));
+        if ((f+GetPixelRed(image,q)) < QuantumRange)
+          SetPixelRed(image,GetPixelRed(image,q)+ClampToQuantum(f),q);
+        else
+          SetPixelRed(image,QuantumRange,q);
+        f/=2.0;
+        if (f < GetPixelGreen(image,q))
+          {
+            SetPixelBlue(image,GetPixelBlue(image,q)-ClampToQuantum(f),q);
+            SetPixelGreen(image,GetPixelBlue(image,q),q);
+          }
+        else
+          {
+            SetPixelGreen(image,0,q);
+            SetPixelBlue(image,0,q);
+          }
+      }
     if (*p < 0)
-    {
-      f = (*p / MaxVal) * (QuantumRange - GetPixelBlue(image,q));
-      if (f + GetPixelBlue(image,q) > QuantumRange)
-        SetPixelBlue(image,QuantumRange,q);
-      else
-        SetPixelBlue(image,GetPixelBlue(image,q)+
-          (int) f,q);
-      if ((int) f / 2.0 > GetPixelGreen(image,q))
-        {
-          SetPixelGreen(image,0,q);
-          SetPixelRed(image,0,q);
-        }
-      else
-        {
-          SetPixelRed(image,GetPixelRed(image,q)-(int) (f/2.0),q);
-          SetPixelGreen(image,GetPixelRed(image,q),q);
-        }
-    }
+      {
+        f=(*p/MaxVal)*(Quantum) (QuantumRange-GetPixelBlue(image,q));
+        if ((f > 0) && ((f+GetPixelBlue(image,q)) < QuantumRange))
+          SetPixelBlue(image,GetPixelBlue(image,q)+ClampToQuantum(f),q);
+        else
+          SetPixelBlue(image,QuantumRange,q);
+        f/=2.0;
+        if (f < GetPixelGreen(image,q))
+          {
+            SetPixelRed(image,GetPixelRed(image,q)-ClampToQuantum(f),q);
+            SetPixelGreen(image,GetPixelRed(image,q),q);
+          }
+        else
+          {
+            SetPixelGreen(image,0,q);
+            SetPixelRed(image,0,q);
+          }
+      }
     p++;
     q++;
   }
@@ -537,6 +537,8 @@ ssize_t TotalSize = 0;
   while(*Size>0 && !EOFBlob(orig))
   {
     magick_size = ReadBlob(orig, (*Size < 16384) ? *Size : 16384, (unsigned char *) cache_block);
+    if (magick_size == 0)
+      break;
     zip_info.next_in = (Bytef *) cache_block;
     zip_info.avail_in = (uInt) magick_size;
 
@@ -556,7 +558,7 @@ ssize_t TotalSize = 0;
     if ((zip_status != Z_OK) && (zip_status != Z_STREAM_END))
       break;
 
-    *Size -= magick_size;
+    *Size -= (unsigned int) magick_size;
   }
 DblBreak:
 
@@ -602,7 +604,7 @@ static Image *ReadMATImageV4(const ImageInfo *image_info,Image *image,
     endian;
 
   Image
-    *rotate_image;
+    *rotated_image;
 
   MagickBooleanType
     status;
@@ -629,10 +631,10 @@ static Image *ReadMATImageV4(const ImageInfo *image_info,Image *image,
   unsigned int
     depth;
 
-
   quantum_info=(QuantumInfo *) NULL;
   (void) SeekBlob(image,0,SEEK_SET);
-  while (EOFBlob(image) != MagickFalse)
+  status=MagickTrue;
+  while (EOFBlob(image) == MagickFalse)
   {
     /*
      Object parser loop.
@@ -667,7 +669,7 @@ static Image *ReadMATImageV4(const ImageInfo *image_info,Image *image,
     if ((HDR.imagf != 0) && (HDR.imagf != 1))
       break;
     if (HDR.nameLen > 0xFFFF)
-      return((Image *) NULL);
+      return(DestroyImageList(image));
     for (i=0; i < (ssize_t) HDR.nameLen; i++)
     {
       int
@@ -686,20 +688,26 @@ static Image *ReadMATImageV4(const ImageInfo *image_info,Image *image,
     }
     image->columns=(size_t) HDR.nRows;
     image->rows=(size_t) HDR.nCols;
-    SetImageColorspace(image,GRAYColorspace,exception);
+    if ((image->columns == 0) || (image->rows == 0))
+      return(DestroyImageList(image));
     if (image_info->ping != MagickFalse)
       {
         Swap(image->columns,image->rows);
         if(HDR.imagf==1) ldblk *= 2;
         SeekBlob(image, HDR.nCols*ldblk, SEEK_CUR);
+        if ((image->columns == 0) || (image->rows == 0))
+          return(image->previous == (Image *) NULL ? DestroyImageList(image)
+            : image);
         goto skip_reading_current;
       }
     status=SetImageExtent(image,image->columns,image->rows,exception);
     if (status == MagickFalse)
-      return((Image *) NULL);
+      return(DestroyImageList(image));
+    (void) SetImageBackgroundColor(image,exception);
+    (void) SetImageColorspace(image,GRAYColorspace,exception);
     quantum_info=AcquireQuantumInfo(image_info,image);
     if (quantum_info == (QuantumInfo *) NULL)
-      return((Image *) NULL);
+      return(DestroyImageList(image));
     switch(HDR.Type[1])
     {
       case 0:
@@ -777,18 +785,23 @@ static Image *ReadMATImageV4(const ImageInfo *image_info,Image *image,
       }
     if (quantum_info != (QuantumInfo *) NULL)
       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;
       }
+    rotated_image=RotateImage(image,90.0,exception);
+    if (rotated_image != (Image *) NULL)
+      {
+        rotated_image->page.x=0;
+        rotated_image->page.y=0;
+        rotated_image->colors = image->colors;
+        DestroyBlob(rotated_image);
+        rotated_image->blob=ReferenceBlob(image->blob);
+        AppendImageToList(&image,rotated_image);
+        DeleteImageFromList(&image);
+      }
     /*
       Proceed to next image.
     */
@@ -802,8 +815,8 @@ skip_reading_current:
     AcquireNextImage(image_info,image,exception);
     if (GetNextImageInList(image) == (Image *) NULL)
       {
-        image=DestroyImageList(image);
-        return((Image *) NULL);
+        status=MagickFalse;
+        break;
       }
     image=SyncNextImageInList(image);
     status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
@@ -812,6 +825,8 @@ skip_reading_current:
       break;
   }
   (void) CloseBlob(image);
+  if (status == MagickFalse)
+    return(DestroyImageList(image));
   return(GetFirstImageInList(image));
 }
 \f
@@ -866,8 +881,6 @@ static Image *ReadMATImage(const ImageInfo *image_info,ExceptionInfo *exception)
   int logging;
   int sample_size;
   MagickOffsetType filepos=0x80;
-  BlobInfo *blob;
-  size_t one;
 
   unsigned int (*ReadBlobXXXLong)(Image *image);
   unsigned short (*ReadBlobXXXShort)(Image *image);
@@ -902,10 +915,15 @@ static Image *ReadMATImage(const ImageInfo *image_info,ExceptionInfo *exception)
     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;
+      image=ReadMATImageV4(image_info,image,exception);
+      if (image == NULL)
+        {
+          if ((image != image2) && (image2 != (Image *) NULL))
+            image2=DestroyImage(image2);
+          if (clone_info != (ImageInfo *) NULL)
+            clone_info=DestroyImageInfo(clone_info);
+          return((Image *) NULL);
+        }
       goto END_OF_READING;
     }
   MATLAB_HDR.Version = ReadBlobLSBShort(image);
@@ -932,9 +950,6 @@ static Image *ReadMATImage(const ImageInfo *image_info,ExceptionInfo *exception)
     image->endian = MSBEndian;
   }
   else
-    goto MATLAB_KO;    /* unsupported endian */
-
-  if (strncmp(MATLAB_HDR.identific, "MATLAB", 6))
     {
 MATLAB_KO:
       if ((image != image2) && (image2 != (Image *) NULL))
@@ -948,7 +963,9 @@ MATLAB_KO:
   while(!EOFBlob(image)) /* object parser loop */
   {
     Frames = 1;
-    (void) SeekBlob(image,filepos,SEEK_SET);
+    if (filepos != (unsigned int) filepos)
+      break;
+    if(SeekBlob(image,filepos,SEEK_SET) != filepos) break;
     /* printf("pos=%X\n",TellBlob(image)); */
 
     MATLAB_HDR.DataType = ReadBlobXXXLong(image);
@@ -957,8 +974,10 @@ MATLAB_KO:
     if(EOFBlob(image)) break;
     if((MagickSizeType) (MATLAB_HDR.ObjectSize+filepos) > GetBlobSize(image))
       goto MATLAB_KO;
-    filepos += MATLAB_HDR.ObjectSize + 4 + 4;
+    filepos += (MagickOffsetType) 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);
@@ -972,9 +991,13 @@ MATLAB_KO:
     }
 #endif
 
-    if (MATLAB_HDR.DataType!=miMATRIX)
+    if (MATLAB_HDR.DataType != miMATRIX)
       {
         clone_info=DestroyImageInfo(clone_info);
+#if defined(MAGICKCORE_ZLIB_DELEGATE)
+        if (image2 != image)
+          DeleteImageFromList(&image2);
+#endif
         continue;  /* skip another objects. */
       }
 
@@ -999,14 +1022,43 @@ MATLAB_KO:
       case  8: z2=z=1; break;      /* 2D matrix*/
       case 12: z2=z = ReadBlobXXXLong(image2);  /* 3D matrix RGB*/
            (void) ReadBlobXXXLong(image2);
-         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 (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(CoderError,
+               "MultidimensionalMatricesAreNotSupported");
+           }
+          Frames = ReadBlobXXXLong(image2);
+          if (Frames == 0)
+            {
+              if (clone_info != (ImageInfo *) NULL)
+                clone_info=DestroyImageInfo(clone_info);
+              if ((image != image2) && (image2 != (Image *) NULL))
+                image2=DestroyImage(image2);
+              ThrowReaderException(CorruptImageError,"ImproperImageHeader");
+            }
+          if (AcquireMagickResource(ListLengthResource,Frames) == MagickFalse)
+            {
+              if (clone_info != (ImageInfo *) NULL)
+                clone_info=DestroyImageInfo(clone_info);
+              if ((image != image2) && (image2 != (Image *) NULL))
+                image2=DestroyImage(image2);
+              ThrowReaderException(ResourceLimitError,"ListLengthExceedsLimit");
+            }
          break;
       default:
         if (clone_info != (ImageInfo *) NULL)
@@ -1032,13 +1084,22 @@ MATLAB_KO:
         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))
+          {
+            CloseBlob(image2);
+            DeleteImageFromList(&image2);
+          }
+        if (clone_info != (ImageInfo *) NULL)
+          clone_info=DestroyImageInfo(clone_info);
+        ThrowReaderException(CoderError,"UnsupportedCellTypeInTheMatrix");
+      }
 
     switch (MATLAB_HDR.NameFlag)
     {
       case 0:
         size = ReadBlobXXXLong(image2);  /* Object name string size */
-        size = 4 * (ssize_t) ((size + 3 + 1) / 4);
+        size = 4 * (((size_t) size + 3 + 1) / 4);
         (void) SeekBlob(image2, size, SEEK_CUR);
         break;
       case 1:
@@ -1056,7 +1117,9 @@ MATLAB_KO:
       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
         "MATLAB_HDR.CellType: %.20g",(double) CellType);
 
-    (void) ReadBlob(image2, 4, (unsigned char *) &size);     /* data size */
+    /* data size */
+    if (ReadBlob(image2, 4, (unsigned char *) &size) != 4)
+      goto MATLAB_KO;
 
     NEXT_FRAME:
     switch (CellType)
@@ -1093,8 +1156,8 @@ MATLAB_KO:
         image->depth = 32;        /* double type cell */
         (void) SetImageOption(clone_info,"quantum:format","floating-point");
         if (MATLAB_HDR.StructureFlag & FLAG_COMPLEX)
-  {              /* complex float type cell */
-  }
+          {              /* complex float type cell */
+          }
         ldblk = (ssize_t) (4 * MATLAB_HDR.SizeX);
         break;
       case miDOUBLE:
@@ -1104,10 +1167,16 @@ MATLAB_KO:
 DisableMSCWarning(4127)
         if (sizeof(double) != 8)
 RestoreMSCWarning
-          ThrowReaderException(CoderError, "IncompatibleSizeOfDouble");
+          {
+            if (clone_info != (ImageInfo *) NULL)
+              clone_info=DestroyImageInfo(clone_info);
+            if ((image != image2) && (image2 != (Image *) NULL))
+              image2=DestroyImage(image2);
+            ThrowReaderException(CoderError, "IncompatibleSizeOfDouble");
+          }
         if (MATLAB_HDR.StructureFlag & FLAG_COMPLEX)
-  {                         /* complex double type cell */
-  }
+          {                         /* complex double type cell */
+          }
         ldblk = (ssize_t) (8 * MATLAB_HDR.SizeX);
         break;
       default:
@@ -1120,11 +1189,10 @@ RestoreMSCWarning
     (void) sample_size;
     image->columns = MATLAB_HDR.SizeX;
     image->rows = MATLAB_HDR.SizeY;
-    one=1;
-    image->colors = one << image->depth;
+    image->colors = GetQuantumRange(image->depth);
     if (image->columns == 0 || image->rows == 0)
       goto MATLAB_KO;
-    if((unsigned long)ldblk*MATLAB_HDR.SizeY > MATLAB_HDR.ObjectSize)
+    if((unsigned int)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) &&
@@ -1149,26 +1217,45 @@ RestoreMSCWarning
     status=SetImageExtent(image,image->columns,image->rows,exception);
     if (status == MagickFalse)
       {
+        if (clone_info != (ImageInfo *) NULL)
+          clone_info=DestroyImageInfo(clone_info);
         if ((image != image2) && (image2 != (Image *) NULL))
           image2=DestroyImage(image2);
         return(DestroyImageList(image));
       }
+    (void) SetImageBackgroundColor(image,exception);
     quantum_info=AcquireQuantumInfo(clone_info,image);
     if (quantum_info == (QuantumInfo *) NULL)
-      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
+      {
+        if (clone_info != (ImageInfo *) NULL)
+          clone_info=DestroyImageInfo(clone_info);
+        if ((image != image2) && (image2 != (Image *) NULL))
+          image2=DestroyImage(image2);
+        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
+      }
 
   /* ----- Load raster data ----- */
     BImgBuff = (unsigned char *) AcquireQuantumMemory((size_t) (ldblk),sizeof(double));    /* Ldblk was set in the check phase */
     if (BImgBuff == NULL)
-      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
-    (void) ResetMagickMemory(BImgBuff,0,ldblk*sizeof(double));
+      {
+        if (clone_info != (ImageInfo *) NULL)
+          clone_info=DestroyImageInfo(clone_info);
+        if ((image != image2) && (image2 != (Image *) NULL))
+          image2=DestroyImage(image2);
+        if (quantum_info != (QuantumInfo *) NULL)
+          quantum_info=DestroyQuantumInfo(quantum_info);
+        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
+      }
+    (void) memset(BImgBuff,0,ldblk*sizeof(double));
 
     MinVal = 0;
     MaxVal = 0;
     if (CellType==miDOUBLE || CellType==miSINGLE)        /* Find Min and Max Values for floats */
-    {
-      CalcMinMax(image2, image_info->endian,  MATLAB_HDR.SizeX, MATLAB_HDR.SizeY, CellType, ldblk, BImgBuff, &quantum_info->minimum, &quantum_info->maximum);
-    }
+      {
+        CalcMinMax(image2,image_info->endian,MATLAB_HDR.SizeX,MATLAB_HDR.SizeY,
+          CellType,ldblk,BImgBuff,&quantum_info->minimum,
+          &quantum_info->maximum);
+      }
 
     /* Main loop for reading all scanlines */
     if(z==1) z=0; /* read grey scanlines */
@@ -1179,45 +1266,45 @@ RestoreMSCWarning
       {
         q=GetAuthenticPixels(image,0,MATLAB_HDR.SizeY-i-1,image->columns,1,exception);
         if (q == (Quantum *) NULL)
-  {
-    if (logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(),
+          {
+            if (logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(),
               "  MAT set image pixels returns unexpected NULL on a row %u.", (unsigned)(MATLAB_HDR.SizeY-i-1));
-    goto done_reading;    /* Skip image rotation, when cannot set image pixels    */
-  }
+            goto done_reading;    /* Skip image rotation, when cannot set image pixels    */
+          }
         if(ReadBlob(image2,ldblk,(unsigned char *)BImgBuff) != (ssize_t) ldblk)
-  {
-    if (logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(),
-             "  MAT cannot read scanrow %u from a file.", (unsigned)(MATLAB_HDR.SizeY-i-1));
-    goto ExitLoop;
-  }
+          {
+            if (logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(),
+              "  MAT cannot read scanrow %u from a file.", (unsigned)(MATLAB_HDR.SizeY-i-1));
+            goto ExitLoop;
+          }
         if((CellType==miINT8 || CellType==miUINT8) && (MATLAB_HDR.StructureFlag & FLAG_LOGICAL))
         {
           FixLogical((unsigned char *)BImgBuff,ldblk);
           if(ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,z2qtype[z],BImgBuff,exception) <= 0)
-    {
+            {
 ImportQuantumPixelsFailed:
-      if (logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(),
-              "  MAT failed to ImportQuantumPixels for a row %u", (unsigned)(MATLAB_HDR.SizeY-i-1));
-      break;
-    }
+              if (logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(),
+                "  MAT failed to ImportQuantumPixels for a row %u", (unsigned)(MATLAB_HDR.SizeY-i-1));
+              break;
+            }
         }
         else
         {
           if(ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,z2qtype[z],BImgBuff,exception) <= 0)
-      goto ImportQuantumPixelsFailed;
+            goto ImportQuantumPixelsFailed;
 
 
           if (z<=1 &&       /* fix only during a last pass z==0 || z==1 */
-          (CellType==miINT8 || CellType==miINT16 || CellType==miINT32 || CellType==miINT64))
-      FixSignedValues(image,q,MATLAB_HDR.SizeX);
+             (CellType==miINT8 || CellType==miINT16 || CellType==miINT32 || CellType==miINT64))
+            FixSignedValues(image,q,MATLAB_HDR.SizeX);
         }
 
         if (!SyncAuthenticPixels(image,exception))
-  {
-    if (logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(),
-            "  MAT failed to sync image pixels for a row %u", (unsigned)(MATLAB_HDR.SizeY-i-1));
-    goto ExitLoop;
-  }
+          {
+            if (logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(),
+              "  MAT failed to sync image pixels for a row %u", (unsigned)(MATLAB_HDR.SizeY-i-1));
+            goto ExitLoop;
+          }
       }
     } while(z-- >= 2);
 ExitLoop:
@@ -1236,19 +1323,19 @@ ExitLoop:
 
       if (CellType==miDOUBLE)
         for (i = 0; i < (ssize_t) MATLAB_HDR.SizeY; i++)
-  {
+        {
           ReadBlobDoublesXXX(image2, ldblk, (double *)BImgBuff);
           InsertComplexDoubleRow(image, (double *)BImgBuff, i, MinVal, MaxVal,
             exception);
-  }
+        }
 
       if (CellType==miSINGLE)
         for (i = 0; i < (ssize_t) MATLAB_HDR.SizeY; i++)
-  {
+        {
           ReadBlobFloatsXXX(image2, ldblk, (float *)BImgBuff);
           InsertComplexFloatRow(image,(float *)BImgBuff,i,MinVal,MaxVal,
             exception);
-  }
+        }
     }
 
       /* Image is gray when no complex flag is set and 2D Matrix AGAIN!!! */
@@ -1268,11 +1355,9 @@ ExitLoop:
         /* Remove page offsets added by RotateImage */
       rotated_image->page.x=0;
       rotated_image->page.y=0;
-
-      blob = rotated_image->blob;
-      rotated_image->blob = image->blob;
       rotated_image->colors = image->colors;
-      image->blob = blob;
+      DestroyBlob(rotated_image);
+      rotated_image->blob=ReferenceBlob(image->blob);
       AppendImageToList(&image,rotated_image);
       DeleteImageFromList(&image);
     }
@@ -1283,16 +1368,18 @@ done_reading:
       if(image2!=image)
       {
         DeleteImageFromList(&image2);
-  if(clone_info)
-  {
+        if(clone_info)
+        {
           if(clone_info->file)
-    {
+          {
             fclose(clone_info->file);
             clone_info->file = NULL;
             (void) remove_utf8(clone_info->filename);
-    }
+          }
         }
       }
+    if (EOFBlob(image) != MagickFalse)
+      break;
 
       /* Allocate next image structure. */
     AcquireNextImage(image_info,image,exception);
@@ -1304,12 +1391,15 @@ 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)
     {
       z = z2;
       if(image2==NULL) image2 = image;
-      goto NEXT_FRAME;
+      if(!EOFBlob(image) && TellBlob(image)<filepos)
+        goto NEXT_FRAME;
     }
     if ((image2!=NULL) && (image2!=image))   /* Does shadow temporary decompressed image exist? */
       {
@@ -1324,10 +1414,8 @@ done_reading:
             (void) remove_utf8(clone_info->filename);
           }
         }
-        }
+      }
 
-    if (quantum_info != (QuantumInfo *) NULL)
-      quantum_info=DestroyQuantumInfo(quantum_info);
     if (clone_info)
       clone_info=DestroyImageInfo(clone_info);
   }
@@ -1488,6 +1576,9 @@ static MagickBooleanType WriteMATImage(const ImageInfo *image_info,Image *image,
   MagickOffsetType
     scene;
 
+  size_t
+    imageListLength;
+
   struct tm
     local_time;
 
@@ -1527,6 +1618,7 @@ static MagickBooleanType WriteMATImage(const ImageInfo *image_info,Image *image,
   MATLAB_HDR[0x7F]='M';
   (void) WriteBlob(image,sizeof(MATLAB_HDR),(unsigned char *) MATLAB_HDR);
   scene=0;
+  imageListLength=GetImageListLength(image);
   do
   {
     char
@@ -1614,8 +1706,7 @@ static MagickBooleanType WriteMATImage(const ImageInfo *image_info,Image *image,
     if (GetNextImageInList(image) == (Image *) NULL)
       break;
     image=SyncNextImageInList(image);
-    status=SetImageProgress(image,SaveImagesTag,scene++,
-      GetImageListLength(image));
+    status=SetImageProgress(image,SaveImagesTag,scene++,imageListLength);
     if (status == MagickFalse)
       break;
   } while (image_info->adjoin != MagickFalse);