]> granicus.if.org Git - imagemagick/commitdiff
(no commit message)
authorcristy <urban-warrior@git.imagemagick.org>
Sun, 23 Jun 2013 10:42:37 +0000 (10:42 +0000)
committercristy <urban-warrior@git.imagemagick.org>
Sun, 23 Jun 2013 10:42:37 +0000 (10:42 +0000)
MagickCore/memory.c
MagickCore/quantize.c
coders/bmp.c

index 25277f9a06fc7cb0da0666f3c537efd56d23706b..1031a26cf6f75a6549d5cb612ddbb7bd3751074f 100644 (file)
@@ -63,6 +63,7 @@
 #include "MagickCore/resource_.h"
 #include "MagickCore/semaphore.h"
 #include "MagickCore/string_.h"
+#include "MagickCore/utility-private.h"
 \f
 /*
   Define declarations.
@@ -117,7 +118,7 @@ typedef struct _MagickMemoryMethods
     destroy_memory_handler;
 } MagickMemoryMethods;
 
-typedef struct _MemoryInfo
+struct _MemoryInfo
 {
   char
     filename[MaxTextExtent];
@@ -125,12 +126,15 @@ typedef struct _MemoryInfo
   MagickBooleanType
     mapped;
 
+  size_t
+    length;
+
   void
     *blob;
 
   size_t
     signature;
-} MemoryInfo;
+};
 
 typedef struct _MemoryPool
 {
@@ -473,18 +477,18 @@ MagickExport void *AcquireMagickMemory(const size_t size)
 %                                                                             %
 %                                                                             %
 %                                                                             %
-%   A c q u i r e V i r t u a l M e m o r y                                   %
+%   A c q u i r e Q u a n t u m M e m o r y                                   %
 %                                                                             %
 %                                                                             %
 %                                                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
-%  AcquireVirtualMemory() allocates a pointer to a block of memory at least size
-%  bytes suitably aligned for any use.
+%  AcquireQuantumMemory() returns a pointer to a block of memory at least
+%  count * quantum bytes suitably aligned for any use.
 %
-%  The format of the AcquireVirtualMemory method is:
+%  The format of the AcquireQuantumMemory method is:
 %
-%      MemoryInfo *AcquireVirtualMemory(const size_t count,const size_t quantum)
+%      void *AcquireQuantumMemory(const size_t count,const size_t quantum)
 %
 %  A description of each parameter follows:
 %
@@ -493,19 +497,18 @@ MagickExport void *AcquireMagickMemory(const size_t size)
 %    o quantum: the number of bytes in each quantum.
 %
 */
-MagickExport MemoryInfo *AcquireVirtualMemory(const size_t count,
-  const size_t quantum)
+MagickExport void *AcquireQuantumMemory(const size_t count,const size_t quantum)
 {
-  MemoryInfo
-    *memory_info;
+  size_t
+    size;
 
-  memory_info=(MemoryInfo *) MagickAssumeAligned(AcquireAlignedMemory(1,
-    sizeof(*memory_info)));
-  if (memory_info == (MemoryInfo *) NULL)
-    ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
-  (void) ResetMagickMemory(memory_info,0,sizeof(*memory_info));
-  memory_info->signature=MagickSignature;
-  return(memory_info);
+  size=count*quantum;
+  if ((count == 0) || (quantum != (size/count)))
+    {
+      errno=ENOMEM;
+      return((void *) NULL);
+    }
+  return(AcquireMagickMemory(size));
 }
 \f
 /*
@@ -513,18 +516,18 @@ MagickExport MemoryInfo *AcquireVirtualMemory(const size_t count,
 %                                                                             %
 %                                                                             %
 %                                                                             %
-%   A c q u i r e Q u a n t u m M e m o r y                                   %
+%   A c q u i r e V i r t u a l M e m o r y                                   %
 %                                                                             %
 %                                                                             %
 %                                                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
-%  AcquireQuantumMemory() returns a pointer to a block of memory at least
-%  count * quantum bytes suitably aligned for any use.
+%  AcquireVirtualMemory() allocates a pointer to a block of memory at least size
+%  bytes suitably aligned for any use.
 %
-%  The format of the AcquireQuantumMemory method is:
+%  The format of the AcquireVirtualMemory method is:
 %
-%      void *AcquireQuantumMemory(const size_t count,const size_t quantum)
+%      MemoryInfo *AcquireVirtualMemory(const size_t count,const size_t quantum)
 %
 %  A description of each parameter follows:
 %
@@ -533,18 +536,60 @@ MagickExport MemoryInfo *AcquireVirtualMemory(const size_t count,
 %    o quantum: the number of bytes in each quantum.
 %
 */
-MagickExport void *AcquireQuantumMemory(const size_t count,const size_t quantum)
+MagickExport MemoryInfo *AcquireVirtualMemory(const size_t count,
+  const size_t quantum)
 {
+  MemoryInfo
+    *memory_info;
+
   size_t
-    size;
+    length;
 
-  size=count*quantum;
-  if ((count == 0) || (quantum != (size/count)))
+  length=count*quantum;
+  if ((count == 0) || (quantum != (length/count)))
     {
       errno=ENOMEM;
       return((void *) NULL);
     }
-  return(AcquireMagickMemory(size));
+  memory_info=(MemoryInfo *) MagickAssumeAligned(AcquireAlignedMemory(1,
+    sizeof(*memory_info)));
+  if (memory_info == (MemoryInfo *) NULL)
+    ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
+  (void) ResetMagickMemory(memory_info,0,sizeof(*memory_info));
+  memory_info->length=length;
+  memory_info->signature=MagickSignature;
+  memory_info->blob=AcquireMagickMemory(length);
+  if (memory_info->blob == NULL)
+    {
+      /*
+        Heap memory failed, try anonymous memory mapping.
+      */
+      memory_info->mapped=MagickTrue;
+      memory_info->blob=MapBlob(-1,IOMode,0,length);
+    }
+  if (memory_info->blob == NULL)
+    {
+      int
+        file;
+
+      /*
+        Anonymous memory mapping failed, try file-backed memory mapping.
+      */
+      file=AcquireUniqueFileResource(memory_info->filename);
+      file=open_utf8(memory_info->filename,O_RDWR | O_CREAT | O_BINARY | O_EXCL,
+        S_MODE);
+      if (file == -1)
+        file=open_utf8(memory_info->filename,O_RDWR | O_BINARY,S_MODE);
+      if (file != -1)
+        {
+          if ((lseek(file,length-1,SEEK_SET) >= 0) && (write(file,"",1) == 1))
+            memory_info->blob=MapBlob(file,IOMode,0,length);
+          (void) close(file);
+        }
+    }
+  if (memory_info->blob == NULL)
+    return(RelinquishVirtualMemory(memory_info));
+  return(memory_info);
 }
 \f
 /*
@@ -926,7 +971,17 @@ MagickExport MemoryInfo *RelinquishVirtualMemory(MemoryInfo *memory_info)
   assert(memory_info != (MemoryInfo *) NULL);
   assert(memory_info->signature == MagickSignature);
   if (memory_info->blob != (void *) NULL)
-    memory_info->blob=(void *) NULL;
+    {
+      if (memory_info->mapped == MagickFalse)
+        memory_info->blob=RelinquishMagickMemory(memory_info->blob);
+      else
+        {
+          (void) UnmapBlob(memory_info->blob,memory_info->length);
+          memory_info->blob=NULL;
+          if (*memory_info->filename != '\0')
+            (void) RelinquishUniqueFileResource(memory_info->filename);
+        }
+    }
   memory_info->signature=(~MagickSignature);
   memory_info=(MemoryInfo *) RelinquishAlignedMemory(memory_info);
   return(memory_info);
index 83a8e661da55e65fffde8b4e8b176dd7800d86aa..a7fe9afaf148b330b70e2518045690826426ba85 100644 (file)
@@ -291,6 +291,9 @@ typedef struct _CubeInfo
   Nodes
     *node_queue;
 
+  MemoryInfo
+    *memory_info;
+
   ssize_t
     *cache;
 
@@ -1345,8 +1348,8 @@ static void DestroyCubeInfo(CubeInfo *cube_info)
       cube_info->node_queue);
     cube_info->node_queue=nodes;
   } while (cube_info->node_queue != (Nodes *) NULL);
-  if (cube_info->cache != (ssize_t *) NULL)
-    cube_info->cache=(ssize_t *) RelinquishMagickMemory(cube_info->cache);
+  if (cube_info->memory_info != (MemoryInfo *) NULL)
+    cube_info->memory_info=RelinquishVirtualMemory(cube_info->memory_info);
   cube_info->quantize_info=DestroyQuantizeInfo(cube_info->quantize_info);
   cube_info=(CubeInfo *) RelinquishMagickMemory(cube_info);
 }
@@ -2045,10 +2048,10 @@ static CubeInfo *GetCubeInfo(const QuantizeInfo *quantize_info,
     Initialize dither resources.
   */
   length=(size_t) (1UL << (4*(8-CacheShift)));
-  cube_info->cache=(ssize_t *) AcquireQuantumMemory(length,
-    sizeof(*cube_info->cache));
-  if (cube_info->cache == (ssize_t *) NULL)
+  cube_info->memory_info=AcquireVirtualMemory(length,sizeof(*cube_info->cache));
+  if (cube_info->memory_info == (MemoryInfo *) NULL)
     return((CubeInfo *) NULL);
+  cube_info->cache=(ssize_t *) GetVirtualMemoryBlob(cube_info->memory_info);
   /*
     Initialize color cache.
   */
index b2d1e9f204c8b620df55e544bf74167b4db83869..a6e4da952c30ac8c45e45e994e64d083047f333a 100644 (file)
@@ -249,16 +249,16 @@ static MagickBooleanType DecodeImage(Image *image,const size_t compression,
         /*
           Encoded mode.
         */
-        count=MagickMin(count,(int) (q-p));
+        count=(int) MagickMin((ssize_t) count,(ssize_t) (q-p));
         byte=(unsigned char) ReadBlobByte(image);
         if (compression == BI_RLE8)
           {
-            for (i=0; i < count; i++)
+            for (i=0; i < (ssize_t) count; i++)
               *p++=(unsigned char) byte;
           }
         else
           {
-            for (i=0; i < count; i++)
+            for (i=0; i < (ssize_t) count; i++)
               *p++=(unsigned char)
                 ((i & 0x01) != 0 ? (byte & 0x0f) : ((byte >> 4) & 0x0f));
           }
@@ -299,12 +299,12 @@ static MagickBooleanType DecodeImage(Image *image,const size_t compression,
             /*
               Absolute mode.
             */
-            count=MagickMin(count,(int) (q-p));
+            count=(int) MagickMin((ssize_t) count,(ssize_t) (q-p));
             if (compression == BI_RLE8)
-              for (i=0; i < count; i++)
+              for (i=0; i < (ssize_t) count; i++)
                 *p++=(unsigned char) ReadBlobByte(image);
             else
-              for (i=0; i < count; i++)
+              for (i=0; i < (ssize_t) count; i++)
               {
                 if ((i & 0x01) == 0)
                   byte=(unsigned char) ReadBlobByte(image);
@@ -327,7 +327,7 @@ static MagickBooleanType DecodeImage(Image *image,const size_t compression,
           }
         }
       }
-    if (SetImageProgress(image,LoadImageTag,y,image->rows) == MagickFalse)
+    if (SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,image->rows) == MagickFalse)
       break;
   }
   (void) ReadBlobByte(image);  /* end of line */
@@ -512,6 +512,9 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
     offset,
     start_position;
 
+  MemoryInfo
+    *memory_info;
+
   Quantum
     index;
 
@@ -611,8 +614,8 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
         /*
           OS/2 BMP image file.
         */
-        bmp_info.width=(short) ReadBlobLSBShort(image);
-        bmp_info.height=(short) ReadBlobLSBShort(image);
+        bmp_info.width=(ssize_t) ((short) ReadBlobLSBShort(image));
+        bmp_info.height=(ssize_t) ((short) ReadBlobLSBShort(image));
         bmp_info.planes=ReadBlobLSBShort(image);
         bmp_info.bits_per_pixel=ReadBlobLSBShort(image);
         bmp_info.x_pixels=0;
@@ -637,8 +640,8 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
         */
         if (bmp_info.size < 40)
           ThrowReaderException(CorruptImageError,"NonOS2HeaderSizeError");
-        bmp_info.width=(int) ReadBlobLSBLong(image);
-        bmp_info.height=(int) ReadBlobLSBLong(image);
+        bmp_info.width=(ssize_t) ((int) ReadBlobLSBLong(image));
+        bmp_info.height=(ssize_t) ((int) ReadBlobLSBLong(image));
         bmp_info.planes=ReadBlobLSBShort(image);
         bmp_info.bits_per_pixel=ReadBlobLSBShort(image);
         bmp_info.compression=ReadBlobLSBLong(image);
@@ -900,9 +903,9 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
         p=bmp_colormap;
         for (i=0; i < (ssize_t) image->colors; i++)
         {
-          image->colormap[i].blue=ScaleCharToQuantum(*p++);
-          image->colormap[i].green=ScaleCharToQuantum(*p++);
-          image->colormap[i].red=ScaleCharToQuantum(*p++);
+          image->colormap[i].blue=(MagickRealType) ScaleCharToQuantum(*p++);
+          image->colormap[i].green=(MagickRealType) ScaleCharToQuantum(*p++);
+          image->colormap[i].red=(MagickRealType) ScaleCharToQuantum(*p++);
           if (packet_size == 4)
             p++;
         }
@@ -924,10 +927,11 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
       bmp_info.bits_per_pixel<<=1;
     bytes_per_line=4*((image->columns*bmp_info.bits_per_pixel+31)/32);
     length=(size_t) bytes_per_line*image->rows;
-    pixels=(unsigned char *) AcquireQuantumMemory((size_t) image->rows,
+    memory_info=AcquireVirtualMemory((size_t) image->rows,
       MagickMax(bytes_per_line,image->columns+256UL)*sizeof(*pixels));
-    if (pixels == (unsigned char *) NULL)
+    if (memory_info == (MemoryInfo *) NULL)
       ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
+    pixels=(unsigned char *) GetVirtualMemoryBlob(memory_info);
     if ((bmp_info.compression == BI_RGB) ||
         (bmp_info.compression == BI_BITFIELDS))
       {
@@ -937,7 +941,7 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
         count=ReadBlob(image,length,pixels);
         if (count != (ssize_t) length)
           {
-            pixels=(unsigned char *) RelinquishMagickMemory(pixels);
+            memory_info=RelinquishVirtualMemory(memory_info);
             ThrowReaderException(CorruptImageError,
               "InsufficientImageDataInFile");
           }
@@ -950,7 +954,7 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
         status=DecodeImage(image,bmp_info.compression,pixels);
         if (status == MagickFalse)
           {
-            pixels=(unsigned char *) RelinquishMagickMemory(pixels);
+            memory_info=RelinquishVirtualMemory(memory_info);
             ThrowReaderException(CorruptImageError,
               "UnableToRunlengthDecodeImage");
           }
@@ -961,7 +965,7 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
     if (bmp_info.compression == BI_RGB)
       {
         bmp_info.alpha_mask=image->alpha_trait == BlendPixelTrait ?
-          0xff000000L : 0L;
+          0xff000000U : 0U;
         bmp_info.red_mask=0x00ff0000U;
         bmp_info.green_mask=0x0000ff00U;
         bmp_info.blue_mask=0x000000ffU;
@@ -1000,19 +1004,19 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
         sample=shift.red;
         while (((bmp_info.red_mask << sample) & 0x80000000UL) != 0)
           sample++;
-        quantum_bits.red=(Quantum) (sample-shift.red);
+        quantum_bits.red=(MagickRealType) (sample-shift.red);
         sample=shift.green;
         while (((bmp_info.green_mask << sample) & 0x80000000UL) != 0)
           sample++;
-        quantum_bits.green=(Quantum) (sample-shift.green);
+        quantum_bits.green=(MagickRealType) (sample-shift.green);
         sample=shift.blue;
         while (((bmp_info.blue_mask << sample) & 0x80000000UL) != 0)
           sample++;
-        quantum_bits.blue=(Quantum) (sample-shift.blue);
+        quantum_bits.blue=(MagickRealType) (sample-shift.blue);
         sample=shift.alpha;
         while (((bmp_info.alpha_mask << sample) & 0x80000000UL) != 0)
           sample++;
-        quantum_bits.alpha=(Quantum) (sample-shift.alpha);
+        quantum_bits.alpha=(MagickRealType) (sample-shift.alpha);
       }
     switch (bmp_info.bits_per_pixel)
     {
@@ -1146,7 +1150,7 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
         if (bmp_info.compression != BI_RGB &&
             bmp_info.compression != BI_BITFIELDS)
           {
-            pixels=(unsigned char *) RelinquishMagickMemory(pixels);
+            memory_info=RelinquishVirtualMemory(memory_info);
             ThrowReaderException(CorruptImageError,
               "UnrecognizedImageCompression");
           }
@@ -1245,7 +1249,7 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
         if ((bmp_info.compression != BI_RGB) &&
             (bmp_info.compression != BI_BITFIELDS))
           {
-            pixels=(unsigned char *) RelinquishMagickMemory(pixels);
+            memory_info=RelinquishVirtualMemory(memory_info);
             ThrowReaderException(CorruptImageError,
               "UnrecognizedImageCompression");
           }
@@ -1301,11 +1305,11 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
       }
       default:
       {
-        pixels=(unsigned char *) RelinquishMagickMemory(pixels);
+        memory_info=RelinquishVirtualMemory(memory_info);
         ThrowReaderException(CorruptImageError,"ImproperImageHeader");
       }
     }
-    pixels=(unsigned char *) RelinquishMagickMemory(pixels);
+    memory_info=RelinquishVirtualMemory(memory_info);
     if (EOFBlob(image) != MagickFalse)
       {
         ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
@@ -1491,6 +1495,9 @@ static MagickBooleanType WriteBMPImage(const ImageInfo *image_info,Image *image,
   MagickOffsetType
     scene;
 
+  MemoryInfo
+    *memory_info;
+
   register const Quantum
     *p;
 
@@ -1650,10 +1657,11 @@ static MagickBooleanType WriteBMPImage(const ImageInfo *image_info,Image *image,
     /*
       Convert MIFF to BMP raster pixels.
     */
-    pixels=(unsigned char *) AcquireQuantumMemory((size_t) bmp_info.image_size,
+    memory_info=AcquireVirtualMemory((size_t) bmp_info.image_size,
       sizeof(*pixels));
-    if (pixels == (unsigned char *) NULL)
+    if (memory_info == (MemoryInfo *) NULL)
       ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
+    pixels=(unsigned char *) GetVirtualMemoryBlob(memory_info);
     (void) ResetMagickMemory(pixels,0,(size_t) bmp_info.image_size);
     switch (bmp_info.bits_per_pixel)
     {
@@ -1712,7 +1720,9 @@ static MagickBooleanType WriteBMPImage(const ImageInfo *image_info,Image *image,
       {
         size_t
           byte,
-          nibble,
+          nibble;
+
+        ssize_t
           offset;
 
         /*
@@ -1848,27 +1858,26 @@ static MagickBooleanType WriteBMPImage(const ImageInfo *image_info,Image *image,
     if ((type > 2) && (bmp_info.bits_per_pixel == 8))
       if (image_info->compression != NoCompression)
         {
-          size_t
-            length;
+          MemoryInfo
+            *rle_info;
 
           /*
             Convert run-length encoded raster pixels.
           */
-          length=(size_t) (2*(bytes_per_line+2)*(image->rows+2)+2);
-          bmp_data=(unsigned char *) NULL;
-          if (~length >= bytes_per_line)
-            bmp_data=(unsigned char *) AcquireQuantumMemory(length+
-              bytes_per_line,sizeof(*bmp_data));
-          if (bmp_data == (unsigned char *) NULL)
+          rle_info=AcquireVirtualMemory((size_t) (2*(bytes_per_line+2)+2),
+            (image->rows+2)*sizeof(*pixels));
+          if (rle_info == (MemoryInfo *) NULL)
             {
-              pixels=(unsigned char *) RelinquishMagickMemory(pixels);
+              memory_info=RelinquishVirtualMemory(memory_info);
               ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
             }
+          bmp_data=(unsigned char *) GetVirtualMemoryBlob(rle_info);
           bmp_info.file_size-=bmp_info.image_size;
           bmp_info.image_size=(unsigned int) EncodeImage(image,bytes_per_line,
             pixels,bmp_data);
           bmp_info.file_size+=bmp_info.image_size;
-          pixels=(unsigned char *) RelinquishMagickMemory(pixels);
+          memory_info=RelinquishVirtualMemory(memory_info);
+          memory_info=rle_info;
           pixels=bmp_data;
           bmp_info.compression=BI_RLE8;
         }
@@ -2057,9 +2066,9 @@ static MagickBooleanType WriteBMPImage(const ImageInfo *image_info,Image *image,
         q=bmp_colormap;
         for (i=0; i < (ssize_t) MagickMin((ssize_t) image->colors,(ssize_t) bmp_info.number_colors); i++)
         {
-          *q++=ScaleQuantumToChar(image->colormap[i].blue);
-          *q++=ScaleQuantumToChar(image->colormap[i].green);
-          *q++=ScaleQuantumToChar(image->colormap[i].red);
+          *q++=ScaleQuantumToChar(ClampToQuantum(image->colormap[i].blue));
+          *q++=ScaleQuantumToChar(ClampToQuantum(image->colormap[i].green));
+          *q++=ScaleQuantumToChar(ClampToQuantum(image->colormap[i].red));
           if (type > 2)
             *q++=(unsigned char) 0x0;
         }
@@ -2083,7 +2092,7 @@ static MagickBooleanType WriteBMPImage(const ImageInfo *image_info,Image *image,
       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
         "  Pixels:  %u bytes",bmp_info.image_size);
     (void) WriteBlob(image,(size_t) bmp_info.image_size,pixels);
-    pixels=(unsigned char *) RelinquishMagickMemory(pixels);
+    memory_info=RelinquishVirtualMemory(memory_info);
     if (GetNextImageInList(image) == (Image *) NULL)
       break;
     image=SyncNextImageInList(image);