From a321eb7fb3b35eed694d0366543450d023900b5b Mon Sep 17 00:00:00 2001 From: cristy Date: Sun, 23 Jun 2013 10:42:37 +0000 Subject: [PATCH] --- MagickCore/memory.c | 113 +++++++++++++++++++++++++++++++----------- MagickCore/quantize.c | 13 +++-- coders/bmp.c | 97 ++++++++++++++++++++---------------- 3 files changed, 145 insertions(+), 78 deletions(-) diff --git a/MagickCore/memory.c b/MagickCore/memory.c index 25277f9a0..1031a26cf 100644 --- a/MagickCore/memory.c +++ b/MagickCore/memory.c @@ -63,6 +63,7 @@ #include "MagickCore/resource_.h" #include "MagickCore/semaphore.h" #include "MagickCore/string_.h" +#include "MagickCore/utility-private.h" /* 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)); } /* @@ -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); } /* @@ -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); diff --git a/MagickCore/quantize.c b/MagickCore/quantize.c index 83a8e661d..a7fe9afaf 100644 --- a/MagickCore/quantize.c +++ b/MagickCore/quantize.c @@ -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. */ diff --git a/coders/bmp.c b/coders/bmp.c index b2d1e9f20..a6e4da952 100644 --- a/coders/bmp.c +++ b/coders/bmp.c @@ -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); -- 2.40.0