]> granicus.if.org Git - imagemagick/blobdiff - coders/mat.c
(no commit message)
[imagemagick] / coders / mat.c
index 53b59c77a66df939b7993b656b70fc289499f9b5..001c4b09d6e5315a3eaa18dab14fef905123fc20 100644 (file)
 /*
   Include declarations.
 */
-#include "magick/studio.h"
-#include "magick/blob.h"
-#include "magick/blob-private.h"
-#include "magick/cache.h"
-#include "magick/color-private.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/magick.h"
-#include "magick/memory_.h"
-#include "magick/monitor.h"
-#include "magick/monitor-private.h"
-#include "magick/quantum-private.h"
-#include "magick/option.h"
-#include "magick/resource_.h"
-#include "magick/shear.h"
-#include "magick/static.h"
-#include "magick/string_.h"
-#include "magick/module.h"
-#include "magick/transform.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-private.h"
+#include "MagickCore/colormap.h"
+#include "MagickCore/colorspace-private.h"
+#include "MagickCore/distort.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/magick.h"
+#include "MagickCore/memory_.h"
+#include "MagickCore/monitor.h"
+#include "MagickCore/monitor-private.h"
+#include "MagickCore/pixel-accessor.h"
+#include "MagickCore/quantum-private.h"
+#include "MagickCore/option.h"
+#include "MagickCore/pixel.h"
+#include "MagickCore/resource_.h"
+#include "MagickCore/static.h"
+#include "MagickCore/string_.h"
+#include "MagickCore/module.h"
+#include "MagickCore/transform.h"
+#include "MagickCore/utility-private.h"
 #if defined(MAGICKCORE_ZLIB_DELEGATE)
  #include "zlib.h"
 #endif
@@ -77,7 +83,7 @@
   Forward declaration.
 */
 static MagickBooleanType
-  WriteMATImage(const ImageInfo *,Image *);
+  WriteMATImage(const ImageInfo *,Image *,ExceptionInfo *);
 
 
 /* Auto coloring method, sorry this creates some artefact inside data
@@ -172,53 +178,62 @@ typedef enum
 static const QuantumType z2qtype[4] = {GrayQuantum, BlueQuantum, GreenQuantum, RedQuantum};
 
 
-static void InsertComplexDoubleRow(double *p, int y, Image * image, double MinVal,
-                                  double MaxVal)
+static void InsertComplexDoubleRow(Image *image,double *p,int y,double MinVal,
+  double MaxVal,ExceptionInfo *exception)
 {
-  ExceptionInfo
-    *exception;
 
   double f;
   int x;
-  register PixelPacket *q;
+  register Quantum *q;
 
   if (MinVal == 0)
     MinVal = -1;
   if (MaxVal == 0)
     MaxVal = 1;
 
-  exception=(&image->exception);
-  q = QueueAuthenticPixels(image, 0, y, image->columns, 1,exception);
-  if (q == (PixelPacket *) NULL)
+  q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
+  if (q == (Quantum *) NULL)
     return;
-  for (x = 0; x < (long) image->columns; x++)
+  for (x = 0; x < (ssize_t) image->columns; x++)
   {
     if (*p > 0)
     {
-      f = (*p / MaxVal) * (QuantumRange - q->red);
-      if (f + q->red > QuantumRange)
-        q->red = QuantumRange;
+      f = (*p / MaxVal) * (QuantumRange-GetPixelRed(image,q));
+      if (f + GetPixelRed(image,q) > QuantumRange)
+        SetPixelRed(image,QuantumRange,q);
       else
-        q->red += (int) f;
-      if ((int) f / 2.0 > q->green)
-        q->green = q->blue = 0;
+        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
-        q->green = q->blue -= (int) (f / 2.0);
+        {
+          SetPixelBlue(image,GetPixelBlue(image,q)-(int) (f/2.0),q);
+          SetPixelGreen(image,GetPixelBlue(image,q),q);
+        }
     }
     if (*p < 0)
     {
-      f = (*p / MaxVal) * (QuantumRange - q->blue);
-      if (f + q->blue > QuantumRange)
-        q->blue = QuantumRange;
+      f = (*p / MaxVal) * (QuantumRange-GetPixelBlue(image,q));
+      if (f+GetPixelBlue(image,q) > QuantumRange)
+        SetPixelBlue(image,QuantumRange,q);
       else
-        q->blue += (int) f;
-      if ((int) f / 2.0 > q->green)
-        q->green = q->red = 0;
+        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
-        q->green = q->red -= (int) (f / 2.0);
+        {
+          SetPixelRed(image,GetPixelRed(image,q)-(int) (f/2.0),q);
+          SetPixelGreen(image,GetPixelRed(image,q),q);
+        }
     }
     p++;
-    q++;
+    q+=GetPixelChannels(image);
   }
   if (!SyncAuthenticPixels(image,exception))
     return;
@@ -226,50 +241,59 @@ static void InsertComplexDoubleRow(double *p, int y, Image * image, double MinVa
 }
 
 
-static void InsertComplexFloatRow(float *p, int y, Image * image, double MinVal,
-                                  double MaxVal)
+static void InsertComplexFloatRow(Image *image,float *p,int y,double MinVal,
+  double MaxVal,ExceptionInfo *exception)
 {
-  ExceptionInfo
-    *exception;
-
   double f;
   int x;
-  register PixelPacket *q;
+  register Quantum *q;
 
   if (MinVal == 0)
     MinVal = -1;
   if (MaxVal == 0)
     MaxVal = 1;
 
-  exception=(&image->exception);
   q = QueueAuthenticPixels(image, 0, y, image->columns, 1,exception);
-  if (q == (PixelPacket *) NULL)
+  if (q == (Quantum *) NULL)
     return;
-  for (x = 0; x < (long) image->columns; x++)
+  for (x = 0; x < (ssize_t) image->columns; x++)
   {
     if (*p > 0)
     {
-      f = (*p / MaxVal) * (QuantumRange - q->red);
-      if (f + q->red > QuantumRange)
-        q->red = QuantumRange;
+      f = (*p / MaxVal) * (QuantumRange-GetPixelRed(image,q));
+      if (f+GetPixelRed(image,q) > QuantumRange)
+        SetPixelRed(image,QuantumRange,q);
       else
-        q->red += (int) f;
-      if ((int) f / 2.0 > q->green)
-        q->green = q->blue = 0;
+        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
-        q->green = q->blue -= (int) (f / 2.0);
+        {
+          SetPixelBlue(image,GetPixelBlue(image,q)-(int) (f/2.0),q);
+          SetPixelGreen(image,GetPixelBlue(image,q),q);
+        }
     }
     if (*p < 0)
     {
-      f = (*p / MaxVal) * (QuantumRange - q->blue);
-      if (f + q->blue > QuantumRange)
-        q->blue = QuantumRange;
+      f = (*p / MaxVal) * (QuantumRange - GetPixelBlue(image,q));
+      if (f + GetPixelBlue(image,q) > QuantumRange)
+        SetPixelBlue(image,QuantumRange,q);
       else
-        q->blue += (int) f;
-      if ((int) f / 2.0 > q->green)
-        q->green = q->red = 0;
+        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
-        q->green = q->red -= (int) (f / 2.0);
+        {
+          SetPixelRed(image,GetPixelRed(image,q)-(int) (f/2.0),q);
+          SetPixelGreen(image,GetPixelRed(image,q),q);
+        }
     }
     p++;
     q++;
@@ -329,7 +353,7 @@ static void ReadBlobDoublesMSB(Image * image, size_t len, double *data)
 }
 
 /* Calculate minimum and maximum from a given block of data */
-static void CalcMinMax(Image *image, int endian_indicator, int SizeX, int SizeY, unsigned long CellType, unsigned ldblk, void *BImgBuff, double *Min, double *Max)
+static void CalcMinMax(Image *image, int endian_indicator, int SizeX, int SizeY, size_t CellType, unsigned ldblk, void *BImgBuff, double *Min, double *Max)
 {
 MagickOffsetType filepos;
 int i, x;
@@ -377,7 +401,7 @@ float *fltrow;
       {
         *Min = *Max = *fltrow;
       }
-    for (x = 0; x < (long) SizeX; x++)
+    for (x = 0; x < (ssize_t) SizeX; x++)
       {
         if (*Min > *fltrow)
           *Min = *fltrow;
@@ -391,16 +415,16 @@ float *fltrow;
 }
 
 
-static void FixSignedValues(PixelPacket *q, int y)
+static void FixSignedValues(const Image *image,Quantum *q, int y)
 {
   while(y-->0)
   {
      /* Please note that negative values will overflow
         Q=8; QuantumRange=255: <0;127> + 127+1 = <128; 255> 
            <-1;-128> + 127+1 = <0; 127> */
-    q->red += QuantumRange/2 + 1;
-    q->green += QuantumRange/ + 1;
-    q->blue += QuantumRange/ + 1;
+    SetPixelRed(image,GetPixelRed(image,q)+QuantumRange/2+1,q);
+    SetPixelGreen(image,GetPixelGreen(image,q)+QuantumRange/2+1,q);
+    SetPixelBlue(image,GetPixelBlue(image,q)+QuantumRange/2+1,q);
     q++;
   }
 }
@@ -445,10 +469,10 @@ static void RelinquishZIPMemory(voidpf context,voidpf memory)
 }
 #endif
 
+#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)
 {
-#if defined(MAGICKCORE_ZLIB_DELEGATE)
 
 Image *image2;
 void *CacheBlock, *DecompressBlock;
@@ -456,6 +480,7 @@ z_stream zip_info;
 FILE *mat_file;
 size_t magick_size;
 size_t extent;
+int file;
 
 int status;
 
@@ -464,7 +489,7 @@ int status;
   {
     fclose(clone_info->file);
     clone_info->file = NULL;
-    (void) unlink(clone_info->filename);
+    (void) remove_utf8(clone_info->filename);
   }
 
   CacheBlock = AcquireQuantumMemory((size_t)((Size<16384)?Size:16384),sizeof(unsigned char *));
@@ -476,7 +501,10 @@ int status;
     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);
@@ -505,6 +533,7 @@ int status;
       zip_info.next_out = (Bytef *) DecompressBlock;
       status = inflate(&zip_info,Z_NO_FLUSH);      
       extent=fwrite(DecompressBlock, 4096-zip_info.avail_out, 1, mat_file);
+      (void) extent;
 
       if(status == Z_STREAM_END) goto DblBreak;
     }
@@ -518,7 +547,7 @@ DblBreak:
   RelinquishMagickMemory(DecompressBlock);
 
   if((clone_info->file=fopen(clone_info->filename,"rb"))==NULL) goto UnlinkFile;
-  if( (image2 = AcquireImage(clone_info))==NULL ) goto EraseFile;  
+  if( (image2 = AcquireImage(clone_info,exception))==NULL ) goto EraseFile;  
   status = OpenBlob(clone_info,image2,ReadBinaryBlobMode,exception);
   if (status == MagickFalse)
   {
@@ -527,19 +556,13 @@ EraseFile:
     fclose(clone_info->file);
     clone_info->file = NULL;
 UnlinkFile:
-    (void) unlink(clone_info->filename);
+    (void) remove_utf8(clone_info->filename);
     return NULL; 
   }
 
   return image2;
-#else
-  (void) orig;
-  (void) Size;
-  (void) clone_info;
-  (void) exception;
-  return NULL;
-#endif
 }
+#endif
 \f
 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -583,24 +606,25 @@ static Image *ReadMATImage(const ImageInfo *image_info,ExceptionInfo *exception)
 {
   Image *image, *image2=NULL,
    *rotated_image;
-  PixelPacket *q;
+  register Quantum *q;
 
   unsigned int status;
   MATHeader MATLAB_HDR;
-  unsigned long size;  
-  unsigned long CellType;
+  size_t size;  
+  size_t CellType;
   QuantumInfo *quantum_info;
   ImageInfo *clone_info;
   int i;
-  long ldblk;
+  ssize_t ldblk;
   unsigned char *BImgBuff = NULL;
   double MinVal, MaxVal;
-  unsigned long Unknown6;
-  unsigned z;
+  unsigned z, z2;
+  unsigned Frames;
   int logging;
   int sample_size;
   MagickOffsetType filepos=0x80;
   BlobInfo *blob;
+  size_t one;
   
   unsigned int (*ReadBlobXXXLong)(Image *image);
   unsigned short (*ReadBlobXXXShort)(Image *image);
@@ -617,7 +641,7 @@ static Image *ReadMATImage(const ImageInfo *image_info,ExceptionInfo *exception)
   /*
      Open image file.
    */
-  image = AcquireImage(image_info);
+  image = AcquireImage(image_info,exception);
 
   status = OpenBlob(image_info, image, ReadBinaryBlobMode, exception);
   if (status == MagickFalse)
@@ -662,6 +686,7 @@ MATLAB_KO: ThrowReaderException(CorruptImageError,"ImproperImageHeader");
   filepos = TellBlob(image);
   while(!EOFBlob(image)) /* object parser loop */
   {
+    Frames = 1;
     (void) SeekBlob(image,filepos,SEEK_SET);
     /* printf("pos=%X\n",TellBlob(image)); */
 
@@ -701,11 +726,16 @@ MATLAB_KO: ThrowReaderException(CorruptImageError,"ImproperImageHeader");
 
     switch(MATLAB_HDR.DimFlag)
     {     
-      case  8: z=1; break;      /* 2D matrix*/
-      case 12: z = ReadBlobXXXLong(image2);  /* 3D matrix RGB*/
-           Unknown6 = ReadBlobXXXLong(image2);
+      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");
          break;
+      case 16: z2=z = ReadBlobXXXLong(image2);  /* 4D matrix animation */
+         if(z!=3 && z!=1)
+            ThrowReaderException(CoderError, "MultidimensionalMatricesAreNotSupported");
+           Frames = ReadBlobXXXLong(image2);
+         break;
       default: ThrowReaderException(CoderError, "MultidimensionalMatricesAreNotSupported");
     }  
 
@@ -731,7 +761,7 @@ MATLAB_KO: ThrowReaderException(CorruptImageError,"ImproperImageHeader");
     {
       case 0:
         size = ReadBlobXXXLong(image2);  /* Object name string size */
-        size = 4 * (long) ((size + 3 + 1) / 4);
+        size = 4 * (ssize_t) ((size + 3 + 1) / 4);
         (void) SeekBlob(image2, size, SEEK_CUR);
         break;
       case 1:
@@ -745,16 +775,13 @@ MATLAB_KO: ThrowReaderException(CorruptImageError,"ImproperImageHeader");
     }
 
     CellType = ReadBlobXXXLong(image2);    /* Additional object type */
-    if (logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(),
-          "MATLAB_HDR.CellType: %ld",CellType);
+    if (logging)
+      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+        "MATLAB_HDR.CellType: %.20g",(double) CellType);
   
     (void) ReadBlob(image2, 4, (unsigned char *) &size);     /* data size */
 
-      /* Image is gray when no complex flag is set and 2D Matrix */
-    if ((MATLAB_HDR.DimFlag == 8) &&
-        ((MATLAB_HDR.StructureFlag & FLAG_COMPLEX) == 0))
-      image->type=GrayscaleType;
-
+    NEXT_FRAME:
     switch (CellType)
     {
       case miINT8:
@@ -764,25 +791,25 @@ MATLAB_KO: ThrowReaderException(CorruptImageError,"ImproperImageHeader");
           image->depth = 1;
         else
           image->depth = 8;         /* Byte type cell */
-        ldblk = (long) MATLAB_HDR.SizeX;      
+        ldblk = (ssize_t) MATLAB_HDR.SizeX;      
         break;
       case miINT16:
       case miUINT16:
         sample_size = 16;
         image->depth = 16;        /* Word type cell */
-        ldblk = (long) (2 * MATLAB_HDR.SizeX);
+        ldblk = (ssize_t) (2 * MATLAB_HDR.SizeX);
         break;
       case miINT32:
       case miUINT32:
         sample_size = 32;
         image->depth = 32;        /* Dword type cell */
-        ldblk = (long) (4 * MATLAB_HDR.SizeX);      
+        ldblk = (ssize_t) (4 * MATLAB_HDR.SizeX);      
         break;
       case miINT64:
       case miUINT64:
         sample_size = 64;
         image->depth = 64;        /* Qword type cell */
-        ldblk = (long) (8 * MATLAB_HDR.SizeX);      
+        ldblk = (ssize_t) (8 * MATLAB_HDR.SizeX);      
         break;   
       case miSINGLE:
         sample_size = 32;
@@ -791,41 +818,42 @@ MATLAB_KO: ThrowReaderException(CorruptImageError,"ImproperImageHeader");
         if (MATLAB_HDR.StructureFlag & FLAG_COMPLEX)
   {              /* complex float type cell */
   }
-        ldblk = (long) (4 * MATLAB_HDR.SizeX);
+        ldblk = (ssize_t) (4 * MATLAB_HDR.SizeX);
         break;
       case miDOUBLE:
         sample_size = 64; 
         image->depth = 64;        /* double type cell */
         (void) SetImageOption(clone_info,"quantum:format","floating-point");
+DisableMSCWarning(4127)
         if (sizeof(double) != 8)
+RestoreMSCWarning
           ThrowReaderException(CoderError, "IncompatibleSizeOfDouble");
         if (MATLAB_HDR.StructureFlag & FLAG_COMPLEX)
   {                         /* complex double type cell */        
   }
-        ldblk = (long) (8 * MATLAB_HDR.SizeX);
+        ldblk = (ssize_t) (8 * MATLAB_HDR.SizeX);
         break;
       default:
         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");
-    image->colors = 1l << image->depth;
+    one=1;
+    image->colors = one << image->depth;
     if (image->columns == 0 || image->rows == 0)
       goto MATLAB_KO;
-
-    /* ----- Create gray palette ----- */
-
-    if (CellType==miUINT8 && z!=3)
-    {
-      if(image->colors>256) image->colors = 256;
-
-      if (!AcquireImageColormap(image, image->colors))
+    /* Image is gray when no complex flag is set and 2D Matrix */
+    if ((MATLAB_HDR.DimFlag == 8) &&
+        ((MATLAB_HDR.StructureFlag & FLAG_COMPLEX) == 0))
       {
- NoMemory:ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");}
-    }
+        image->type=GrayscaleType;
+        SetImageColorspace(image,GRAYColorspace,exception);
+      }
+
 
     /*
       If ping is true, then only set image size and colors without
@@ -833,16 +861,16 @@ MATLAB_KO: ThrowReaderException(CorruptImageError,"ImproperImageHeader");
     */
     if (image_info->ping)
     {
-      unsigned long temp = image->columns;
+      size_t temp = image->columns;
       image->columns = image->rows;
       image->rows = temp;
       goto done_reading; /* !!!!!! BAD  !!!! */
     }  
 
   /* ----- Load raster data ----- */
-    BImgBuff = (unsigned char *) AcquireQuantumMemory((size_t) (ldblk),sizeof(unsigned char *));    /* Ldblk was set in the check phase */
+    BImgBuff = (unsigned char *) AcquireQuantumMemory((size_t) (ldblk),sizeof(unsigned char));    /* Ldblk was set in the check phase */
     if (BImgBuff == NULL)
-      goto NoMemory;
+      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
 
     MinVal = 0;
     MaxVal = 0;
@@ -856,10 +884,10 @@ MATLAB_KO: ThrowReaderException(CorruptImageError,"ImproperImageHeader");
     /* else read color scanlines */
     do
     {
-      for (i = 0; i < (long) MATLAB_HDR.SizeY; i++)
+      for (i = 0; i < (ssize_t) MATLAB_HDR.SizeY; i++)
       {
-        q=QueueAuthenticPixels(image,0,MATLAB_HDR.SizeY-i-1,image->columns,1,exception);
-        if (q == (PixelPacket *)NULL)
+        q=GetAuthenticPixels(image,0,MATLAB_HDR.SizeY-i-1,image->columns,1,exception);
+        if (q == (Quantum *)NULL)
   {
     if (logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(),
               "  MAT set image pixels returns unexpected NULL on a row %u.", (unsigned)(MATLAB_HDR.SizeY-i-1));
@@ -890,7 +918,7 @@ ImportQuantumPixelsFailed:
 
           if (z<=1 &&       /* fix only during a last pass z==0 || z==1 */
           (CellType==miINT8 || CellType==miINT16 || CellType==miINT32 || CellType==miINT64))
-      FixSignedValues(q,MATLAB_HDR.SizeX);
+      FixSignedValues(image,q,MATLAB_HDR.SizeX);
         }
 
         if (!SyncAuthenticPixels(image,exception))
@@ -916,17 +944,19 @@ ExitLoop:
       }
 
       if (CellType==miDOUBLE)
-        for (i = 0; i < (long) MATLAB_HDR.SizeY; i++)
+        for (i = 0; i < (ssize_t) MATLAB_HDR.SizeY; i++)
   {
           ReadBlobDoublesXXX(image2, ldblk, (double *)BImgBuff);
-          InsertComplexDoubleRow((double *)BImgBuff, i, image, MinVal, MaxVal);
+          InsertComplexDoubleRow(image, (double *)BImgBuff, i, MinVal, MaxVal,
+            exception);
   }
 
       if (CellType==miSINGLE)
-        for (i = 0; i < (long) MATLAB_HDR.SizeY; i++)
+        for (i = 0; i < (ssize_t) MATLAB_HDR.SizeY; i++)
   {
           ReadBlobFloatsXXX(image2, ldblk, (float *)BImgBuff);
-          InsertComplexFloatRow((float *)BImgBuff, i, image, MinVal, MaxVal);
+          InsertComplexFloatRow(image,(float *)BImgBuff,i,MinVal,MaxVal,
+            exception);
   }    
     }
 
@@ -968,13 +998,13 @@ done_reading:
     {
             fclose(clone_info->file);
             clone_info->file = NULL;
-            (void) unlink(clone_info->filename);
+            (void) remove_utf8(clone_info->filename);
     }
         }    
       }
 
       /* Allocate next image structure. */    
-    AcquireNextImage(image_info,image);
+    AcquireNextImage(image_info,image,exception);
     if (image->next == (Image *) NULL) break;                
     image=SyncNextImageInList(image);
     image->columns=image->rows=0;
@@ -983,16 +1013,37 @@ done_reading:
       /* row scan buffer is no longer needed */
     RelinquishMagickMemory(BImgBuff);
     BImgBuff = NULL;
+
+    if(--Frames>0)
+    {
+      z = z2;
+      if(image2==NULL) image2 = image;
+      goto NEXT_FRAME;
+    }
+    if ((image2!=NULL) && (image2!=image))   /* Does shadow temporary decompressed image exist? */
+      {
+/*  CloseBlob(image2); */
+        DeleteImageFromList(&image2);
+        if(clone_info)
+        {
+          if(clone_info->file)
+          {
+            fclose(clone_info->file);
+            clone_info->file = NULL;
+            (void) remove_utf8(clone_info->filename);
+          }
+        }
+        }
   }
-    clone_info=DestroyImageInfo(clone_info);
 
+  clone_info=DestroyImageInfo(clone_info);
   RelinquishMagickMemory(BImgBuff);
   CloseBlob(image);
 
 
   {
     Image *p;    
-    long scene=0;
+    ssize_t scene=0;
     
     /*
       Rewind list, removing any empty images while rewinding.
@@ -1024,7 +1075,7 @@ done_reading:
     {
       fclose(clone_info->file);
       clone_info->file = NULL;
-      (void) unlink(clone_info->filename);
+      (void) remove_utf8(clone_info->filename);
     }
     DestroyImageInfo(clone_info);
     clone_info = NULL;
@@ -1055,10 +1106,10 @@ done_reading:
 %
 %  The format of the RegisterMATImage method is:
 %
-%      unsigned long RegisterMATImage(void)
+%      size_t RegisterMATImage(void)
 %
 */
-ModuleExport unsigned long RegisterMATImage(void)
+ModuleExport size_t RegisterMATImage(void)
 {
   MagickInfo
     *entry;
@@ -1068,7 +1119,7 @@ ModuleExport unsigned long RegisterMATImage(void)
   entry->encoder=(EncodeImageHandler *) WriteMATImage;
   entry->blob_support=MagickFalse;
   entry->seekable_stream=MagickTrue;
-  entry->description=AcquireString("MATLAB image format");
+  entry->description=AcquireString("MATLAB level 5 image format");
   entry->module=AcquireString("MAT");
   (void) RegisterMagickInfo(entry);
   return(MagickImageCoderSignature);
@@ -1113,31 +1164,28 @@ ModuleExport void UnregisterMATImage(void)
 %
 %  The format of the WriteMATImage method is:
 %
-%      unsigned int WriteMATImage(const ImageInfo *image_info,Image *image)
+%      MagickBooleanType WriteMATImage(const ImageInfo *image_info,
+%        Image *image,ExceptionInfo *exception)
 %
 %  A description of each parameter follows.
 %
-%    o status: Function WriteMATImage return True if the image is written.
-%      False is returned is there is a memory shortage or if the image file
-%      fails to write.
-%
 %    o image_info: Specifies a pointer to a ImageInfo structure.
 %
 %    o image:  A pointer to an Image structure.
 %
+%    o exception: return any errors or warnings in this structure.
+%
 */
-static MagickBooleanType WriteMATImage(const ImageInfo *image_info,Image *image)
+static MagickBooleanType WriteMATImage(const ImageInfo *image_info,Image *image,
+  ExceptionInfo *exception)
 {
-  ExceptionInfo
-    *exception;
-
-  long y;
+  ssize_t y;
   unsigned z;
-  const PixelPacket *p;
+  register const Quantum *p;
 
   unsigned int status;
   int logging;
-  unsigned long DataSize;
+  size_t DataSize;
   char padding;
   char MATLAB_HDR[0x80];
   time_t current_time;
@@ -1159,7 +1207,10 @@ static MagickBooleanType WriteMATImage(const ImageInfo *image_info,Image *image)
   assert(image != (Image *) NULL);
   assert(image->signature == MagickSignature);
   logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter MAT");
-  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+  (void) logging;
+  assert(exception != (ExceptionInfo *) NULL);
+  assert(exception->signature == MagickSignature);
+  status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
   if (status == MagickFalse)
     return(MagickFalse);
   image->depth=8;
@@ -1171,7 +1222,8 @@ static MagickBooleanType WriteMATImage(const ImageInfo *image_info,Image *image)
   (void) memcpy(&local_time,localtime(&current_time),sizeof(local_time));
 #endif
   (void) memset(MATLAB_HDR,' ',MagickMin(sizeof(MATLAB_HDR),124));
-  FormatMagickString(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);
@@ -1183,10 +1235,8 @@ static MagickBooleanType WriteMATImage(const ImageInfo *image_info,Image *image)
   scene=0;
   do
   {
-    if (image->colorspace != RGBColorspace)
-      (void) TransformImageColorspace(image,RGBColorspace);
-
-    is_gray = IsGrayImage(image,&image->exception);
+    (void) TransformImageColorspace(image,sRGBColorspace,exception);
+    is_gray = IsImageGray(image,exception);
     z = is_gray ? 0 : 3;
 
     /*
@@ -1197,15 +1247,15 @@ static MagickBooleanType WriteMATImage(const ImageInfo *image_info,Image *image)
     padding=((unsigned char)(DataSize-1) & 0x7) ^ 0x7;
 
     (void) WriteBlobLSBLong(image, miMATRIX);
-    (void) WriteBlobLSBLong(image, DataSize+padding+(is_gray ? 48l : 56l));
+    (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, image->rows);    /* x: 0xA0 */  
-    (void) WriteBlobLSBLong(image, image->columns); /* y: 0xA4 */  
+    (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 */  
@@ -1215,28 +1265,27 @@ static MagickBooleanType WriteMATImage(const ImageInfo *image_info,Image *image)
     (void) WriteBlobLSBShort(image, 1);  /* 0xB2 */
     (void) WriteBlobLSBLong(image, 'M'); /* 0xB4 */
     (void) WriteBlobLSBLong(image, 0x2); /* 0xB8 */  
-    (void) WriteBlobLSBLong(image, DataSize); /* 0xBC */
+    (void) WriteBlobLSBLong(image, (unsigned int) DataSize); /* 0xBC */
 
     /*
       Store image data.
     */
-    exception=(&image->exception);
     quantum_info=AcquireQuantumInfo(image_info,image);
     if (quantum_info == (QuantumInfo *) NULL)
       ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
     pixels=GetQuantumPixels(quantum_info);
     do
     {
-      for (y=0; y < (long)image->columns; y++)
+      for (y=0; y < (ssize_t)image->columns; y++)
       {
-        p=GetVirtualPixels(image,y,0,1,image->rows,&image->exception);
-        if (p == (const PixelPacket *) NULL)
+        p=GetVirtualPixels(image,y,0,1,image->rows,exception);
+        if (p == (const Quantum *) NULL)
           break;
-        (void) ExportQuantumPixels(image,(const CacheView *) NULL,quantum_info,
+        (void) ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
           z2qtype[z],pixels,exception);
         (void) WriteBlob(image,image->rows,pixels);
       }    
-      if (!SyncAuthenticPixels(image,exception))
+      if (SyncAuthenticPixels(image,exception) == MagickFalse)
         break;
     } while(z-- >= 2);
     while(padding-->0) (void) WriteBlobByte(image,0);