]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/blob.c
(no commit message)
[imagemagick] / MagickCore / blob.c
index 9751155ff00b16e265bf2995d7d8f28b86bae4f5..cbcae1bd5063ffeb1e453b86999f59a78472d9ef 100644 (file)
 %                     MagickCore Binary Large OBjectS Methods                 %
 %                                                                             %
 %                              Software Design                                %
-%                                John Cristy                                  %
+%                                   Cristy                                    %
 %                                 July 1999                                   %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2013 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2014 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  %
@@ -41,7 +41,6 @@
   Include declarations.
 */
 #include "MagickCore/studio.h"
-#include "MagickCore/nt-base-private.h"
 #include "MagickCore/blob.h"
 #include "MagickCore/blob-private.h"
 #include "MagickCore/cache.h"
@@ -56,6 +55,7 @@
 #include "MagickCore/log.h"
 #include "MagickCore/magick.h"
 #include "MagickCore/memory_.h"
+#include "MagickCore/nt-base-private.h"
 #include "MagickCore/policy.h"
 #include "MagickCore/resource_.h"
 #include "MagickCore/semaphore.h"
@@ -355,10 +355,10 @@ MagickExport Image *BlobToImage(const ImageInfo *image_info,const void *blob,
   magick_info=GetMagickInfo(blob_info->magick,exception);
   if (magick_info == (const MagickInfo *) NULL)
     {
-      blob_info=DestroyImageInfo(blob_info);
       (void) ThrowMagickException(exception,GetMagickModule(),
         MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
-        image_info->filename);
+        blob_info->magick);
+      blob_info=DestroyImageInfo(blob_info);
       return((Image *) NULL);
     }
   if (GetMagickBlobSupport(magick_info) != MagickFalse)
@@ -399,14 +399,16 @@ MagickExport Image *BlobToImage(const ImageInfo *image_info,const void *blob,
         *images;
 
       /*
-        Restore original filenames.
+        Restore original filenames and image format.
       */
       for (images=GetFirstImageInList(image); images != (Image *) NULL; )
       {
-        (void) CopyMagickMemory(images->filename,image_info->filename,
-          sizeof(images->filename));
-        (void) CopyMagickMemory(images->magick_filename,image_info->filename,
-          sizeof(images->magick_filename));
+        (void) CopyMagickString(images->filename,image_info->filename,
+          MaxTextExtent);
+        (void) CopyMagickString(images->magick_filename,image_info->filename,
+          MaxTextExtent);
+        (void) CopyMagickString(images->magick,magick_info->name,
+          MaxTextExtent);
         images=GetNextImageInList(images);
       }
     }
@@ -652,7 +654,7 @@ MagickExport void DestroyBlob(Image *image)
       RelinquishMagickResource(MapResource,image->blob->length);
     }
   if (image->blob->semaphore != (SemaphoreInfo *) NULL)
-    DestroySemaphoreInfo(&image->blob->semaphore);
+    RelinquishSemaphoreInfo(&image->blob->semaphore);
   image->blob->signature=(~MagickSignature);
   image->blob=(BlobInfo *) RelinquishMagickMemory(image->blob);
 }
@@ -690,6 +692,7 @@ MagickExport unsigned char *DetachBlob(BlobInfo *blob_info)
   if (blob_info->mapped != MagickFalse)
     {
       (void) UnmapBlob(blob_info->data,blob_info->length);
+      blob_info->data=(unsigned char *) NULL;
       RelinquishMagickResource(MapResource,blob_info->length);
     }
   blob_info->mapped=MagickFalse;
@@ -964,7 +967,8 @@ MagickExport unsigned char *FileToBlob(const char *filename,const size_t extent,
     }
   offset=(MagickOffsetType) lseek(file,0,SEEK_END);
   count=0;
-  if ((offset < 0) || (offset != (MagickOffsetType) ((ssize_t) offset)))
+  if ((file == fileno(stdin)) || (offset < 0) ||
+      (offset != (MagickOffsetType) ((ssize_t) offset)))
     {
       size_t
         quantum;
@@ -975,6 +979,7 @@ MagickExport unsigned char *FileToBlob(const char *filename,const size_t extent,
       /*
         Stream is not seekable.
       */
+      offset=(MagickOffsetType) lseek(file,0,SEEK_SET);
       quantum=(size_t) MagickMaxBufferExtent;
       if ((fstat(file,&file_stats) == 0) && (file_stats.st_size != 0))
         quantum=(size_t) MagickMin((MagickSizeType) file_stats.st_size,
@@ -1110,8 +1115,8 @@ static inline ssize_t WriteBlobStream(Image *image,const size_t length,
   extent=(MagickSizeType) (image->blob->offset+(MagickOffsetType) length);
   if (extent >= image->blob->extent)
     {
-      image->blob->quantum<<=1;
       extent=image->blob->extent+image->blob->quantum+length;
+      image->blob->quantum<<=1;
       if (SetBlobExtent(image,extent) == MagickFalse)
         return(0);
     }
@@ -1160,6 +1165,7 @@ MagickExport MagickBooleanType FileToImage(Image *image,const char *filename,
   blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
   if (blob == (unsigned char *) NULL)
     {
+      file=close(file);
       ThrowFileException(exception,ResourceLimitError,"MemoryAllocationFailed",
         filename);
       return(MagickFalse);
@@ -1281,7 +1287,7 @@ MagickPrivate void GetBlobInfo(BlobInfo *blob_info)
   blob_info->properties.st_ctime=time((time_t *) NULL);
   blob_info->debug=IsEventLogging();
   blob_info->reference_count=1;
-  blob_info->semaphore=AllocateSemaphoreInfo();
+  blob_info->semaphore=AcquireSemaphoreInfo();
   blob_info->signature=MagickSignature;
 }
 \f
@@ -1483,8 +1489,7 @@ MagickPrivate StreamHandler GetBlobStreamHandler(const Image *image)
 %
 %    o image: the image.
 %
-%    o length: This pointer to a size_t integer sets the initial length of the
-%      blob.  On return, it reflects the actual length of the blob.
+%    o length: return the actual length of the blob.
 %
 %    o exception: return any errors or warnings in this structure.
 %
@@ -1524,7 +1529,8 @@ MagickExport unsigned char *ImageToBlob(const ImageInfo *image_info,
     {
       (void) ThrowMagickException(exception,GetMagickModule(),
         MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
-        image->filename);
+        image->magick);
+      blob_info=DestroyImageInfo(blob_info);
       return(blob);
     }
   (void) CopyMagickString(blob_info->magick,image->magick,MaxTextExtent);
@@ -1579,9 +1585,10 @@ MagickExport unsigned char *ImageToBlob(const ImageInfo *image_info,
               (void) FormatLocaleString(image->filename,MaxTextExtent,"%s:%s",
                 image->magick,unique);
               status=WriteImage(blob_info,image,exception);
+              (void) CloseBlob(image);
               (void) fclose(blob_info->file);
               if (status != MagickFalse)
-                blob=FileToBlob(image->filename,~0UL,length,exception);
+                blob=FileToBlob(unique,~0UL,length,exception);
             }
           (void) RelinquishUniqueFileResource(unique);
         }
@@ -1697,6 +1704,8 @@ MagickExport MagickBooleanType ImageToFile(Image *image,char *filename,
   buffer=(unsigned char *) RelinquishMagickMemory(buffer);
   if ((file == -1) || (i < length))
     {
+      if (file != -1)
+        file=close(file);
       ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
       return(MagickFalse);
     }
@@ -1733,8 +1742,7 @@ MagickExport MagickBooleanType ImageToFile(Image *image,char *filename,
 %
 %    o images: the image list.
 %
-%    o length: This pointer to a size_t integer sets the initial length of the
-%      blob.  On return, it reflects the actual length of the blob.
+%    o length: return the actual length of the blob.
 %
 %    o exception: return any errors or warnings in this structure.
 %
@@ -1769,19 +1777,20 @@ MagickExport unsigned char *ImagesToBlob(const ImageInfo *image_info,
     exception);
   if (*blob_info->magick != '\0')
     (void) CopyMagickString(images->magick,blob_info->magick,MaxTextExtent);
-  if (blob_info->adjoin == MagickFalse)
-    {
-      blob_info=DestroyImageInfo(blob_info);
-      return(ImageToBlob(image_info,images,length,exception));
-    }
   magick_info=GetMagickInfo(images->magick,exception);
   if (magick_info == (const MagickInfo *) NULL)
     {
       (void) ThrowMagickException(exception,GetMagickModule(),
         MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
-        images->filename);
+        images->magick);
+      blob_info=DestroyImageInfo(blob_info);
       return(blob);
     }
+  if (GetMagickAdjoin(magick_info) == MagickFalse)
+    {
+      blob_info=DestroyImageInfo(blob_info);
+      return(ImageToBlob(image_info,images,length,exception));
+    }
   (void) CopyMagickString(blob_info->magick,images->magick,MaxTextExtent);
   if (GetMagickBlobSupport(magick_info) != MagickFalse)
     {
@@ -1796,16 +1805,17 @@ MagickExport unsigned char *ImagesToBlob(const ImageInfo *image_info,
           ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename);
       else
         {
+          (void) CloseBlob(images);
           images->blob->exempt=MagickTrue;
           *images->filename='\0';
           status=WriteImages(blob_info,images,images->filename,exception);
-          if ((status != MagickFalse) && (images->blob->length != 0))
-            {
-              *length=images->blob->length;
-              blob=DetachBlob(images->blob);
-              blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
-                sizeof(*blob));
-            }
+          *length=images->blob->length;
+          blob=DetachBlob(images->blob);
+          if (status == MagickFalse)
+            blob=(unsigned char *) RelinquishMagickMemory(blob);
+          else
+            blob=(unsigned char *) ResizeQuantumMemory(blob,*length+1,
+              sizeof(*blob));
         }
     }
   else
@@ -1834,9 +1844,10 @@ MagickExport unsigned char *ImagesToBlob(const ImageInfo *image_info,
               (void) FormatLocaleString(filename,MaxTextExtent,"%s:%s",
                 images->magick,unique);
               status=WriteImages(blob_info,images,filename,exception);
+              (void) CloseBlob(images);
               (void) fclose(blob_info->file);
               if (status != MagickFalse)
-                blob=FileToBlob(images->filename,~0UL,length,exception);
+                blob=FileToBlob(unique,~0UL,length,exception);
             }
           (void) RelinquishUniqueFileResource(unique);
         }
@@ -2142,7 +2153,7 @@ MagickPrivate MagickBooleanType IsBlobTemporary(const Image *image)
 MagickExport unsigned char *MapBlob(int file,const MapMode mode,
   const MagickOffsetType offset,const size_t length)
 {
-#if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
+#if defined(MAGICKCORE_HAVE_MMAP)
   int
     flags,
     protection;
@@ -2157,9 +2168,6 @@ MagickExport unsigned char *MapBlob(int file,const MapMode mode,
   if (file == -1)
 #if defined(MAP_ANONYMOUS)
     flags|=MAP_ANONYMOUS;
-#if defined(MAGICKCORE_HAVE_HUGEPAGES) && defined(MAP_HUGETLB)
-    flags|=MAP_HUGETLB;
-#endif
 #else
     return((unsigned char *) NULL);
 #endif
@@ -2170,31 +2178,31 @@ MagickExport unsigned char *MapBlob(int file,const MapMode mode,
     {
       protection=PROT_READ;
       flags|=MAP_PRIVATE;
-      map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
-        (off_t) offset);
       break;
     }
     case WriteMode:
     {
       protection=PROT_WRITE;
       flags|=MAP_SHARED;
-      map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
-        (off_t) offset);
-#if defined(MAGICKCORE_HAVE_POSIX_MADVISE)
-      (void) posix_madvise(map,length,POSIX_MADV_SEQUENTIAL |
-        POSIX_MADV_WILLNEED);
-#endif
       break;
     }
     case IOMode:
     {
       protection=PROT_READ | PROT_WRITE;
       flags|=MAP_SHARED;
-      map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
-        (off_t) offset);
       break;
     }
   }
+#if !defined(MAGICKCORE_HAVE_HUGEPAGES) || !defined(MAP_HUGETLB)
+  map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
+    (off_t) offset);
+#else
+  map=(unsigned char *) mmap((char *) NULL,length,protection,flags |
+    MAP_HUGETLB,file,(off_t) offset);
+  if (map == (unsigned char *) MAP_FAILED)
+    map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
+      (off_t) offset);
+#endif
   if (map == (unsigned char *) MAP_FAILED)
     return((unsigned char *) NULL);
   return(map);
@@ -2455,7 +2463,7 @@ MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
 #endif
   status=GetPathAttributes(filename,&image->blob->properties);
 #if defined(S_ISFIFO)
-  if ((status == MagickTrue) && S_ISFIFO(image->blob->properties.st_mode))
+  if ((status != MagickFalse) && S_ISFIFO(image->blob->properties.st_mode))
     {
       image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
       if (image->blob->file_info.file == (FILE *) NULL)
@@ -2534,7 +2542,9 @@ MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
             if (((int) magick[0] == 0x1F) && ((int) magick[1] == 0x8B) &&
                 ((int) magick[2] == 0x08))
               {
-                (void) fclose(image->blob->file_info.file);
+                if (image->blob->file_info.file != (FILE *) NULL)
+                  (void) fclose(image->blob->file_info.file);
+                image->blob->file_info.file=(FILE *) NULL;
                 image->blob->file_info.gzfile=gzopen(filename,type);
                 if (image->blob->file_info.gzfile != (gzFile) NULL)
                   image->blob->type=ZipStream;
@@ -2543,7 +2553,9 @@ MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
 #if defined(MAGICKCORE_BZLIB_DELEGATE)
             if (strncmp((char *) magick,"BZh",3) == 0)
               {
-                (void) fclose(image->blob->file_info.file);
+                if (image->blob->file_info.file != (FILE *) NULL)
+                  (void) fclose(image->blob->file_info.file);
+                image->blob->file_info.file=(FILE *) NULL;
                 image->blob->file_info.bzfile=BZ2_bzopen(filename,type);
                 if (image->blob->file_info.bzfile != (BZFILE *) NULL)
                   image->blob->type=BZipStream;
@@ -3590,6 +3602,8 @@ MagickExport MagickOffsetType SeekBlob(Image *image,
       return(-1);
     case FileStream:
     {
+      if ((whence == SEEK_SET) && (offset < 0))
+        return(-1);
       if (fseek(image->blob->file_info.file,offset,whence) < 0)
         return(-1);
       image->blob->offset=TellBlob(image);
@@ -3646,6 +3660,7 @@ MagickExport MagickOffsetType SeekBlob(Image *image,
           {
             image->blob->extent=(size_t) (image->blob->offset+
               image->blob->quantum);
+            image->blob->quantum<<=1;
             image->blob->data=(unsigned char *) ResizeQuantumMemory(
               image->blob->data,image->blob->extent+1,
               sizeof(*image->blob->data));
@@ -4002,7 +4017,7 @@ MagickExport MagickOffsetType TellBlob(const Image *image)
 */
 MagickExport MagickBooleanType UnmapBlob(void *map,const size_t length)
 {
-#if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
+#if defined(MAGICKCORE_HAVE_MMAP)
   int
     status;
 
@@ -4158,8 +4173,8 @@ MagickExport ssize_t WriteBlob(Image *image,const size_t length,
         {
           if (image->blob->mapped != MagickFalse)
             return(0);
-          image->blob->quantum<<=1;
           image->blob->extent+=length+image->blob->quantum;
+          image->blob->quantum<<=1;
           image->blob->data=(unsigned char *) ResizeQuantumMemory(
             image->blob->data,image->blob->extent+1,sizeof(*image->blob->data));
           (void) SyncBlob(image);