]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/blob.c
(no commit message)
[imagemagick] / MagickCore / blob.c
index f697e9ea9787c549676c3bae25e40ab260e19e54..3abb8ba9859e116735952dd40a9ac46924b5d1ed 100644 (file)
@@ -56,6 +56,7 @@
 #include "MagickCore/magick.h"
 #include "MagickCore/memory_.h"
 #include "MagickCore/nt-base-private.h"
+#include "MagickCore/option.h"
 #include "MagickCore/policy.h"
 #include "MagickCore/resource_.h"
 #include "MagickCore/semaphore.h"
@@ -74,7 +75,7 @@
 /*
   Define declarations.
 */
-#define MagickMaxBlobExtent  65541
+#define MagickMaxBlobExtent  (8*8192)
 #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
 # define MAP_ANONYMOUS  MAP_ANON
 #endif
@@ -140,7 +141,7 @@ struct _BlobInfo
   StreamHandler
     stream;
 
-  void
+  unsigned char
     *data;
 
   MagickBooleanType
@@ -358,9 +359,9 @@ MagickExport Image *BlobToImage(const ImageInfo *image_info,const void *blob,
         Native blob support for this image format.
       */
       (void) CopyMagickString(blob_info->filename,image_info->filename,
-        MaxTextExtent);
+        MagickPathExtent);
       (void) CopyMagickString(blob_info->magick,image_info->magick,
-        MaxTextExtent);
+        MagickPathExtent);
       image=ReadImage(blob_info,exception);
       if (image != (Image *) NULL)
         (void) DetachBlob(image->blob);
@@ -381,7 +382,7 @@ MagickExport Image *BlobToImage(const ImageInfo *image_info,const void *blob,
       return((Image *) NULL);
     }
   clone_info=CloneImageInfo(blob_info);
-  (void) FormatLocaleString(clone_info->filename,MaxTextExtent,"%s:%s",
+  (void) FormatLocaleString(clone_info->filename,MagickPathExtent,"%s:%s",
     blob_info->magick,blob_info->filename);
   image=ReadImage(clone_info,exception);
   if (image != (Image *) NULL)
@@ -395,11 +396,11 @@ MagickExport Image *BlobToImage(const ImageInfo *image_info,const void *blob,
       for (images=GetFirstImageInList(image); images != (Image *) NULL; )
       {
         (void) CopyMagickString(images->filename,image_info->filename,
-          MaxTextExtent);
+          MagickPathExtent);
         (void) CopyMagickString(images->magick_filename,image_info->filename,
-          MaxTextExtent);
+          MagickPathExtent);
         (void) CopyMagickString(images->magick,magick_info->name,
-          MaxTextExtent);
+          MagickPathExtent);
         images=GetNextImageInList(images);
       }
     }
@@ -683,7 +684,7 @@ MagickExport void *DetachBlob(BlobInfo *blob_info)
   if (blob_info->mapped != MagickFalse)
     {
       (void) UnmapBlob(blob_info->data,blob_info->length);
-      blob_info->data=(void *) NULL;
+      blob_info->data=(unsigned char *) NULL;
       RelinquishMagickResource(MapResource,blob_info->length);
     }
   blob_info->mapped=MagickFalse;
@@ -1041,8 +1042,8 @@ MagickExport void *FileToBlob(const char *filename,const size_t extent,
     }
   *length=(size_t) MagickMin((MagickSizeType) offset,extent);
   blob=(unsigned char *) NULL;
-  if (~(*length) >= (MaxTextExtent-1))
-    blob=(unsigned char *) AcquireQuantumMemory(*length+MaxTextExtent,
+  if (~(*length) >= (MagickPathExtent-1))
+    blob=(unsigned char *) AcquireQuantumMemory(*length+MagickPathExtent,
       sizeof(*blob));
   if (blob == (unsigned char *) NULL)
     {
@@ -1116,7 +1117,7 @@ MagickExport void *FileToBlob(const char *filename,const size_t extent,
 */
 
 static inline ssize_t WriteBlobStream(Image *image,const size_t length,
-  const unsigned char *data)
+  const void *data)
 {
   MagickSizeType
     extent;
@@ -1125,10 +1126,10 @@ static inline ssize_t WriteBlobStream(Image *image,const size_t length,
     *q;
 
   assert(image->blob != (BlobInfo *) NULL);
+  assert(image->blob->type != UndefinedStream);
+  assert(data != NULL);
   if (image->blob->type != BlobStream)
     return(WriteBlob(image,length,data));
-  assert(image->blob->type != UndefinedStream);
-  assert(data != (void *) NULL);
   extent=(MagickSizeType) (image->blob->offset+(MagickOffsetType) length);
   if (extent >= image->blob->extent)
     {
@@ -1541,7 +1542,7 @@ MagickExport void *ImageToBlob(const ImageInfo *image_info,
   blob_info->adjoin=MagickFalse;
   (void) SetImageInfo(blob_info,1,exception);
   if (*blob_info->magick != '\0')
-    (void) CopyMagickString(image->magick,blob_info->magick,MaxTextExtent);
+    (void) CopyMagickString(image->magick,blob_info->magick,MagickPathExtent);
   magick_info=GetMagickInfo(image->magick,exception);
   if (magick_info == (const MagickInfo *) NULL)
     {
@@ -1551,7 +1552,7 @@ MagickExport void *ImageToBlob(const ImageInfo *image_info,
       blob_info=DestroyImageInfo(blob_info);
       return(blob);
     }
-  (void) CopyMagickString(blob_info->magick,image->magick,MaxTextExtent);
+  (void) CopyMagickString(blob_info->magick,image->magick,MagickPathExtent);
   if (GetMagickBlobSupport(magick_info) != MagickFalse)
     {
       /*
@@ -1581,7 +1582,7 @@ MagickExport void *ImageToBlob(const ImageInfo *image_info,
   else
     {
       char
-        unique[MaxTextExtent];
+        unique[MagickPathExtent];
 
       int
         file;
@@ -1600,7 +1601,7 @@ MagickExport void *ImageToBlob(const ImageInfo *image_info,
           blob_info->file=fdopen(file,"wb");
           if (blob_info->file != (FILE *) NULL)
             {
-              (void) FormatLocaleString(image->filename,MaxTextExtent,"%s:%s",
+              (void) FormatLocaleString(image->filename,MagickPathExtent,"%s:%s",
                 image->magick,unique);
               status=WriteImage(blob_info,image,exception);
               (void) CloseBlob(image);
@@ -1794,7 +1795,7 @@ MagickExport void *ImagesToBlob(const ImageInfo *image_info,Image *images,
   (void) SetImageInfo(blob_info,(unsigned int) GetImageListLength(images),
     exception);
   if (*blob_info->magick != '\0')
-    (void) CopyMagickString(images->magick,blob_info->magick,MaxTextExtent);
+    (void) CopyMagickString(images->magick,blob_info->magick,MagickPathExtent);
   magick_info=GetMagickInfo(images->magick,exception);
   if (magick_info == (const MagickInfo *) NULL)
     {
@@ -1809,7 +1810,7 @@ MagickExport void *ImagesToBlob(const ImageInfo *image_info,Image *images,
       blob_info=DestroyImageInfo(blob_info);
       return(ImageToBlob(image_info,images,length,exception));
     }
-  (void) CopyMagickString(blob_info->magick,images->magick,MaxTextExtent);
+  (void) CopyMagickString(blob_info->magick,images->magick,MagickPathExtent);
   if (GetMagickBlobSupport(magick_info) != MagickFalse)
     {
       /*
@@ -1839,8 +1840,8 @@ MagickExport void *ImagesToBlob(const ImageInfo *image_info,Image *images,
   else
     {
       char
-        filename[MaxTextExtent],
-        unique[MaxTextExtent];
+        filename[MagickPathExtent],
+        unique[MagickPathExtent];
 
       int
         file;
@@ -1859,7 +1860,7 @@ MagickExport void *ImagesToBlob(const ImageInfo *image_info,Image *images,
           blob_info->file=fdopen(file,"wb");
           if (blob_info->file != (FILE *) NULL)
             {
-              (void) FormatLocaleString(filename,MaxTextExtent,"%s:%s",
+              (void) FormatLocaleString(filename,MagickPathExtent,"%s:%s",
                 images->magick,unique);
               status=WriteImages(blob_info,images,filename,exception);
               (void) CloseBlob(images);
@@ -1910,7 +1911,7 @@ MagickExport MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
   Image *image,Image *inject_image,const char *format,ExceptionInfo *exception)
 {
   char
-    filename[MaxTextExtent];
+    filename[MagickPathExtent];
 
   FILE
     *unique_file;
@@ -1960,7 +1961,7 @@ MagickExport MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
     unique_file=fdopen(file,"wb");
   if ((file == -1) || (unique_file == (FILE *) NULL))
     {
-      (void) CopyMagickString(image->filename,filename,MaxTextExtent);
+      (void) CopyMagickString(image->filename,filename,MagickPathExtent);
       ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
         image->filename);
       return(MagickFalse);
@@ -1972,7 +1973,7 @@ MagickExport MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
       (void) RelinquishUniqueFileResource(filename);
       return(MagickFalse);
     }
-  (void) FormatLocaleString(byte_image->filename,MaxTextExtent,"%s:%s",format,
+  (void) FormatLocaleString(byte_image->filename,MagickPathExtent,"%s:%s",format,
     filename);
   DestroyBlob(byte_image);
   byte_image->blob=CloneBlobInfo((BlobInfo *) NULL);
@@ -1994,7 +1995,6 @@ MagickExport MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
   if (file == -1)
     {
       (void) RelinquishUniqueFileResource(filename);
-      file=close(file);
       ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
         image_info->filename);
       return(MagickFalse);
@@ -2358,12 +2358,34 @@ MagickExport void MSBOrderShort(unsigned char *p,const size_t length)
 %    o mode: the mode for opening the file.
 %
 */
+
+static inline MagickBooleanType SetStreamBuffering(const ImageInfo *image_info,
+  Image *image)
+{
+  const char
+    *option;
+
+  int
+    status;
+
+  size_t
+    size;
+
+  size=16384;
+  option=GetImageOption(image_info,"stream:buffer-size");
+  if (option != (const char *) NULL)
+    size=StringToUnsignedLong(option);
+  status=setvbuf(image->blob->file_info.file,(char *) NULL,size == 0 ?
+    _IONBF : _IOFBF,size);
+  return(status == 0 ? MagickTrue : MagickFalse);
+}
+
 MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
   Image *image,const BlobMode mode,ExceptionInfo *exception)
 {
   char
-    extension[MaxTextExtent],
-    filename[MaxTextExtent];
+    extension[MagickPathExtent],
+    filename[MagickPathExtent];
 
   const char
     *type;
@@ -2414,7 +2436,7 @@ MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
     Open image file.
   */
   *filename='\0';
-  (void) CopyMagickString(filename,image->filename,MaxTextExtent);
+  (void) CopyMagickString(filename,image->filename,MagickPathExtent);
   rights=ReadPolicyRights;
   if (*type == 'w')
     rights=WritePolicyRights;
@@ -2435,12 +2457,12 @@ MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
 #endif
       image->blob->type=StandardStream;
       image->blob->exempt=MagickTrue;
-      return(MagickTrue);
+      return(SetStreamBuffering(image_info,image));
     }
   if (LocaleNCompare(filename,"fd:",3) == 0)
     {
       char
-        mode[MaxTextExtent];
+        mode[MagickPathExtent];
 
       *mode=(*type);
       mode[1]='\0';
@@ -2451,13 +2473,13 @@ MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
 #endif
       image->blob->type=StandardStream;
       image->blob->exempt=MagickTrue;
-      return(MagickTrue);
+      return(SetStreamBuffering(image_info,image));
     }
 #if defined(MAGICKCORE_HAVE_POPEN)
   if (*filename == '|')
     {
       char
-        mode[MaxTextExtent];
+        mode[MagickPathExtent];
 
       /*
         Pipe image to or from a system command.
@@ -2476,7 +2498,7 @@ MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
         }
       image->blob->type=PipeStream;
       image->blob->exempt=MagickTrue;
-      return(MagickTrue);
+      return(SetStreamBuffering(image_info,image));
     }
 #endif
   status=GetPathAttributes(filename,&image->blob->properties);
@@ -2491,13 +2513,13 @@ MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
         }
       image->blob->type=FileStream;
       image->blob->exempt=MagickTrue;
-      return(MagickTrue);
+      return(SetStreamBuffering(image_info,image));
     }
 #endif
   GetPathComponent(image->filename,ExtensionPath,extension);
   if (*type == 'w')
     {
-      (void) CopyMagickString(filename,image->filename,MaxTextExtent);
+      (void) CopyMagickString(filename,image->filename,MagickPathExtent);
       if ((image_info->adjoin == MagickFalse) ||
           (strchr(filename,'%') != (char *) NULL))
         {
@@ -2511,17 +2533,17 @@ MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
                (GetNextImageInList(image) != (Image *) NULL)))
             {
               char
-                path[MaxTextExtent];
+                path[MagickPathExtent];
 
               GetPathComponent(image->filename,RootPath,path);
               if (*extension == '\0')
-                (void) FormatLocaleString(filename,MaxTextExtent,"%s-%.20g",
+                (void) FormatLocaleString(filename,MagickPathExtent,"%s-%.20g",
                   path,(double) image->scene);
               else
-                (void) FormatLocaleString(filename,MaxTextExtent,"%s-%.20g.%s",
+                (void) FormatLocaleString(filename,MagickPathExtent,"%s-%.20g.%s",
                   path,(double) image->scene,extension);
             }
-          (void) CopyMagickString(image->filename,filename,MaxTextExtent);
+          (void) CopyMagickString(image->filename,filename,MagickPathExtent);
 #if defined(macintosh)
           SetApplicationType(filename,image_info->magick,'8BIM');
 #endif
@@ -2546,10 +2568,7 @@ MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
               magick[3];
 
             image->blob->type=FileStream;
-#if defined(MAGICKCORE_HAVE_SETVBUF)
-            (void) setvbuf(image->blob->file_info.file,(char *) NULL,(int)
-              _IOFBF,16384);
-#endif
+            (void) SetStreamBuffering(image_info,image);
             (void) ResetMagickMemory(magick,0,sizeof(magick));
             count=fread(magick,1,sizeof(magick),image->blob->file_info.file);
             (void) fseek(image->blob->file_info.file,-((off_t) count),SEEK_CUR);
@@ -2596,7 +2615,7 @@ MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
                 length=(size_t) image->blob->properties.st_size;
                 if ((magick_info != (const MagickInfo *) NULL) &&
                     (GetMagickBlobSupport(magick_info) != MagickFalse) &&
-                    (length <= MagickMaxBufferExtent) &&
+                    (length > MagickMaxBufferExtent) &&
                     (AcquireMagickResource(MapResource,length) != MagickFalse))
                   {
                     void
@@ -2654,10 +2673,7 @@ MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
               if (image->blob->file_info.file != (FILE *) NULL)
                 {
                   image->blob->type=FileStream;
-#if defined(MAGICKCORE_HAVE_SETVBUF)
-                  (void) setvbuf(image->blob->file_info.file,(char *) NULL,(int)
-                    _IOFBF,16384);
-#endif
+                  (void) SetStreamBuffering(image_info,image);
                 }
        }
   image->blob->status=MagickFalse;
@@ -2813,24 +2829,6 @@ MagickExport ssize_t ReadBlob(Image *image,const size_t length,void *data)
     case UndefinedStream:
       break;
     case StandardStream:
-    {
-      register ssize_t
-        i;
-
-      for (i=0; i < (ssize_t) length; i+=count)
-      {
-        count=read(fileno(image->blob->file_info.file),q+i,MagickMin(length-i,
-          (size_t) SSIZE_MAX));
-        if (count <= 0)
-          {
-            count=0;
-            if (errno != EINTR)
-              break;
-          }
-      }
-      count=i;
-      break;
-    }
     case FileStream:
     case PipeStream:
     {
@@ -2841,6 +2839,22 @@ MagickExport ssize_t ReadBlob(Image *image,const size_t length,void *data)
           count=(ssize_t) fread(q,1,length,image->blob->file_info.file);
           break;
         }
+        case 4:
+        {
+          c=getc(image->blob->file_info.file);
+          if (c == EOF)
+            break;
+          *q++=(unsigned char) c;
+          count++;
+        }
+        case 3:
+        {
+          c=getc(image->blob->file_info.file);
+          if (c == EOF)
+            break;
+          *q++=(unsigned char) c;
+          count++;
+        }
         case 2:
         {
           c=getc(image->blob->file_info.file);
@@ -2873,6 +2887,22 @@ MagickExport ssize_t ReadBlob(Image *image,const size_t length,void *data)
             (unsigned int) length);
           break;
         }
+        case 4:
+        {
+          c=gzgetc(image->blob->file_info.gzfile);
+          if (c == EOF)
+            break;
+          *q++=(unsigned char) c;
+          count++;
+        }
+        case 3:
+        {
+          c=gzgetc(image->blob->file_info.gzfile);
+          if (c == EOF)
+            break;
+          *q++=(unsigned char) c;
+          count++;
+        }
         case 2:
         {
           c=gzgetc(image->blob->file_info.gzfile);
@@ -3579,7 +3609,7 @@ MagickExport char *ReadBlobString(Image *image,char *string)
 
   assert(image != (Image *) NULL);
   assert(image->signature == MagickSignature);
-  for (i=0; i < (MaxTextExtent-1L); i++)
+  for (i=0; i < (MagickPathExtent-1L); i++)
   {
     p=ReadBlobStream(image,1,buffer,&count);
     if (count != 1)
@@ -3744,7 +3774,7 @@ MagickExport MagickOffsetType SeekBlob(Image *image,
         break;
       image->blob->extent=(size_t) (image->blob->offset+image->blob->quantum);
       image->blob->quantum<<=1;
-      image->blob->data=ResizeQuantumMemory(image->blob->data,
+      image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
         image->blob->extent+1,sizeof(*image->blob->data));
       (void) SyncBlob(image);
       if (image->blob->data == NULL)
@@ -3849,6 +3879,8 @@ MagickPrivate MagickBooleanType SetBlobExtent(Image *image,
       if ((MagickSizeType) offset >= extent)
         break;
       offset=SeekBlob(image,(MagickOffsetType) extent-1,SEEK_SET);
+      if (offset < 0)
+        break;
       count=(ssize_t) fwrite((const unsigned char *) "",1,1,
         image->blob->file_info.file);
 #if defined(MAGICKCORE_HAVE_POSIX_FALLOCATE)
@@ -4166,10 +4198,6 @@ MagickExport ssize_t WriteBlob(Image *image,const size_t length,
     case UndefinedStream:
       break;
     case StandardStream:
-    {
-      count=write(fileno(image->blob->file_info.file),data,length);
-      break;
-    }
     case FileStream:
     case PipeStream:
     {
@@ -4181,6 +4209,20 @@ MagickExport ssize_t WriteBlob(Image *image,const size_t length,
             image->blob->file_info.file);
           break;
         }
+        case 4:
+        {
+          c=putc((int) *p++,image->blob->file_info.file);
+          if (c == EOF)
+            break;
+          count++;
+        }
+        case 3:
+        {
+          c=putc((int) *p++,image->blob->file_info.file);
+          if (c == EOF)
+            break;
+          count++;
+        }
         case 2:
         {
           c=putc((int) *p++,image->blob->file_info.file);
@@ -4211,6 +4253,20 @@ MagickExport ssize_t WriteBlob(Image *image,const size_t length,
             (unsigned int) length);
           break;
         }
+        case 4:
+        {
+          c=gzputc(image->blob->file_info.gzfile,(int) *p++);
+          if (c == EOF)
+            break;
+          count++;
+        }
+        case 3:
+        {
+          c=gzputc(image->blob->file_info.gzfile,(int) *p++);
+          if (c == EOF)
+            break;
+          count++;
+        }
         case 2:
         {
           c=gzputc(image->blob->file_info.gzfile,(int) *p++);