#include "MagickCore/utility.h"
#include "ghostscript-private.h"
\f
+/*
+ Typedef declaractions.
+*/
+typedef struct _PSInfo
+{
+ MagickBooleanType
+ cmyk;
+
+ SegmentInfo
+ bounds;
+
+ unsigned long
+ columns,
+ rows;
+
+ StringInfo
+ *icc_profile,
+ *photoshop_profile,
+ *xmp_profile;
+
+} PSInfo;
+\f
/*
Forward declarations.
*/
return(value);
}
-static Image *ReadPSImage(const ImageInfo *image_info,ExceptionInfo *exception)
+static void ReadPSInfo(const ImageInfo *image_info,Image *image,
+ PSInfo *ps_info,ExceptionInfo *exception)
{
-#define BoundingBox "BoundingBox:"
#define BeginDocument "BeginDocument:"
-#define BeginXMPPacket "<?xpacket begin="
-#define EndXMPPacket "<?xpacket end="
-#define ICCProfile "BeginICCProfile:"
+#define EndDocument "EndDocument:"
+#define PostscriptLevel "!PS-"
+#define ImageData "ImageData:"
+#define DocumentProcessColors "DocumentProcessColors:"
#define CMYKCustomColor "CMYKCustomColor:"
#define CMYKProcessColor "CMYKProcessColor:"
-#define DocumentMedia "DocumentMedia:"
#define DocumentCustomColors "DocumentCustomColors:"
-#define DocumentProcessColors "DocumentProcessColors:"
-#define EndDocument "EndDocument:"
+#define SpotColor "+ "
+#define BoundingBox "BoundingBox:"
+#define DocumentMedia "DocumentMedia:"
#define HiResBoundingBox "HiResBoundingBox:"
-#define ImageData "ImageData:"
#define PageBoundingBox "PageBoundingBox:"
-#define LanguageLevel "LanguageLevel:"
#define PageMedia "PageMedia:"
-#define Pages "Pages:"
+#define ICCProfile "BeginICCProfile:"
#define PhotoshopProfile "BeginPhotoshop:"
-#define PostscriptLevel "!PS-"
-#define SpotColor "+ "
+#define BeginXMPPacket "<?xpacket begin="
+#define EndXMPPacket "<?xpacket end="
char
- command[MagickPathExtent],
- *density,
- filename[MagickPathExtent],
- geometry[MagickPathExtent],
- input_filename[MagickPathExtent],
- message[MagickPathExtent],
- *options,
- postscript_filename[MagickPathExtent];
-
- const char
- *option;
-
- const DelegateInfo
- *delegate_info;
-
- GeometryInfo
- geometry_info;
-
- Image
- *image,
- *next,
- *postscript_image;
-
- ImageInfo
- *read_info;
+ command[MagickPathExtent];
int
- c,
- file;
+ c;
MagickBooleanType
- cmyk,
- fitPage,
- skip,
- status;
-
- MagickStatusType
- flags;
-
- PointInfo
- delta,
- resolution;
-
- RectangleInfo
- page;
+ skip;
register char
*p;
i;
SegmentInfo
- bounds,
- hires_bounds;
-
- short int
- hex_digits[256];
+ bounds;
size_t
length;
count,
priority;
- StringInfo
- *profile;
+ short int
+ hex_digits[256];
unsigned long
- columns,
extent,
- language_level,
- pages,
- rows,
- scene,
spotcolor;
- /*
- Open image file.
- */
- assert(image_info != (const ImageInfo *) NULL);
- assert(image_info->signature == MagickCoreSignature);
- if (image_info->debug != MagickFalse)
- (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
- image_info->filename);
- assert(exception != (ExceptionInfo *) NULL);
- assert(exception->signature == MagickCoreSignature);
- image=AcquireImage(image_info,exception);
- status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
- if (status == MagickFalse)
- {
- image=DestroyImageList(image);
- return((Image *) NULL);
- }
- status=AcquireUniqueSymbolicLink(image_info->filename,input_filename);
- if (status == MagickFalse)
- {
- ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
- image_info->filename);
- image=DestroyImageList(image);
- return((Image *) NULL);
- }
+ (void) memset(&bounds,0,sizeof(bounds));
+ (void) memset(ps_info,0,sizeof(*ps_info));
+ ps_info->cmyk=image_info->colorspace == CMYKColorspace ? MagickTrue :
+ MagickFalse;
/*
Initialize hex values.
*/
hex_digits[(int) 'D']=13;
hex_digits[(int) 'E']=14;
hex_digits[(int) 'F']=15;
- /*
- Set the page density.
- */
- delta.x=DefaultResolution;
- delta.y=DefaultResolution;
- if ((image->resolution.x == 0.0) || (image->resolution.y == 0.0))
- {
- flags=ParseGeometry(PSDensityGeometry,&geometry_info);
- image->resolution.x=geometry_info.rho;
- image->resolution.y=geometry_info.sigma;
- if ((flags & SigmaValue) == 0)
- image->resolution.y=image->resolution.x;
- }
- if (image_info->density != (char *) NULL)
- {
- flags=ParseGeometry(image_info->density,&geometry_info);
- image->resolution.x=geometry_info.rho;
- image->resolution.y=geometry_info.sigma;
- if ((flags & SigmaValue) == 0)
- image->resolution.y=image->resolution.x;
- }
- (void) ParseAbsoluteGeometry(PSPageGeometry,&page);
- if (image_info->page != (char *) NULL)
- (void) ParseAbsoluteGeometry(image_info->page,&page);
- resolution=image->resolution;
- page.width=(size_t) ceil((double) (page.width*resolution.x/delta.x)-0.5);
- page.height=(size_t) ceil((double) (page.height*resolution.y/delta.y)-0.5);
- /*
- Determine page geometry from the Postscript bounding box.
- */
- (void) memset(&bounds,0,sizeof(bounds));
- (void) memset(command,0,sizeof(command));
- cmyk=image_info->colorspace == CMYKColorspace ? MagickTrue : MagickFalse;
- (void) memset(&hires_bounds,0,sizeof(hires_bounds));
- columns=0;
- rows=0;
- priority=0;
- rows=0;
extent=0;
+ priority=0;
spotcolor=0;
- language_level=1;
- pages=(~0UL);
skip=MagickFalse;
p=command;
for (c=ReadBlobByte(image); c != EOF; c=ReadBlobByte(image))
if (skip != MagickFalse)
continue;
if (LocaleNCompare(PostscriptLevel,command,strlen(PostscriptLevel)) == 0)
- {
- (void) SetImageProperty(image,"ps:Level",command+4,exception);
- if (GlobExpression(command,"*EPSF-*",MagickTrue) != MagickFalse)
- pages=1;
- }
- if (LocaleNCompare(LanguageLevel,command,strlen(LanguageLevel)) == 0)
- (void) sscanf(command,LanguageLevel " %lu",&language_level);
- if (LocaleNCompare(Pages,command,strlen(Pages)) == 0)
- (void) sscanf(command,Pages " %lu",&pages);
+ (void) SetImageProperty(image,"ps:Level",command+4,exception);
if (LocaleNCompare(ImageData,command,strlen(ImageData)) == 0)
- (void) sscanf(command,ImageData " %lu %lu",&columns,&rows);
+ (void) sscanf(command,ImageData " %lu %lu",&ps_info->columns,
+ &ps_info->rows);
/*
Is this a CMYK document?
*/
if ((GlobExpression(command,"*Cyan*",MagickTrue) != MagickFalse) ||
(GlobExpression(command,"*Magenta*",MagickTrue) != MagickFalse) ||
(GlobExpression(command,"*Yellow*",MagickTrue) != MagickFalse))
- cmyk=MagickTrue;
+ ps_info->cmyk=MagickTrue;
}
if (LocaleNCompare(CMYKCustomColor,command,strlen(CMYKCustomColor)) == 0)
- cmyk=MagickTrue;
+ ps_info->cmyk=MagickTrue;
if (LocaleNCompare(CMYKProcessColor,command,strlen(CMYKProcessColor)) == 0)
- cmyk=MagickTrue;
+ ps_info->cmyk=MagickTrue;
length=strlen(DocumentCustomColors);
if ((LocaleNCompare(DocumentCustomColors,command,length) == 0) ||
(LocaleNCompare(CMYKCustomColor,command,strlen(CMYKCustomColor)) == 0) ||
value=DestroyString(value);
continue;
}
+ if (LocaleNCompare(ICCProfile,command,strlen(ICCProfile)) == 0)
+ {
+ unsigned char
+ *datum;
+
+ /*
+ Read ICC profile.
+ */
+ ps_info->icc_profile=AcquireStringInfo(MagickPathExtent);
+ datum=GetStringInfoDatum(ps_info->icc_profile);
+ for (i=0; (c=ProfileInteger(image,hex_digits)) != EOF; i++)
+ {
+ if (i >= (ssize_t) GetStringInfoLength(ps_info->icc_profile))
+ {
+ SetStringInfoLength(ps_info->icc_profile,(size_t) i << 1);
+ datum=GetStringInfoDatum(ps_info->icc_profile);
+ }
+ datum[i]=(unsigned char) c;
+ }
+ SetStringInfoLength(ps_info->icc_profile,(size_t) i+1);
+ continue;
+ }
+ if (LocaleNCompare(PhotoshopProfile,command,strlen(PhotoshopProfile)) == 0)
+ {
+ unsigned char
+ *q;
+
+ /*
+ Read Photoshop profile.
+ */
+ count=(ssize_t) sscanf(command,PhotoshopProfile " %lu",&extent);
+ if (count != 1)
+ continue;
+ length=extent;
+ if ((MagickSizeType) length > GetBlobSize(image))
+ continue;
+ ps_info->photoshop_profile=BlobToStringInfo((const void *) NULL,length);
+ if (ps_info->photoshop_profile != (StringInfo *) NULL)
+ {
+ q=GetStringInfoDatum(ps_info->photoshop_profile);
+ for (i=0; i < (ssize_t) length; i++)
+ *q++=(unsigned char) ProfileInteger(image,hex_digits);
+ }
+ continue;
+ }
+ if (LocaleNCompare(BeginXMPPacket,command,strlen(BeginXMPPacket)) == 0)
+ {
+ /*
+ Read XMP profile.
+ */
+ p=command;
+ ps_info->xmp_profile=StringToStringInfo(command);
+ for (i=(ssize_t) GetStringInfoLength(ps_info->xmp_profile)-1; c != EOF; i++)
+ {
+ SetStringInfoLength(ps_info->xmp_profile,(size_t) (i+1));
+ c=ReadBlobByte(image);
+ GetStringInfoDatum(ps_info->xmp_profile)[i]=(unsigned char) c;
+ *p++=(char) c;
+ if ((strchr("\n\r%",c) == (char *) NULL) &&
+ ((size_t) (p-command) < (MagickPathExtent-1)))
+ continue;
+ *p='\0';
+ p=command;
+ if (LocaleNCompare(EndXMPPacket,command,strlen(EndXMPPacket)) == 0)
+ break;
+ }
+ SetStringInfoLength(ps_info->xmp_profile,(size_t) i);
+ continue;
+ }
if (image_info->page != (char *) NULL)
continue;
/*
}
if ((count != 4) || (i < (ssize_t) priority))
continue;
- if ((fabs(bounds.x2-bounds.x1) <= fabs(hires_bounds.x2-hires_bounds.x1)) ||
- (fabs(bounds.y2-bounds.y1) <= fabs(hires_bounds.y2-hires_bounds.y1)))
+ if ((fabs(bounds.x2-bounds.x1) <= fabs(ps_info->bounds.x2-ps_info->bounds.x1)) ||
+ (fabs(bounds.y2-bounds.y1) <= fabs(ps_info->bounds.y2-ps_info->bounds.y1)))
if (i == (ssize_t) priority)
continue;
- hires_bounds=bounds;
+ ps_info->bounds=bounds;
priority=i;
}
- if ((fabs(hires_bounds.x2-hires_bounds.x1) >= MagickEpsilon) &&
- (fabs(hires_bounds.y2-hires_bounds.y1) >= MagickEpsilon))
+}
+
+static inline void CleanupPSInfo(PSInfo *pdf_info)
+{
+ if (pdf_info->icc_profile != (StringInfo *) NULL)
+ pdf_info->icc_profile=DestroyStringInfo(pdf_info->icc_profile);
+ if (pdf_info->photoshop_profile != (StringInfo *) NULL)
+ pdf_info->photoshop_profile=DestroyStringInfo(pdf_info->photoshop_profile);
+ if (pdf_info->xmp_profile != (StringInfo *) NULL)
+ pdf_info->xmp_profile=DestroyStringInfo(pdf_info->xmp_profile);
+}
+
+static Image *ReadPSImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ char
+ command[MagickPathExtent],
+ *density,
+ filename[MagickPathExtent],
+ geometry[MagickPathExtent],
+ input_filename[MagickPathExtent],
+ message[MagickPathExtent],
+ *options,
+ postscript_filename[MagickPathExtent];
+
+ const char
+ *option;
+
+ const DelegateInfo
+ *delegate_info;
+
+ GeometryInfo
+ geometry_info;
+
+ Image
+ *image,
+ *next,
+ *postscript_image;
+
+ ImageInfo
+ *read_info;
+
+ int
+ file;
+
+ MagickBooleanType
+ fitPage,
+ status;
+
+ MagickStatusType
+ flags;
+
+ PointInfo
+ delta,
+ resolution;
+
+ PSInfo
+ info;
+
+ RectangleInfo
+ page;
+
+ register ssize_t
+ i;
+
+ ssize_t
+ count;
+
+ unsigned long
+ scene;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickCoreSignature);
+ if (image_info->debug != MagickFalse)
+ (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
+ image_info->filename);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickCoreSignature);
+ image=AcquireImage(image_info,exception);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == MagickFalse)
+ {
+ image=DestroyImageList(image);
+ return((Image *) NULL);
+ }
+ status=AcquireUniqueSymbolicLink(image_info->filename,input_filename);
+ if (status == MagickFalse)
+ {
+ ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
+ image_info->filename);
+ image=DestroyImageList(image);
+ return((Image *) NULL);
+ }
+ /*
+ Set the page density.
+ */
+ delta.x=DefaultResolution;
+ delta.y=DefaultResolution;
+ if ((image->resolution.x == 0.0) || (image->resolution.y == 0.0))
+ {
+ flags=ParseGeometry(PSDensityGeometry,&geometry_info);
+ image->resolution.x=geometry_info.rho;
+ image->resolution.y=geometry_info.sigma;
+ if ((flags & SigmaValue) == 0)
+ image->resolution.y=image->resolution.x;
+ }
+ if (image_info->density != (char *) NULL)
+ {
+ flags=ParseGeometry(image_info->density,&geometry_info);
+ image->resolution.x=geometry_info.rho;
+ image->resolution.y=geometry_info.sigma;
+ if ((flags & SigmaValue) == 0)
+ image->resolution.y=image->resolution.x;
+ }
+ (void) ParseAbsoluteGeometry(PSPageGeometry,&page);
+ if (image_info->page != (char *) NULL)
+ (void) ParseAbsoluteGeometry(image_info->page,&page);
+ resolution=image->resolution;
+ page.width=(size_t) ceil((double) (page.width*resolution.x/delta.x)-0.5);
+ page.height=(size_t) ceil((double) (page.height*resolution.y/delta.y)-0.5);
+ /*
+ Determine page geometry from the Postscript bounding box.
+ */
+ ReadPSInfo(image_info,image,&info,exception);
+ (void) CloseBlob(image);
+ /*
+ Set Postscript render geometry.
+ */
+ if ((fabs(info.bounds.x2-info.bounds.x1) >= MagickEpsilon) &&
+ (fabs(info.bounds.y2-info.bounds.y1) >= MagickEpsilon))
{
- /*
- Set Postscript render geometry.
- */
(void) FormatLocaleString(geometry,MagickPathExtent,"%gx%g%+.15g%+.15g",
- hires_bounds.x2-hires_bounds.x1,hires_bounds.y2-hires_bounds.y1,
- hires_bounds.x1,hires_bounds.y1);
+ info.bounds.x2-info.bounds.x1,info.bounds.y2-info.bounds.y1,
+ info.bounds.x1,info.bounds.y1);
(void) SetImageProperty(image,"ps:HiResBoundingBox",geometry,exception);
- page.width=(size_t) ceil((double) ((hires_bounds.x2-hires_bounds.x1)*
+ page.width=(size_t) ceil((double) ((info.bounds.x2-info.bounds.x1)*
resolution.x/delta.x)-0.5);
- page.height=(size_t) ceil((double) ((hires_bounds.y2-hires_bounds.y1)*
+ page.height=(size_t) ceil((double) ((info.bounds.y2-info.bounds.y1)*
resolution.y/delta.y)-0.5);
}
fitPage=MagickFalse;
fitPage=MagickTrue;
}
if (IssRGBCompatibleColorspace(image_info->colorspace) != MagickFalse)
- cmyk=MagickFalse;
+ info.cmyk=MagickFalse;
/*
Create Ghostscript control file.
*/
{
ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
image_info->filename);
+ CleanupPSInfo(&info);
image=DestroyImageList(image);
return((Image *) NULL);
}
translate_geometry[MagickPathExtent];
(void) FormatLocaleString(translate_geometry,MagickPathExtent,
- "%g %g translate\n",-bounds.x1,-bounds.y1);
+ "%g %g translate\n",-info.bounds.x1,-info.bounds.y1);
count=write(file,translate_geometry,(unsigned int)
strlen(translate_geometry));
}
if (image_info->monochrome != MagickFalse)
delegate_info=GetDelegateInfo("ps:mono",(char *) NULL,exception);
else
- if (cmyk != MagickFalse)
+ if (info.cmyk != MagickFalse)
delegate_info=GetDelegateInfo("ps:cmyk",(char *) NULL,exception);
else
delegate_info=GetDelegateInfo("ps:alpha",(char *) NULL,exception);
if (delegate_info == (const DelegateInfo *) NULL)
{
(void) RelinquishUniqueFileResource(postscript_filename);
+ CleanupPSInfo(&info);
image=DestroyImageList(image);
return((Image *) NULL);
}
if (*message != '\0')
(void) ThrowMagickException(exception,GetMagickModule(),
DelegateError,"PostscriptDelegateFailed","`%s'",message);
+ CleanupPSInfo(&info);
image=DestroyImageList(image);
return((Image *) NULL);
}
postscript_image=cmyk_image;
}
}
- (void) SeekBlob(image,0,SEEK_SET);
- for (c=ReadBlobByte(image); c != EOF; c=ReadBlobByte(image))
- {
- /*
- Note document structuring comments.
- */
- *p++=(char) c;
- if ((strchr("\n\r%",c) == (char *) NULL) &&
- ((size_t) (p-command) < (MagickPathExtent-1)))
- continue;
- *p='\0';
- p=command;
- /*
- Skip %%BeginDocument thru %%EndDocument.
- */
- if (LocaleNCompare(BeginDocument,command,strlen(BeginDocument)) == 0)
- skip=MagickTrue;
- if (LocaleNCompare(EndDocument,command,strlen(EndDocument)) == 0)
- skip=MagickFalse;
- if (skip != MagickFalse)
- continue;
- if (LocaleNCompare(ICCProfile,command,strlen(ICCProfile)) == 0)
- {
- unsigned char
- *datum;
-
- /*
- Read ICC profile.
- */
- profile=AcquireStringInfo(MagickPathExtent);
- datum=GetStringInfoDatum(profile);
- for (i=0; (c=ProfileInteger(image,hex_digits)) != EOF; i++)
- {
- if (i >= (ssize_t) GetStringInfoLength(profile))
- {
- SetStringInfoLength(profile,(size_t) i << 1);
- datum=GetStringInfoDatum(profile);
- }
- datum[i]=(unsigned char) c;
- }
- SetStringInfoLength(profile,(size_t) i+1);
- (void) SetImageProfile(image,"icc",profile,exception);
- profile=DestroyStringInfo(profile);
- continue;
- }
- if (LocaleNCompare(PhotoshopProfile,command,strlen(PhotoshopProfile)) == 0)
- {
- unsigned char
- *q;
-
- /*
- Read Photoshop profile.
- */
- count=(ssize_t) sscanf(command,PhotoshopProfile " %lu",&extent);
- if (count != 1)
- continue;
- length=extent;
- if ((MagickSizeType) length > GetBlobSize(image))
- ThrowReaderException(CorruptImageError,"InsufficientImageDataInFile");
- profile=BlobToStringInfo((const void *) NULL,length);
- if (profile != (StringInfo *) NULL)
- {
- q=GetStringInfoDatum(profile);
- for (i=0; i < (ssize_t) length; i++)
- *q++=(unsigned char) ProfileInteger(image,hex_digits);
- (void) SetImageProfile(image,"8bim",profile,exception);
- profile=DestroyStringInfo(profile);
- }
- continue;
- }
- if (LocaleNCompare(BeginXMPPacket,command,strlen(BeginXMPPacket)) == 0)
- {
- /*
- Read XMP profile.
- */
- p=command;
- profile=StringToStringInfo(command);
- for (i=(ssize_t) GetStringInfoLength(profile)-1; c != EOF; i++)
- {
- SetStringInfoLength(profile,(size_t) (i+1));
- c=ReadBlobByte(image);
- GetStringInfoDatum(profile)[i]=(unsigned char) c;
- *p++=(char) c;
- if ((strchr("\n\r%",c) == (char *) NULL) &&
- ((size_t) (p-command) < (MagickPathExtent-1)))
- continue;
- *p='\0';
- p=command;
- if (LocaleNCompare(EndXMPPacket,command,strlen(EndXMPPacket)) == 0)
- break;
- }
- SetStringInfoLength(profile,(size_t) i);
- (void) SetImageProfile(image,"xmp",profile,exception);
- profile=DestroyStringInfo(profile);
- continue;
- }
- }
- (void) CloseBlob(image);
+ if (info.icc_profile != (StringInfo *) NULL)
+ (void) SetImageProfile(image,"icc",info.icc_profile,exception);
+ if (info.photoshop_profile != (StringInfo *) NULL)
+ (void) SetImageProfile(image,"8bim",info.photoshop_profile,exception);
+ if (info.xmp_profile != (StringInfo *) NULL)
+ (void) SetImageProfile(image,"xmp",info.xmp_profile,exception);
+ CleanupPSInfo(&info);
if (image_info->number_scenes != 0)
{
Image
MagickPathExtent);
(void) CopyMagickString(postscript_image->magick,image->magick,
MagickPathExtent);
- if (columns != 0)
- postscript_image->magick_columns=columns;
- if (rows != 0)
- postscript_image->magick_rows=rows;
+ if (info.columns != 0)
+ postscript_image->magick_columns=info.columns;
+ if (info.rows != 0)
+ postscript_image->magick_rows=info.rows;
postscript_image->page=page;
(void) CloneImageProfiles(postscript_image,image);
(void) CloneImageProperties(postscript_image,image);