]> granicus.if.org Git - imagemagick/blobdiff - magick/blob.c
(no commit message)
[imagemagick] / magick / blob.c
index 932d8004d9e226727e1fa456958838714f26bb56..98cd9fe7744aa30b22c5671e3b2fc66f1ef57b57 100644 (file)
@@ -17,7 +17,7 @@
 %                                 July 1999                                   %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2010 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2011 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  %
@@ -51,6 +51,7 @@
 #include "magick/exception-private.h"
 #include "magick/image-private.h"
 #include "magick/list.h"
+#include "magick/locale_.h"
 #include "magick/log.h"
 #include "magick/magick.h"
 #include "magick/memory_.h"
   Define declarations.
 */
 #define MagickMaxBlobExtent  65541
-#if defined(MAGICKCORE_HAVE_FSEEKO)
-# define fseek  fseeko
-# define ftell  ftello
-#endif
 #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
 # define MAP_ANONYMOUS  MAP_ANON
 #endif
@@ -227,7 +224,8 @@ MagickExport void AttachBlob(BlobInfo *blob_info,const void *blob,
 %
 */
 
-static inline size_t MagickMin(const size_t x,const size_t y)
+static inline MagickSizeType MagickMin(const MagickSizeType x,
+  const MagickSizeType y)
 {
   if (x < y)
     return(x);
@@ -260,8 +258,8 @@ MagickExport MagickBooleanType BlobToFile(char *filename,const void *blob,
     }
   for (i=0; i < length; i+=count)
   {
-    count=(ssize_t) write(file,(const char *) blob+i,MagickMin(length-i,(size_t)
-      SSIZE_MAX));
+    count=(ssize_t) write(file,(const char *) blob+i,(size_t) MagickMin(length-
+      i,(MagickSizeType) SSIZE_MAX));
     if (count <= 0)
       {
         count=0;
@@ -269,8 +267,8 @@ MagickExport MagickBooleanType BlobToFile(char *filename,const void *blob,
           break;
       }
   }
-  file=close(file)-1;
-  if (i < length)
+  file=close(file);
+  if ((file == -1) || (i < length))
     {
       ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
       return(MagickFalse);
@@ -380,7 +378,7 @@ MagickExport Image *BlobToImage(const ImageInfo *image_info,const void *blob,
       return((Image *) NULL);
     }
   clone_info=CloneImageInfo(blob_info);
-  (void) FormatMagickString(clone_info->filename,MaxTextExtent,"%s:%s",
+  (void) FormatLocaleString(clone_info->filename,MaxTextExtent,"%s:%s",
     blob_info->magick,blob_info->filename);
   image=ReadImage(clone_info,exception);
   clone_info=DestroyImageInfo(clone_info);
@@ -417,7 +415,7 @@ MagickExport BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
   BlobInfo
     *clone_info;
 
-  clone_info=(BlobInfo *) AcquireAlignedMemory(1,sizeof(*clone_info));
+  clone_info=(BlobInfo *) AcquireMagickMemory(sizeof(*clone_info));
   if (clone_info == (BlobInfo *) NULL)
     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
   GetBlobInfo(clone_info);
@@ -530,7 +528,10 @@ MagickExport MagickBooleanType CloseBlob(Image *image)
     case StandardStream:
     {
       if (image->blob->synchronize != MagickFalse)
-        status=fsync(fileno(image->blob->file));
+        {
+          status=fflush(image->blob->file);
+          status=fsync(fileno(image->blob->file));
+        }
       status=fclose(image->blob->file);
       break;
     }
@@ -556,8 +557,17 @@ MagickExport MagickBooleanType CloseBlob(Image *image)
       break;
     }
     case FifoStream:
+      break;
     case BlobStream:
+    {
+      if (image->blob->file != (FILE *) NULL)
+        {
+          if (image->blob->synchronize != MagickFalse)
+            (void) fsync(fileno(image->blob->file));
+          status=fclose(image->blob->file);
+        }
       break;
+    }
   }
   (void) DetachBlob(image->blob);
   image->blob->status=status < 0 ? MagickTrue : MagickFalse;
@@ -665,6 +675,88 @@ MagickExport unsigned char *DetachBlob(BlobInfo *blob_info)
 %                                                                             %
 %                                                                             %
 %                                                                             %
++  D i s c a r d B l o b B y t e s                                            %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  DiscardBlobBytes() discards bytes in a blob.
+%
+%  The format of the DiscardBlobBytes method is:
+%
+%      MagickBooleanType DiscardBlobBytes(Image *image,const size_t length)
+%
+%  A description of each parameter follows.
+%
+%    o image: the image.
+%
+%    o length:  the number of bytes to skip.
+%
+*/
+
+static inline const unsigned char *ReadBlobStream(Image *image,
+  const size_t length,unsigned char *data,ssize_t *count)
+{
+  assert(count != (ssize_t *) NULL);
+  assert(image->blob != (BlobInfo *) NULL);
+  if (image->blob->type != BlobStream)
+    {
+      *count=ReadBlob(image,length,data);
+      return(data);
+    }
+  if (image->blob->offset >= (MagickOffsetType) image->blob->length)
+    {
+      *count=0;
+      image->blob->eof=MagickTrue;
+      return(data);
+    }
+  data=image->blob->data+image->blob->offset;
+  *count=(ssize_t) MagickMin(length,(MagickSizeType) (image->blob->length-
+    image->blob->offset));
+  image->blob->offset+=(*count);
+  if (*count != (ssize_t) length)
+    image->blob->eof=MagickTrue;
+  return(data);
+}
+
+MagickExport MagickBooleanType DiscardBlobBytes(Image *image,
+  const MagickSizeType length)
+{
+  register MagickOffsetType
+    i;
+
+  size_t
+    quantum;
+
+  ssize_t
+    count;
+
+  unsigned char
+    buffer[16384];
+
+  assert(image != (Image *) NULL);
+  assert(image->signature == MagickSignature);
+  count=0;
+  for (i=0; i < (MagickOffsetType) length; i+=count)
+  {
+    quantum=(size_t) MagickMin(length-i,sizeof(buffer));
+    (void) ReadBlobStream(image,quantum,buffer,&count);
+    if (count <= 0)
+      {
+        count=0;
+        if (errno != EINTR)
+          break;
+      }
+  }
+  return(i < (MagickOffsetType) length ? MagickFalse : MagickTrue);
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
 +   D u p l i c a t e s B l o b                                               %
 %                                                                             %
 %                                                                             %
@@ -777,8 +869,10 @@ MagickExport int EOFBlob(const Image *image)
 %                                                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
-%  FileToBlob() returns the contents of a file as a blob.  It returns the
-%  file as a blob and its length.  If an error occurs, NULL is returned.
+%  FileToBlob() returns the contents of a file as a buffer terminated with
+%  the '\0' character.  The length of the buffer (not including the extra
+%  terminating '\0' character) is returned via the 'length' parameter.  Free
+%  the buffer with RelinquishMagickMemory().
 %
 %  The format of the FileToBlob method is:
 %
@@ -832,7 +926,7 @@ MagickExport unsigned char *FileToBlob(const char *filename,const size_t extent,
       ThrowFileException(exception,BlobError,"UnableToOpenFile",filename);
       return((unsigned char *) NULL);
     }
-  offset=(MagickOffsetType) MagickSeek(file,0,SEEK_END);
+  offset=(MagickOffsetType) lseek(file,0,SEEK_END);
   count=0;
   if ((offset < 0) || (offset != (MagickOffsetType) ((ssize_t) offset)))
     {
@@ -847,7 +941,8 @@ MagickExport unsigned char *FileToBlob(const char *filename,const size_t extent,
       */
       quantum=(size_t) MagickMaxBufferExtent;
       if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
-        quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
+        quantum=(size_t) MagickMin((MagickSizeType) file_info.st_size,
+          MagickMaxBufferExtent);
       blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
       for (i=0; blob != (unsigned char *) NULL; i+=count)
       {
@@ -868,25 +963,32 @@ MagickExport unsigned char *FileToBlob(const char *filename,const size_t extent,
         if ((size_t) (i+count) >= extent)
           break;
       }
-      file=close(file)-1;
+      if (LocaleCompare(filename,"-") != 0)
+        file=close(file);
       if (blob == (unsigned char *) NULL)
         {
           (void) ThrowMagickException(exception,GetMagickModule(),
             ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
           return((unsigned char *) NULL);
         }
-      *length=MagickMin(i+count,extent);
+      if (file == -1)
+        {
+          blob=(unsigned char *) RelinquishMagickMemory(blob);
+          ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
+          return((unsigned char *) NULL);
+        }
+      *length=(size_t) MagickMin(i+count,extent);
       blob[*length]='\0';
       return(blob);
     }
-  *length=MagickMin((size_t) offset,extent);
+  *length=(size_t) MagickMin((MagickSizeType) offset,extent);
   blob=(unsigned char *) NULL;
-  if (~(*length) >= MaxTextExtent)
+  if (~(*length) >= (MaxTextExtent-1))
     blob=(unsigned char *) AcquireQuantumMemory(*length+MaxTextExtent,
       sizeof(*blob));
   if (blob == (unsigned char *) NULL)
     {
-      file=close(file)-1;
+      file=close(file);
       (void) ThrowMagickException(exception,GetMagickModule(),
         ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
       return((unsigned char *) NULL);
@@ -894,16 +996,16 @@ MagickExport unsigned char *FileToBlob(const char *filename,const size_t extent,
   map=MapBlob(file,ReadMode,0,*length);
   if (map != (unsigned char *) NULL)
     {
-      (void) CopyMagickMemory(blob,map,*length);
+      (void) memcpy(blob,map,*length);
       (void) UnmapBlob(map,*length);
     }
   else
     {
-      (void) MagickSeek(file,0,SEEK_SET);
+      (void) lseek(file,0,SEEK_SET);
       for (i=0; i < *length; i+=count)
       {
-        count=(ssize_t) read(file,blob+i,MagickMin(*length-i,(size_t)
-          SSIZE_MAX));
+        count=(ssize_t) read(file,blob+i,(size_t) MagickMin(*length-i,
+          (MagickSizeType) SSIZE_MAX));
         if (count <= 0)
           {
             count=0;
@@ -919,8 +1021,14 @@ MagickExport unsigned char *FileToBlob(const char *filename,const size_t extent,
           return((unsigned char *) NULL);
         }
     }
-  file=close(file)-1;
   blob[*length]='\0';
+  if (LocaleCompare(filename,"-") != 0)
+    file=close(file);
+  if (file == -1)
+    {
+      blob=(unsigned char *) RelinquishMagickMemory(blob);
+      ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
+    }
   return(blob);
 }
 \f
@@ -972,7 +1080,7 @@ static inline ssize_t WriteBlobStream(Image *image,const size_t length,
         return(0);
     }
   q=image->blob->data+image->blob->offset;
-  (void) CopyMagickMemory(q,data,length);
+  (void) memcpy(q,data,length);
   image->blob->offset+=length;
   if (image->blob->offset >= (MagickOffsetType) image->blob->length)
     image->blob->length=(size_t) image->blob->offset;
@@ -1010,7 +1118,7 @@ MagickExport MagickBooleanType FileToImage(Image *image,const char *filename)
     }
   quantum=(size_t) MagickMaxBufferExtent;
   if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
-    quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
+    quantum=(size_t) MagickMin(file_info.st_size,MagickMaxBufferExtent);
   blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
   if (blob == (unsigned char *) NULL)
     {
@@ -1036,7 +1144,10 @@ MagickExport MagickBooleanType FileToImage(Image *image,const char *filename)
         break;
       }
   }
-  file=close(file)-1;
+  file=close(file);
+  if (file == -1)
+    ThrowFileException(&image->exception,BlobError,"UnableToWriteBlob",
+      filename);
   blob=(unsigned char *) RelinquishMagickMemory(blob);
   return(MagickTrue);
 }
@@ -1316,8 +1427,10 @@ MagickExport StreamHandler GetBlobStreamHandler(const Image *image)
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
 %  ImageToBlob() implements direct to memory image formats.  It returns the
-%  image as a blob and its length.  The magick member of the ImageInfo structure
-%  determines the format of the returned blob (GIF, JPEG,  PNG, etc.)
+%  image as a formatted blob and its length.  The magick member of the Image
+%  structure determines the format of the returned blob (GIF, JPEG, PNG,
+%  etc.).  This method is the equivalent of WriteImage(), but writes the
+%  formatted "file" to a memory buffer rather than to an actual file.
 %
 %  The format of the ImageToBlob method is:
 %
@@ -1425,7 +1538,7 @@ MagickExport unsigned char *ImageToBlob(const ImageInfo *image_info,
           blob_info->file=fdopen(file,"wb");
           if (blob_info->file != (FILE *) NULL)
             {
-              (void) FormatMagickString(image->filename,MaxTextExtent,"%s:%s",
+              (void) FormatLocaleString(image->filename,MaxTextExtent,"%s:%s",
                 image->magick,unique);
               status=WriteImage(blob_info,image);
               (void) fclose(blob_info->file);
@@ -1469,32 +1582,6 @@ MagickExport unsigned char *ImageToBlob(const ImageInfo *image_info,
 %    o exception: return any errors or warnings in this structure.
 %
 */
-
-static inline const unsigned char *ReadBlobStream(Image *image,
-  const size_t length,unsigned char *data,ssize_t *count)
-{
-  assert(count != (ssize_t *) NULL);
-  assert(image->blob != (BlobInfo *) NULL);
-  if (image->blob->type != BlobStream)
-    {
-      *count=ReadBlob(image,length,data);
-      return(data);
-    }
-  if (image->blob->offset >= (MagickOffsetType) image->blob->length)
-    {
-      *count=0;
-      image->blob->eof=MagickTrue;
-      return(data);
-    }
-  data=image->blob->data+image->blob->offset;
-  *count=(ssize_t) MagickMin(length,(size_t) (image->blob->length-
-    image->blob->offset));
-  image->blob->offset+=(*count);
-  if (*count != (ssize_t) length)
-    image->blob->eof=MagickTrue;
-  return(data);
-}
-
 MagickExport MagickBooleanType ImageToFile(Image *image,char *filename,
   ExceptionInfo *exception)
 {
@@ -1541,7 +1628,8 @@ MagickExport MagickBooleanType ImageToFile(Image *image,char *filename,
     }
   quantum=(size_t) MagickMaxBufferExtent;
   if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
-    quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
+    quantum=(size_t) MagickMin((MagickSizeType) file_info.st_size,
+      MagickMaxBufferExtent);
   buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
   if (buffer == (unsigned char *) NULL)
     {
@@ -1568,9 +1656,10 @@ MagickExport MagickBooleanType ImageToFile(Image *image,char *filename,
     if (i < length)
       break;
   }
-  file=close(file)-1;
+  if (LocaleCompare(filename,"-") != 0)
+    file=close(file);
   buffer=(unsigned char *) RelinquishMagickMemory(buffer);
-  if (i < length)
+  if ((file == -1) || (i < length))
     {
       ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
       return(MagickFalse);
@@ -1708,7 +1797,7 @@ MagickExport unsigned char *ImagesToBlob(const ImageInfo *image_info,
           blob_info->file=fdopen(file,"wb");
           if (blob_info->file != (FILE *) NULL)
             {
-              (void) FormatMagickString(filename,MaxTextExtent,"%s:%s",
+              (void) FormatLocaleString(filename,MaxTextExtent,"%s:%s",
                 images->magick,unique);
               status=WriteImages(blob_info,images,filename,exception);
               (void) fclose(blob_info->file);
@@ -1822,7 +1911,7 @@ MagickExport MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
       (void) RelinquishUniqueFileResource(filename);
       return(MagickFalse);
     }
-  (void) FormatMagickString(byte_image->filename,MaxTextExtent,"%s:%s",format,
+  (void) FormatLocaleString(byte_image->filename,MaxTextExtent,"%s:%s",format,
     filename);
   DestroyBlob(byte_image);
   byte_image->blob=CloneBlobInfo((BlobInfo *) NULL);
@@ -1850,7 +1939,7 @@ MagickExport MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
     }
   quantum=(size_t) MagickMaxBufferExtent;
   if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
-    quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
+    quantum=(size_t) MagickMin(file_info.st_size,MagickMaxBufferExtent);
   buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
   if (buffer == (unsigned char *) NULL)
     {
@@ -1870,7 +1959,9 @@ MagickExport MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
     status=WriteBlobStream(image,(size_t) count,buffer) == count ? MagickTrue :
       MagickFalse;
   }
-  file=close(file)-1;
+  file=close(file);
+  if (file == -1)
+    ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",filename);
   (void) RelinquishUniqueFileResource(filename);
   buffer=(unsigned char *) RelinquishMagickMemory(buffer);
   return(status);
@@ -2197,6 +2288,7 @@ MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
   Image *image,const BlobMode mode,ExceptionInfo *exception)
 {
   char
+    extension[MaxTextExtent],
     filename[MaxTextExtent];
 
   const char
@@ -2328,11 +2420,12 @@ MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
       return(MagickTrue);
     }
 #endif
+  GetPathComponent(image->filename,ExtensionPath,extension);
   if (*type == 'w')
     {
       (void) CopyMagickString(filename,image->filename,MaxTextExtent);
       if ((image_info->adjoin == MagickFalse) ||
-          (IsGlob(filename) != MagickFalse))
+          (strchr(filename,'%') != (char *) NULL))
         {
           /*
             Form filename for multi-part images.
@@ -2344,17 +2437,15 @@ MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
                (GetNextImageInList(image) != (Image *) NULL)))
             {
               char
-                extension[MaxTextExtent],
                 path[MaxTextExtent];
 
               GetPathComponent(image->filename,RootPath,path);
-              GetPathComponent(image->filename,ExtensionPath,extension);
               if (*extension == '\0')
-                (void) FormatMagickString(filename,MaxTextExtent,"%s-%lu",
-                  path,(unsigned long) image->scene);
+                (void) FormatLocaleString(filename,MaxTextExtent,"%s-%.20g",
+                  path,(double) image->scene);
               else
-                (void) FormatMagickString(filename,MaxTextExtent,
-                  "%s-%lu.%s",path,(unsigned long) image->scene,extension);
+                (void) FormatLocaleString(filename,MaxTextExtent,"%s-%.20g.%s",
+                  path,(double) image->scene,extension);
             }
           (void) CopyMagickString(image->filename,filename,MaxTextExtent);
 #if defined(macintosh)
@@ -2362,127 +2453,133 @@ MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
 #endif
         }
     }
-#if defined(MAGICKCORE_ZLIB_DELEGATE)
-  if (((strlen(filename) > 2) &&
-       (LocaleCompare(filename+strlen(filename)-2,".Z") == 0)) ||
-      ((strlen(filename) > 3) &&
-       (LocaleCompare(filename+strlen(filename)-3,".gz") == 0)) ||
-      ((strlen(filename) > 4) &&
-       (LocaleCompare(filename+strlen(filename)-4,".wmz") == 0)) ||
-      ((strlen(filename) > 5) &&
-       (LocaleCompare(filename+strlen(filename)-5,".svgz") == 0)))
+  if (image_info->file != (FILE *) NULL)
     {
-      image->blob->file=(FILE *) gzopen(filename,type);
-      if (image->blob->file != (FILE *) NULL)
-        image->blob->type=ZipStream;
+      image->blob->file=image_info->file;
+      image->blob->type=FileStream;
+      image->blob->exempt=MagickTrue;
     }
   else
-#endif
-#if defined(MAGICKCORE_BZLIB_DELEGATE)
-    if ((strlen(filename) > 4) &&
-        (LocaleCompare(filename+strlen(filename)-4,".bz2") == 0))
+    if (*type == 'r')
       {
-        image->blob->file=(FILE *) BZ2_bzopen(filename,type);
+        image->blob->file=(FILE *) OpenMagickStream(filename,type);
         if (image->blob->file != (FILE *) NULL)
-          image->blob->type=BZipStream;
-      }
-    else
-#endif
-      if (image_info->file != (FILE *) NULL)
-        {
-          image->blob->file=image_info->file;
-          image->blob->type=FileStream;
-          image->blob->exempt=MagickTrue;
-        }
-      else
-        {
-          image->blob->file=(FILE *) OpenMagickStream(filename,type);
-          if (image->blob->file != (FILE *) NULL)
-            {
-              image->blob->type=FileStream;
-#if defined(MAGICKCORE_HAVE_SETVBUF)
-              (void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF,
-                16384);
-#endif
-              if (*type == 'r')
-                {
-                  size_t
-                    count;
+          {
+            size_t
+              count;
 
-                  unsigned char
-                    magick[3];
+            unsigned char
+              magick[3];
 
-                  (void) ResetMagickMemory(magick,0,sizeof(magick));
-                  count=fread(magick,1,sizeof(magick),image->blob->file);
-                  (void) rewind(image->blob->file);
-                  (void) LogMagickEvent(BlobEvent,GetMagickModule(),
-                     "  read %lu magic header bytes",(unsigned long) count);
+            image->blob->type=FileStream;
+#if defined(MAGICKCORE_HAVE_SETVBUF)
+            (void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF,16384);
+#endif
+            (void) ResetMagickMemory(magick,0,sizeof(magick));
+            count=fread(magick,1,sizeof(magick),image->blob->file);
+            (void) rewind(image->blob->file);
+            (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+               "  read %.20g magic header bytes",(double) count);
 #if defined(MAGICKCORE_ZLIB_DELEGATE)
-                  if (((int) magick[0] == 0x1F) && ((int) magick[1] == 0x8B) &&
-                      ((int) magick[2] == 0x08))
-                    {
-                      (void) fclose(image->blob->file);
-                      image->blob->file=(FILE *) gzopen(filename,type);
-                      if (image->blob->file != (FILE *) NULL)
-                        image->blob->type=ZipStream;
-                     }
+            if (((int) magick[0] == 0x1F) && ((int) magick[1] == 0x8B) &&
+                ((int) magick[2] == 0x08))
+              {
+                (void) fclose(image->blob->file);
+                image->blob->file=(FILE *) gzopen(filename,type);
+                if (image->blob->file != (FILE *) NULL)
+                  image->blob->type=ZipStream;
+               }
 #endif
 #if defined(MAGICKCORE_BZLIB_DELEGATE)
-                  if (strncmp((char *) magick,"BZh",3) == 0)
-                    {
-                      (void) fclose(image->blob->file);
-                      image->blob->file=(FILE *) BZ2_bzopen(filename,type);
-                      if (image->blob->file != (FILE *) NULL)
-                        image->blob->type=BZipStream;
-                    }
+            if (strncmp((char *) magick,"BZh",3) == 0)
+              {
+                (void) fclose(image->blob->file);
+                image->blob->file=(FILE *) BZ2_bzopen(filename,type);
+                if (image->blob->file != (FILE *) NULL)
+                  image->blob->type=BZipStream;
+              }
 #endif
-                }
-            }
-        }
-    if ((image->blob->type == FileStream) && (*type == 'r'))
-      {
-        const MagickInfo
-          *magick_info;
-
-        ExceptionInfo
-          *sans_exception;
-
-        struct stat
-          *properties;
-
-        sans_exception=AcquireExceptionInfo();
-        magick_info=GetMagickInfo(image_info->magick,sans_exception);
-        sans_exception=DestroyExceptionInfo(sans_exception);
-        properties=(&image->blob->properties);
-        if ((magick_info != (const MagickInfo *) NULL) &&
-            (GetMagickBlobSupport(magick_info) != MagickFalse) &&
-            (properties->st_size <= MagickMaxBufferExtent))
-          {
-            size_t
-              length;
-
-            void
-              *blob;
-
-            length=(size_t) properties->st_size;
-            blob=MapBlob(fileno(image->blob->file),ReadMode,0,length);
-            if (blob != (void *) NULL)
+            if (image->blob->type == FileStream)
               {
-                /*
-                  Format supports blobs-- use memory-mapped I/O.
-                */
-                if (image_info->file != (FILE *) NULL)
-                  image->blob->exempt=MagickFalse;
-                else
+                const MagickInfo
+                  *magick_info;
+
+                ExceptionInfo
+                  *sans_exception;
+
+                struct stat
+                  *properties;
+
+                sans_exception=AcquireExceptionInfo();
+                magick_info=GetMagickInfo(image_info->magick,sans_exception);
+                sans_exception=DestroyExceptionInfo(sans_exception);
+                properties=(&image->blob->properties);
+                if ((magick_info != (const MagickInfo *) NULL) &&
+                    (GetMagickBlobSupport(magick_info) != MagickFalse) &&
+                    (properties->st_size <= MagickMaxBufferExtent))
                   {
-                    (void) fclose(image->blob->file);
-                    image->blob->file=(FILE *) NULL;
+                    size_t
+                      length;
+
+                    void
+                      *blob;
+
+                    length=(size_t) properties->st_size;
+                    blob=MapBlob(fileno(image->blob->file),ReadMode,0,length);
+                    if (blob != (void *) NULL)
+                      {
+                        /*
+                          Format supports blobs-- use memory-mapped I/O.
+                        */
+                        if (image_info->file != (FILE *) NULL)
+                          image->blob->exempt=MagickFalse;
+                        else
+                          {
+                            (void) fclose(image->blob->file);
+                            image->blob->file=(FILE *) NULL;
+                          }
+                        AttachBlob(image->blob,blob,length);
+                        image->blob->mapped=MagickTrue;
+                      }
                   }
-                AttachBlob(image->blob,blob,length);
-                image->blob->mapped=MagickTrue;
               }
           }
-      }
+        }
+      else
+#if defined(MAGICKCORE_ZLIB_DELEGATE)
+        if ((LocaleCompare(extension,"Z") == 0) ||
+            (LocaleCompare(extension,"gz") == 0) ||
+            (LocaleCompare(extension,"wmz") == 0) ||
+            (LocaleCompare(extension,"svgz") == 0))
+          {
+            if (mode == WriteBinaryBlobMode)
+              type="wb";
+            image->blob->file=(FILE *) gzopen(filename,type);
+            if (image->blob->file != (FILE *) NULL)
+              image->blob->type=ZipStream;
+          }
+        else
+#endif
+#if defined(MAGICKCORE_BZLIB_DELEGATE)
+          if (LocaleCompare(extension,".bz2") == 0)
+            {
+              image->blob->file=(FILE *) BZ2_bzopen(filename,type);
+              if (image->blob->file != (FILE *) NULL)
+                image->blob->type=BZipStream;
+            }
+          else
+#endif
+            {
+              image->blob->file=(FILE *) OpenMagickStream(filename,type);
+              if (image->blob->file != (FILE *) NULL)
+                {
+                  image->blob->type=FileStream;
+#if defined(MAGICKCORE_HAVE_SETVBUF)
+                  (void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF,
+                    16384);
+#endif
+                }
+       }
   image->blob->status=MagickFalse;
   if (image->blob->type != UndefinedStream)
     image->blob->size=GetBlobSize(image);
@@ -2571,7 +2668,7 @@ MagickExport Image *PingBlob(const ImageInfo *image_info,const void *blob,
         ResourceLimitFatalError,"MemoryAllocationFailed","`%s'","");
       return((Image *) NULL);
     }
-  (void) CopyMagickMemory(ping_info->blob,blob,length);
+  (void) memcpy(ping_info->blob,blob,length);
   ping_info->length=length;
   ping_info->ping=MagickTrue;
   image=ReadStream(ping_info,&PingStream,exception);
@@ -2718,12 +2815,11 @@ MagickExport ssize_t ReadBlob(Image *image,const size_t length,
           break;
         }
       p=image->blob->data+image->blob->offset;
-      count=(ssize_t) MagickMin(length,(size_t) (image->blob->length-
-        image->blob->offset));
+      count=(ssize_t) MagickMin(length,image->blob->length-image->blob->offset);
       image->blob->offset+=count;
       if (count != (ssize_t) length)
         image->blob->eof=MagickTrue;
-      (void) CopyMagickMemory(q,p,(size_t) count);
+      (void) memcpy(q,p,(size_t) count);
       break;
     }
   }
@@ -2918,12 +3014,12 @@ MagickExport unsigned int ReadBlobLong(Image *image)
 %                                                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
-%  ReadBlobLongLong() reads a ssize_t value as a 64-bit quantity in the byte-order
-%  specified by the endian member of the image structure.
+%  ReadBlobLongLong() reads a long long value as a 64-bit quantity in the
+%  byte-order specified by the endian member of the image structure.
 %
-%  The format of the ReadBlobLong method is:
+%  The format of the ReadBlobLongLong method is:
 %
-%      MagickSizeType ReadBlobLong(Image *image)
+%      MagickSizeType ReadBlobLongLong(Image *image)
 %
 %  A description of each parameter follows.
 %
@@ -2932,6 +3028,9 @@ MagickExport unsigned int ReadBlobLong(Image *image)
 */
 MagickExport MagickSizeType ReadBlobLongLong(Image *image)
 {
+  MagickSizeType
+    value;
+
   register const unsigned char
     *p;
 
@@ -2941,9 +3040,6 @@ MagickExport MagickSizeType ReadBlobLongLong(Image *image)
   unsigned char
     buffer[8];
 
-  MagickSizeType
-    value;
-
   assert(image != (Image *) NULL);
   assert(image->signature == MagickSignature);
   *buffer='\0';
@@ -3210,7 +3306,7 @@ MagickExport MagickSizeType ReadBlobMSBLongLong(Image *image)
     count;
 
   unsigned char
-    buffer[4];
+    buffer[8];
 
   assert(image != (Image *) NULL);
   assert(image->signature == MagickSignature);
@@ -3328,9 +3424,11 @@ MagickExport char *ReadBlobString(Image *image,char *string)
         break;
       }
     string[i]=(char) (*p);
-    if ((string[i] == '\n') || (string[i] == '\r'))
+    if ((string[i] == '\r') || (string[i] == '\n'))
       break;
   }
+  if (string[i] == '\r')
+    (void) ReadBlobStream(image,1,buffer,&count);
   string[i]='\0';
   return(string);
 }
@@ -3974,7 +4072,7 @@ MagickExport ssize_t WriteBlob(Image *image,const size_t length,
             }
         }
       q=image->blob->data+image->blob->offset;
-      (void) CopyMagickMemory(q,p,length);
+      (void) memcpy(q,p,length);
       image->blob->offset+=length;
       if (image->blob->offset >= (MagickOffsetType) image->blob->length)
         image->blob->length=(size_t) image->blob->offset;