/coders/ps.c
C | 2311 lines | 1919 code | 84 blank | 308 comment | 452 complexity | cdd1d70af24fe8f16b47fe67a77d5aa9 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception
Large files files are truncated, but you can click here to view the full file
- /*
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % %
- % %
- % %
- % PPPP SSSSS %
- % P P SS %
- % PPPP SSS %
- % P SS %
- % P SSSSS %
- % %
- % %
- % Read/Write Postscript Format %
- % %
- % Software Design %
- % Cristy %
- % July 1992 %
- % %
- % %
- % Copyright 1999-2019 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 %
- % obtain a copy of the License at %
- % %
- % https://imagemagick.org/script/license.php %
- % %
- % Unless required by applicable law or agreed to in writing, software %
- % distributed under the License is distributed on an "AS IS" BASIS, %
- % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
- % See the License for the specific language governing permissions and %
- % limitations under the License. %
- % %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- %
- */
- /*
- Include declarations.
- */
- #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/color.h"
- #include "MagickCore/color-private.h"
- #include "MagickCore/colorspace.h"
- #include "MagickCore/colorspace-private.h"
- #include "MagickCore/constitute.h"
- #include "MagickCore/delegate.h"
- #include "MagickCore/delegate-private.h"
- #include "MagickCore/draw.h"
- #include "MagickCore/exception.h"
- #include "MagickCore/exception-private.h"
- #include "MagickCore/geometry.h"
- #include "MagickCore/image.h"
- #include "MagickCore/image-private.h"
- #include "MagickCore/list.h"
- #include "MagickCore/magick.h"
- #include "MagickCore/memory_.h"
- #include "MagickCore/module.h"
- #include "MagickCore/monitor.h"
- #include "MagickCore/monitor-private.h"
- #include "MagickCore/nt-base-private.h"
- #include "MagickCore/option.h"
- #include "MagickCore/profile.h"
- #include "MagickCore/resource_.h"
- #include "MagickCore/pixel-accessor.h"
- #include "MagickCore/property.h"
- #include "MagickCore/quantum-private.h"
- #include "MagickCore/static.h"
- #include "MagickCore/string_.h"
- #include "MagickCore/timer-private.h"
- #include "MagickCore/token.h"
- #include "MagickCore/transform.h"
- #include "MagickCore/utility.h"
- /*
- Forward declarations.
- */
- static MagickBooleanType
- WritePSImage(const ImageInfo *,Image *,ExceptionInfo *);
- /*
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % %
- % %
- % %
- % I n v o k e P o s t s r i p t D e l e g a t e %
- % %
- % %
- % %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- % InvokePostscriptDelegate() executes the Postscript interpreter with the
- % specified command.
- %
- % The format of the InvokePostscriptDelegate method is:
- %
- % MagickBooleanType InvokePostscriptDelegate(
- % const MagickBooleanType verbose,const char *command,
- % ExceptionInfo *exception)
- %
- % A description of each parameter follows:
- %
- % o verbose: A value other than zero displays the command prior to
- % executing it.
- %
- % o command: the address of a character string containing the command to
- % execute.
- %
- % o exception: return any errors or warnings in this structure.
- %
- */
- #if defined(MAGICKCORE_GS_DELEGATE) || defined(MAGICKCORE_WINDOWS_SUPPORT)
- static int MagickDLLCall PostscriptDelegateMessage(void *handle,
- const char *message,int length)
- {
- char
- **messages;
- ssize_t
- offset;
- offset=0;
- messages=(char **) handle;
- if (*messages == (char *) NULL)
- *messages=(char *) AcquireQuantumMemory((size_t) length+1,sizeof(char *));
- else
- {
- offset=(ssize_t) strlen(*messages);
- *messages=(char *) ResizeQuantumMemory(*messages,(size_t) offset+length+1,
- sizeof(char *));
- }
- if (*messages == (char *) NULL)
- return(0);
- (void) memcpy(*messages+offset,message,(size_t) length);
- (*messages)[length+offset] ='\0';
- return(length);
- }
- #endif
- static MagickBooleanType InvokePostscriptDelegate(
- const MagickBooleanType verbose,const char *command,char *message,
- ExceptionInfo *exception)
- {
- int
- status;
- #if defined(MAGICKCORE_GS_DELEGATE) || defined(MAGICKCORE_WINDOWS_SUPPORT)
- #define SetArgsStart(command,args_start) \
- if (args_start == (const char *) NULL) \
- { \
- if (*command != '"') \
- args_start=strchr(command,' '); \
- else \
- { \
- args_start=strchr(command+1,'"'); \
- if (args_start != (const char *) NULL) \
- args_start++; \
- } \
- }
- #define ExecuteGhostscriptCommand(command,status) \
- { \
- status=ExternalDelegateCommand(MagickFalse,verbose,command,message, \
- exception); \
- if (status == 0) \
- return(MagickTrue); \
- if (status < 0) \
- return(MagickFalse); \
- (void) ThrowMagickException(exception,GetMagickModule(),DelegateError, \
- "FailedToExecuteCommand","`%s' (%d)",command,status); \
- return(MagickFalse); \
- }
- char
- **argv,
- *errors;
- const char
- *args_start = (const char *) NULL;
- const GhostInfo
- *ghost_info;
- gs_main_instance
- *interpreter;
- gsapi_revision_t
- revision;
- int
- argc,
- code;
- register ssize_t
- i;
- #if defined(MAGICKCORE_WINDOWS_SUPPORT)
- ghost_info=NTGhostscriptDLLVectors();
- #else
- GhostInfo
- ghost_info_struct;
- ghost_info=(&ghost_info_struct);
- (void) memset(&ghost_info_struct,0,sizeof(ghost_info_struct));
- ghost_info_struct.delete_instance=(void (*)(gs_main_instance *))
- gsapi_delete_instance;
- ghost_info_struct.exit=(int (*)(gs_main_instance *)) gsapi_exit;
- ghost_info_struct.new_instance=(int (*)(gs_main_instance **,void *))
- gsapi_new_instance;
- ghost_info_struct.init_with_args=(int (*)(gs_main_instance *,int,char **))
- gsapi_init_with_args;
- ghost_info_struct.run_string=(int (*)(gs_main_instance *,const char *,int,
- int *)) gsapi_run_string;
- ghost_info_struct.set_stdio=(int (*)(gs_main_instance *,int (*)(void *,char *,
- int),int (*)(void *,const char *,int),int (*)(void *, const char *, int)))
- gsapi_set_stdio;
- ghost_info_struct.revision=(int (*)(gsapi_revision_t *,int)) gsapi_revision;
- #endif
- if (ghost_info == (GhostInfo *) NULL)
- ExecuteGhostscriptCommand(command,status);
- if ((ghost_info->revision)(&revision,(int) sizeof(revision)) != 0)
- revision.revision=0;
- if (verbose != MagickFalse)
- {
- (void) fprintf(stdout,"[ghostscript library %.2f]",(double)
- revision.revision/100.0);
- SetArgsStart(command,args_start);
- (void) fputs(args_start,stdout);
- }
- interpreter=(gs_main_instance *) NULL;
- errors=(char *) NULL;
- status=(ghost_info->new_instance)(&interpreter,(void *) &errors);
- if (status < 0)
- ExecuteGhostscriptCommand(command,status);
- code=0;
- argv=StringToArgv(command,&argc);
- if (argv == (char **) NULL)
- {
- (ghost_info->delete_instance)(interpreter);
- return(MagickFalse);
- }
- (void) (ghost_info->set_stdio)(interpreter,(int (MagickDLLCall *)(void *,
- char *,int)) NULL,PostscriptDelegateMessage,PostscriptDelegateMessage);
- status=(ghost_info->init_with_args)(interpreter,argc-1,argv+1);
- if (status == 0)
- status=(ghost_info->run_string)(interpreter,"systemdict /start get exec\n",
- 0,&code);
- (ghost_info->exit)(interpreter);
- (ghost_info->delete_instance)(interpreter);
- for (i=0; i < (ssize_t) argc; i++)
- argv[i]=DestroyString(argv[i]);
- argv=(char **) RelinquishMagickMemory(argv);
- if (status != 0)
- {
- SetArgsStart(command,args_start);
- if (status == -101) /* quit */
- (void) FormatLocaleString(message,MagickPathExtent,
- "[ghostscript library %.2f]%s: %s",(double) revision.revision/100.0,
- args_start,errors);
- else
- {
- (void) ThrowMagickException(exception,GetMagickModule(),
- DelegateError,"PostscriptDelegateFailed",
- "`[ghostscript library %.2f]%s': %s",(double) revision.revision/
- 100.0,args_start,errors);
- if (errors != (char *) NULL)
- errors=DestroyString(errors);
- (void) LogMagickEvent(CoderEvent,GetMagickModule(),
- "Ghostscript returns status %d, exit code %d",status,code);
- return(MagickFalse);
- }
- }
- if (errors != (char *) NULL)
- errors=DestroyString(errors);
- return(MagickTrue);
- #else
- status=ExternalDelegateCommand(MagickFalse,verbose,command,message,exception);
- return(status == 0 ? MagickTrue : MagickFalse);
- #endif
- }
- /*
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % %
- % %
- % %
- % I s P S %
- % %
- % %
- % %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- % IsPS() returns MagickTrue if the image format type, identified by the
- % magick string, is PS.
- %
- % The format of the IsPS method is:
- %
- % MagickBooleanType IsPS(const unsigned char *magick,const size_t length)
- %
- % A description of each parameter follows:
- %
- % o magick: compare image format pattern against these bytes.
- %
- % o length: Specifies the length of the magick string.
- %
- */
- static MagickBooleanType IsPS(const unsigned char *magick,const size_t length)
- {
- if (length < 4)
- return(MagickFalse);
- if (memcmp(magick,"%!",2) == 0)
- return(MagickTrue);
- if (memcmp(magick,"\004%!",3) == 0)
- return(MagickTrue);
- return(MagickFalse);
- }
- /*
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % %
- % %
- % %
- % R e a d P S I m a g e %
- % %
- % %
- % %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- % ReadPSImage() reads a Postscript image file and returns it. It allocates
- % the memory necessary for the new Image structure and returns a pointer
- % to the new image.
- %
- % The format of the ReadPSImage method is:
- %
- % Image *ReadPSImage(const ImageInfo *image_info,ExceptionInfo *exception)
- %
- % A description of each parameter follows:
- %
- % o image_info: the image info.
- %
- % o exception: return any errors or warnings in this structure.
- %
- */
- static MagickBooleanType IsPostscriptRendered(const char *path)
- {
- MagickBooleanType
- status;
- struct stat
- attributes;
- if ((path == (const char *) NULL) || (*path == '\0'))
- return(MagickFalse);
- status=GetPathAttributes(path,&attributes);
- if ((status != MagickFalse) && S_ISREG(attributes.st_mode) &&
- (attributes.st_size > 0))
- return(MagickTrue);
- return(MagickFalse);
- }
- static inline int ProfileInteger(Image *image,short int *hex_digits)
- {
- int
- c,
- l,
- value;
- register ssize_t
- i;
- l=0;
- value=0;
- for (i=0; i < 2; )
- {
- c=ReadBlobByte(image);
- if ((c == EOF) || ((c == '%') && (l == '%')))
- {
- value=(-1);
- break;
- }
- l=c;
- c&=0xff;
- if (isxdigit(c) == MagickFalse)
- continue;
- value=(int) ((size_t) value << 4)+hex_digits[c];
- i++;
- }
- return(value);
- }
- static Image *ReadPSImage(const ImageInfo *image_info,ExceptionInfo *exception)
- {
- #define BoundingBox "BoundingBox:"
- #define BeginDocument "BeginDocument:"
- #define BeginXMPPacket "<?xpacket begin="
- #define EndXMPPacket "<?xpacket end="
- #define ICCProfile "BeginICCProfile:"
- #define CMYKCustomColor "CMYKCustomColor:"
- #define CMYKProcessColor "CMYKProcessColor:"
- #define DocumentMedia "DocumentMedia:"
- #define DocumentCustomColors "DocumentCustomColors:"
- #define DocumentProcessColors "DocumentProcessColors:"
- #define EndDocument "EndDocument:"
- #define HiResBoundingBox "HiResBoundingBox:"
- #define ImageData "ImageData:"
- #define PageBoundingBox "PageBoundingBox:"
- #define LanguageLevel "LanguageLevel:"
- #define PageMedia "PageMedia:"
- #define Pages "Pages:"
- #define PhotoshopProfile "BeginPhotoshop:"
- #define PostscriptLevel "!PS-"
- #define RenderPostscriptText " Rendering Postscript... "
- #define SpotColor "+ "
- 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
- c,
- file;
- MagickBooleanType
- cmyk,
- fitPage,
- skip,
- status;
- MagickStatusType
- flags;
- PointInfo
- delta,
- resolution;
- RectangleInfo
- page;
- register char
- *p;
- register ssize_t
- i;
- SegmentInfo
- bounds,
- hires_bounds;
- short int
- hex_digits[256];
- size_t
- length;
- ssize_t
- count,
- priority;
- StringInfo
- *profile;
- 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);
- }
- /*
- Initialize hex values.
- */
- (void) memset(hex_digits,0,sizeof(hex_digits));
- hex_digits[(int) '0']=0;
- hex_digits[(int) '1']=1;
- hex_digits[(int) '2']=2;
- hex_digits[(int) '3']=3;
- hex_digits[(int) '4']=4;
- hex_digits[(int) '5']=5;
- hex_digits[(int) '6']=6;
- hex_digits[(int) '7']=7;
- hex_digits[(int) '8']=8;
- hex_digits[(int) '9']=9;
- hex_digits[(int) 'a']=10;
- hex_digits[(int) 'b']=11;
- hex_digits[(int) 'c']=12;
- hex_digits[(int) 'd']=13;
- hex_digits[(int) 'e']=14;
- hex_digits[(int) 'f']=15;
- hex_digits[(int) 'A']=10;
- hex_digits[(int) 'B']=11;
- hex_digits[(int) 'C']=12;
- 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;
- spotcolor=0;
- language_level=1;
- pages=(~0UL);
- skip=MagickFalse;
- p=command;
- 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(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);
- if (LocaleNCompare(ImageData,command,strlen(ImageData)) == 0)
- (void) sscanf(command,ImageData " %lu %lu",&columns,&rows);
- /*
- Is this a CMYK document?
- */
- length=strlen(DocumentProcessColors);
- if (LocaleNCompare(DocumentProcessColors,command,length) == 0)
- {
- if ((GlobExpression(command,"*Cyan*",MagickTrue) != MagickFalse) ||
- (GlobExpression(command,"*Magenta*",MagickTrue) != MagickFalse) ||
- (GlobExpression(command,"*Yellow*",MagickTrue) != MagickFalse))
- cmyk=MagickTrue;
- }
- if (LocaleNCompare(CMYKCustomColor,command,strlen(CMYKCustomColor)) == 0)
- cmyk=MagickTrue;
- if (LocaleNCompare(CMYKProcessColor,command,strlen(CMYKProcessColor)) == 0)
- cmyk=MagickTrue;
- length=strlen(DocumentCustomColors);
- if ((LocaleNCompare(DocumentCustomColors,command,length) == 0) ||
- (LocaleNCompare(CMYKCustomColor,command,strlen(CMYKCustomColor)) == 0) ||
- (LocaleNCompare(SpotColor,command,strlen(SpotColor)) == 0))
- {
- char
- property[MagickPathExtent],
- *value;
- register char
- *q;
- /*
- Note spot names.
- */
- (void) FormatLocaleString(property,MagickPathExtent,
- "ps:SpotColor-%.20g",(double) (spotcolor++));
- for (q=command; *q != '\0'; q++)
- if (isspace((int) (unsigned char) *q) != 0)
- break;
- value=ConstantString(q);
- (void) SubstituteString(&value,"(","");
- (void) SubstituteString(&value,")","");
- (void) StripString(value);
- if (*value != '\0')
- (void) SetImageProperty(image,property,value,exception);
- value=DestroyString(value);
- continue;
- }
- if (image_info->page != (char *) NULL)
- continue;
- /*
- Note region defined by bounding box.
- */
- count=0;
- i=0;
- if (LocaleNCompare(BoundingBox,command,strlen(BoundingBox)) == 0)
- {
- count=(ssize_t) sscanf(command,BoundingBox " %lf %lf %lf %lf",
- &bounds.x1,&bounds.y1,&bounds.x2,&bounds.y2);
- i=2;
- }
- if (LocaleNCompare(DocumentMedia,command,strlen(DocumentMedia)) == 0)
- {
- count=(ssize_t) sscanf(command,DocumentMedia " %lf %lf %lf %lf",
- &bounds.x1,&bounds.y1,&bounds.x2,&bounds.y2);
- i=1;
- }
- if (LocaleNCompare(HiResBoundingBox,command,strlen(HiResBoundingBox)) == 0)
- {
- count=(ssize_t) sscanf(command,HiResBoundingBox " %lf %lf %lf %lf",
- &bounds.x1,&bounds.y1,&bounds.x2,&bounds.y2);
- i=3;
- }
- if (LocaleNCompare(PageBoundingBox,command,strlen(PageBoundingBox)) == 0)
- {
- count=(ssize_t) sscanf(command,PageBoundingBox " %lf %lf %lf %lf",
- &bounds.x1,&bounds.y1,&bounds.x2,&bounds.y2);
- i=1;
- }
- if (LocaleNCompare(PageMedia,command,strlen(PageMedia)) == 0)
- {
- count=(ssize_t) sscanf(command,PageMedia " %lf %lf %lf %lf",
- &bounds.x1,&bounds.y1,&bounds.x2,&bounds.y2);
- i=1;
- }
- 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 (i == (ssize_t) priority)
- continue;
- hires_bounds=bounds;
- priority=i;
- }
- if ((fabs(hires_bounds.x2-hires_bounds.x1) >= MagickEpsilon) &&
- (fabs(hires_bounds.y2-hires_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);
- (void) SetImageProperty(image,"ps:HiResBoundingBox",geometry,exception);
- page.width=(size_t) ceil((double) ((hires_bounds.x2-hires_bounds.x1)*
- resolution.x/delta.x)-0.5);
- page.height=(size_t) ceil((double) ((hires_bounds.y2-hires_bounds.y1)*
- resolution.y/delta.y)-0.5);
- }
- fitPage=MagickFalse;
- option=GetImageOption(image_info,"eps:fit-page");
- if (option != (char *) NULL)
- {
- char
- *page_geometry;
- page_geometry=GetPageGeometry(option);
- flags=ParseMetaGeometry(page_geometry,&page.x,&page.y,&page.width,
- &page.height);
- if (flags == NoValue)
- {
- (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
- "InvalidGeometry","`%s'",option);
- image=DestroyImage(image);
- return((Image *) NULL);
- }
- page.width=(size_t) ceil((double) (page.width*image->resolution.x/delta.x)
- -0.5);
- page.height=(size_t) ceil((double) (page.height*image->resolution.y/
- delta.y) -0.5);
- page_geometry=DestroyString(page_geometry);
- fitPage=MagickTrue;
- }
- if (IssRGBCompatibleColorspace(image_info->colorspace) != MagickFalse)
- cmyk=MagickFalse;
- /*
- Create Ghostscript control file.
- */
- file=AcquireUniqueFileResource(postscript_filename);
- if (file == -1)
- {
- ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
- image_info->filename);
- image=DestroyImageList(image);
- return((Image *) NULL);
- }
- (void) CopyMagickString(command,"/setpagedevice {pop} bind 1 index where {"
- "dup wcheck {3 1 roll put} {pop def} ifelse} {def} ifelse\n"
- "<</UseCIEColor true>>setpagedevice\n",MagickPathExtent);
- count=write(file,command,(unsigned int) strlen(command));
- if (image_info->page == (char *) NULL)
- {
- char
- translate_geometry[MagickPathExtent];
- (void) FormatLocaleString(translate_geometry,MagickPathExtent,
- "%g %g translate\n",-bounds.x1,-bounds.y1);
- count=write(file,translate_geometry,(unsigned int)
- strlen(translate_geometry));
- }
- file=close(file)-1;
- /*
- Render Postscript with the Ghostscript delegate.
- */
- if (image_info->monochrome != MagickFalse)
- delegate_info=GetDelegateInfo("ps:mono",(char *) NULL,exception);
- else
- if (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);
- image=DestroyImageList(image);
- return((Image *) NULL);
- }
- density=AcquireString("");
- options=AcquireString("");
- (void) FormatLocaleString(density,MagickPathExtent,"%gx%g",resolution.x,
- resolution.y);
- (void) FormatLocaleString(options,MagickPathExtent,"-g%.20gx%.20g ",(double)
- page.width,(double) page.height);
- read_info=CloneImageInfo(image_info);
- *read_info->magick='\0';
- if (read_info->number_scenes != 0)
- {
- char
- pages[MagickPathExtent];
- (void) FormatLocaleString(pages,MagickPathExtent,"-dFirstPage=%.20g "
- "-dLastPage=%.20g ",(double) read_info->scene+1,(double)
- (read_info->scene+read_info->number_scenes));
- (void) ConcatenateMagickString(options,pages,MagickPathExtent);
- read_info->number_scenes=0;
- if (read_info->scenes != (char *) NULL)
- *read_info->scenes='\0';
- }
- if (*image_info->magick == 'E')
- {
- option=GetImageOption(image_info,"eps:use-cropbox");
- if ((option == (const char *) NULL) ||
- (IsStringTrue(option) != MagickFalse))
- (void) ConcatenateMagickString(options,"-dEPSCrop ",MagickPathExtent);
- if (fitPage != MagickFalse)
- (void) ConcatenateMagickString(options,"-dEPSFitPage ",
- MagickPathExtent);
- }
- (void) CopyMagickString(filename,read_info->filename,MagickPathExtent);
- (void) AcquireUniqueFilename(filename);
- (void) RelinquishUniqueFileResource(filename);
- (void) ConcatenateMagickString(filename,"%d",MagickPathExtent);
- (void) FormatLocaleString(command,MagickPathExtent,
- GetDelegateCommands(delegate_info),
- read_info->antialias != MagickFalse ? 4 : 1,
- read_info->antialias != MagickFalse ? 4 : 1,density,options,filename,
- postscript_filename,input_filename);
- options=DestroyString(options);
- density=DestroyString(density);
- *message='\0';
- status=InvokePostscriptDelegate(read_info->verbose,command,message,exception);
- (void) InterpretImageFilename(image_info,image,filename,1,
- read_info->filename,exception);
- if ((status == MagickFalse) ||
- (IsPostscriptRendered(read_info->filename) == MagickFalse))
- {
- (void) ConcatenateMagickString(command," -c showpage",MagickPathExtent);
- status=InvokePostscriptDelegate(read_info->verbose,command,message,
- exception);
- }
- (void) RelinquishUniqueFileResource(postscript_filename);
- (void) RelinquishUniqueFileResource(input_filename);
- postscript_image=(Image *) NULL;
- if (status == MagickFalse)
- for (i=1; ; i++)
- {
- (void) InterpretImageFilename(image_info,image,filename,(int) i,
- read_info->filename,exception);
- if (IsPostscriptRendered(read_info->filename) == MagickFalse)
- break;
- (void) RelinquishUniqueFileResource(read_info->filename);
- }
- else
- for (i=1; ; i++)
- {
- (void) InterpretImageFilename(image_info,image,filename,(int) i,
- read_info->filename,exception);
- if (IsPostscriptRendered(read_info->filename) == MagickFalse)
- break;
- read_info->blob=NULL;
- read_info->length=0;
- next=ReadImage(read_info,exception);
- (void) RelinquishUniqueFileResource(read_info->filename);
- if (next == (Image *) NULL)
- break;
- AppendImageToList(&postscript_image,next);
- }
- (void) RelinquishUniqueFileResource(read_info->filename);
- read_info=DestroyImageInfo(read_info);
- if (postscript_image == (Image *) NULL)
- {
- if (*message != '\0')
- (void) ThrowMagickException(exception,GetMagickModule(),
- DelegateError,"PostscriptDelegateFailed","`%s'",message);
- image=DestroyImageList(image);
- return((Image *) NULL);
- }
- if (LocaleCompare(postscript_image->magick,"BMP") == 0)
- {
- Image
- *cmyk_image;
- cmyk_image=ConsolidateCMYKImages(postscript_image,exception);
- if (cmyk_image != (Image *) NULL)
- {
- postscript_image=DestroyImageList(postscript_image);
- 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 (image_info->number_scenes != 0)
- {
- Image
- *clone_image;
- /*
- Add place holder images to meet the subimage specification requirement.
- */
- for (i=0; i < (ssize_t) image_info->scene; i++)
- {
- clone_image=CloneImage(postscript_image,1,1,MagickTrue,exception);
- if (clone_image != (Image *) NULL)
- PrependImageToList(&postscript_image,clone_image);
- }
- }
- do
- {
- (void) CopyMagickString(postscript_image->filename,filename,
- 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;
- postscript_image->page=page;
- (void) CloneImageProfiles(postscript_image,image);
- (void) CloneImageProperties(postscript_image,image);
- next=SyncNextImageInList(postscript_image);
- if (next != (Image *) NULL)
- postscript_image=next;
- } while (next != (Image *) NULL);
- image=DestroyImageList(image);
- scene=0;
- for (next=GetFirstImageInList(postscript_image); next != (Image *) NULL; )
- {
- next->scene=scene++;
- next=GetNextImageInList(next);
- }
- return(GetFirstImageInList(postscript_image));
- }
- /*
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % %
- % %
- % %
- % R e g i s t e r P S I m a g e %
- % %
- % %
- % %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- % RegisterPSImage() adds properties for the PS image format to
- % the list of supported formats. The properties include the image format
- % tag, a method to read and/or write the format, whether the format
- % supports the saving of more than one frame to the same file or blob,
- % whether the format supports native in-memory I/O, and a brief
- % description of the format.
- %
- % The format of the RegisterPSImage method is:
- %
- % size_t RegisterPSImage(void)
- %
- */
- ModuleExport size_t RegisterPSImage(void)
- {
- MagickInfo
- *entry;
- entry=AcquireMagickInfo("PS","EPI",
- "Encapsulated PostScript Interchange format");
- entry->decoder=(DecodeImageHandler *) ReadPSImage;
- entry->encoder=(EncodeImageHandler *) WritePSImage;
- entry->magick=(IsImageFormatHandler *) IsPS;
- entry->flags|=CoderDecoderSeekableStreamFlag;
- entry->flags^=CoderAdjoinFlag;
- entry->flags^=CoderBlobSupportFlag;
- entry->mime_type=ConstantString("application/postscript");
- (void) RegisterMagickInfo(entry);
- entry=AcquireMagickInfo("PS","EPS","Encapsulated PostScript");
- entry->decoder=(DecodeImageHandler *) ReadPSImage;
- entry->encoder=(EncodeImageHandler *) WritePSImage;
- entry->magick=(IsImageFormatHandler *) IsPS;
- entry->flags|=CoderDecoderSeekableStreamFlag;
- entry->flags^=CoderAdjoinFlag;
- entry->flags^=CoderBlobSupportFlag;
- entry->mime_type=ConstantString("application/postscript");
- (void) RegisterMagickInfo(entry);
- entry=AcquireMagickInfo("PS","EPSF","Encapsulated PostScript");
- entry->decoder=(DecodeImageHandler *) ReadPSImage;
- entry->encoder=(EncodeImageHandler *) WritePSImage;
- entry->magick=(IsImageFormatHandler *) IsPS;
- entry->flags|=CoderDecoderSeekableStreamFlag;
- entry->flags^=CoderAdjoinFlag;
- entry->flags^=CoderBlobSupportFlag;
- entry->mime_type=ConstantString("application/postscript");
- (void) RegisterMagickInfo(entry);
- entry=AcquireMagickInfo("PS","EPSI",
- "Encapsulated PostScript Interchange format");
- entry->decoder=(DecodeImageHandler *) ReadPSImage;
- entry->encoder=(EncodeImageHandler *) WritePSImage;
- entry->magick=(IsImageFormatHandler *) IsPS;
- entry->flags|=CoderDecoderSeekableStreamFlag;
- entry->flags^=CoderAdjoinFlag;
- entry->flags^=CoderBlobSupportFlag;
- entry->mime_type=ConstantString("application/postscript");
- (void) RegisterMagickInfo(entry);
- entry=AcquireMagickInfo("PS","PS","PostScript");
- entry->decoder=(DecodeImageHandler *) ReadPSImage;
- entry->encoder=(EncodeImageHandler *) WritePSImage;
- entry->magick=(IsImageFormatHandler *) IsPS;
- entry->mime_type=ConstantString("application/postscript");
- entry->flags|=CoderDecoderSeekableStreamFlag;
- entry->flags^=CoderBlobSupportFlag;
- (void) RegisterMagickInfo(entry);
- return(MagickImageCoderSignature);
- }
- /*
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % %
- % %
- % %
- % U n r e g i s t e r P S I m a g e %
- % %
- % %
- % %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- % UnregisterPSImage() removes format registrations made by the
- % PS module from the list of supported formats.
- %
- % The format of the UnregisterPSImage method is:
- %
- % UnregisterPSImage(void)
- %
- */
- ModuleExport void UnregisterPSImage(void)
- {
- (void) UnregisterMagickInfo("EPI");
- (void) UnregisterMagickInfo("EPS");
- (void) UnregisterMagickInfo("EPSF");
- (void) UnregisterMagickInfo("EPSI");
- (void) UnregisterMagickInfo("PS");
- }
- /*
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % %
- % %
- % %
- % W r i t e P S I m a g e %
- % %
- % %
- % %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- % WritePSImage translates an image to encapsulated Postscript
- % Level I for printing. If the supplied geometry is null, the image is
- % centered on the Postscript page. Otherwise, the image is positioned as
- % specified by the geometry.
- %
- % The format of the WritePSImage method is:
- %
- % MagickBooleanType WritePSImage(const ImageInfo *image_info,
- % Image *image,ExceptionInfo *exception)
- %
- % A description of each parameter follows:
- %
- % o image_info: the image info.
- %
- % o image: the image.
- %
- % o exception: return any errors or warnings in this structure.
- %
- */
- static inline unsigned char *PopHexPixel(const char hex_digits[][3],
- const size_t pixel,unsigned char *pixels)
- {
- register const char
- *hex;
- hex=hex_digits[pixel];
- *pixels++=(unsigned char) (*hex++ & 0xff);
- *pixels++=(unsigned char) (*hex & 0xff);
- return(pixels);
- }
- static MagickBooleanType WritePSImage(const ImageInfo *image_info,Image *image,
- ExceptionInfo *exception)
- {
- #define WriteRunlengthPacket(image,pixel,length,p) \
- { \
- if ((image->alpha_trait != UndefinedPixelTrait) && (length != 0) && \
- (GetPixelAlpha(image,p) == (Quantum) TransparentAlpha)) \
- { \
- q=PopHexPixel(hex_digits,0xff,q); \
- q=PopHexPixel(hex_digits,0xff,q); \
- q=PopHexPixel(hex_digits,0xff,q); \
- } \
- else \
- { \
- q=PopHexPixel(hex_digits,ScaleQuantumToChar(ClampToQuantum(pixel.red)),q); \
- q=PopHexPixel(hex_digits,ScaleQuantumToChar(ClampToQuantum(pixel.green)),q); \
- q=PopHexPixel(hex_digits,ScaleQuantumToChar(ClampToQuantum(pixel.blue)),q); \
- } \
- q=PopHexPixel(hex_digits,(size_t) MagickMin(length,0xff),q); \
- }
- static const char
- hex_digits[][3] =
- {
- "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0A", "0B",
- "0C", "0D", "0E", "0F", "10", "11", "12", "13", "14", "15", "16", "17",
- "18", "19", "1A", "1B", "1C", "1D", "1E", "1F", "20", "21", "22", "23",
- "24", "25", "26", "27", "28", "29", "2A", "2B", "2C", "2D", "2E", "2F",
- "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3A", "3B",
- "3C", "3D", "3E", "3F", "40", "41", "42", "43", "44", "45", "46", "47",
- "48", "49", "4A", "4B", "4C", "4D", "4E", "4F", "50", "51", "52", "53",
- "54", "55", "56", "57", "58", "59", "5A", "5B", "5C", "5D", "5E", "5F",
- "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6A", "6B",
- "6C", "6D", "6E", "6F", "70", "71", "72", "73", "74", "75", "76", "77",
- "78", "79", "7A", "7B", "7C", "7D", "7E", "7F", "80", "81", "82", "83",
- "84", "85", "86", "87", "88", "89", "8A", "8B", "8C", "8D", "8E", "8F",
- "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9A", "9B",
- "9C", "9D", "9E", "9F", "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7",
- "A8", "A9", "AA", "AB", "AC", "AD", "AE", "AF", "B0", "B1", "B2", "B3",
- "B4", "B5", "B6", "B7", "B8", "B9", "BA", "BB", "BC", "BD", "BE", "BF",
- "C0", "C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "CA", "CB",
- "CC", "CD", "CE", "CF", "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
- "D8", "D9", "DA", "DB", "DC", "DD", "DE", "DF", "E0", "E1", "E2", "E3",
- "E4", "E5", "E6", "E7", "E8", "E9", "EA", "EB", "EC", "ED", "EE", "EF",
- "F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "FA", "FB",
- "FC", "FD", "FE", "FF"
- },
- PostscriptProlog[] =
- "%%BeginProlog\n"
- "%\n"
- "% Display a color image. The image is displayed in color on\n"
- "% Postscript viewers or printers that support color, otherwise\n"
- "% it is displayed as grayscale.\n"
- "%\n"
- "/DirectClassPacket\n"
- "{\n"
- " %\n"
- " % Get a DirectClass packet.\n"
- " %\n"
- " % Parameters:\n"
- " % red.\n"
- " % green.\n"
- " % blue.\n"
- " % length: number of pixels minus one of this color (optional).\n"
- " %\n"
- " currentfile color_packet readhexstring pop pop\n"
- " compression 0 eq\n"
- " {\n"
- " /number_pixels 3 def\n"
- " }\n"
- " {\n"
- " currentfile byte readhexstring pop 0 get\n"
- " /number_pixels exch 1 add 3 mul def\n"
- " } ifelse\n"
- " 0 3 number_pixels 1 sub\n"
- " {\n"
- " pixels exch color_packet putinterval\n"
- " } for\n"
- " pixels 0 number_pixels getinterval\n"
- "} bind def\n"
- "\n"
- "/DirectClassImage\n"
- "{\n"
- " %\n"
- " % Display a DirectClass image.\n"
- " %\n"
- " systemdict /colorimage known\n"
- " {\n"
- " columns rows 8\n"
- " [\n"
- " columns 0 0\n"
- " rows neg 0 rows\n"
- " ]\n"
- " { DirectClassPacket } false 3 colorimage\n"
- " }\n"
- " {\n"
- " %\n"
- " % No colorimage operator; convert to grayscale.\n"
- " %\n"
- " columns rows 8\n"
- " [\n"
- " columns 0 0\n"
- " rows neg 0 rows\n"
- " ]\n"
- " { GrayDirectClassPacket } image\n"
- " } ifelse\n"
- "} bind def\n"
- "\n"
- "/GrayDirectClassPacket\n"
- "{\n"
- " %\n"
- " % Get a DirectClass packet; convert to grayscale.\n"
- " %\n"
- " % Parameters:\n"
- " % red\n"
- " % green\n"
- " % blue\n"
- " % length: number of pixels minus one of this color (optional).\n"
- " %\n"
- " currentfile color_packet readhexstring pop pop\n"
- " color_packet 0 get 0.299 mul\n"
- " color_packet 1 get 0.587 mul add\n"
- " color_packet 2 get 0.114 mul add\n"
- " cvi\n"
- " /gray_packet exch def\n"
- " compression 0 eq\n"
- " {\n"
- " /number_pixels 1 def\n"
- " }\n"
- " {\n"
- " currentfile byte readhexstring pop 0 get\n"
- " /number_pixels exch 1 add def\n"
- " } ifelse\n"
- " 0 1 number_pixels 1 sub\n"
- " {\n"
- " pixels exch gray_packet put\n"
- " } for\n"
- " pixels 0 number_pixels getinterval\n"
- "} bind def\n"
- "\n"
- "/GrayPseudoClassPacket\n"
- "{\n"
- " %\n"
- " % Get a PseudoClass packet; convert to grayscale.\n"
- " %\n"
- " % Parameters:\n"
- " % index: index into the colormap.\n"
- " % length: number of pixels minus one of this color (optional).\n"
- " %\n"
- " currentfile byte readhexstring pop 0 get\n"
- " /offset exch 3 mul def\n"
- " /color_packet colormap offset 3 getinterval def\n"
- " color_packet 0 get 0.299 mul\n"
- " color_packet 1 get 0.587 mul add\n"
- " color_packet 2 get 0.114 mul add\n"
- " cvi\n"
- " /gray_packet exch def\n"
- " compression 0 eq\n"
- " {\n"
- " /number_pixels 1 def\n"
- " }\n"
- " {\n"
- " currentfile byte readhexstring pop 0 get\n"
- " /number_pixels exch 1 add def\n"
- " } ifelse\n"
- " 0 1 number_pixels 1 sub\n"
- " {\n"
- " pixels exch gray_packet put\n"
- " } for\n"
- " pixels 0 number_pixels getinterval\n"
- "} bind def\n"
- "\n"
- "/PseudoClassPacket\n"
- "{\n"
- " %\n"
- " % Get a PseudoClass packet.\n"
- " %\n"
- " % Parameters:\n"
- " % index: index into the colormap.\n"
- " % length: number of pixels minus one of this color (optional).\n"
- " %\n"
- " currentfile byte readhexstring pop 0 get\n"
- " /offset exch 3 mul def\n"
- " /color_packet colormap offset 3 getinterval def\n"
- " compression 0 eq\n"
- " {\n"
- " /number_pixels 3 def\n"
- " }\n"
- " {\n"
- " currentfile byte readhexstring pop 0 get\n"
- " /number_pixels exch 1 add 3 mul def\n"
- " } ifelse\n"
- " 0 3 number_pixels 1 sub\n"
- " {\n"
- " pixels exch color_packet putinterval\n"
- " } for\n"
- " pixels 0 number_pixels getinterval\n"
- "} bind def\n"
- "\n"
- "/PseudoClassImage\n"
- "{\n"
- " %\n"
- " % Display a PseudoClass image.\n"
- " %\n"
- " % Parameters:\n"
- " % class: 0-PseudoClass or 1-Grayscale.\n"
- " %\n"
- " currentfile buffer readline pop\n"
- " token pop /class exch def pop\n"
- " class 0 gt\n"
- " {\n"
- " currentfile buffer readline pop\n"
- " token pop /depth exch def pop\n"
- " /grays columns 8 add depth sub depth mul 8 idiv string def\n"
- " columns rows depth\n"
- " [\n"
- " columns 0 0\n"
- " rows neg 0 rows\n"
- " ]\n"
- " { currentfile grays readhexstring pop } image\n"
- " }\n"
- " {\n"
- " %\n"
- " % Parameters:\n"
- " % colors: number of colors in the colormap.\n"
- " % colormap: red, green, blue color packets.\n"
- " %\n"
- " currentfile buffer readline pop\n"
- " token pop /colors exch def pop\n"
- " /colors colors 3 mul def\n"
- " /colormap colors string def\n"
- " currentfile colormap readhexstring pop pop\n"
- " systemdict /colorimage known\n"
- " {\n"
- " columns rows 8\n"
- " [\n"
- " columns 0 0\n"
- " rows neg 0 rows\n"
- " ]\n"
- " { PseudoClassPacket } false 3 colorimage\n"
- " }\n"
- " {\n"
- " %\n"
- " % No colorimage operator; convert to grayscale.\n"
- " %\n"
- " columns rows 8\n"
- " [\n"
- " columns 0 0\n"
- " rows neg 0 rows\n"
- " ]\n"
- " { G…
Large files files are truncated, but you can click here to view the full file