% Read/Write Apple Macintosh QuickDraw/PICT Format %
% %
% Software Design %
-% John Cristy %
+% Cristy %
% July 1992 %
% %
% %
-% Copyright 1999-2011 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 %
ThrowReaderException(CorruptImageError,"ImproperImageHeader"); \
}
-#define ReadRectangle(image,rectangle) \
-{ \
- rectangle.top=(short) ReadBlobMSBShort(image); \
- rectangle.left=(short) ReadBlobMSBShort(image); \
- rectangle.bottom=(short) ReadBlobMSBShort(image); \
- rectangle.right=(short) ReadBlobMSBShort(image); \
- if ((rectangle.left > rectangle.right) || \
- (rectangle.top > rectangle.bottom)) \
- ThrowReaderException(CorruptImageError,"ImproperImageHeader"); \
-}
-
typedef struct _PICTCode
{
const char
}
static unsigned char *DecodeImage(Image *blob,Image *image,
- size_t bytes_per_line,const unsigned int bits_per_pixel,size_t *extent)
+ size_t bytes_per_line,const unsigned int bits_per_pixel,size_t *extent,
+ ExceptionInfo *exception)
{
MagickSizeType
number_pixels;
}
else
if (bits_per_pixel == 32)
- width*=image->matte ? 4 : 3;
+ width*=image->alpha_trait ? 4 : 3;
if (bytes_per_line == 0)
bytes_per_line=width;
row_bytes=(size_t) (image->columns | 0x8000);
p=ExpandBuffer(scanline,&number_pixels,bits_per_pixel);
if ((q+number_pixels) > (pixels+(*extent)))
{
- (void) ThrowMagickException(&image->exception,GetMagickModule(),
+ (void) ThrowMagickException(exception,GetMagickModule(),
CorruptImageError,"UnableToUncompressImage","`%s'",
image->filename);
break;
scanline_length=1UL*ReadBlobByte(blob);
if (scanline_length >= row_bytes)
{
- (void) ThrowMagickException(&image->exception,GetMagickModule(),
+ (void) ThrowMagickException(exception,GetMagickModule(),
CorruptImageError,"UnableToUncompressImage","`%s'",image->filename);
break;
}
*/
static MagickBooleanType IsPICT(const unsigned char *magick,const size_t length)
{
+ if (length < 12)
+ return(MagickFalse);
+ /*
+ Embedded OLE2 macintosh have "PICT" instead of 512 platform header.
+ */
+ if (memcmp(magick,"PICT",4) == 0)
+ return(MagickTrue);
if (length < 528)
return(MagickFalse);
if (memcmp(magick+522,"\000\021\002\377\014\000",6) == 0)
return(y);
}
+static MagickBooleanType ReadRectangle(Image *image,PICTRectangle *rectangle)
+{
+ rectangle->top=(short) ReadBlobMSBShort(image);
+ rectangle->left=(short) ReadBlobMSBShort(image);
+ rectangle->bottom=(short) ReadBlobMSBShort(image);
+ rectangle->right=(short) ReadBlobMSBShort(image);
+ if ((rectangle->left > rectangle->right) ||
+ (rectangle->top > rectangle->bottom))
+ return(MagickFalse);
+ return(MagickTrue);
+}
+
static Image *ReadPICTImage(const ImageInfo *image_info,
ExceptionInfo *exception)
{
char
- geometry[MaxTextExtent];
+ geometry[MaxTextExtent],
+ header_ole[4];
Image
*image;
image_info->filename);
assert(exception != (ExceptionInfo *) NULL);
assert(exception->signature == MagickSignature);
- image=AcquireImage(image_info);
- image->depth=8;
+ image=AcquireImage(image_info,exception);
status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
if (status == MagickFalse)
{
*/
pixmap.bits_per_pixel=0;
pixmap.component_count=0;
- for (i=0; i < 512; i++)
- (void) ReadBlobByte(image); /* skip header */
+ /*
+ Skip header : 512 for standard PICT and 4, ie "PICT" for OLE2.
+ */
+ header_ole[0]=ReadBlobByte(image);
+ header_ole[1]=ReadBlobByte(image);
+ header_ole[2]=ReadBlobByte(image);
+ header_ole[3]=ReadBlobByte(image);
+ if (!((header_ole[0] == 0x50) && (header_ole[1] == 0x49) &&
+ (header_ole[2] == 0x43) && (header_ole[3] == 0x54 )))
+ for (i=0; i < 508; i++)
+ (void) ReadBlobByte(image);
(void) ReadBlobMSBShort(image); /* skip picture size */
- ReadRectangle(image,frame);
+ if (ReadRectangle(image,&frame) == MagickFalse)
+ ThrowReaderException(CorruptImageError,"ImproperImageHeader");
while ((c=ReadBlobByte(image)) == 0) ;
if (c != 0x11)
ThrowReaderException(CorruptImageError,"ImproperImageHeader");
Create black canvas.
*/
flags=0;
+ image->depth=8;
image->columns=1UL*(frame.right-frame.left);
image->rows=1UL*(frame.bottom-frame.top);
- image->x_resolution=DefaultResolution;
- image->y_resolution=DefaultResolution;
+ image->resolution.x=DefaultResolution;
+ image->resolution.y=DefaultResolution;
image->units=UndefinedResolution;
/*
Interpret PICT opcodes.
code=ReadBlobByte(image);
if (version == 2)
code=(int) ReadBlobMSBShort(image);
+ if (code < 0)
+ break;
if (code > 0xa1)
{
if (image->debug != MagickFalse)
(void) ReadBlobByte(image);
break;
}
- ReadRectangle(image,frame);
+ if (ReadRectangle(image,&frame) == MagickFalse)
+ ThrowReaderException(CorruptImageError,"ImproperImageHeader");
if (((frame.left & 0x8000) != 0) || ((frame.top & 0x8000) != 0))
break;
image->columns=1UL*(frame.right-frame.left);
image->rows=1UL*(frame.bottom-frame.top);
- (void) SetImageBackgroundColor(image);
+ (void) SetImageBackgroundColor(image,exception);
break;
}
case 0x12:
if (pattern != 1)
ThrowReaderException(CorruptImageError,"UnknownPatternType");
length=ReadBlobMSBShort(image);
- ReadRectangle(image,frame);
+ if (ReadRectangle(image,&frame) == MagickFalse)
+ ThrowReaderException(CorruptImageError,"ImproperImageHeader");
ReadPixmap(pixmap);
image->depth=1UL*pixmap.component_size;
- image->x_resolution=1.0*pixmap.horizontal_resolution;
- image->y_resolution=1.0*pixmap.vertical_resolution;
+ image->resolution.x=1.0*pixmap.horizontal_resolution;
+ image->resolution.y=1.0*pixmap.vertical_resolution;
image->units=PixelsPerInchResolution;
(void) ReadBlobMSBLong(image);
flags=1L*ReadBlobMSBShort(image);
(void) ReadBlobMSBShort(image);
(void) ReadBlobMSBShort(image);
}
- ReadRectangle(image,frame);
+ if (ReadRectangle(image,&frame) == MagickFalse)
+ ThrowReaderException(CorruptImageError,"ImproperImageHeader");
/*
Initialize tile image.
*/
{
ReadPixmap(pixmap);
tile_image->depth=1UL*pixmap.component_size;
- tile_image->matte=pixmap.component_count == 4 ?
- MagickTrue : MagickFalse;
- tile_image->x_resolution=(double) pixmap.horizontal_resolution;
- tile_image->y_resolution=(double) pixmap.vertical_resolution;
+ tile_image->alpha_trait=pixmap.component_count == 4 ?
+ BlendPixelTrait : UndefinedPixelTrait;
+ tile_image->resolution.x=(double) pixmap.horizontal_resolution;
+ tile_image->resolution.y=(double) pixmap.vertical_resolution;
tile_image->units=PixelsPerInchResolution;
- if (tile_image->matte != MagickFalse)
- image->matte=tile_image->matte;
+ if (tile_image->alpha_trait == BlendPixelTrait)
+ image->alpha_trait=tile_image->alpha_trait;
}
if ((code != 0x9a) && (code != 0x9b))
{
flags=1L*ReadBlobMSBShort(image);
tile_image->colors=1UL*ReadBlobMSBShort(image)+1;
}
- status=AcquireImageColormap(tile_image,tile_image->colors);
+ status=AcquireImageColormap(tile_image,tile_image->colors,
+ exception);
if (status == MagickFalse)
{
tile_image=DestroyImage(tile_image);
}
}
}
- ReadRectangle(image,source);
- ReadRectangle(image,destination);
+ if (ReadRectangle(image,&source) == MagickFalse)
+ ThrowReaderException(CorruptImageError,"ImproperImageHeader");
+ if (ReadRectangle(image,&destination) == MagickFalse)
+ ThrowReaderException(CorruptImageError,"ImproperImageHeader");
(void) ReadBlobMSBShort(image);
if ((code == 0x91) || (code == 0x99) || (code == 0x9b))
{
}
if ((code != 0x9a) && (code != 0x9b) &&
(bytes_per_line & 0x8000) == 0)
- pixels=DecodeImage(image,tile_image,1UL*bytes_per_line,1,&extent);
+ pixels=DecodeImage(image,tile_image,1UL*bytes_per_line,1,&extent,
+ exception);
else
pixels=DecodeImage(image,tile_image,1UL*bytes_per_line,1U*
- pixmap.bits_per_pixel,&extent);
+ pixmap.bits_per_pixel,&extent,exception);
if (pixels == (unsigned char *) NULL)
{
tile_image=DestroyImage(tile_image);
ThrowReaderException(CorruptImageError,"NotEnoughPixelData");
q=QueueAuthenticPixels(tile_image,0,y,tile_image->columns,1,
exception);
- if (q == (const Quantum *) NULL)
+ if (q == (Quantum *) NULL)
break;
for (x=0; x < (ssize_t) tile_image->columns; x++)
{
if (tile_image->storage_class == PseudoClass)
{
- index=ConstrainColormapIndex(tile_image,*p);
+ index=ConstrainColormapIndex(tile_image,*p,exception);
SetPixelIndex(tile_image,index,q);
SetPixelRed(tile_image,
tile_image->colormap[(ssize_t) index].red,q);
(unsigned char) ((j & 0x1f) << 3)),q);
}
else
- if (tile_image->matte == MagickFalse)
+ if (tile_image->alpha_trait != BlendPixelTrait)
{
if (p > (pixels+extent+2*image->columns))
ThrowReaderException(CorruptImageError,
if (jpeg == MagickFalse)
if ((code == 0x9a) || (code == 0x9b) ||
((bytes_per_line & 0x8000) != 0))
- (void) CompositeImage(image,CopyCompositeOp,tile_image,
- destination.left,destination.top);
+ (void) CompositeImage(image,tile_image,CopyCompositeOp,
+ MagickTrue,destination.left,destination.top,exception);
tile_image=DestroyImage(tile_image);
break;
}
{
if (length == 0)
break;
- profile=AcquireStringInfo(length);
+ profile=BlobToStringInfo((const void *) NULL,length);
SetStringInfoDatum(profile,info);
- status=SetImageProfile(image,"icc",profile);
+ status=SetImageProfile(image,"icc",profile,exception);
profile=DestroyStringInfo(profile);
if (status == MagickFalse)
ThrowReaderException(ResourceLimitError,
{
if (length == 0)
break;
- profile=AcquireStringInfo(length);
+ profile=BlobToStringInfo((const void *) NULL,length);
SetStringInfoDatum(profile,info);
- status=SetImageProfile(image,"iptc",profile);
+ status=SetImageProfile(image,"iptc",profile,exception);
if (status == MagickFalse)
ThrowReaderException(ResourceLimitError,
"MemoryAllocationFailed");
/*
Skip to next op code.
*/
+ if (code < 0)
+ break;
if (codes[code].length == -1)
(void) ReadBlobMSBShort(image);
else
file=fdopen(unique_file,"wb");
if ((unique_file == -1) || (file == (FILE *) NULL))
{
+ if (file != (FILE *) NULL)
+ (void) fclose(file);
(void) CopyMagickString(image->filename,read_info->filename,
MaxTextExtent);
ThrowFileException(exception,FileOpenError,
length=ReadBlobMSBLong(image);
for (i=0; i < 6; i++)
(void) ReadBlobMSBLong(image);
- ReadRectangle(image,frame);
+ if (ReadRectangle(image,&frame) == MagickFalse)
+ {
+ (void) fclose(file);
+ ThrowReaderException(CorruptImageError,"ImproperImageHeader");
+ }
for (i=0; i < 122; i++)
(void) ReadBlobByte(image);
for (i=0; i < (ssize_t) (length-154); i++)
(void) fputc(c,file);
}
(void) fclose(file);
+ (void) close(unique_file);
tile_image=ReadImage(read_info,exception);
(void) RelinquishUniqueFileResource(read_info->filename);
read_info=DestroyImageInfo(read_info);
(void) SetImageExtent(image,
MagickMax(image->columns,tile_image->columns),
MagickMax(image->rows,tile_image->rows),exception);
- if (IsRGBColorspace(image->colorspace) == MagickFalse)
- (void) TransformImageColorspace(image,tile_image->colorspace);
- (void) CompositeImage(image,CopyCompositeOp,tile_image,frame.left,
- frame.right);
+ (void) TransformImageColorspace(image,tile_image->colorspace,exception);
+ (void) CompositeImage(image,tile_image,CopyCompositeOp,MagickTrue,
+ frame.left,frame.right,exception);
image->compression=tile_image->compression;
tile_image=DestroyImage(tile_image);
continue;
status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
if (status == MagickFalse)
return(status);
- if (IsRGBColorspace(image->colorspace) == MagickFalse)
- (void) TransformImageColorspace(image,RGBColorspace);
+ (void) TransformImageColorspace(image,sRGBColorspace,exception);
/*
Initialize image info.
*/
pixmap.table=0;
pixmap.reserved=0;
transfer_mode=0;
- x_resolution=image->x_resolution != 0.0 ? image->x_resolution :
+ x_resolution=image->resolution.x != 0.0 ? image->resolution.x :
DefaultResolution;
- y_resolution=image->y_resolution != 0.0 ? image->y_resolution :
+ y_resolution=image->resolution.y != 0.0 ? image->resolution.y :
DefaultResolution;
storage_class=image->storage_class;
if (image_info->compression == JPEGCompression)
storage_class=DirectClass;
- if ((storage_class == DirectClass) || (image->matte != MagickFalse))
+ if (storage_class == DirectClass)
{
- pixmap.component_count=image->matte ? 4 : 3;
+ pixmap.component_count=image->alpha_trait == BlendPixelTrait ? 4 : 3;
pixmap.pixel_type=16;
pixmap.bits_per_pixel=32;
pixmap.pack_type=0x04;
Allocate memory.
*/
bytes_per_line=image->columns;
- if ((storage_class == DirectClass) || (image->matte != MagickFalse))
- bytes_per_line*=image->matte ? 4 : 3;
+ if (storage_class == DirectClass)
+ bytes_per_line*=image->alpha_trait == BlendPixelTrait ? 4 : 3;
buffer=(unsigned char *) AcquireQuantumMemory(PictInfoSize,sizeof(*buffer));
packed_scanline=(unsigned char *) AcquireQuantumMemory((size_t)
(row_bytes+MaxCount),sizeof(*packed_scanline));
Write picture data.
*/
count=0;
- if ((storage_class == PseudoClass) && (image->matte == MagickFalse))
+ if (storage_class == PseudoClass)
for (y=0; y < (ssize_t) image->rows; y++)
{
p=GetVirtualPixels(image,0,y,image->columns,1,exception);
red=scanline;
green=scanline+image->columns;
blue=scanline+2*image->columns;
- if (image->matte != MagickFalse)
+ if (image->alpha_trait == BlendPixelTrait)
{
opacity=scanline;
red=scanline+image->columns;
*red++=ScaleQuantumToChar(GetPixelRed(image,p));
*green++=ScaleQuantumToChar(GetPixelGreen(image,p));
*blue++=ScaleQuantumToChar(GetPixelBlue(image,p));
- if (image->matte != MagickFalse)
+ if (image->alpha_trait == BlendPixelTrait)
*opacity++=ScaleQuantumToChar((Quantum) (GetPixelAlpha(image,p)));
p+=GetPixelChannels(image);
}