File GraphicsMagick-xwd.c-update.patch of Package GraphicsMagick.10305
Index: GraphicsMagick-1.3.29/coders/xwd.c
===================================================================
--- GraphicsMagick-1.3.29.orig/coders/xwd.c 2017-12-09 21:02:45.000000000 +0100
+++ GraphicsMagick-1.3.29/coders/xwd.c 2019-04-30 12:01:19.204675966 +0200
@@ -1,5 +1,5 @@
/*
-% Copyright (C) 2003-2015 GraphicsMagick Group
+% Copyright (C) 2003-2019 GraphicsMagick Group
% Copyright (C) 2002 ImageMagick Studio
% Copyright 1991-1999 E. I. du Pont de Nemours and Company
%
@@ -96,6 +96,143 @@ static unsigned int IsXWD(const unsigned
#if defined(HasX11)
#include "magick/xwindow.h"
+
+static void TraceXWDHeader(const XWDFileHeader *header)
+{
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "XWDFileHeader:\n"
+ " header_size : %u\n"
+ " file_version : %u\n"
+ " pixmap_format : %s\n"
+ " pixmap_depth : %u\n"
+ " pixmap_width : %u\n"
+ " pixmap_height : %u\n"
+ " xoffset : %u\n"
+ " byte_order : %s\n"
+ " bitmap_unit : %u\n"
+ " bitmap_bit_order : %s\n"
+ " bitmap_pad : %u\n"
+ " bits_per_pixel : %u\n"
+ " bytes_per_line : %u\n"
+ " visual_class : %s\n"
+ " red_mask : 0x%06X\n"
+ " green_mask : 0x%06X\n"
+ " blue_mask : 0x%06X\n"
+ " bits_per_rgb : %u\n"
+ " colormap_entries : %u\n"
+ " ncolors : %u\n"
+ " window_width : %u\n"
+ " window_height : %u\n"
+ " window_x : %u\n"
+ " window_y : %u\n"
+ " window_bdrwidth : %u",
+ (unsigned int) header->header_size,
+ (unsigned int) header->file_version,
+ /* (unsigned int) header->pixmap_format, */
+ (header->pixmap_format == XYBitmap ? "XYBitmap" :
+ (header->pixmap_format == XYPixmap ? "XYPixmap" :
+ (header->pixmap_format == ZPixmap ? "ZPixmap" : "?"))),
+ (unsigned int) header->pixmap_depth,
+ (unsigned int) header->pixmap_width,
+ (unsigned int) header->pixmap_height,
+ (unsigned int) header->xoffset,
+ (header->byte_order == MSBFirst? "MSBFirst" :
+ (header->byte_order == LSBFirst ? "LSBFirst" : "?")),
+ (unsigned int) header->bitmap_unit,
+ (header->bitmap_bit_order == MSBFirst? "MSBFirst" :
+ (header->bitmap_bit_order == LSBFirst ? "LSBFirst" :
+ "?")),
+ (unsigned int) header->bitmap_pad,
+ (unsigned int) header->bits_per_pixel,
+ (unsigned int) header->bytes_per_line,
+ (header->visual_class == StaticGray ? "StaticGray" :
+ (header->visual_class == GrayScale ? "GrayScale" :
+ (header->visual_class == StaticColor ? "StaticColor" :
+ (header->visual_class == PseudoColor ? "PseudoColor" :
+ (header->visual_class == TrueColor ? "TrueColor" :
+ (header->visual_class == DirectColor ?
+ "DirectColor" : "?")))))),
+ (unsigned int) header->red_mask,
+ (unsigned int) header->green_mask,
+ (unsigned int) header->blue_mask,
+ (unsigned int) header->bits_per_rgb,
+ (unsigned int) header->colormap_entries,
+ (unsigned int) header->ncolors,
+ (unsigned int) header->window_width,
+ (unsigned int) header->window_height,
+ (unsigned int) header->window_x,
+ (unsigned int) header->window_y,
+ (unsigned int) header->window_bdrwidth
+ );
+}
+
+static void TraceXImage(const XImage *ximage)
+{
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "XImage:\n"
+ " width: %d\n"
+ " height: %d\n"
+ " xoffset: %d\n"
+ " format: %s\n"
+ " data: %p\n"
+ " byte_order: %s\n"
+ " bitmap_unit: %d\n"
+ " bitmap_bit_order: %s\n"
+ " bitmap_pad: %d\n"
+ " depth: %d\n"
+ " bytes_per_line: %d\n"
+ " bits_per_pixel: %d\n"
+ " red_mask: %06lX\n"
+ " green_mask: %06lX\n"
+ " blue_mask: %06lX\n",
+ ximage->width,
+ ximage->height,
+ ximage->xoffset,
+ (ximage->format == XYBitmap ? "XYBitmap" :
+ (ximage->format == XYPixmap ? "XYPixmap" :
+ (ximage->format == ZPixmap ? "ZPixmap" : "?"))),
+ ximage->data,
+ (ximage->byte_order == MSBFirst? "MSBFirst" :
+ (ximage->byte_order == LSBFirst ? "LSBFirst" : "?")),
+ ximage->bitmap_unit,
+ (ximage->bitmap_bit_order == MSBFirst? "MSBFirst" :
+ (ximage->bitmap_bit_order == LSBFirst ? "LSBFirst" :
+ "?")),
+ ximage->bitmap_pad,
+ ximage->depth,
+ ximage->bytes_per_line,
+ ximage->bits_per_pixel,
+ ximage->red_mask,
+ ximage->green_mask,
+ ximage->blue_mask);
+}
+
+/*
+ Compute required allocation sizes
+
+ FIXME: This is still a work in progress.
+
+ BitmapUnit (pixmap_depth) is the size of each data unit in each
+ scan line. This value may be 8, 16, or 32.
+
+ BitmapPad (bitmap_pad) is the number of bits of padding added to
+ each scan line. This value may be 8, 16, or 32.
+*/
+static MagickPassFail BytesPerLine(size_t *bytes_per_line,
+ size_t *scanline_bits,
+ const size_t pixmap_width,
+ const size_t pixmap_depth,
+ const size_t bitmap_pad)
+{
+ *bytes_per_line=0;
+ *scanline_bits=MagickArraySize(pixmap_width,pixmap_depth);
+ if ((*scanline_bits > 0) && (((~(size_t)0) - *scanline_bits > (bitmap_pad)-1)))
+ *bytes_per_line=((((*scanline_bits)+((bitmap_pad)-1))/
+ (bitmap_pad))*((bitmap_pad) >> 3));
+
+ return (*bytes_per_line !=0 && *scanline_bits != 0) ? MagickPass : MagickFail;
+}
+
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
@@ -129,7 +266,6 @@ static unsigned int IsXWD(const unsigned
*/
#define ThrowXWDReaderException(code_,reason_,image_) \
do { \
- MagickFreeMemory(comment); \
if (ximage) \
MagickFreeMemory(ximage->data); \
MagickFreeMemory(ximage); \
@@ -140,7 +276,7 @@ do { \
static Image *ReadXWDImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
char
- *comment = (char *) NULL;
+ comment[MaxTextExtent];
Image
*image;
@@ -211,71 +347,11 @@ static Image *ReadXWDImage(const ImageIn
if (*(char *) &lsb_first)
MSBOrderLong((unsigned char *) &header,sz_XWDheader);
- (void) LogMagickEvent(CoderEvent,GetMagickModule(),
- "XWDFileHeader:\n"
- " header_size : %u\n"
- " file_version : %u\n"
- " pixmap_format : %s\n"
- " pixmap_depth : %u\n"
- " pixmap_width : %u\n"
- " pixmap_height : %u\n"
- " xoffset : %u\n"
- " byte_order : %s\n"
- " bitmap_unit : %u\n"
- " bitmap_bit_order : %s\n"
- " bitmap_pad : %u\n"
- " bits_per_pixel : %u\n"
- " bytes_per_line : %u\n"
- " visual_class : %s\n"
- " red_mask : 0x%06X\n"
- " green_mask : 0x%06X\n"
- " blue_mask : 0x%06X\n"
- " bits_per_rgb : %u\n"
- " colormap_entries : %u\n"
- " ncolors : %u\n"
- " window_width : %u\n"
- " window_height : %u\n"
- " window_x : %u\n"
- " window_y : %u\n"
- " window_bdrwidth : %u",
- (unsigned int) header.header_size,
- (unsigned int) header.file_version,
- /* (unsigned int) header.pixmap_format, */
- (header.pixmap_format == XYBitmap ? "XYBitmap" :
- (header.pixmap_format == XYPixmap ? "XYPixmap" :
- (header.pixmap_format == ZPixmap ? "ZPixmap" : "?"))),
- (unsigned int) header.pixmap_depth,
- (unsigned int) header.pixmap_width,
- (unsigned int) header.pixmap_height,
- (unsigned int) header.xoffset,
- (header.byte_order == MSBFirst? "MSBFirst" :
- (header.byte_order == LSBFirst ? "LSBFirst" : "?")),
- (unsigned int) header.bitmap_unit,
- (header.bitmap_bit_order == MSBFirst? "MSBFirst" :
- (header.bitmap_bit_order == LSBFirst ? "LSBFirst" :
- "?")),
- (unsigned int) header.bitmap_pad,
- (unsigned int) header.bits_per_pixel,
- (unsigned int) header.bytes_per_line,
- (header.visual_class == StaticGray ? "StaticGray" :
- (header.visual_class == GrayScale ? "GrayScale" :
- (header.visual_class == StaticColor ? "StaticColor" :
- (header.visual_class == PseudoColor ? "PseudoColor" :
- (header.visual_class == TrueColor ? "TrueColor" :
- (header.visual_class == DirectColor ?
- "DirectColor" : "?")))))),
- (unsigned int) header.red_mask,
- (unsigned int) header.green_mask,
- (unsigned int) header.blue_mask,
- (unsigned int) header.bits_per_rgb,
- (unsigned int) header.colormap_entries,
- (unsigned int) header.ncolors,
- (unsigned int) header.window_width,
- (unsigned int) header.window_height,
- (unsigned int) header.window_x,
- (unsigned int) header.window_y,
- (unsigned int) header.window_bdrwidth
- );
+ /*
+ Trace XWD header
+ */
+ if (image->logging)
+ TraceXWDHeader(&header);
/*
Check to see if the dump file is in the proper format.
@@ -283,7 +359,19 @@ static Image *ReadXWDImage(const ImageIn
if (header.file_version != XWD_FILE_VERSION)
ThrowXWDReaderException(CorruptImageError,InvalidFileFormatVersion,image);
if (header.header_size < sz_XWDheader)
- ThrowXWDReaderException(CorruptImageError,CorruptImage,image);
+ ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
+
+ /*
+ Detect signed integer overflow
+ */
+ if (((magick_uint32_t) header.pixmap_depth | header.pixmap_format |
+ header.xoffset | header.pixmap_width | header.pixmap_height |
+ header.bitmap_pad | header.bytes_per_line | header.byte_order |
+ header.bitmap_unit | header.bitmap_bit_order |
+ header.bits_per_pixel) >> 31)
+ ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
+
+ /* Display classes used in opening the connection */
switch (header.visual_class)
{
case StaticGray:
@@ -295,37 +383,152 @@ static Image *ReadXWDImage(const ImageIn
break;
default:
{
- ThrowXWDReaderException(CorruptImageError,CorruptImage,image);
+ ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
}
}
+
+ /* XYBitmap, XYPixmap, ZPixmap */
switch (header.pixmap_format)
{
- case XYBitmap:
- case XYPixmap:
- case ZPixmap:
+ case XYBitmap: /* 1 bit bitmap format */
+ if (header.pixmap_depth != 1)
+ ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
+ break;
+ case XYPixmap: /* Single plane bitmap. */
+ case ZPixmap: /* Bitmap with 2 or more planes */
+ if ((header.pixmap_depth < 1) || (header.pixmap_depth > 32))
+ ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
break;
default:
{
- ThrowXWDReaderException(CorruptImageError,CorruptImage,image);
+ ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
}
}
+ /* Data byte order, LSBFirst, MSBFirst */
+ switch (header.byte_order)
+ {
+ case LSBFirst:
+ case MSBFirst:
+ break;
+ default:
+ {
+ ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
+ }
+ }
+
+ /* Quant. of scanline 8, 16, 32 */
+ switch (header.bitmap_unit)
+ {
+ case 8:
+ case 16:
+ case 32:
+ break;
+ default:
+ {
+ ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
+ }
+ }
+
+ /* LSBFirst, MSBFirst */
+ switch (header.bitmap_bit_order)
+ {
+ case LSBFirst:
+ case MSBFirst:
+ break;
+ default:
+ {
+ ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
+ }
+ }
+
+ /* 8, 16, 32 either XY or ZPixmap */
+ if ((header.pixmap_format == XYPixmap) || (header.pixmap_format == ZPixmap))
+ switch (header.bitmap_pad)
+ {
+ case 8:
+ case 16:
+ case 32:
+ break;
+ default:
+ {
+ ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
+ }
+ }
+
+ /* xoffset should be in the bounds of pixmap_width */
+ if (header.xoffset >= header.pixmap_width)
+ ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
+
+ /* Bits per pixel (ZPixmap) */
+ switch (header.visual_class)
+ {
+ case StaticGray:
+ case GrayScale:
+ /* Gray-scale image */
+ if (header.bits_per_pixel != 1)
+ ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
+ break;
+ case StaticColor:
+ case PseudoColor:
+ /* Color-mapped image */
+ if ((header.bits_per_pixel < 1) || (header.bits_per_pixel > 15) ||
+ (header.ncolors == 0))
+ ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
+ break;
+ case TrueColor:
+ case DirectColor:
+ /* True-color image */
+ if ((header.bits_per_pixel != 16) && (header.bits_per_pixel != 24) &&
+ (header.bits_per_pixel != 32))
+ ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
+ break;
+ }
+
+ /* Place an arbitrary limit on colormap size */
+ if (header.ncolors > 4096)
+ ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
+
+
+ /* 8, 16, 32 either XY or ZPixmap */
+ if ((header.bitmap_pad % 8 != 0) || (header.bitmap_pad > 32))
+ ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
+
+ {
+ size_t
+ bytes_per_line=0,
+ scanline_bits;
+
+ if (BytesPerLine(&bytes_per_line,&scanline_bits,
+ header.pixmap_width,header.pixmap_depth,header.bitmap_pad)
+ == MagickFail)
+ ThrowReaderException(CoderError,ArithmeticOverflow,image);
+
+ if (header.bytes_per_line < bytes_per_line)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Header bytes_per_line = %" MAGICK_SIZE_T_F "u,"
+ " expected %" MAGICK_SIZE_T_F "u",
+ (MAGICK_SIZE_T) header.bytes_per_line,
+ (MAGICK_SIZE_T) bytes_per_line);
+ ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
+ }
+ }
+
+
/*
Retrieve comment (if any)
*/
length=header.header_size-sz_XWDheader;
- if (length > ((~0UL)/sizeof(*comment)))
+ if (length >= MaxTextExtent)
ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
- comment=MagickAllocateMemory(char *,length+1);
- if (comment == (char *) NULL)
- ThrowXWDReaderException(ResourceLimitError,MemoryAllocationFailed,image);
count=ReadBlob(image,length,comment);
if (count != length)
ThrowXWDReaderException(CorruptImageError,UnableToReadWindowNameFromDumpFile,
image);
comment[length]='\0';
(void) SetImageAttribute(image,"comment",comment);
- MagickFreeMemory(comment);
+
/*
Initialize the X image.
@@ -348,37 +551,29 @@ static Image *ReadXWDImage(const ImageIn
ximage->red_mask=header.red_mask;
ximage->green_mask=header.green_mask;
ximage->blue_mask=header.blue_mask;
- /*
- XImage uses signed integers rather than unsigned. Check for
- overflow due to assignment.
- */
- if (ximage->width < 0 ||
- ximage->height < 0 ||
- ximage->format < 0 ||
- ximage->byte_order < 0 ||
- ximage->bitmap_unit < 0 ||
- ximage->bitmap_bit_order < 0 ||
- ximage->bitmap_pad < 0 ||
- ximage->depth < 0 ||
- ximage->bytes_per_line < 0 ||
- ximage->bits_per_pixel < 0)
- ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
- /* Guard against buffer overflow in libX11. */
- if (ximage->bits_per_pixel > 32 || ximage->bitmap_unit > 32)
- ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
+
status=XInitImage(ximage);
if (status == False)
ThrowXWDReaderException(CorruptImageError,UnrecognizedXWDHeader,image);
- image->columns=ximage->width;
- image->rows=ximage->height;
+
+ if (image->logging)
+ TraceXImage(ximage);
+
+ image->columns=(unsigned long) ximage->width;
+ image->rows=(unsigned long) ximage->height;
if (!image_info->ping)
if (CheckImagePixelLimits(image, exception) != MagickPass)
ThrowXWDReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
image->depth=8;
- if ((header.ncolors == 0U) ||
- ((ximage->red_mask != 0) ||
- (ximage->green_mask != 0) ||
- (ximage->blue_mask != 0)))
+
+ /*
+ FIXME: This block of logic should be re-worked.
+ */
+ if ((header.visual_class != StaticGray) &&
+ ((header.ncolors == 0U) ||
+ ((ximage->red_mask != 0) ||
+ (ximage->green_mask != 0) ||
+ (ximage->blue_mask != 0))))
{
image->storage_class=DirectClass;
if (!image_info->ping)
@@ -390,8 +585,8 @@ static Image *ReadXWDImage(const ImageIn
else
{
image->storage_class=PseudoClass;
+ image->colors=header.visual_class == StaticGray ? 2 : header.ncolors; /* FIXME! */
}
- image->colors=header.ncolors;
if (!image_info->ping)
{
/*
@@ -403,17 +598,14 @@ static Image *ReadXWDImage(const ImageIn
XWDColor
color;
- register long
+ register unsigned int
i;
- length=(size_t) header.ncolors;
- if (length > ((~0UL)/sizeof(*colors)))
- ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
- colors=MagickAllocateArray(XColor *,length,sizeof(XColor));
+ colors=MagickAllocateArray(XColor *,header.ncolors,sizeof(XColor));
if (colors == (XColor *) NULL)
ThrowXWDReaderException(ResourceLimitError,MemoryAllocationFailed,
image);
- for (i=0; i < (long) header.ncolors; i++)
+ for (i=0; i < header.ncolors; i++)
{
count=ReadBlob(image,sz_XWDColor,(char *) &color);
if (count != sz_XWDColor)
@@ -430,7 +622,7 @@ static Image *ReadXWDImage(const ImageIn
*/
lsb_first=1;
if (*(char *) &lsb_first)
- for (i=0; i < (long) header.ncolors; i++)
+ for (i=0; i < header.ncolors; i++)
{
MSBOrderLong((unsigned char *) &colors[i].pixel,
sizeof(unsigned long));
@@ -444,18 +636,32 @@ static Image *ReadXWDImage(const ImageIn
/*
Allocate the pixel buffer.
*/
-#define XWD_OVERFLOW(c,a,b) ((b) != 0 && ((c)/((size_t) b) != ((size_t) a)))
- length=ximage->bytes_per_line*ximage->height;
- if (XWD_OVERFLOW(length,ximage->bytes_per_line,ximage->height))
+ length=MagickArraySize(ximage->bytes_per_line,ximage->height);
+ if (0 == length)
ThrowXWDReaderException(ResourceLimitError,MemoryAllocationFailed,image);
if (ximage->format != ZPixmap)
{
- size_t tmp=length;
- length*=ximage->depth;
- if (XWD_OVERFLOW(length,tmp,ximage->depth))
+ length=MagickArraySize(length,ximage->depth);
+ if (0 == length)
ThrowXWDReaderException(ResourceLimitError,MemoryAllocationFailed,
image);
}
+ {
+
+ magick_off_t
+ file_size;
+
+ file_size=GetBlobSize(image);
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "File size %" MAGICK_OFF_F "d,"
+ "Pixels allocation size %" MAGICK_SIZE_T_F "u",
+ file_size, (MAGICK_SIZE_T) length);
+
+ if ((file_size != 0) && ((size_t) file_size < length))
+ ThrowXWDReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ }
+
ximage->data=MagickAllocateMemory(char *,length);
if (ximage->data == (char *) NULL)
ThrowXWDReaderException(ResourceLimitError,MemoryAllocationFailed,image);
@@ -507,7 +713,7 @@ static Image *ReadXWDImage(const ImageIn
/*
Convert X image to DirectClass packets.
*/
- if (image->colors != 0)
+ if (header.ncolors != 0)
{
for (y=0; y < (long) image->rows; y++)
{
@@ -519,12 +725,15 @@ static Image *ReadXWDImage(const ImageIn
pixel=XGetPixel(ximage,(int) x,(int) y);
index_val=(unsigned short)
((pixel >> red_shift) & red_mask);
+ VerifyColormapIndexWithColors(image,index_val,header.ncolors);
q->red=ScaleShortToQuantum(colors[index_val].red);
index_val=(unsigned short)
((pixel >> green_shift) & green_mask);
+ VerifyColormapIndexWithColors(image,index_val,header.ncolors);
q->green=ScaleShortToQuantum(colors[index_val].green);
index_val=(unsigned short)
((pixel >> blue_shift) & blue_mask);
+ VerifyColormapIndexWithColors(image,index_val,header.ncolors);
q->blue=ScaleShortToQuantum(colors[index_val].blue);
q++;
}
@@ -575,17 +784,21 @@ static Image *ReadXWDImage(const ImageIn
/*
Convert X image to PseudoClass packets.
*/
- register long
+ register unsigned int
i;
if (!AllocateImageColormap(image,image->colors))
ThrowXWDReaderException(ResourceLimitError,MemoryAllocationFailed,
image);
- for (i=0; i < (long) image->colors; i++)
+ if (colors != (XColor *) NULL)
{
- image->colormap[i].red=ScaleShortToQuantum(colors[i].red);
- image->colormap[i].green=ScaleShortToQuantum(colors[i].green);
- image->colormap[i].blue=ScaleShortToQuantum(colors[i].blue);
+ const unsigned int min_colors = Min(image->colors,header.ncolors);
+ for (i=0; i < min_colors; i++)
+ {
+ image->colormap[i].red=ScaleShortToQuantum(colors[i].red);
+ image->colormap[i].green=ScaleShortToQuantum(colors[i].green);
+ image->colormap[i].blue=ScaleShortToQuantum(colors[i].blue);
+ }
}
for (y=0; y < (long) image->rows; y++)
{
@@ -722,16 +935,16 @@ ModuleExport void UnregisterXWDImage(voi
*/
static unsigned int WriteXWDImage(const ImageInfo *image_info,Image *image)
{
- long
+ unsigned long
y;
register const PixelPacket
*p;
- register long
+ register unsigned long
x;
- register long
+ register unsigned int
i;
register unsigned char
@@ -740,17 +953,22 @@ static unsigned int WriteXWDImage(const
unsigned char
*pixels;
+ unsigned int
+ bits_per_pixel;
+
size_t
- pixels_size;
+ bytes_per_line=0,
+ scanline_bits,
+ scanline_pad=0;
unsigned int
+ bitmap_pad;
+
+ MagickPassFail
status;
unsigned long
- bits_per_pixel,
- bytes_per_line,
- lsb_first,
- scanline_pad;
+ lsb_first;
XWDFileHeader
xwd_info;
@@ -763,7 +981,7 @@ static unsigned int WriteXWDImage(const
assert(image != (Image *) NULL);
assert(image->signature == MagickSignature);
status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
- if (status == False)
+ if (status == MagickFail)
ThrowWriterException(FileOpenError,UnableToOpenFile,image);
(void) TransformColorspace(image,RGBColorspace);
/*
@@ -771,6 +989,40 @@ static unsigned int WriteXWDImage(const
*/
if ((image->storage_class == PseudoClass) && (image->colors > 256))
SetImageType(image,TrueColorType);
+
+ /*
+ Compute required allocation sizes
+
+ BitmapUnit is the size of each data unit in each scan line. This
+ value may be 8, 16, or 32.
+
+ BitmapPad is the number of bits of padding added to each scan
+ line. This value may be 8, 16, or 32.
+ */
+ bits_per_pixel=(image->storage_class == DirectClass ? 24 : 8);
+ bitmap_pad=(image->storage_class == DirectClass ? 32 : 8);
+
+ if (BytesPerLine(&bytes_per_line,&scanline_bits,image->columns,
+ bits_per_pixel,bitmap_pad) != MagickFail)
+ scanline_pad=(bytes_per_line-(scanline_bits >> 3));
+
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " image->columns=%lu,"
+ " bits_per_pixel=%u,"
+ " bytes_per_line=%" MAGICK_SIZE_T_F "u,"
+ " bitmap_pad=%u",
+ image->columns,
+ bits_per_pixel,
+ (MAGICK_SIZE_T) bytes_per_line,
+ bitmap_pad);
+ if ((scanline_bits == 0) || (bytes_per_line < (scanline_bits >> 3)))
+ ThrowWriterException(CoderError,ArithmeticOverflow,image);
+
+ if (((bytes_per_line & 0x7fffffff) != bytes_per_line) ||
+ ((image->rows & 0x7fffffff) != image->rows))
+ ThrowWriterException(CoderError,ImageColumnOrRowSizeIsNotSupported,image);
+
/*
Initialize XWD file header.
*/
@@ -785,19 +1037,14 @@ static unsigned int WriteXWDImage(const
xwd_info.byte_order=(CARD32) MSBFirst;
xwd_info.bitmap_unit=(CARD32) (image->storage_class == DirectClass ? 32 : 8);
xwd_info.bitmap_bit_order=(CARD32) MSBFirst;
- xwd_info.bitmap_pad=(CARD32) (image->storage_class == DirectClass ? 32 : 8);
- bits_per_pixel=(image->storage_class == DirectClass ? 24 : 8);
+ xwd_info.bitmap_pad=(CARD32) bitmap_pad;
xwd_info.bits_per_pixel=(CARD32) bits_per_pixel;
- bytes_per_line=(CARD32) ((((xwd_info.bits_per_pixel*
- xwd_info.pixmap_width)+((xwd_info.bitmap_pad)-1))/
- (xwd_info.bitmap_pad))*((xwd_info.bitmap_pad) >> 3));
xwd_info.bytes_per_line=(CARD32) bytes_per_line;
xwd_info.visual_class=(CARD32)
(image->storage_class == DirectClass ? DirectColor : PseudoColor);
xwd_info.red_mask=(CARD32)
(image->storage_class == DirectClass ? 0xff0000 : 0);
- xwd_info.green_mask=(CARD32)
- (image->storage_class == DirectClass ? 0xff00 : 0);
+ xwd_info.green_mask=(CARD32)(image->storage_class == DirectClass ? 0xff00 : 0);
xwd_info.blue_mask=(CARD32) (image->storage_class == DirectClass ? 0xff : 0);
xwd_info.bits_per_rgb=(CARD32) (image->storage_class == DirectClass ? 24 : 8);
xwd_info.colormap_entries=(CARD32)
@@ -809,6 +1056,20 @@ static unsigned int WriteXWDImage(const
xwd_info.window_x=0;
xwd_info.window_y=0;
xwd_info.window_bdrwidth=(CARD32) 0;
+
+ /*
+ Trace XWD header
+ */
+ if (image->logging)
+ TraceXWDHeader(&xwd_info);
+
+ /*
+ Allocate memory for pixels.
+ */
+ pixels=MagickAllocateMemory(unsigned char *,bytes_per_line);
+ if (pixels == (unsigned char *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+
/*
Write XWD header.
*/
@@ -832,7 +1093,7 @@ static unsigned int WriteXWDImage(const
colors=MagickAllocateArray(XColor *,image->colors,sizeof(XColor));
if (colors == (XColor *) NULL)
ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
- for (i=0; i < (long) image->colors; i++)
+ for (i=0; i < image->colors; i++)
{
colors[i].pixel=i;
colors[i].red=ScaleQuantumToShort(image->colormap[i].red);
@@ -846,30 +1107,22 @@ static unsigned int WriteXWDImage(const
MSBOrderShort((unsigned char *) &colors[i].red,3*sizeof(short));
}
}
- for (i=0; i < (long) image->colors; i++)
+ for (i=0; i < image->colors; i++)
{
color.pixel=(CARD32) colors[i].pixel;
color.red=colors[i].red;
color.green=colors[i].green;
color.blue=colors[i].blue;
color.flags=colors[i].flags;
- (void) WriteBlob(image,sz_XWDColor,(char *) &color);
+ if (WriteBlob(image,sz_XWDColor,(char *) &color) != sz_XWDColor)
+ break;
}
MagickFreeMemory(colors);
}
/*
- Allocate memory for pixels.
- */
- scanline_pad=(bytes_per_line-((image->columns*bits_per_pixel) >> 3));
- pixels_size=image->columns*(image->storage_class == PseudoClass ? 1 : 3)+scanline_pad;
- pixels=MagickAllocateMemory(unsigned char *,pixels_size);
- if (pixels == (unsigned char *) NULL)
- ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
- (void) memset(pixels,0,pixels_size);
- /*
Convert MIFF to XWD raster pixels.
*/
- for (y=0; y < (long) image->rows; y++)
+ for (y=0; y < image->rows; y++)
{
p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
if (p == (const PixelPacket *) NULL)
@@ -882,12 +1135,12 @@ static unsigned int WriteXWDImage(const
*indexes;
indexes=AccessImmutableIndexes(image);
- for (x=0; x < (long) image->columns; x++)
+ for (x=0; x < image->columns; x++)
*q++=(unsigned char) indexes[x];
}
else
{
- for (x=(long) image->columns; x > 0; x--)
+ for (x=0; x < image->columns; x++)
{
*q++=ScaleQuantumToChar(p->red);
@@ -898,7 +1151,8 @@ static unsigned int WriteXWDImage(const
}
for (x=(long) scanline_pad; x > 0; x--)
*q++=0;
- (void) WriteBlob(image,(size_t) (q-pixels),(char *) pixels);
+ if (WriteBlob(image,(size_t) (q-pixels),(char *) pixels) != (size_t) (q-pixels))
+ break;
if (image->previous == (Image *) NULL)
if (QuantumTick(y,image->rows))
if (!MagickMonitorFormatted(y,image->rows,&image->exception,
@@ -908,6 +1162,6 @@ static unsigned int WriteXWDImage(const
}
MagickFreeMemory(pixels);
CloseBlob(image);
- return(True);
+ return (y < image->rows ? MagickFail : MagickPass);
}
#endif