#include "MagickCore/resource_.h"
#include "MagickCore/semaphore.h"
#include "MagickCore/string_.h"
+#include "MagickCore/utility-private.h"
\f
/*
Define declarations.
destroy_memory_handler;
} MagickMemoryMethods;
-typedef struct _MemoryInfo
+struct _MemoryInfo
{
char
filename[MaxTextExtent];
MagickBooleanType
mapped;
+ size_t
+ length;
+
void
*blob;
size_t
signature;
-} MemoryInfo;
+};
typedef struct _MemoryPool
{
% %
% %
% %
-% 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:
%
% 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
/*
% %
% %
% %
-% 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:
%
% 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
/*
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);
/*
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));
}
/*
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);
}
}
}
- if (SetImageProgress(image,LoadImageTag,y,image->rows) == MagickFalse)
+ if (SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,image->rows) == MagickFalse)
break;
}
(void) ReadBlobByte(image); /* end of line */
offset,
start_position;
+ MemoryInfo
+ *memory_info;
+
Quantum
index;
/*
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;
*/
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);
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++;
}
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))
{
count=ReadBlob(image,length,pixels);
if (count != (ssize_t) length)
{
- pixels=(unsigned char *) RelinquishMagickMemory(pixels);
+ memory_info=RelinquishVirtualMemory(memory_info);
ThrowReaderException(CorruptImageError,
"InsufficientImageDataInFile");
}
status=DecodeImage(image,bmp_info.compression,pixels);
if (status == MagickFalse)
{
- pixels=(unsigned char *) RelinquishMagickMemory(pixels);
+ memory_info=RelinquishVirtualMemory(memory_info);
ThrowReaderException(CorruptImageError,
"UnableToRunlengthDecodeImage");
}
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;
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)
{
if (bmp_info.compression != BI_RGB &&
bmp_info.compression != BI_BITFIELDS)
{
- pixels=(unsigned char *) RelinquishMagickMemory(pixels);
+ memory_info=RelinquishVirtualMemory(memory_info);
ThrowReaderException(CorruptImageError,
"UnrecognizedImageCompression");
}
if ((bmp_info.compression != BI_RGB) &&
(bmp_info.compression != BI_BITFIELDS))
{
- pixels=(unsigned char *) RelinquishMagickMemory(pixels);
+ memory_info=RelinquishVirtualMemory(memory_info);
ThrowReaderException(CorruptImageError,
"UnrecognizedImageCompression");
}
}
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",
MagickOffsetType
scene;
+ MemoryInfo
+ *memory_info;
+
register const Quantum
*p;
/*
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)
{
{
size_t
byte,
- nibble,
+ nibble;
+
+ ssize_t
offset;
/*
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;
}
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;
}
(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);