% July 1992 %
% %
% %
-% Copyright 1999-2010 ImageMagick Studio LLC, a non-profit organization %
+% Copyright 1999-2011 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 %
/*
Include declarations.
*/
-#include "magick/studio.h"
-#include "magick/artifact.h"
-#include "magick/blob.h"
-#include "magick/blob-private.h"
-#include "magick/cache.h"
-#include "magick/colormap.h"
-#include "magick/colorspace.h"
-#include "magick/constitute.h"
-#include "magick/enhance.h"
-#include "magick/exception.h"
-#include "magick/exception-private.h"
-#include "magick/image.h"
-#include "magick/image-private.h"
-#include "magick/list.h"
-#include "magick/log.h"
-#include "magick/magick.h"
-#include "magick/memory_.h"
-#include "magick/module.h"
-#include "magick/monitor-private.h"
-#include "magick/profile.h"
-#include "magick/property.h"
-#include "magick/quantum-private.h"
-#include "magick/static.h"
-#include "magick/string_.h"
+#include "MagickCore/studio.h"
+#include "MagickCore/artifact.h"
+#include "MagickCore/attribute.h"
+#include "MagickCore/blob.h"
+#include "MagickCore/blob-private.h"
+#include "MagickCore/cache.h"
+#include "MagickCore/colormap.h"
+#include "MagickCore/colorspace.h"
+#include "MagickCore/colorspace-private.h"
+#include "MagickCore/constitute.h"
+#include "MagickCore/enhance.h"
+#include "MagickCore/exception.h"
+#include "MagickCore/exception-private.h"
+#include "MagickCore/image.h"
+#include "MagickCore/image-private.h"
+#include "MagickCore/list.h"
+#include "MagickCore/log.h"
+#include "MagickCore/magick.h"
+#include "MagickCore/memory_.h"
+#include "MagickCore/module.h"
+#include "MagickCore/monitor-private.h"
+#include "MagickCore/pixel.h"
+#include "MagickCore/pixel-accessor.h"
+#include "MagickCore/profile.h"
+#include "MagickCore/property.h"
+#include "MagickCore/quantum-private.h"
+#include "MagickCore/static.h"
+#include "MagickCore/string_.h"
\f
/*
Define declaractions.
*/
#define MaxPSDChannels 56
-#define PSDQuantum(x) (((long) (x)+1) & -2)
+#define PSDQuantum(x) (((ssize_t) (x)+1) & -2)
\f
/*
Enumerated declaractions.
short int
type;
- unsigned long
+ size_t
size;
} ChannelInfo;
visible,
flags;
- unsigned long
+ size_t
offset_x,
offset_y;
unsigned char
reserved[6];
- unsigned long
+ size_t
rows,
columns;
Forward declarations.
*/
static MagickBooleanType
- WritePSDImage(const ImageInfo *,Image *);
+ WritePSDImage(const ImageInfo *,Image *,ExceptionInfo *);
\f
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
}
static ssize_t DecodePSDPixels(const size_t number_compact_pixels,
- const unsigned char *compact_pixels,const long depth,
+ const unsigned char *compact_pixels,const ssize_t depth,
const size_t number_pixels,unsigned char *pixels)
{
int
i,
j;
- ssize_t
- packets;
-
size_t
length;
+ ssize_t
+ packets;
+
packets=(ssize_t) number_compact_pixels;
for (i=0; (packets > 1) && (i < (ssize_t) number_pixels); )
{
return((MagickSizeType) ReadBlobMSBLongLong(image));
}
-static inline long MagickAbsoluteValue(const long x)
+static inline ssize_t MagickAbsoluteValue(const ssize_t x)
{
if (x < 0)
return(-x);
StringInfo
*profile;
- unsigned long
+ unsigned int
count,
long_sans;
if (length < 16)
return(MagickFalse);
- profile=AcquireStringInfo(length);
+ profile=BlobToStringInfo((const void *) NULL,length);
SetStringInfoDatum(profile,blocks);
(void) SetImageProfile(image,"8bim",profile);
profile=DestroyStringInfo(profile);
{
if (LocaleNCompare((const char *) p,"8BIM",4) != 0)
break;
- p=PushLongPixel(LSBEndian,p,&long_sans);
- p=PushShortPixel(LSBEndian,p,&id);
- p=PushShortPixel(LSBEndian,p,&short_sans);
- p=PushLongPixel(LSBEndian,p,&count);
+ p=PushLongPixel(MSBEndian,p,&long_sans);
+ p=PushShortPixel(MSBEndian,p,&id);
+ p=PushShortPixel(MSBEndian,p,&short_sans);
+ p=PushLongPixel(MSBEndian,p,&count);
switch (id)
{
case 0x03ed:
{
+ char
+ value[MaxTextExtent];
+
unsigned short
resolution;
/*
Resolution info.
*/
- p=PushShortPixel(LSBEndian,p,&resolution);
+ p=PushShortPixel(MSBEndian,p,&resolution);
image->x_resolution=(double) resolution;
- p=PushShortPixel(LSBEndian,p,&short_sans);
- p=PushShortPixel(LSBEndian,p,&short_sans);
- p=PushShortPixel(LSBEndian,p,&short_sans);
- p=PushShortPixel(LSBEndian,p,&resolution);
+ (void) FormatLocaleString(value,MaxTextExtent,"%g",image->x_resolution);
+ (void) SetImageProperty(image,"tiff:XResolution",value);
+ p=PushShortPixel(MSBEndian,p,&short_sans);
+ p=PushShortPixel(MSBEndian,p,&short_sans);
+ p=PushShortPixel(MSBEndian,p,&short_sans);
+ p=PushShortPixel(MSBEndian,p,&resolution);
image->y_resolution=(double) resolution;
- p=PushShortPixel(LSBEndian,p,&short_sans);
- p=PushShortPixel(LSBEndian,p,&short_sans);
- p=PushShortPixel(LSBEndian,p,&short_sans);
+ (void) FormatLocaleString(value,MaxTextExtent,"%g",image->y_resolution);
+ (void) SetImageProperty(image,"tiff:YResolution",value);
+ p=PushShortPixel(MSBEndian,p,&short_sans);
+ p=PushShortPixel(MSBEndian,p,&short_sans);
+ p=PushShortPixel(MSBEndian,p,&short_sans);
break;
}
default:
return(OverCompositeOp);
}
-static MagickBooleanType ReadPSDLayer(Image *image,
- const unsigned long channels,const unsigned long type,
- const MagickOffsetType *offsets,ExceptionInfo *exception)
+static MagickBooleanType ReadPSDLayer(Image *image,const size_t channels,
+ const ssize_t type,const MagickOffsetType *offsets,ExceptionInfo *exception)
{
- long
- y;
+ ColorspaceType
+ colorspace;
Quantum
pixel;
- register IndexPacket
- *indexes;
-
- register long
- x;
+ register const unsigned char
+ *p;
- register PixelPacket
+ register Quantum
*q;
- register const unsigned char
- *p;
+ register ssize_t
+ x;
size_t
packet_size;
ssize_t
- count;
+ count,
+ y;
unsigned char
*compact_pixels,
length;
length=0;
- for (y=0; y < (long) image->rows; y++)
+ for (y=0; y < (ssize_t) image->rows; y++)
if ((MagickOffsetType) length < offsets[y])
length=(size_t) offsets[y];
compact_pixels=(unsigned char *) AcquireQuantumMemory(length,
image->filename);
(void) ResetMagickMemory(compact_pixels,0,length*sizeof(*compact_pixels));
}
- for (y=0; y < (long) image->rows; y++)
+ colorspace=image->colorspace;
+ for (y=0; y < (ssize_t) image->rows; y++)
{
- if (image->compression != RLECompression)
- count=ReadBlob(image,packet_size*image->columns,pixels);
+ if (image->depth == 1)
+ {
+ if (image->compression != RLECompression)
+ count=ReadBlob(image,(image->columns+7)/8,pixels);
+ else
+ {
+ count=ReadBlob(image,(size_t) offsets[y],compact_pixels);
+ if (count != (ssize_t) offsets[y])
+ break;
+ count=DecodePSDPixels((size_t) offsets[y],compact_pixels,
+ (ssize_t) 123456,(size_t) ((image->columns+7)/8),pixels);
+ }
+ if (count < (ssize_t) ((image->columns+7)/8))
+ break;
+ }
else
{
- count=ReadBlob(image,(size_t) offsets[y],compact_pixels);
- if (count != (ssize_t) offsets[y])
+ if (image->compression != RLECompression)
+ count=ReadBlob(image,packet_size*image->columns,pixels);
+ else
+ {
+ count=ReadBlob(image,(size_t) offsets[y],compact_pixels);
+ if (count != (ssize_t) offsets[y])
+ break;
+ count=DecodePSDPixels((size_t) offsets[y],compact_pixels,
+ (ssize_t) image->depth,packet_size*image->columns,pixels);
+ }
+ if (count < (ssize_t) (packet_size*image->columns))
break;
- count=DecodePSDPixels((size_t) offsets[y],compact_pixels,
- (long) image->depth,packet_size*image->columns,pixels);
}
- if (count < (ssize_t) (packet_size*image->columns))
- break;
q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
- if (q == (PixelPacket *) NULL)
+ if (q == (Quantum *) NULL)
break;
- indexes=GetAuthenticIndexQueue(image);
p=pixels;
- for (x=0; x < (long) image->columns; x++)
+ for (x=0; x < (ssize_t) image->columns; x++)
{
if (packet_size == 1)
pixel=ScaleCharToQuantum(*p++);
{
case -1:
{
- q->opacity=(Quantum) (QuantumRange-pixel);
+ SetPixelAlpha(image,pixel,q);
break;
}
case 0:
{
- q->red=pixel;
+ SetPixelRed(image,pixel,q);
if (channels == 1)
{
- q->green=q->red;
- q->blue=q->red;
+ SetPixelGreen(image,GetPixelRed(image,q),q);
+ SetPixelBlue(image,GetPixelRed(image,q),q);
}
if (image->storage_class == PseudoClass)
{
if (packet_size == 1)
- indexes[x]=(IndexPacket) ScaleQuantumToChar(pixel);
+ SetPixelIndex(image,ScaleQuantumToChar(pixel),q);
else
- indexes[x]=(IndexPacket) ScaleQuantumToShort(pixel);
- *q=image->colormap[(long) indexes[x]];
- q->red=image->colormap[(long) indexes[x]].red;
- q->green=image->colormap[(long) indexes[x]].green;
- q->blue=image->colormap[(long) indexes[x]].blue;
+ SetPixelIndex(image,ScaleQuantumToShort(pixel),q);
+ SetPixelPacket(image,image->colormap+(ssize_t)
+ GetPixelIndex(image,q),q);
+ if (image->depth == 1)
+ {
+ ssize_t
+ bit,
+ number_bits;
+
+ number_bits=image->columns-x;
+ if (number_bits > 8)
+ number_bits=8;
+ for (bit=0; bit < number_bits; bit++)
+ {
+ SetPixelIndex(image,(((unsigned char) pixel) &
+ (0x01 << (7-bit))) != 0 ? 0 : 255,q);
+ SetPixelPacket(image,image->colormap+(ssize_t)
+ GetPixelIndex(image,q),q);
+ q+=GetPixelChannels(image);
+ x++;
+ }
+ q--;
+ x--;
+ }
}
break;
}
case 1:
{
if (image->storage_class == PseudoClass)
- q->opacity=(Quantum) (QuantumRange-pixel);
+ SetPixelAlpha(image,pixel,q);
else
- q->green=pixel;
+ SetPixelGreen(image,pixel,q);
break;
}
case 2:
{
- q->blue=pixel;
+ if (image->storage_class == PseudoClass)
+ SetPixelAlpha(image,pixel,q);
+ else
+ SetPixelBlue(image,pixel,q);
break;
}
case 3:
{
if (image->colorspace == CMYKColorspace)
- indexes[x]=(IndexPacket) pixel;
+ SetPixelBlack(image,pixel,q);
else
- q->opacity=(Quantum) (QuantumRange-pixel);
+ SetPixelAlpha(image,pixel,q);
break;
}
case 4:
{
- q->opacity=(Quantum) (QuantumRange-pixel);
+ if ((IsRGBColorspace(image->colorspace) == MagickTrue) && (channels > 3))
+ break;
+ SetPixelAlpha(image,pixel,q);
break;
}
default:
break;
}
- q++;
+ q+=GetPixelChannels(image);
}
if (SyncAuthenticPixels(image,exception) == MagickFalse)
break;
}
+ image->colorspace=colorspace;
if (image->compression == RLECompression)
compact_pixels=(unsigned char *) RelinquishMagickMemory(compact_pixels);
pixels=(unsigned char *) RelinquishMagickMemory(pixels);
Image
*image;
- IndexPacket
- *indexes;
-
LayerInfo
*layer_info;
- long
- j,
- number_layers,
- y;
-
MagickBooleanType
status;
PSDInfo
psd_info;
- register long
+ register Quantum
+ *q;
+
+ register ssize_t
i,
x;
- register PixelPacket
- *q;
+ size_t
+ mask_size,
+ skip_first_alpha = 0;
ssize_t
- count;
+ count,
+ j,
+ number_layers,
+ y;
unsigned char
*data;
unsigned short
compression;
- unsigned long
- mask_size,
- skip_first_alpha = 0;
-
/*
Open image file.
*/
image_info->filename);
assert(exception != (ExceptionInfo *) NULL);
assert(exception->signature == MagickSignature);
- image=AcquireImage(image_info);
+ image=AcquireImage(image_info,exception);
status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
if (status == MagickFalse)
{
psd_info.mode=ReadBlobMSBShort(image);
if (image->debug != MagickFalse)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
- " Image is %ld x %ld with channels=%d, depth=%d, mode=%s",
- psd_info.columns,psd_info.rows,psd_info.channels,psd_info.depth,
- ModeToString((PSDImageType) psd_info.mode));
+ " Image is %.20g x %.20g with channels=%.20g, depth=%.20g, mode=%s",
+ (double) psd_info.columns,(double) psd_info.rows,(double)
+ psd_info.channels,(double) psd_info.depth,ModeToString((PSDImageType)
+ psd_info.mode));
/*
Initialize image.
*/
if ((psd_info.mode == BitmapMode) || (psd_info.mode == GrayscaleMode) ||
(psd_info.mode == DuotoneMode))
{
- if (AcquireImageColormap(image,256) == MagickFalse)
+ if (AcquireImageColormap(image,256,exception) == MagickFalse)
ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
image->matte=psd_info.channels >= 2 ? MagickTrue : MagickFalse;
if (image->debug != MagickFalse)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
- " ImageColorMap allocated");
+ " Image colormap allocated");
image->colorspace=GRAYColorspace;
}
if (image->debug != MagickFalse)
/*
Read PSD raster colormap.
*/
- if (AcquireImageColormap(image,(unsigned long) (length/3)) == MagickFalse)
+ if (AcquireImageColormap(image,(size_t) (length/3),exception) == MagickFalse)
ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
- for (i=0; i < (long) image->colors; i++)
+ for (i=0; i < (ssize_t) image->colors; i++)
image->colormap[i].red=ScaleCharToQuantum((unsigned char)
ReadBlobByte(image));
- for (i=0; i < (long) image->colors; i++)
+ for (i=0; i < (ssize_t) image->colors; i++)
image->colormap[i].green=ScaleCharToQuantum((unsigned char)
ReadBlobByte(image));
- for (i=0; i < (long) image->colors; i++)
+ for (i=0; i < (ssize_t) image->colors; i++)
image->colormap[i].blue=ScaleCharToQuantum((unsigned char)
ReadBlobByte(image));
image->matte=psd_info.channels >= 2 ? MagickTrue : MagickFalse;
*/
if (image->debug != MagickFalse)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
- " reading image resource blocks - %ld bytes",(long) length);
+ " reading image resource blocks - %.20g bytes",(double)
+ ((MagickOffsetType) length));
blocks=(unsigned char *) AcquireQuantumMemory((size_t) length,
sizeof(*blocks));
if (blocks == (unsigned char *) NULL)
(void) ParseImageResourceBlocks(image,blocks,(size_t) length);
blocks=(unsigned char *) RelinquishMagickMemory(blocks);
}
- /*
- If we are only "pinging" the image, then we're done - so return.
- */
- if (image_info->ping != MagickFalse)
- {
- (void) CloseBlob(image);
- return(GetFirstImageInList(image));
- }
/*
Layer and mask block.
*/
length=ReadBlobMSBLong(image);
}
if ((image_info->number_scenes == 1) && (image_info->scene == 0))
- for ( ; length != 0; length--)
- if (ReadBlobByte(image) == EOF)
- {
- ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
- image->filename);
- break;
- }
+ {
+ if (DiscardBlobBytes(image,length) == MagickFalse)
+ ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
+ image->filename);
+ length=0;
+ }
if (length == 0)
{
if (image->debug != MagickFalse)
size=GetPSDSize(&psd_info,image);
if (size == 0)
{
- unsigned long
+ size_t
quantum;
+ unsigned long
+ tag;
+
/*
Skip layers & masks.
*/
quantum=psd_info.version == 1 ? 4UL : 8UL;
- for (j=0; j < (long) (length-quantum); j++)
- (void) ReadBlobByte(image);
+ tag=ReadBlobMSBLong(image);
+ (void) tag;
+ count=ReadBlob(image,4,(unsigned char *) type);
+ if ((count == 0) || (LocaleNCompare(type,"8BIM",4) != 0))
+ {
+ if (DiscardBlobBytes(image,length-quantum-8) == MagickFalse)
+ ThrowFileException(exception,CorruptImageError,
+ "UnexpectedEndOfFile",image->filename);
+ }
+ else
+ {
+ count=ReadBlob(image,4,(unsigned char *) type);
+ if ((count != 0) && (LocaleNCompare(type,"Lr16",4) == 0))
+ size=GetPSDSize(&psd_info,image);
+ else
+ if (DiscardBlobBytes(image,length-quantum-12) == MagickFalse)
+ ThrowFileException(exception,CorruptImageError,
+ "UnexpectedEndOfFile",image->filename);
+ }
}
- else
+ if (size != 0)
{
MagickOffsetType
layer_offset;
number_layers=(short) ReadBlobMSBShort(image);
if (image->debug != MagickFalse)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
- " image contains %ld layers", number_layers);
+ " image contains %.20g layers",(double) number_layers);
if (number_layers < 0)
{
/*
Weird hack in PSD format to ignore first alpha channel.
*/
skip_first_alpha=1;
+ (void) skip_first_alpha;
number_layers=MagickAbsoluteValue(number_layers);
if (image->debug != MagickFalse)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
sizeof(*layer_info));
for (i=0; i < number_layers; i++)
{
+ int
+ x,
+ y;
+
if (image->debug != MagickFalse)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
- " reading layer #%ld",i+1);
- layer_info[i].page.y=(long) ReadBlobMSBLong(image);
- layer_info[i].page.x=(long) ReadBlobMSBLong(image);
- layer_info[i].page.height=(unsigned long)
- ReadBlobMSBLong(image)-layer_info[i].page.y;
- layer_info[i].page.width=(unsigned long)
- ReadBlobMSBLong(image)-layer_info[i].page.x;
+ " reading layer #%.20g",(double) i+1);
+ layer_info[i].page.y=(int) ReadBlobMSBLong(image);
+ layer_info[i].page.x=(int) ReadBlobMSBLong(image);
+ y=(int) ReadBlobMSBLong(image);
+ x=(int) ReadBlobMSBLong(image);
+ layer_info[i].page.width=(ssize_t) (x-layer_info[i].page.x);
+ layer_info[i].page.height=(ssize_t) (y-layer_info[i].page.y);
layer_info[i].channels=ReadBlobMSBShort(image);
if (layer_info[i].channels > MaxPSDChannels)
ThrowReaderException(CorruptImageError,"MaximumChannelsExceeded");
if (image->debug != MagickFalse)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
- " offset(%ld,%ld), size(%ld,%ld), channels=%d",
- layer_info[i].page.x, layer_info[i].page.y,
- layer_info[i].page.height,layer_info[i].page.width,
- layer_info[i].channels);
- for (j=0; j < (long) layer_info[i].channels; j++)
+ " offset(%.20g,%.20g), size(%.20g,%.20g), channels=%.20g",
+ (double) layer_info[i].page.x,(double) layer_info[i].page.y,
+ (double) layer_info[i].page.height,(double)
+ layer_info[i].page.width,(double) layer_info[i].channels);
+ for (j=0; j < (ssize_t) layer_info[i].channels; j++)
{
layer_info[i].channel_info[j].type=(short)
ReadBlobMSBShort(image);
- layer_info[i].channel_info[j].size=(unsigned long)
+ layer_info[i].channel_info[j].size=(size_t)
GetPSDSize(&psd_info,image);
if (image->debug != MagickFalse)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
- " channel[%ld]: type=%d, size=%ld",j,
- layer_info[i].channel_info[j].type,
- (long) layer_info[i].channel_info[j].size);
+ " channel[%.20g]: type=%.20g, size=%.20g",(double) j,
+ (double) layer_info[i].channel_info[j].type,
+ (double) layer_info[i].channel_info[j].size);
}
count=ReadBlob(image,4,(unsigned char *) type);
if ((count == 0) || (LocaleNCompare(type,"8BIM",4) != 0))
ThrowReaderException(CorruptImageError,"ImproperImageHeader");
}
count=ReadBlob(image,4,(unsigned char *) layer_info[i].blendkey);
- layer_info[i].opacity=(Quantum) (QuantumRange-ScaleCharToQuantum(
- (unsigned char) ReadBlobByte(image)));
+ layer_info[i].opacity=(Quantum) ScaleCharToQuantum((unsigned char)
+ ReadBlobByte(image));
layer_info[i].clipping=(unsigned char) ReadBlobByte(image);
layer_info[i].flags=(unsigned char) ReadBlobByte(image);
layer_info[i].visible=!(layer_info[i].flags & 0x02);
if (image->debug != MagickFalse)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
- " blend=%.4s, opacity=%lu, clipping=%s, flags=%d, visible=%s",
- layer_info[i].blendkey,(unsigned long) layer_info[i].opacity,
+ " blend=%.4s, opacity=%.20g, clipping=%s, flags=%d, visible=%s",
+ layer_info[i].blendkey,(double) layer_info[i].opacity,
layer_info[i].clipping ? "true" : "false",layer_info[i].flags,
layer_info[i].visible ? "true" : "false");
(void) ReadBlobByte(image); /* filler */
/*
Layer mask info.
*/
- layer_info[i].mask.y=(long) ReadBlobMSBLong(image);
- layer_info[i].mask.x=(long) ReadBlobMSBLong(image);
- layer_info[i].mask.height=(unsigned long)
+ layer_info[i].mask.y=(int) ReadBlobMSBLong(image);
+ layer_info[i].mask.x=(int) ReadBlobMSBLong(image);
+ layer_info[i].mask.height=(size_t)
(ReadBlobMSBLong(image)-layer_info[i].mask.y);
- layer_info[i].mask.width=(unsigned long)
+ layer_info[i].mask.width=(size_t)
(ReadBlobMSBLong(image)-layer_info[i].mask.x);
if (image->debug != MagickFalse)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
- " layer mask: offset(%ld,%ld), size(%ld,%ld), length=%ld",
- layer_info[i].mask.x,layer_info[i].mask.y,
- layer_info[i].mask.width, layer_info[i].mask.height,
- (long) length-16);
+ " layer mask: offset(%.20g,%.20g), size(%.20g,%.20g), length=%.20g",
+ (double) layer_info[i].mask.x,(double) layer_info[i].mask.y,
+ (double) layer_info[i].mask.width,(double)
+ layer_info[i].mask.height,(double)
+ ((MagickOffsetType) length-16));
/*
Skip over the rest of the layer mask information.
*/
- for (j=0; j < (long) (length-16); j++)
- (void) ReadBlobByte(image);
+ if (DiscardBlobBytes(image,length-16) == MagickFalse)
+ ThrowFileException(exception,CorruptImageError,
+ "UnexpectedEndOfFile",image->filename);
}
combinedlength+=length+4; /* +4 for length */
length=ReadBlobMSBLong(image);
*/
if (image->debug != MagickFalse)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
- " layer blending ranges: length=%ld",(long) length);
+ " layer blending ranges: length=%.20g",(double)
+ ((MagickOffsetType) length));
/*
We read it, but don't use it...
*/
- for (j=0; j < (long) (length); j+=8)
+ for (j=0; j < (ssize_t) (length); j+=8)
{
size_t blend_source=ReadBlobMSBLong(image);
size_t blend_dest=ReadBlobMSBLong(image);
Layer name.
*/
length=(size_t) ReadBlobByte(image);
- for (j=0; j < (long) length; j++)
+ for (j=0; j < (ssize_t) length; j++)
layer_info[i].name[j]=(unsigned char) ReadBlobByte(image);
layer_info[i].name[j]='\0';
if (image->debug != MagickFalse)
Adjustment layers and other stuff...
*/
{
- char alsig[4],
- alkey[4];
+ char alsig[4], alkey[4];
count=ReadBlob(image,4,alsig);
if ((count == 0) || (LocaleNCompare(alsig,"8BIM",4) != 0)) {
if (debug != MagickFalse)
{
- if (image->debug != MagickFalse)
+ if (image->debug != MagickFalse)
(void) LogMagickEvent(CoderEvent,GetMagickModule()," adjustment layer type was %.4s instead of 8BIM", alsig);
}
ThrowReaderException(CorruptImageError,"ImproperImageHeader");
length=ReadBlobMSBLong(image);
if (debug != MagickFalse)
{
- if (image->debug != MagickFalse)
+ if (image->debug != MagickFalse)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
- " adjustment layer key: %.4s, data length=%ld",
- alkey, length);
+ " adjustment layer key: %.4s, data length=%.20g",
+ alkey, (double) length);
}
if ( length ) {
- for (j=0; j < (long) (length); j++)
+ for (j=0; j < (ssize_t) (length); j++)
(void) ReadBlobByte(image);
}
*/
if (image->debug != MagickFalse)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
- " unsupported data: length=%ld",(long)
- (size-combinedlength));
- for (j=0; j < (long) (size-combinedlength); j++)
- (void) ReadBlobByte(image);
+ " unsupported data: length=%.20g",(double)
+ ((MagickOffsetType) (size-combinedlength)));
+ if (DiscardBlobBytes(image,size-combinedlength) == MagickFalse)
+ ThrowFileException(exception,CorruptImageError,
+ "UnexpectedEndOfFile",image->filename);
}
/*
Allocate layered image.
*/
layer_info[i].image=CloneImage(image,layer_info[i].page.width,
- layer_info[i].page.height,MagickFalse,&image->exception);
+ layer_info[i].page.height == ~0U ? 1 : layer_info[i].page.height,
+ MagickFalse,&image->exception);
if (layer_info[i].image == (Image *) NULL)
{
for (j=0; j < i; j++)
layer_info[j].image=DestroyImage(layer_info[j].image);
if (image->debug != MagickFalse)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
- " allocation of image for layer %ld failed", i);
+ " allocation of image for layer %.20g failed",(double) i);
ThrowReaderException(ResourceLimitError,
"MemoryAllocationFailed");
}
if (image->debug != MagickFalse)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
" setting up new layer image");
- (void) SetImageBackgroundColor(layer_info[i].image);
+ if (image_info->ping != MagickFalse)
+ (void) SetImageBackgroundColor(layer_info[i].image);
layer_info[i].image->compose=
PSDBlendModeToCompositeOperator(layer_info[i].blendkey);
if (layer_info[i].visible == MagickFalse)
(psd_info.mode == GrayscaleMode) ||
(psd_info.mode == DuotoneMode))
layer_info[i].image->colorspace=GRAYColorspace;
- for (j=0; j < (long) layer_info[i].channels; j++)
+ for (j=0; j < (ssize_t) layer_info[i].channels; j++)
if (layer_info[i].channel_info[j].type == -1)
layer_info[i].image->matte=MagickTrue;
/*
Set up some hidden attributes for folks that need them.
*/
- (void) FormatMagickString(message,MaxTextExtent,"%ld",
- layer_info[i].page.x);
+ (void) FormatLocaleString(message,MaxTextExtent,"%.20gld",
+ (double) layer_info[i].page.x);
(void) SetImageArtifact(layer_info[i].image,"psd:layer.x",message);
- (void) FormatMagickString(message,MaxTextExtent,"%ld",
- layer_info[i].page.y);
+ (void) FormatLocaleString(message,MaxTextExtent,"%.20g",
+ (double) layer_info[i].page.y);
(void) SetImageArtifact(layer_info[i].image,"psd:layer.y",message);
- (void) FormatMagickString(message,MaxTextExtent,"%lu",
- (unsigned long) layer_info[i].opacity);
+ (void) FormatLocaleString(message,MaxTextExtent,"%.20g",
+ (double) layer_info[i].opacity);
(void) SetImageArtifact(layer_info[i].image,"psd:layer.opacity",
message);
(void) SetImageProperty(layer_info[i].image,"label",(char *)
{
if (image->debug != MagickFalse)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
- " reading data for layer %ld",i);
- for (j=0; j < (long) layer_info[i].channels; j++)
+ " reading data for layer %.20g",(double) i);
+ for (j=0; j < (ssize_t) layer_info[i].channels; j++)
{
if (image->debug != MagickFalse)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
- " reading data for channel %ld", j);
+ " reading data for channel %.20g",(double) j);
#if 1
if (layer_info[i].channel_info[j].size <= (2*layer_info[i].image->rows))
{
- long
+ ssize_t
k;
if (image->debug != MagickFalse)
/*
A layer without data.
*/
- for (k=0; k < (long) layer_info[i].channel_info[j].size; k++)
+ for (k=0; k < (ssize_t) layer_info[i].channel_info[j].size; k++)
(void) ReadBlobByte(layer_info[i].image);
continue;
}
if (offsets == (MagickOffsetType *) NULL)
ThrowReaderException(ResourceLimitError,
"MemoryAllocationFailed");
- for (y=0; y < (long) layer_info[i].image->rows; y++)
+ for (y=0; y < (ssize_t) layer_info[i].image->rows; y++)
offsets[y]=GetPSDOffset(&psd_info,layer_info[i].image);
}
status=ReadPSDLayer(layer_info[i].image,
- layer_info[i].channels,(unsigned long)
- layer_info[i].channel_info[j].type,offsets,exception);
+ layer_info[i].channels,layer_info[i].channel_info[j].type,
+ offsets,exception);
if (compression == 1)
offsets=(MagickOffsetType *) RelinquishMagickMemory(
offsets);
break;
}
}
- if (layer_info[i].opacity != OpaqueOpacity)
+ if (layer_info[i].opacity != OpaqueAlpha)
{
/*
Correct for opacity level.
*/
- for (y=0; y < (long) layer_info[i].image->rows; y++)
+ for (y=0; y < (ssize_t) layer_info[i].image->rows; y++)
{
q=GetAuthenticPixels(layer_info[i].image,0,y,
layer_info[i].image->columns,1,exception);
- if (q == (PixelPacket *) NULL)
+ if (q == (Quantum *) NULL)
break;
- indexes=GetAuthenticIndexQueue(layer_info[i].image);
- for (x=0; x < (long) layer_info[i].image->columns; x++)
+ for (x=0; x < (ssize_t) layer_info[i].image->columns; x++)
{
- q->opacity=(Quantum) (QuantumRange-(Quantum) (QuantumScale*
- ((QuantumRange-q->opacity)*(QuantumRange-
- layer_info[i].opacity))));
- q++;
+ SetPixelAlpha(layer_info[i].image,(Quantum)
+ (QuantumScale*(GetPixelAlpha(layer_info[i].image,q))*
+ layer_info[i].opacity),q);
+ q+=GetPixelChannels(layer_info[i].image);
}
if (SyncAuthenticPixels(layer_info[i].image,exception) == MagickFalse)
break;
}
}
if (layer_info[i].image->colorspace == CMYKColorspace)
- (void) NegateImage(layer_info[i].image,MagickFalse);
+ (void) NegateImage(layer_info[i].image,MagickFalse,exception);
status=SetImageProgress(image,LoadImagesTag,i,(MagickSizeType)
number_layers);
if (status == MagickFalse)
}
}
mask_size = ReadBlobMSBLong(image); /* global mask size: currently ignored */
+ (void) mask_size;
if (number_layers > 0)
{
if (image->debug != MagickFalse)
psd_info.channels*sizeof(*offsets));
if (offsets == (MagickOffsetType *) NULL)
ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
- for (i=0; i < (long) (image->rows*psd_info.channels); i++)
+ for (i=0; i < (ssize_t) (image->rows*psd_info.channels); i++)
offsets[i]=GetPSDOffset(&psd_info,image);
}
- for (i=0; i < (long) psd_info.channels; i++)
+ for (i=0; i < (ssize_t) psd_info.channels; i++)
{
- status=ReadPSDLayer(image,psd_info.channels,(unsigned long) i,offsets+i*
- image->rows,exception);
+ status=ReadPSDLayer(image,psd_info.channels,i,offsets+i*image->rows,
+ exception);
if (status == MagickFalse)
break;
status=SetImageProgress(image,LoadImagesTag,i,psd_info.channels);
if (compression == 1)
offsets=(MagickOffsetType *) RelinquishMagickMemory(offsets);
if (image->colorspace == CMYKColorspace)
- (void) NegateImage(image,MagickFalse);
+ (void) NegateImage(image,MagickFalse,exception);
(void) CloseBlob(image);
return(GetFirstImageInList(image));
}
%
% The format of the RegisterPSDImage method is:
%
-% unsigned long RegisterPSDImage(void)
+% size_t RegisterPSDImage(void)
%
*/
-ModuleExport unsigned long RegisterPSDImage(void)
+ModuleExport size_t RegisterPSDImage(void)
{
MagickInfo
*entry;
entry->decoder=(DecodeImageHandler *) ReadPSDImage;
entry->encoder=(EncodeImageHandler *) WritePSDImage;
entry->magick=(IsImageFormatHandler *) IsPSD;
+ entry->seekable_stream=MagickTrue;
entry->description=ConstantString("Adobe Large Document Format");
entry->module=ConstantString("PSD");
(void) RegisterMagickInfo(entry);
entry->decoder=(DecodeImageHandler *) ReadPSDImage;
entry->encoder=(EncodeImageHandler *) WritePSDImage;
entry->magick=(IsImageFormatHandler *) IsPSD;
+ entry->seekable_stream=MagickTrue;
entry->description=ConstantString("Adobe Photoshop bitmap");
entry->module=ConstantString("PSD");
(void) RegisterMagickInfo(entry);
%
% The format of the WritePSDImage method is:
%
-% MagickBooleanType WritePSDImage(const ImageInfo *image_info,Image *image)
+% MagickBooleanType WritePSDImage(const ImageInfo *image_info,
+% Image *image,ExceptionInfo *exception)
%
% A description of each parameter follows.
%
%
% o image: The image.
%
+% o exception: return any errors or warnings in this structure.
%
*/
}
static size_t PSDPackbitsEncodeImage(Image *image,const size_t length,
- const unsigned char *pixels,unsigned char *compact_pixels)
+ const unsigned char *pixels,unsigned char *compact_pixels,
+ ExceptionInfo *exception)
{
int
count;
- register long
+ register ssize_t
i,
j;
ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
image->filename);
q=compact_pixels;
- for (i=(long) length; i != 0; )
+ for (i=(ssize_t) length; i != 0; )
{
switch (i)
{
Packed run.
*/
count=3;
- while (((long) count < i) && (*pixels == *(pixels+count)))
+ while (((ssize_t) count < i) && (*pixels == *(pixels+count)))
{
count++;
if (count >= 127)
{
packbits[count+1]=pixels[count];
count++;
- if (((long) count >= (i-3)) || (count >= 127))
+ if (((ssize_t) count >= (i-3)) || (count >= 127))
break;
}
i-=count;
*packbits=(unsigned char) (count-1);
- for (j=0; j <= (long) count; j++)
+ for (j=0; j <= (ssize_t) count; j++)
*q++=packbits[j];
pixels+=count;
break;
}
static void WritePackbitsLength(const PSDInfo *psd_info,
- const ImageInfo *image_info,Image *image,Image *tmp_image,
- unsigned char *pixels,unsigned char *compact_pixels,
- const QuantumType quantum_type)
+ const ImageInfo *image_info,Image *image,Image *next_image,
+ unsigned char *compact_pixels,const QuantumType quantum_type,
+ ExceptionInfo *exception)
{
- int
- y;
-
QuantumInfo
*quantum_info;
- register const PixelPacket
+ register const Quantum
*p;
size_t
length,
packet_size;
- if (tmp_image->depth > 8)
- tmp_image->depth=16;
- packet_size=tmp_image->depth > 8UL ? 2UL : 1UL;
+ ssize_t
+ y;
+
+ unsigned char
+ *pixels;
+
+ if (next_image->depth > 8)
+ next_image->depth=16;
+ packet_size=next_image->depth > 8UL ? 2UL : 1UL;
+ (void) packet_size;
quantum_info=AcquireQuantumInfo(image_info,image);
- for (y=0; y < (long) tmp_image->rows; y++)
+ pixels=GetQuantumPixels(quantum_info);
+ for (y=0; y < (ssize_t) next_image->rows; y++)
{
- p=GetVirtualPixels(tmp_image,0,y,tmp_image->columns,1,&image->exception);
- if (p == (const PixelPacket *) NULL)
+ p=GetVirtualPixels(next_image,0,y,next_image->columns,1,&image->exception);
+ if (p == (const Quantum *) NULL)
break;
- length=ExportQuantumPixels(tmp_image,(CacheView *) NULL,quantum_info,
+ length=ExportQuantumPixels(next_image,(CacheView *) NULL,quantum_info,
quantum_type,pixels,&image->exception);
- length=PSDPackbitsEncodeImage(image,length,pixels,compact_pixels);
+ length=PSDPackbitsEncodeImage(image,length,pixels,compact_pixels,
+ exception);
(void) SetPSDOffset(psd_info,image,length);
}
quantum_info=DestroyQuantumInfo(quantum_info);
}
static void WriteOneChannel(const PSDInfo *psd_info,const ImageInfo *image_info,
- Image *image,Image *tmp_image,unsigned char *pixels,
- unsigned char *compact_pixels,const QuantumType quantum_type,
- const MagickBooleanType compression_flag)
+ Image *image,Image *next_image,unsigned char *compact_pixels,
+ const QuantumType quantum_type,const MagickBooleanType compression_flag,
+ ExceptionInfo *exception)
{
int
y;
QuantumInfo
*quantum_info;
- register const PixelPacket
+ register const Quantum
*p;
- register long
+ register ssize_t
i;
size_t
length,
packet_size;
+ unsigned char
+ *pixels;
+
(void) psd_info;
if ((compression_flag != MagickFalse) &&
- (tmp_image->compression != RLECompression))
+ (next_image->compression != RLECompression))
(void) WriteBlobMSBShort(image,0);
- if (tmp_image->depth > 8)
- tmp_image->depth=16;
- monochrome=IsMonochromeImage(image,&image->exception);
- packet_size=tmp_image->depth > 8UL ? 2UL : 1UL;
+ if (next_image->depth > 8)
+ next_image->depth=16;
+ monochrome=IsImageMonochrome(image,&image->exception) && (image->depth == 1)
+ ? MagickTrue : MagickFalse;
+ packet_size=next_image->depth > 8UL ? 2UL : 1UL;
+ (void) packet_size;
quantum_info=AcquireQuantumInfo(image_info,image);
- for (y=0; y < (long) tmp_image->rows; y++)
+ pixels=GetQuantumPixels(quantum_info);
+ for (y=0; y < (ssize_t) next_image->rows; y++)
{
- p=GetVirtualPixels(tmp_image,0,y,tmp_image->columns,1,&image->exception);
- if (p == (const PixelPacket *) NULL)
+ p=GetVirtualPixels(next_image,0,y,next_image->columns,1,&image->exception);
+ if (p == (const Quantum *) NULL)
break;
- length=ExportQuantumPixels(tmp_image,(CacheView *) NULL,quantum_info,
+ length=ExportQuantumPixels(next_image,(CacheView *) NULL,quantum_info,
quantum_type,pixels,&image->exception);
if (monochrome != MagickFalse)
- for (i=0; i < (long) length; i++)
+ for (i=0; i < (ssize_t) length; i++)
pixels[i]=(~pixels[i]);
- if (tmp_image->compression != RLECompression)
+ if (next_image->compression != RLECompression)
(void) WriteBlob(image,length,pixels);
else
{
- length=PSDPackbitsEncodeImage(image,length,pixels,compact_pixels);
+ length=PSDPackbitsEncodeImage(image,length,pixels,compact_pixels,
+ exception);
(void) WriteBlob(image,length,compact_pixels);
}
}
}
static MagickBooleanType WriteImageChannels(const PSDInfo *psd_info,
- const ImageInfo *image_info,Image *image,Image *tmp_image,
- const MagickBooleanType separate)
+ const ImageInfo *image_info,Image *image,Image *next_image,
+ const MagickBooleanType separate,ExceptionInfo *exception)
{
int
i;
packet_size;
unsigned char
- *compact_pixels,
- *pixels;
+ *compact_pixels;
/*
Write uncompressed pixels as separate planes.
*/
channels=1;
- packet_size=tmp_image->depth > 8UL ? 2UL : 1UL;
- pixels=(unsigned char *) AcquireQuantumMemory(channels*tmp_image->columns,
- packet_size*sizeof(*pixels));
- compact_pixels=(unsigned char *) AcquireQuantumMemory(2*channels*
- tmp_image->columns,packet_size*sizeof(*pixels));
- if ((pixels == (unsigned char *) NULL) ||
- (compact_pixels == (unsigned char *) NULL))
+ packet_size=next_image->depth > 8UL ? 2UL : 1UL;
+ compact_pixels=(unsigned char *) NULL;
+ if (next_image->compression == RLECompression)
{
- if (pixels != (unsigned char *) NULL)
- pixels=(unsigned char *) RelinquishMagickMemory(pixels);
- if (compact_pixels != (unsigned char *) NULL)
- compact_pixels=(unsigned char *)
- RelinquishMagickMemory(compact_pixels);
- ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
+ compact_pixels=(unsigned char *) AcquireQuantumMemory(2*channels*
+ next_image->columns,packet_size*sizeof(*compact_pixels));
+ if (compact_pixels == (unsigned char *) NULL)
+ ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
}
i=0;
- if (IsGrayImage(tmp_image,&tmp_image->exception) != MagickFalse)
+ if (IsImageGray(next_image,&next_image->exception) != MagickFalse)
{
- if (tmp_image->compression == RLECompression)
+ if (next_image->compression == RLECompression)
{
/*
Packbits compression.
*/
(void) WriteBlobMSBShort(image,1);
- if (tmp_image->matte != MagickFalse)
- WritePackbitsLength(psd_info,image_info,image,tmp_image,pixels,
- compact_pixels,AlphaQuantum);
- WritePackbitsLength(psd_info,image_info,image,tmp_image,pixels,
- compact_pixels,GrayQuantum);
+ WritePackbitsLength(psd_info,image_info,image,next_image,
+ compact_pixels,GrayQuantum,exception);
+ if (next_image->matte != MagickFalse)
+ WritePackbitsLength(psd_info,image_info,image,next_image,
+ compact_pixels,AlphaQuantum,exception);
}
- if (tmp_image->matte != MagickFalse)
- WriteOneChannel(psd_info,image_info,image,tmp_image,pixels,
- compact_pixels,AlphaQuantum,(i++ == 0) ||
- (separate != MagickFalse) ? MagickTrue : MagickFalse);
- WriteOneChannel(psd_info,image_info,image,tmp_image,pixels,
- compact_pixels,GrayQuantum,(i++ == 0) ||
- (separate != MagickFalse) ? MagickTrue : MagickFalse);
+ WriteOneChannel(psd_info,image_info,image,next_image,compact_pixels,
+ GrayQuantum,(i++ == 0) || (separate != MagickFalse) ? MagickTrue :
+ MagickFalse,exception);
+ if (next_image->matte != MagickFalse)
+ WriteOneChannel(psd_info,image_info,image,next_image,compact_pixels,
+ AlphaQuantum,(i++ == 0) || (separate != MagickFalse) ? MagickTrue :
+ MagickFalse,exception);
(void) SetImageProgress(image,SaveImagesTag,0,1);
}
else
- if (tmp_image->storage_class == PseudoClass)
+ if (next_image->storage_class == PseudoClass)
{
- if (tmp_image->compression == RLECompression)
+ if (next_image->compression == RLECompression)
{
/*
Packbits compression.
*/
(void) WriteBlobMSBShort(image,1);
- if (tmp_image->matte != MagickFalse)
- WritePackbitsLength(psd_info,image_info,image,tmp_image,pixels,
- compact_pixels,AlphaQuantum);
- WritePackbitsLength(psd_info,image_info,image,tmp_image,pixels,
- compact_pixels,IndexQuantum);
+ WritePackbitsLength(psd_info,image_info,image,next_image,
+ compact_pixels,IndexQuantum,exception);
+ if (next_image->matte != MagickFalse)
+ WritePackbitsLength(psd_info,image_info,image,next_image,
+ compact_pixels,AlphaQuantum,exception);
}
- if (tmp_image->matte != MagickFalse)
- WriteOneChannel(psd_info,image_info,image,tmp_image,pixels,
- compact_pixels,AlphaQuantum,(i++ == 0) ||
- (separate != MagickFalse) ? MagickTrue : MagickFalse);
- WriteOneChannel(psd_info,image_info,image,tmp_image,pixels,
- compact_pixels,IndexQuantum,(i++ == 0) ||
- (separate != MagickFalse) ? MagickTrue : MagickFalse);
+ WriteOneChannel(psd_info,image_info,image,next_image,compact_pixels,
+ IndexQuantum,(i++ == 0) || (separate != MagickFalse) ? MagickTrue :
+ MagickFalse,exception);
+ if (next_image->matte != MagickFalse)
+ WriteOneChannel(psd_info,image_info,image,next_image,compact_pixels,
+ AlphaQuantum,(i++ == 0) || (separate != MagickFalse) ? MagickTrue :
+ MagickFalse,exception);
(void) SetImageProgress(image,SaveImagesTag,0,1);
}
else
{
- if (tmp_image->colorspace == CMYKColorspace)
- {
- tmp_image->compression=NoCompression;
- (void) NegateImage(tmp_image,MagickFalse);
- }
- if (tmp_image->compression == RLECompression)
+ if (next_image->colorspace == CMYKColorspace)
+ (void) NegateImage(next_image,MagickFalse,&next_image->exception);
+ if (next_image->compression == RLECompression)
{
/*
Packbits compression.
*/
(void) WriteBlobMSBShort(image,1);
- if (tmp_image->matte != MagickFalse)
- WritePackbitsLength(psd_info,image_info,image,tmp_image,pixels,
- compact_pixels,AlphaQuantum);
- WritePackbitsLength(psd_info,image_info,image,tmp_image,pixels,
- compact_pixels,RedQuantum);
- WritePackbitsLength(psd_info,image_info,image,tmp_image,pixels,
- compact_pixels,GreenQuantum);
- WritePackbitsLength(psd_info,image_info,image,tmp_image,pixels,
- compact_pixels,BlueQuantum);
- if (tmp_image->colorspace == CMYKColorspace)
- WritePackbitsLength(psd_info,image_info,image,tmp_image,pixels,
- compact_pixels,BlackQuantum);
+ WritePackbitsLength(psd_info,image_info,image,next_image,
+ compact_pixels,RedQuantum,exception);
+ WritePackbitsLength(psd_info,image_info,image,next_image,
+ compact_pixels,GreenQuantum,exception);
+ WritePackbitsLength(psd_info,image_info,image,next_image,
+ compact_pixels,BlueQuantum,exception);
+ if (next_image->colorspace == CMYKColorspace)
+ WritePackbitsLength(psd_info,image_info,image,next_image,
+ compact_pixels,BlackQuantum,exception);
+ if (next_image->matte != MagickFalse)
+ WritePackbitsLength(psd_info,image_info,image,next_image,
+ compact_pixels,AlphaQuantum,exception);
}
(void) SetImageProgress(image,SaveImagesTag,0,6);
- if (tmp_image->matte != MagickFalse)
- WriteOneChannel(psd_info,image_info,image,tmp_image,pixels,
- compact_pixels,AlphaQuantum,(i++ == 0) ||
- (separate != MagickFalse) ? MagickTrue : MagickFalse);
+ WriteOneChannel(psd_info,image_info,image,next_image,compact_pixels,
+ RedQuantum,(i++ == 0) || (separate != MagickFalse) ? MagickTrue :
+ MagickFalse,exception);
(void) SetImageProgress(image,SaveImagesTag,1,6);
- WriteOneChannel(psd_info,image_info,image,tmp_image,pixels,
- compact_pixels,RedQuantum,(i++ == 0) || (separate != MagickFalse) ?
- MagickTrue : MagickFalse);
+ WriteOneChannel(psd_info,image_info,image,next_image,compact_pixels,
+ GreenQuantum,(i++ == 0) || (separate != MagickFalse) ? MagickTrue :
+ MagickFalse,exception);
(void) SetImageProgress(image,SaveImagesTag,2,6);
- WriteOneChannel(psd_info,image_info,image,tmp_image,pixels,
- compact_pixels,GreenQuantum,(i++ == 0) || (separate != MagickFalse) ?
- MagickTrue : MagickFalse);
+ WriteOneChannel(psd_info,image_info,image,next_image,compact_pixels,
+ BlueQuantum,(i++ == 0) || (separate != MagickFalse) ? MagickTrue :
+ MagickFalse,exception);
(void) SetImageProgress(image,SaveImagesTag,3,6);
- WriteOneChannel(psd_info,image_info,image,tmp_image,pixels,
- compact_pixels,BlueQuantum,(i++ == 0) || (separate != MagickFalse) ?
- MagickTrue : MagickFalse);
+ if (next_image->colorspace == CMYKColorspace)
+ WriteOneChannel(psd_info,image_info,image,next_image,compact_pixels,
+ BlackQuantum,(i++ == 0) || (separate != MagickFalse) ? MagickTrue :
+ MagickFalse,exception);
(void) SetImageProgress(image,SaveImagesTag,4,6);
- if (tmp_image->colorspace == CMYKColorspace)
- {
- WriteOneChannel(psd_info,image_info,image,tmp_image,pixels,
- compact_pixels,BlackQuantum,(i++ == 0) ||
- (separate != MagickFalse) ? MagickTrue : MagickFalse);
- (void) NegateImage(tmp_image,MagickFalse);
- }
+ if (next_image->matte != MagickFalse)
+ WriteOneChannel(psd_info,image_info,image,next_image,compact_pixels,
+ AlphaQuantum,(i++ == 0) || (separate != MagickFalse) ? MagickTrue :
+ MagickFalse,exception);
(void) SetImageProgress(image,SaveImagesTag,5,6);
+ if (next_image->colorspace == CMYKColorspace)
+ (void) NegateImage(next_image,MagickFalse,&next_image->exception);
}
- pixels=(unsigned char *) RelinquishMagickMemory(pixels);
+ if (next_image->compression == RLECompression)
+ compact_pixels=(unsigned char *) RelinquishMagickMemory(compact_pixels);
return(MagickTrue);
}
static void WritePascalString(Image* inImage,const char *inString,int inPad)
{
size_t
- strLength;
- int i;
-
- /* max length is 255 */
+ length;
- strLength = (strlen(inString) > 255UL ) ? 255UL : strlen(inString);
+ register ssize_t
+ i;
- if ( strLength != 0 )
- {
- (void) WriteBlobByte(inImage,(unsigned char) strLength);
- (void) WriteBlob(inImage, strLength, (const unsigned char *) inString);
- }
+ /*
+ Max length is 255.
+ */
+ length=(strlen(inString) > 255UL ) ? 255UL : strlen(inString);
+ if (length == 0)
+ (void) WriteBlobByte(inImage,0);
else
- (void) WriteBlobByte(inImage, 0);
-
- strLength ++;
-
- if ( (strLength % inPad) == 0 )
+ {
+ (void) WriteBlobByte(inImage,(unsigned char) length);
+ (void) WriteBlob(inImage, length, (const unsigned char *) inString);
+ }
+ length++;
+ if ((length % inPad) == 0)
return;
- for (i=0; i < (long) (inPad-(strLength % inPad)); i++)
+ for (i=0; i < (ssize_t) (inPad-(length % inPad)); i++)
(void) WriteBlobByte(inImage,0);
}
(void) WriteBlobMSBShort(image,units); /* height unit */
}
-static MagickBooleanType WritePSDImage(const ImageInfo *image_info,Image *image)
+static void RemoveICCProfileFromResourceBlock(StringInfo *bim_profile)
+{
+ register const unsigned char
+ *p;
+
+ size_t
+ length;
+
+ unsigned char
+ *datum;
+
+ unsigned int
+ count,
+ long_sans;
+
+ unsigned short
+ id,
+ short_sans;
+
+ length=GetStringInfoLength(bim_profile);
+ if (length < 16)
+ return;
+ datum=GetStringInfoDatum(bim_profile);
+ for (p=datum; (p >= datum) && (p < (datum+length-16)); )
+ {
+ register unsigned char
+ *q;
+
+ q=(unsigned char *) p;
+ if (LocaleNCompare((const char *) p,"8BIM",4) != 0)
+ break;
+ p=PushLongPixel(MSBEndian,p,&long_sans);
+ p=PushShortPixel(MSBEndian,p,&id);
+ p=PushShortPixel(MSBEndian,p,&short_sans);
+ p=PushLongPixel(MSBEndian,p,&count);
+ if (id == 0x0000040f)
+ {
+ (void) CopyMagickMemory(q,q+PSDQuantum(count)+12,length-
+ (PSDQuantum(count)+12)-(q-datum));
+ SetStringInfoLength(bim_profile,length-(PSDQuantum(count)+12));
+ break;
+ }
+ p+=count;
+ if ((count & 0x01) != 0)
+ p++;
+ }
+}
+
+static void RemoveResolutionFromResourceBlock(StringInfo *bim_profile)
+{
+ register const unsigned char
+ *p;
+
+ size_t
+ length;
+
+ unsigned char
+ *datum;
+
+ unsigned int
+ count,
+ long_sans;
+
+ unsigned short
+ id,
+ short_sans;
+
+ length=GetStringInfoLength(bim_profile);
+ if (length < 16)
+ return;
+ datum=GetStringInfoDatum(bim_profile);
+ for (p=datum; (p >= datum) && (p < (datum+length-16)); )
+ {
+ register unsigned char
+ *q;
+
+ q=(unsigned char *) p;
+ if (LocaleNCompare((const char *) p,"8BIM",4) != 0)
+ break;
+ p=PushLongPixel(MSBEndian,p,&long_sans);
+ p=PushShortPixel(MSBEndian,p,&id);
+ p=PushShortPixel(MSBEndian,p,&short_sans);
+ p=PushLongPixel(MSBEndian,p,&count);
+ if ((id == 0x000003ed) && (PSDQuantum(count) < (ssize_t) (length-12)))
+ {
+ (void) CopyMagickMemory(q,q+PSDQuantum(count)+12,length-
+ (PSDQuantum(count)+12)-(q-datum));
+ SetStringInfoLength(bim_profile,length-(PSDQuantum(count)+12));
+ break;
+ }
+ p+=count;
+ if ((count & 0x01) != 0)
+ p++;
+ }
+}
+
+static MagickBooleanType WritePSDImage(const ImageInfo *image_info,Image *image,
+ ExceptionInfo *exception)
{
const char
- *theAttr;
+ *property;
const StringInfo
- *bim_profile,
*icc_profile;
+ Image
+ *base_image,
+ *next_image;
+
MagickBooleanType
- invert_layer_count = MagickFalse,
status;
PSDInfo
psd_info;
- register long
+ register ssize_t
i;
size_t
- length,
- num_channels,
- packet_size;
-
- unsigned char
- layer_name[4];
-
- unsigned long
channel_size,
channelLength,
layer_count,
layer_info_size,
+ length,
+ num_channels,
+ packet_size,
rounded_layer_info_size;
- Image
- * tmp_image = (Image *) NULL,
- * base_image = GetNextImageInList(image);
+ StringInfo
+ *bim_profile;
+
+ unsigned char
+ layer_name[4];
/*
Open image file.
assert(image->signature == MagickSignature);
if (image->debug != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
- status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
if (status == MagickFalse)
return(status);
packet_size=(size_t) (image->depth > 8 ? 6 : 3);
(void) WriteBlobMSBShort(image,psd_info.version); /* version */
for (i=1; i <= 6; i++)
(void) WriteBlobByte(image, 0); /* 6 bytes of reserved */
- if (IsGrayImage(image,&image->exception) != MagickFalse)
+ if (IsImageGray(image,exception) != MagickFalse)
num_channels=(image->matte != MagickFalse ? 2UL : 1UL);
else
if (image->storage_class == PseudoClass)
(void) WriteBlobMSBShort(image,(unsigned short) num_channels);
(void) WriteBlobMSBLong(image,(unsigned int) image->rows);
(void) WriteBlobMSBLong(image,(unsigned int) image->columns);
- if (IsGrayImage(image,&image->exception) != MagickFalse)
+ if (IsImageGray(image,exception) != MagickFalse)
{
MagickBooleanType
monochrome;
/*
Write depth & mode.
*/
- monochrome=IsMonochromeImage(image,&image->exception);
+ monochrome=IsImageMonochrome(image,exception) && (image->depth == 1) ?
+ MagickTrue : MagickFalse;
(void) WriteBlobMSBShort(image,(unsigned short)
(monochrome != MagickFalse ? 1 : image->depth > 8 ? 16 : 8));
- (void) WriteBlobMSBShort(image,monochrome != MagickFalse ?
- BitmapMode : GrayscaleMode);
+ (void) WriteBlobMSBShort(image,(unsigned short)
+ (monochrome != MagickFalse ? BitmapMode : GrayscaleMode));
}
else
{
- (void) WriteBlobMSBShort(image,(unsigned short)
- (image->storage_class == PseudoClass ? 8 : image->depth > 8 ? 16 : 8));
- if (((image->colorspace != UndefinedColorspace) ||
+ (void) WriteBlobMSBShort(image,(unsigned short) (image->storage_class ==
+ PseudoClass ? 8 : image->depth > 8 ? 16 : 8));
+ if (((image_info->colorspace != UndefinedColorspace) ||
(image->colorspace != CMYKColorspace)) &&
- (image->colorspace != CMYKColorspace))
+ (image_info->colorspace != CMYKColorspace))
{
- if (image->colorspace != RGBColorspace)
+ if (IsRGBColorspace(image->colorspace) == MagickFalse)
(void) TransformImageColorspace(image,RGBColorspace);
(void) WriteBlobMSBShort(image,(unsigned short)
(image->storage_class == PseudoClass ? IndexedMode : RGBMode));
}
else
{
- if (image->colorspace != RGBColorspace)
+ if (image->colorspace != CMYKColorspace)
(void) TransformImageColorspace(image,CMYKColorspace);
(void) WriteBlobMSBShort(image,CMYKMode);
}
}
- if ((IsGrayImage(image,&image->exception) != MagickFalse) ||
+ if ((IsImageGray(image,exception) != MagickFalse) ||
(image->storage_class == DirectClass) || (image->colors > 256))
(void) WriteBlobMSBLong(image,0);
else
Write PSD raster colormap.
*/
(void) WriteBlobMSBLong(image,768);
- for (i=0; i < (long) image->colors; i++)
+ for (i=0; i < (ssize_t) image->colors; i++)
(void) WriteBlobByte(image,ScaleQuantumToChar(image->colormap[i].red));
for ( ; i < 256; i++)
(void) WriteBlobByte(image,0);
- for (i=0; i < (long) image->colors; i++)
- (void) WriteBlobByte(image,ScaleQuantumToChar(image->colormap[i].green));
+ for (i=0; i < (ssize_t) image->colors; i++)
+ (void) WriteBlobByte(image,ScaleQuantumToChar(
+ image->colormap[i].green));
for ( ; i < 256; i++)
(void) WriteBlobByte(image,0);
- for (i=0; i < (long) image->colors; i++)
+ for (i=0; i < (ssize_t) image->colors; i++)
(void) WriteBlobByte(image,ScaleQuantumToChar(image->colormap[i].blue));
for ( ; i < 256; i++)
(void) WriteBlobByte(image,0);
Image resource block.
*/
length=28; /* 0x03EB */
- bim_profile=(StringInfo *) NULL;
+ bim_profile=(StringInfo *) GetImageProfile(image,"8bim");
icc_profile=GetImageProfile(image,"icc");
- if (icc_profile != (StringInfo *) NULL)
- length+=PSDQuantum(GetStringInfoLength(icc_profile))+12;
- else
+ if (bim_profile != (StringInfo *) NULL)
{
- bim_profile=GetImageProfile(image,"8bim");
- if (bim_profile != (StringInfo *) NULL)
- length+=GetStringInfoLength(bim_profile);
+ bim_profile=CloneStringInfo(bim_profile);
+ if (icc_profile != (StringInfo *) NULL)
+ RemoveICCProfileFromResourceBlock(bim_profile);
+ RemoveResolutionFromResourceBlock(bim_profile);
+ length+=PSDQuantum(GetStringInfoLength(bim_profile));
}
+ if (icc_profile != (const StringInfo *) NULL)
+ length+=PSDQuantum(GetStringInfoLength(icc_profile))+12;
(void) WriteBlobMSBLong(image,(unsigned int) length);
WriteResolutionResourceBlock(image);
if (bim_profile != (StringInfo *) NULL)
- (void) WriteBlob(image,GetStringInfoLength(bim_profile),GetStringInfoDatum(
- bim_profile));
+ {
+ (void) WriteBlob(image,GetStringInfoLength(bim_profile),
+ GetStringInfoDatum(bim_profile));
+ bim_profile=DestroyStringInfo(bim_profile);
+ }
if (icc_profile != (StringInfo *) NULL)
{
(void) WriteBlob(image,4,(const unsigned char *) "8BIM");
- (void) WriteBlobMSBShort(image,0x040F);
+ (void) WriteBlobMSBShort(image,0x0000040F);
(void) WriteBlobMSBShort(image,0);
(void) WriteBlobMSBLong(image,(unsigned int) GetStringInfoLength(
icc_profile));
PSDQuantum(GetStringInfoLength(icc_profile)))
(void) WriteBlobByte(image,0);
}
-
-compute_layer_info:
- layer_count = 0;
- layer_info_size = 2;
- tmp_image = base_image;
- while ( tmp_image != NULL ) {
- packet_size=tmp_image->depth > 8 ? 2UL : 1UL;
-
- if (IsGrayImage(image,&image->exception) != MagickFalse)
- num_channels=tmp_image->matte != MagickFalse ? 2UL : 1UL;
+ layer_count=0;
+ layer_info_size=2;
+ base_image=GetNextImageInList(image);
+ if ((image->matte != MagickFalse) && (base_image == (Image *) NULL))
+ base_image=image;
+ next_image=base_image;
+ while ( next_image != NULL )
+ {
+ packet_size=next_image->depth > 8 ? 2UL : 1UL;
+ if (IsImageGray(next_image,exception) != MagickFalse)
+ num_channels=next_image->matte != MagickFalse ? 2UL : 1UL;
else
- if (tmp_image->storage_class == PseudoClass)
- num_channels=tmp_image->matte != MagickFalse ? 2UL : 1UL;
+ if (next_image->storage_class == PseudoClass)
+ num_channels=next_image->matte != MagickFalse ? 2UL : 1UL;
else
- if (tmp_image->colorspace != CMYKColorspace)
- num_channels=tmp_image->matte != MagickFalse ? 4UL : 3UL;
+ if (next_image->colorspace != CMYKColorspace)
+ num_channels=next_image->matte != MagickFalse ? 4UL : 3UL;
else
- num_channels=tmp_image->matte != MagickFalse ? 5UL : 4UL;
-
- channelLength=(unsigned long) (tmp_image->columns * tmp_image->rows *
- packet_size + 2);
- layer_info_size += (unsigned long) (4*4 + 2 + num_channels * 6 +
- (psd_info.version == 1 ? 8 : 16) + 4 * 1 + 4 + num_channels *
- channelLength);
- theAttr=(const char *) GetImageProperty(tmp_image,"label");
- if (!theAttr)
- layer_info_size += 16;
+ num_channels=next_image->matte != MagickFalse ? 5UL : 4UL;
+ channelLength=(size_t) (next_image->columns*next_image->rows*packet_size+2);
+ layer_info_size+=(size_t) (4*4+2+num_channels*6+(psd_info.version == 1 ? 8 :
+ 16)+4*1+4+num_channels*channelLength);
+ property=(const char *) GetImageProperty(next_image,"label");
+ if (property == (const char *) NULL)
+ layer_info_size+=16;
else
{
- size_t length=strlen(theAttr);
- layer_info_size += 8+length+(4-(length % 4))+1;
+ size_t
+ length;
+
+ length=strlen(property);
+ layer_info_size+=8+length+(4-(length % 4));
}
layer_count++;
- tmp_image = GetNextImageInList(tmp_image);
- }
-
- /* if the image has a matte, then we need to use layers */
- if ( layer_count == 0 && image->matte == MagickTrue )
- {
- invert_layer_count = MagickTrue;
- base_image = image;
- goto compute_layer_info; /* yes, goto's suck, but it keeps the code cleaner! */
+ next_image=GetNextImageInList(next_image);
}
-
- if ( layer_count == 0 )
+ if (layer_count == 0)
(void) SetPSDSize(&psd_info,image,0);
else
- {
- (void) SetPSDSize(&psd_info,image,layer_info_size+
- (psd_info.version == 1 ? 8 : 16));
- if ( layer_info_size/2 != (layer_info_size+1)/2 ) /* odd */
- rounded_layer_info_size = layer_info_size + 1;
- else
- rounded_layer_info_size = layer_info_size;
- (void) SetPSDSize(&psd_info,image,rounded_layer_info_size);
-
- if ( invert_layer_count )
- layer_count *= -1; /* if we have a matte, then use negative count! */
- (void) WriteBlobMSBShort(image,(unsigned short) layer_count);
-
- layer_count = 1;
- tmp_image = base_image;
- tmp_image->compression=NoCompression;
- while ( tmp_image != NULL ) {
- (void) WriteBlobMSBLong(image,0);
- (void) WriteBlobMSBLong(image,0);
- (void) WriteBlobMSBLong(image,(unsigned int) tmp_image->rows);
- (void) WriteBlobMSBLong(image,(unsigned int) tmp_image->columns);
-
- packet_size=tmp_image->depth > 8 ? 2UL : 1UL;
- channel_size=(unsigned int) ((packet_size*tmp_image->rows*
- tmp_image->columns)+2);
- if ((IsGrayImage(tmp_image,&image->exception) != MagickFalse) ||
- (tmp_image->storage_class == PseudoClass)) {
- (void) WriteBlobMSBShort(image,(unsigned short)
- (tmp_image->matte != MagickFalse ? 2 : 1));
- if (tmp_image->matte != MagickFalse) {
- (void) WriteBlobMSBShort(image,(unsigned short) -1);
- (void) SetPSDSize(&psd_info,image,channel_size);
- }
- (void) WriteBlobMSBShort(image, 0);
- (void) SetPSDSize(&psd_info,image,channel_size);
- } else
- if (tmp_image->colorspace != CMYKColorspace)
- {
- (void) WriteBlobMSBShort(image,(unsigned short)
- (tmp_image->matte != MagickFalse ? 4 : 3));
- if (tmp_image->matte!= MagickFalse ) {
- (void) WriteBlobMSBShort(image,(unsigned short) -1);
- (void) SetPSDSize(&psd_info,image,channel_size);
- }
- (void) WriteBlobMSBShort(image, 0);
- (void) SetPSDSize(&psd_info,image,channel_size);
- (void) WriteBlobMSBShort(image, 1);
- (void) SetPSDSize(&psd_info,image,channel_size);
- (void) WriteBlobMSBShort(image, 2);
- (void) SetPSDSize(&psd_info,image,channel_size);
- }
+ {
+ CompressionType
+ compression;
+
+ (void) SetPSDSize(&psd_info,image,layer_info_size+
+ (psd_info.version == 1 ? 8 : 16));
+ if ((layer_info_size/2) != ((layer_info_size+1)/2))
+ rounded_layer_info_size=layer_info_size+1;
else
+ rounded_layer_info_size=layer_info_size;
+ (void) SetPSDSize(&psd_info,image,rounded_layer_info_size);
+ (void) WriteBlobMSBShort(image,(unsigned short) layer_count);
+ layer_count=1;
+ compression=base_image->compression;
+ next_image=base_image;
+ while (next_image != NULL)
{
- (void) WriteBlobMSBShort(image,(unsigned short)
- (tmp_image->matte ? 5 : 4));
- if (tmp_image->matte) {
- (void) WriteBlobMSBShort(image,(unsigned short) -1);
- (void) SetPSDSize(&psd_info,image,channel_size);
- }
- (void) WriteBlobMSBShort(image, 0);
- (void) SetPSDSize(&psd_info,image,channel_size);
- (void) WriteBlobMSBShort(image, 1);
- (void) SetPSDSize(&psd_info,image,channel_size);
- (void) WriteBlobMSBShort(image, 2);
- (void) SetPSDSize(&psd_info,image,channel_size);
- (void) WriteBlobMSBShort(image, 3);
- (void) SetPSDSize(&psd_info,image,channel_size);
- }
-
- (void) WriteBlob(image,4,(const unsigned char *) "8BIM");
- (void) WriteBlob(image,4,(const unsigned char *)
- CompositeOperatorToPSDBlendMode(tmp_image->compose));
- (void) WriteBlobByte(image, 255); /* BOGUS: layer opacity */
- (void) WriteBlobByte(image, 0);
- (void) WriteBlobByte(image, 1); /* BOGUS: layer attributes - visible, etc. */
- (void) WriteBlobByte(image, 0);
-
-
- theAttr=(const char *) GetImageProperty(tmp_image,"label");
- if (!theAttr) {
- (void) WriteBlobMSBLong(image, 16);
- (void) WriteBlobMSBLong(image, 0);
- (void) WriteBlobMSBLong(image, 0);
- (void) FormatMagickString((char *) layer_name,MaxTextExtent,"L%06ld",
- layer_count++ );
- WritePascalString( image, (char*)layer_name, 4 );
- } else {
- size_t length=strlen(theAttr);
- (void) WriteBlobMSBLong(image,(unsigned int) (length+(4-(length % 4))+
- 1+8));
+ next_image->compression=NoCompression;
(void) WriteBlobMSBLong(image,0);
(void) WriteBlobMSBLong(image,0);
- WritePascalString( image, theAttr, 4 );
+ (void) WriteBlobMSBLong(image,(unsigned int) next_image->rows);
+ (void) WriteBlobMSBLong(image,(unsigned int) next_image->columns);
+ packet_size=next_image->depth > 8 ? 2UL : 1UL;
+ channel_size=(unsigned int) ((packet_size*next_image->rows*
+ next_image->columns)+2);
+ if ((IsImageGray(next_image,exception) != MagickFalse) ||
+ (next_image->storage_class == PseudoClass))
+ {
+ (void) WriteBlobMSBShort(image,(unsigned short)
+ (next_image->matte != MagickFalse ? 2 : 1));
+ (void) WriteBlobMSBShort(image,0);
+ (void) SetPSDSize(&psd_info,image,channel_size);
+ if (next_image->matte != MagickFalse)
+ {
+ (void) WriteBlobMSBShort(image,(unsigned short) -1);
+ (void) SetPSDSize(&psd_info,image,channel_size);
+ }
+ }
+ else
+ if (next_image->colorspace != CMYKColorspace)
+ {
+ (void) WriteBlobMSBShort(image,(unsigned short)
+ (next_image->matte != MagickFalse ? 4 : 3));
+ (void) WriteBlobMSBShort(image,0);
+ (void) SetPSDSize(&psd_info,image,channel_size);
+ (void) WriteBlobMSBShort(image,1);
+ (void) SetPSDSize(&psd_info,image,channel_size);
+ (void) WriteBlobMSBShort(image,2);
+ (void) SetPSDSize(&psd_info,image,channel_size);
+ if (next_image->matte!= MagickFalse )
+ {
+ (void) WriteBlobMSBShort(image,(unsigned short) -1);
+ (void) SetPSDSize(&psd_info,image,channel_size);
+ }
+ }
+ else
+ {
+ (void) WriteBlobMSBShort(image,(unsigned short)
+ (next_image->matte ? 5 : 4));
+ (void) WriteBlobMSBShort(image,0);
+ (void) SetPSDSize(&psd_info,image,channel_size);
+ (void) WriteBlobMSBShort(image,1);
+ (void) SetPSDSize(&psd_info,image,channel_size);
+ (void) WriteBlobMSBShort(image,2);
+ (void) SetPSDSize(&psd_info,image,channel_size);
+ (void) WriteBlobMSBShort(image,3);
+ (void) SetPSDSize(&psd_info,image,channel_size);
+ if (next_image->matte)
+ {
+ (void) WriteBlobMSBShort(image,(unsigned short) -1);
+ (void) SetPSDSize(&psd_info,image,channel_size);
+ }
+ }
+ (void) WriteBlob(image,4,(const unsigned char *) "8BIM");
+ (void) WriteBlob(image,4,(const unsigned char *)
+ CompositeOperatorToPSDBlendMode(next_image->compose));
+ (void) WriteBlobByte(image,255); /* layer opacity */
+ (void) WriteBlobByte(image,0);
+ (void) WriteBlobByte(image,1); /* layer propertys - visible, etc. */
+ (void) WriteBlobByte(image,0);
+ property=(const char *) GetImageProperty(next_image,"label");
+ if (property == (const char *) NULL)
+ {
+ (void) WriteBlobMSBLong(image,16);
+ (void) WriteBlobMSBLong(image,0);
+ (void) WriteBlobMSBLong(image,0);
+ (void) FormatLocaleString((char *) layer_name,MaxTextExtent,
+ "L%06ld",(long) layer_count++);
+ WritePascalString( image, (char*)layer_name, 4 );
+ }
+ else
+ {
+ size_t
+ length;
+
+ length=strlen(property);
+ (void) WriteBlobMSBLong(image,(unsigned int) (length+(4-
+ (length % 4))+8));
+ (void) WriteBlobMSBLong(image,0);
+ (void) WriteBlobMSBLong(image,0);
+ WritePascalString(image,property,4);
+ }
+ next_image=GetNextImageInList(next_image);
}
- tmp_image = GetNextImageInList(tmp_image);
- };
-
- /* now the image data! */
- tmp_image = base_image;
- while ( tmp_image != NULL ) {
- status=WriteImageChannels(&psd_info,image_info,image,tmp_image,MagickTrue);
-
- /* add in the pad! */
- if ( rounded_layer_info_size != layer_info_size )
- (void) WriteBlobByte(image,'\0');
-
- tmp_image = GetNextImageInList(tmp_image);
- };
-
- /* user mask data */
- (void) WriteBlobMSBLong(image, 0);
-
- }
-
- /* now the background image data! */
- status=WriteImageChannels(&psd_info,image_info,image,image,MagickFalse);
-
+ /*
+ Now the image data!
+ */
+ next_image=base_image;
+ while (next_image != NULL)
+ {
+ status=WriteImageChannels(&psd_info,image_info,image,next_image,
+ MagickTrue,exception);
+ next_image=GetNextImageInList(next_image);
+ }
+ (void) WriteBlobMSBLong(image,0); /* user mask data */
+ base_image->compression=compression;
+ }
+ /*
+ Write composite image.
+ */
+ status=WriteImageChannels(&psd_info,image_info,image,image,MagickFalse,
+ exception);
(void) CloseBlob(image);
return(status);
}