/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % G e t D e l e g a t e C o m m a n d % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Method GetDelegateCommand replaces any embedded formatting characters with % the appropriate image attribute and returns the resulting command. % % The format of the GetDelegateCommand method is: % % char *GetDelegateCommand(const ImageInfo *image_info,Image *image, % const char *decode,const char *encode,ExceptionInfo *exception) % % A description of each parameter follows: % % o command: Method GetDelegateCommand returns the command associated % with specified delegate tag. % % o image_info: The image info. % % o image: The image. % % o decode: Specifies the decode delegate we are searching for as a % character string. % % o encode: Specifies the encode delegate we are searching for as a % character string. % % o exception: Return any errors or warnings in this structure. % % */ MagickExport char *GetDelegateCommand(const ImageInfo *image_info,Image *image, const char *decode,const char *encode,ExceptionInfo *exception) { char *command, **commands; const DelegateInfo *delegate_info; register long i; assert(image_info != (ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(image != (Image *) NULL); assert(image->signature == MagickSignature); delegate_info=GetDelegateInfo(decode,encode,exception); if (delegate_info == (const DelegateInfo *) NULL) { ThrowException(exception,DelegateError,NoTagFound, decode ? decode : encode); return((char *) NULL); } commands=StringToList(delegate_info->commands); if (commands == (char **) NULL) { ThrowException(exception,ResourceLimitError,MemoryAllocationFailed, decode ? decode : encode); return((char *) NULL); } command=TranslateText(image_info,image,commands[0]); if (command == (char *) NULL) ThrowException(exception,ResourceLimitError,MemoryAllocationFailed, commands[0]); /* Free resources. */ for (i=0; commands[i] != (char *) NULL; i++) MagickFreeMemory(commands[i]); MagickFreeMemory(commands); return(command); }
static MagickBooleanType WritePS2Image(const ImageInfo *image_info,Image *image) { static const char *PostscriptProlog[]= { "%%%%BeginProlog", "%%", "%% Display a color image. The image is displayed in color on", "%% Postscript viewers or printers that support color, otherwise", "%% it is displayed as grayscale.", "%%", "/DirectClassImage", "{", " %%", " %% Display a DirectClass image.", " %%", " colorspace 0 eq", " {", " /DeviceRGB setcolorspace", " <<", " /ImageType 1", " /Width columns", " /Height rows", " /BitsPerComponent 8", " /Decode [0 1 0 1 0 1]", " /ImageMatrix [columns 0 0 rows neg 0 rows]", " compression 0 gt", " { /DataSource pixel_stream %s }", " { /DataSource pixel_stream %s } ifelse", " >> image", " }", " {", " /DeviceCMYK setcolorspace", " <<", " /ImageType 1", " /Width columns", " /Height rows", " /BitsPerComponent 8", " /Decode [1 0 1 0 1 0 1 0]", " /ImageMatrix [columns 0 0 rows neg 0 rows]", " compression 0 gt", " { /DataSource pixel_stream %s }", " { /DataSource pixel_stream %s } ifelse", " >> image", " } ifelse", "} bind def", "", "/PseudoClassImage", "{", " %%", " %% Display a PseudoClass image.", " %%", " %% Parameters:", " %% colors: number of colors in the colormap.", " %%", " currentfile buffer readline pop", " token pop /colors exch def pop", " colors 0 eq", " {", " %%", " %% Image is grayscale.", " %%", " currentfile buffer readline pop", " token pop /bits exch def pop", " /DeviceGray setcolorspace", " <<", " /ImageType 1", " /Width columns", " /Height rows", " /BitsPerComponent bits", " /Decode [0 1]", " /ImageMatrix [columns 0 0 rows neg 0 rows]", " compression 0 gt", " { /DataSource pixel_stream %s }", " {", " /DataSource pixel_stream %s", " <<", " /K "CCITTParam, " /Columns columns", " /Rows rows", " >> /CCITTFaxDecode filter", " } ifelse", " >> image", " }", " {", " %%", " %% Parameters:", " %% colormap: red, green, blue color packets.", " %%", " /colormap colors 3 mul string def", " currentfile colormap readhexstring pop pop", " currentfile buffer readline pop", " [ /Indexed /DeviceRGB colors 1 sub colormap ] setcolorspace", " <<", " /ImageType 1", " /Width columns", " /Height rows", " /BitsPerComponent 8", " /Decode [0 255]", " /ImageMatrix [columns 0 0 rows neg 0 rows]", " compression 0 gt", " { /DataSource pixel_stream %s }", " { /DataSource pixel_stream %s } ifelse", " >> image", " } ifelse", "} bind def", "", "/DisplayImage", "{", " %%", " %% Display a DirectClass or PseudoClass image.", " %%", " %% Parameters:", " %% x & y translation.", " %% x & y scale.", " %% label pointsize.", " %% image label.", " %% image columns & rows.", " %% class: 0-DirectClass or 1-PseudoClass.", " %% colorspace: 0-RGB or 1-CMYK.", " %% compression: 0-RLECompression or 1-NoCompression.", " %% hex color packets.", " %%", " gsave", " /buffer 512 string def", " /pixel_stream currentfile def", "", " currentfile buffer readline pop", " token pop /x exch def", " token pop /y exch def pop", " x y translate", " currentfile buffer readline pop", " token pop /x exch def", " token pop /y exch def pop", " currentfile buffer readline pop", " token pop /pointsize exch def pop", " /Helvetica findfont pointsize scalefont setfont", (char *) NULL }, *PostscriptEpilog[]= { " x y scale", " currentfile buffer readline pop", " token pop /columns exch def", " token pop /rows exch def pop", " currentfile buffer readline pop", " token pop /class exch def pop", " currentfile buffer readline pop", " token pop /colorspace exch def pop", " currentfile buffer readline pop", " token pop /compression exch def pop", " class 0 gt { PseudoClassImage } { DirectClassImage } ifelse", (char *) NULL }; char buffer[MaxTextExtent], date[MaxTextExtent], page_geometry[MaxTextExtent], **labels; CompressionType compression; const char **q, *value; double pointsize; GeometryInfo geometry_info; MagickOffsetType scene, start, stop; MagickBooleanType progress, status; MagickOffsetType offset; MagickSizeType number_pixels; MagickStatusType flags; PointInfo delta, resolution, scale; RectangleInfo geometry, media_info, page_info; register const IndexPacket *indexes; register const PixelPacket *p; register ssize_t x; register ssize_t i; SegmentInfo bounds; size_t length, page, text_size; ssize_t j, y; time_t timer; unsigned char *pixels; /* Open output image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(image != (Image *) NULL); assert(image->signature == MagickSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == MagickFalse) return(status); compression=image->compression; if (image_info->compression != UndefinedCompression) compression=image_info->compression; switch (compression) { #if !defined(MAGICKCORE_JPEG_DELEGATE) case JPEGCompression: { compression=RLECompression; (void) ThrowMagickException(&image->exception,GetMagickModule(), MissingDelegateError,"DelegateLibrarySupportNotBuiltIn","`%s' (JPEG)", image->filename); break; } #endif default: break; } (void) ResetMagickMemory(&bounds,0,sizeof(bounds)); page=1; scene=0; do { /* Scale relative to dots-per-inch. */ delta.x=DefaultResolution; delta.y=DefaultResolution; resolution.x=image->x_resolution; resolution.y=image->y_resolution; if ((resolution.x == 0.0) || (resolution.y == 0.0)) { flags=ParseGeometry(PSDensityGeometry,&geometry_info); resolution.x=geometry_info.rho; resolution.y=geometry_info.sigma; if ((flags & SigmaValue) == 0) resolution.y=resolution.x; } if (image_info->density != (char *) NULL) { flags=ParseGeometry(image_info->density,&geometry_info); resolution.x=geometry_info.rho; resolution.y=geometry_info.sigma; if ((flags & SigmaValue) == 0) resolution.y=resolution.x; } if (image->units == PixelsPerCentimeterResolution) { resolution.x=(size_t) (100.0*2.54*resolution.x+0.5)/100.0; resolution.y=(size_t) (100.0*2.54*resolution.y+0.5)/100.0; } SetGeometry(image,&geometry); (void) FormatLocaleString(page_geometry,MaxTextExtent,"%.20gx%.20g", (double) image->columns,(double) image->rows); if (image_info->page != (char *) NULL) (void) CopyMagickString(page_geometry,image_info->page,MaxTextExtent); else if ((image->page.width != 0) && (image->page.height != 0)) (void) FormatLocaleString(page_geometry,MaxTextExtent, "%.20gx%.20g%+.20g%+.20g",(double) image->page.width,(double) image->page.height,(double) image->page.x,(double) image->page.y); else if ((image->gravity != UndefinedGravity) && (LocaleCompare(image_info->magick,"PS") == 0)) (void) CopyMagickString(page_geometry,PSPageGeometry,MaxTextExtent); (void) ConcatenateMagickString(page_geometry,">",MaxTextExtent); (void) ParseMetaGeometry(page_geometry,&geometry.x,&geometry.y, &geometry.width,&geometry.height); scale.x=(double) (geometry.width*delta.x)/resolution.x; geometry.width=(size_t) floor(scale.x+0.5); scale.y=(double) (geometry.height*delta.y)/resolution.y; geometry.height=(size_t) floor(scale.y+0.5); (void) ParseAbsoluteGeometry(page_geometry,&media_info); (void) ParseGravityGeometry(image,page_geometry,&page_info, &image->exception); if (image->gravity != UndefinedGravity) { geometry.x=(-page_info.x); geometry.y=(ssize_t) (media_info.height+page_info.y-image->rows); } pointsize=12.0; if (image_info->pointsize != 0.0) pointsize=image_info->pointsize; text_size=0; value=GetImageProperty(image,"label"); if (value != (const char *) NULL) text_size=(size_t) (MultilineCensus(value)*pointsize+12); if (page == 1) { /* Output Postscript header. */ if (LocaleCompare(image_info->magick,"PS2") == 0) (void) CopyMagickString(buffer,"%!PS-Adobe-3.0\n",MaxTextExtent); else (void) CopyMagickString(buffer,"%!PS-Adobe-3.0 EPSF-3.0\n", MaxTextExtent); (void) WriteBlobString(image,buffer); (void) WriteBlobString(image,"%%Creator: (ImageMagick)\n"); (void) FormatLocaleString(buffer,MaxTextExtent,"%%%%Title: (%s)\n", image->filename); (void) WriteBlobString(image,buffer); timer=time((time_t *) NULL); (void) FormatMagickTime(timer,MaxTextExtent,date); (void) FormatLocaleString(buffer,MaxTextExtent, "%%%%CreationDate: (%s)\n",date); (void) WriteBlobString(image,buffer); bounds.x1=(double) geometry.x; bounds.y1=(double) geometry.y; bounds.x2=(double) geometry.x+geometry.width; bounds.y2=(double) geometry.y+geometry.height+text_size; if ((image_info->adjoin != MagickFalse) && (GetNextImageInList(image) != (Image *) NULL)) (void) CopyMagickString(buffer,"%%BoundingBox: (atend)\n", MaxTextExtent); else { (void) FormatLocaleString(buffer,MaxTextExtent, "%%%%BoundingBox: %.20g %.20g %.20g %.20g\n",ceil(bounds.x1-0.5), ceil(bounds.y1-0.5),floor(bounds.x2+0.5),floor(bounds.y2+0.5)); (void) WriteBlobString(image,buffer); (void) FormatLocaleString(buffer,MaxTextExtent, "%%%%HiResBoundingBox: %g %g %g %g\n",bounds.x1, bounds.y1,bounds.x2,bounds.y2); } (void) WriteBlobString(image,buffer); value=GetImageProperty(image,"label"); if (value != (const char *) NULL) (void) WriteBlobString(image, "%%DocumentNeededResources: font Helvetica\n"); (void) WriteBlobString(image,"%%LanguageLevel: 2\n"); if (LocaleCompare(image_info->magick,"PS2") != 0) (void) WriteBlobString(image,"%%Pages: 1\n"); else { (void) WriteBlobString(image,"%%Orientation: Portrait\n"); (void) WriteBlobString(image,"%%PageOrder: Ascend\n"); if (image_info->adjoin == MagickFalse) (void) CopyMagickString(buffer,"%%Pages: 1\n",MaxTextExtent); else (void) FormatLocaleString(buffer,MaxTextExtent, "%%%%Pages: %.20g\n",(double) GetImageListLength(image)); (void) WriteBlobString(image,buffer); } (void) WriteBlobString(image,"%%EndComments\n"); (void) WriteBlobString(image,"\n%%BeginDefaults\n"); (void) WriteBlobString(image,"%%EndDefaults\n\n"); /* Output Postscript commands. */ for (q=PostscriptProlog; *q; q++) { switch (compression) { case NoCompression: { (void) FormatLocaleString(buffer,MaxTextExtent,*q, "/ASCII85Decode filter"); break; } case JPEGCompression: { (void) FormatLocaleString(buffer,MaxTextExtent,*q, "/DCTDecode filter"); break; } case LZWCompression: { (void) FormatLocaleString(buffer,MaxTextExtent,*q, "/LZWDecode filter"); break; } case FaxCompression: case Group4Compression: { (void) FormatLocaleString(buffer,MaxTextExtent,*q," "); break; } default: { (void) FormatLocaleString(buffer,MaxTextExtent,*q, "/RunLengthDecode filter"); break; } } (void) WriteBlobString(image,buffer); (void) WriteBlobByte(image,'\n'); } value=GetImageProperty(image,"label"); if (value != (const char *) NULL) for (j=(ssize_t) MultilineCensus(value)-1; j >= 0; j--) { (void) WriteBlobString(image," /label 512 string def\n"); (void) WriteBlobString(image," currentfile label readline pop\n"); (void) FormatLocaleString(buffer,MaxTextExtent, " 0 y %g add moveto label show pop\n",j*pointsize+12); (void) WriteBlobString(image,buffer); } for (q=PostscriptEpilog; *q; q++) { (void) FormatLocaleString(buffer,MaxTextExtent,"%s\n",*q); (void) WriteBlobString(image,buffer); } if (LocaleCompare(image_info->magick,"PS2") == 0) (void) WriteBlobString(image," showpage\n"); (void) WriteBlobString(image,"} bind def\n"); (void) WriteBlobString(image,"%%EndProlog\n"); } (void) FormatLocaleString(buffer,MaxTextExtent,"%%%%Page: 1 %.20g\n", (double) page++); (void) WriteBlobString(image,buffer); (void) FormatLocaleString(buffer,MaxTextExtent, "%%%%PageBoundingBox: %.20g %.20g %.20g %.20g\n",(double) geometry.x, (double) geometry.y,geometry.x+(double) geometry.width,geometry.y+(double) (geometry.height+text_size)); (void) WriteBlobString(image,buffer); if ((double) geometry.x < bounds.x1) bounds.x1=(double) geometry.x; if ((double) geometry.y < bounds.y1) bounds.y1=(double) geometry.y; if ((double) (geometry.x+geometry.width-1) > bounds.x2) bounds.x2=(double) geometry.x+geometry.width-1; if ((double) (geometry.y+(geometry.height+text_size)-1) > bounds.y2) bounds.y2=(double) geometry.y+(geometry.height+text_size)-1; value=GetImageProperty(image,"label"); if (value != (const char *) NULL) (void) WriteBlobString(image,"%%PageResources: font Times-Roman\n"); if (LocaleCompare(image_info->magick,"PS2") != 0) (void) WriteBlobString(image,"userdict begin\n"); start=TellBlob(image); (void) FormatLocaleString(buffer,MaxTextExtent, "%%%%BeginData:%13ld %s Bytes\n",0L, compression == NoCompression ? "ASCII" : "Binary"); (void) WriteBlobString(image,buffer); stop=TellBlob(image); (void) WriteBlobString(image,"DisplayImage\n"); /* Output image data. */ (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g %.20g\n%g %g\n%g\n", (double) geometry.x,(double) geometry.y,scale.x,scale.y,pointsize); (void) WriteBlobString(image,buffer); labels=(char **) NULL; value=GetImageProperty(image,"label"); if (value != (const char *) NULL) labels=StringToList(value); if (labels != (char **) NULL) { for (i=0; labels[i] != (char *) NULL; i++) { (void) FormatLocaleString(buffer,MaxTextExtent,"%s \n", labels[i]); (void) WriteBlobString(image,buffer); labels[i]=DestroyString(labels[i]); } labels=(char **) RelinquishMagickMemory(labels); } number_pixels=(MagickSizeType) image->columns*image->rows; if (number_pixels != (MagickSizeType) ((size_t) number_pixels)) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); if ((compression == FaxCompression) || (compression == Group4Compression) || ((image_info->type != TrueColorType) && (IsGrayImage(image,&image->exception) != MagickFalse))) { (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g %.20g\n1\n%d\n", (double) image->columns,(double) image->rows,(int) (image->colorspace == CMYKColorspace)); (void) WriteBlobString(image,buffer); (void) FormatLocaleString(buffer,MaxTextExtent,"%d\n", (int) ((compression != FaxCompression) && (compression != Group4Compression))); (void) WriteBlobString(image,buffer); (void) WriteBlobString(image,"0\n"); (void) FormatLocaleString(buffer,MaxTextExtent,"%d\n", (compression == FaxCompression) || (compression == Group4Compression) ? 1 : 8); (void) WriteBlobString(image,buffer); switch (compression) { case FaxCompression: case Group4Compression: { if (LocaleCompare(CCITTParam,"0") == 0) { (void) HuffmanEncodeImage(image_info,image,image); break; } (void) Huffman2DEncodeImage(image_info,image,image); break; } case JPEGCompression: { status=InjectImageBlob(image_info,image,image,"jpeg", &image->exception); if (status == MagickFalse) ThrowWriterException(CoderError,image->exception.reason); break; } case RLECompression: default: { register unsigned char *q; /* Allocate pixel array. */ length=(size_t) number_pixels; pixels=(unsigned char *) AcquireQuantumMemory(length, sizeof(*pixels)); if (pixels == (unsigned char *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); /* Dump Runlength encoded pixels. */ q=pixels; for (y=0; y < (ssize_t) image->rows; y++) { p=GetVirtualPixels(image,0,y,image->columns,1, &image->exception); if (p == (const PixelPacket *) NULL) break; for (x=0; x < (ssize_t) image->columns; x++) { *q++=ScaleQuantumToChar(PixelIntensityToQuantum(p)); p++; } progress=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, image->rows); if (progress == MagickFalse) break; } length=(size_t) (q-pixels); if (compression == LZWCompression) status=LZWEncodeImage(image,length,pixels); else status=PackbitsEncodeImage(image,length,pixels); pixels=(unsigned char *) RelinquishMagickMemory(pixels); if (status == MagickFalse) { (void) CloseBlob(image); return(MagickFalse); } break; } case NoCompression: { /* Dump uncompressed PseudoColor packets. */ Ascii85Initialize(image); for (y=0; y < (ssize_t) image->rows; y++) { p=GetVirtualPixels(image,0,y,image->columns,1, &image->exception); if (p == (const PixelPacket *) NULL) break; for (x=0; x < (ssize_t) image->columns; x++) { Ascii85Encode(image,ScaleQuantumToChar( PixelIntensityToQuantum(p))); p++; } progress=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,image->rows); if (progress == MagickFalse) break; } Ascii85Flush(image); break; } } } else if ((image->storage_class == DirectClass) || (image->colors > 256) || (compression == JPEGCompression) || (image->matte != MagickFalse)) { (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g %.20g\n0\n%d\n", (double) image->columns,(double) image->rows,(int) (image->colorspace == CMYKColorspace)); (void) WriteBlobString(image,buffer); (void) FormatLocaleString(buffer,MaxTextExtent,"%d\n", (int) (compression == NoCompression)); (void) WriteBlobString(image,buffer); switch (compression) { case JPEGCompression: { status=InjectImageBlob(image_info,image,image,"jpeg", &image->exception); if (status == MagickFalse) ThrowWriterException(CoderError,image->exception.reason); break; } case RLECompression: default: { register unsigned char *q; /* Allocate pixel array. */ length=(size_t) number_pixels; pixels=(unsigned char *) AcquireQuantumMemory(length, 4*sizeof(*pixels)); if (pixels == (unsigned char *) NULL) ThrowWriterException(ResourceLimitError, "MemoryAllocationFailed"); /* Dump Packbit encoded pixels. */ q=pixels; for (y=0; y < (ssize_t) image->rows; y++) { p=GetVirtualPixels(image,0,y,image->columns,1, &image->exception); if (p == (const PixelPacket *) NULL) break; indexes=GetVirtualIndexQueue(image); for (x=0; x < (ssize_t) image->columns; x++) { if ((image->matte != MagickFalse) && (GetPixelOpacity(p) == (Quantum) TransparentOpacity)) { *q++=ScaleQuantumToChar((Quantum) QuantumRange); *q++=ScaleQuantumToChar((Quantum) QuantumRange); *q++=ScaleQuantumToChar((Quantum) QuantumRange); } else if (image->colorspace != CMYKColorspace) { *q++=ScaleQuantumToChar(GetPixelRed(p)); *q++=ScaleQuantumToChar(GetPixelGreen(p)); *q++=ScaleQuantumToChar(GetPixelBlue(p)); } else { *q++=ScaleQuantumToChar(GetPixelRed(p)); *q++=ScaleQuantumToChar(GetPixelGreen(p)); *q++=ScaleQuantumToChar(GetPixelBlue(p)); *q++=ScaleQuantumToChar(GetPixelIndex( indexes+x)); } p++; } progress=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,image->rows); if (progress == MagickFalse) break; } length=(size_t) (q-pixels); if (compression == LZWCompression) status=LZWEncodeImage(image,length,pixels); else status=PackbitsEncodeImage(image,length,pixels); if (status == MagickFalse) { (void) CloseBlob(image); return(MagickFalse); } pixels=(unsigned char *) RelinquishMagickMemory(pixels); break; } case NoCompression: { /* Dump uncompressed DirectColor packets. */ Ascii85Initialize(image); for (y=0; y < (ssize_t) image->rows; y++) { p=GetVirtualPixels(image,0,y,image->columns,1, &image->exception); if (p == (const PixelPacket *) NULL) break; indexes=GetVirtualIndexQueue(image); for (x=0; x < (ssize_t) image->columns; x++) { if ((image->matte != MagickFalse) && (GetPixelOpacity(p) == (Quantum) TransparentOpacity)) { Ascii85Encode(image,ScaleQuantumToChar((Quantum) QuantumRange)); Ascii85Encode(image,ScaleQuantumToChar((Quantum) QuantumRange)); Ascii85Encode(image,ScaleQuantumToChar((Quantum) QuantumRange)); } else if (image->colorspace != CMYKColorspace) { Ascii85Encode(image,ScaleQuantumToChar( GetPixelRed(p))); Ascii85Encode(image,ScaleQuantumToChar( GetPixelGreen(p))); Ascii85Encode(image,ScaleQuantumToChar( GetPixelBlue(p))); } else { Ascii85Encode(image,ScaleQuantumToChar( GetPixelRed(p))); Ascii85Encode(image,ScaleQuantumToChar( GetPixelGreen(p))); Ascii85Encode(image,ScaleQuantumToChar( GetPixelBlue(p))); Ascii85Encode(image,ScaleQuantumToChar( GetPixelIndex(indexes+x))); } p++; } progress=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,image->rows); if (progress == MagickFalse) break; } Ascii85Flush(image); break; } } } else { /* Dump number of colors and colormap. */ (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g %.20g\n1\n%d\n", (double) image->columns,(double) image->rows,(int) (image->colorspace == CMYKColorspace)); (void) WriteBlobString(image,buffer); (void) FormatLocaleString(buffer,MaxTextExtent,"%d\n", (int) (compression == NoCompression)); (void) WriteBlobString(image,buffer); (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g\n",(double) image->colors); (void) WriteBlobString(image,buffer); for (i=0; i < (ssize_t) image->colors; i++) { (void) FormatLocaleString(buffer,MaxTextExtent,"%02X%02X%02X\n", ScaleQuantumToChar(image->colormap[i].red), ScaleQuantumToChar(image->colormap[i].green), ScaleQuantumToChar(image->colormap[i].blue)); (void) WriteBlobString(image,buffer); } switch (compression) { case RLECompression: default: { register unsigned char *q; /* Allocate pixel array. */ length=(size_t) number_pixels; pixels=(unsigned char *) AcquireQuantumMemory(length, sizeof(*pixels)); if (pixels == (unsigned char *) NULL) ThrowWriterException(ResourceLimitError, "MemoryAllocationFailed"); /* Dump Runlength encoded pixels. */ q=pixels; for (y=0; y < (ssize_t) image->rows; y++) { p=GetVirtualPixels(image,0,y,image->columns,1, &image->exception); if (p == (const PixelPacket *) NULL) break; indexes=GetVirtualIndexQueue(image); for (x=0; x < (ssize_t) image->columns; x++) *q++=(unsigned char) GetPixelIndex(indexes+x); progress=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,image->rows); if (progress == MagickFalse) break; } length=(size_t) (q-pixels); if (compression == LZWCompression) status=LZWEncodeImage(image,length,pixels); else status=PackbitsEncodeImage(image,length,pixels); pixels=(unsigned char *) RelinquishMagickMemory(pixels); if (status == MagickFalse) { (void) CloseBlob(image); return(MagickFalse); } break; } case NoCompression: { /* Dump uncompressed PseudoColor packets. */ Ascii85Initialize(image); for (y=0; y < (ssize_t) image->rows; y++) { p=GetVirtualPixels(image,0,y,image->columns,1, &image->exception); if (p == (const PixelPacket *) NULL) break; indexes=GetVirtualIndexQueue(image); for (x=0; x < (ssize_t) image->columns; x++) Ascii85Encode(image,(unsigned char) GetPixelIndex( indexes+x)); progress=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,image->rows); if (progress == MagickFalse) break; } Ascii85Flush(image); break; } } } (void) WriteBlobByte(image,'\n'); length=(size_t) (TellBlob(image)-stop); stop=TellBlob(image); offset=SeekBlob(image,start,SEEK_SET); if (offset < 0) ThrowWriterException(CorruptImageError,"ImproperImageHeader"); (void) FormatLocaleString(buffer,MaxTextExtent, "%%%%BeginData:%13ld %s Bytes\n",(long) length, compression == NoCompression ? "ASCII" : "Binary"); (void) WriteBlobString(image,buffer); offset=SeekBlob(image,stop,SEEK_SET); (void) WriteBlobString(image,"%%EndData\n"); if (LocaleCompare(image_info->magick,"PS2") != 0) (void) WriteBlobString(image,"end\n"); (void) WriteBlobString(image,"%%PageTrailer\n"); if (GetNextImageInList(image) == (Image *) NULL) break; image=SyncNextImageInList(image); status=SetImageProgress(image,SaveImagesTag,scene++, GetImageListLength(image)); if (status == MagickFalse) break; } while (image_info->adjoin != MagickFalse); (void) WriteBlobString(image,"%%Trailer\n"); if (page > 1) { (void) FormatLocaleString(buffer,MaxTextExtent, "%%%%BoundingBox: %.20g %.20g %.20g %.20g\n",ceil(bounds.x1-0.5), ceil(bounds.y1-0.5),floor(bounds.x2+0.5),floor(bounds.y2+0.5)); (void) WriteBlobString(image,buffer); (void) FormatLocaleString(buffer,MaxTextExtent, "%%%%HiResBoundingBox: %g %g %g %g\n",bounds.x1,bounds.y1, bounds.x2,bounds.y2); (void) WriteBlobString(image,buffer); } (void) WriteBlobString(image,"%%EOF\n"); (void) CloseBlob(image); return(MagickTrue); }
// do the action required to open a single atomic tag (iAction) void CMUSHclientDoc::MXP_OpenAtomicTag (const CString strTag, int iAction, CStyle * pStyle, CString & strAction, // new action CString & strHint, // new hint CString & strVariable, // new variable CArgumentList & ArgumentList) { CString strArgument; CString strArgumentName; bool bIgnoreUnusedArgs = false; // cut down on some spam by setting this COLORREF colour1, colour2; unsigned short iFlags = pStyle->iFlags; COLORREF iForeColour = pStyle->iForeColour; COLORREF iBackColour = pStyle->iBackColour; // call script if required if (m_dispidOnMXP_OpenTag != DISPID_UNKNOWN || m_bPluginProcessesOpenTag) { // dummy-up an argument list CString strArgument; CArgument * pArgument; POSITION pos; // put the arguments into the array for (pos = ArgumentList.GetHeadPosition (); pos; ) { pArgument = ArgumentList.GetNext (pos); // empty ones we will put there by position if (pArgument->strName.IsEmpty ()) strArgument += CFormat ("'%s'", (LPCTSTR) pArgument->strValue); else strArgument += CFormat ("%s='%s'", (LPCTSTR) pArgument->strName, (LPCTSTR) pArgument->strValue); if (pos) strArgument += " "; } // end of looping through each argument bool bNotWanted = MXP_StartTagScript (strTag, strArgument, ArgumentList); // re-get current style in case the script did a world.note pStyle = m_pCurrentLine->styleList.GetTail (); // put things backt to how they were pStyle->iFlags = iFlags; pStyle->iForeColour = iForeColour; pStyle->iBackColour = iBackColour; if (bNotWanted) return; // they didn't want to go ahead with this tag } // find current foreground and background RGB values GetStyleRGB (pStyle, colour1, colour2); // special processing for Pueblo // a tag like this: <A XCH_CMD="examine #1"> // will convert to a SEND tag if (iAction == MXP_ACTION_HYPERLINK && PUEBLO_ACTIVE) { strArgument = GetArgument (ArgumentList, "xch_cmd", 0, true); if (!strArgument.IsEmpty ()) { m_bPuebloActive = true; // for correct newline processing iAction = MXP_ACTION_SEND; } } // now take the action switch (iAction) { // temporarily make headlines the same as bold case MXP_ACTION_H1: case MXP_ACTION_H2: case MXP_ACTION_H3: case MXP_ACTION_H4: case MXP_ACTION_H5: case MXP_ACTION_H6: case MXP_ACTION_BOLD: pStyle->iFlags |= HILITE; break; case MXP_ACTION_UNDERLINE: pStyle->iFlags |= UNDERLINE; break; case MXP_ACTION_ITALIC: pStyle->iFlags |= BLINK; break; case MXP_ACTION_COLOR: { pStyle->iForeColour = colour1; pStyle->iBackColour = colour2; // convert to RGB colour to start with in case only FORE or BACK supplied pStyle->iFlags &= ~COLOURTYPE; // clear bits, eg. custom pStyle->iFlags |= COLOUR_RGB; // foreground colour strArgument = GetArgument (ArgumentList, "fore", 1, true); // get foreground colour if (!m_bIgnoreMXPcolourChanges) if (SetColour (strArgument, pStyle->iForeColour)) MXP_error (DBG_ERROR, errMXP_UnknownColour, TFormat ("Unknown colour: \"%s\"" , (LPCTSTR) strArgument)); // background colour strArgument = GetArgument (ArgumentList, "back", 2, true); // get background colour if (!m_bIgnoreMXPcolourChanges) if (SetColour (strArgument, pStyle->iBackColour)) MXP_error (DBG_ERROR, errMXP_UnknownColour, TFormat ("Unknown colour: \"%s\"" , (LPCTSTR) strArgument)); } break; // end of COLOR case MXP_ACTION_HIGH: { CColor clr; pStyle->iForeColour = colour1; pStyle->iBackColour = colour2; // convert to RGB colour to start with pStyle->iFlags &= ~COLOURTYPE; // clear bits, eg. custom pStyle->iFlags |= COLOUR_RGB; clr.SetColor (colour1); float lum = clr.GetLuminance (); lum += 0.15f; if (lum > 1.0f) lum = 1.0f; clr.SetLuminance (lum); pStyle->iForeColour = clr; } break; // end of COLOR case MXP_ACTION_SEND: // send to mud hyperlink pStyle->iFlags &= ~ACTIONTYPE; // cancel old actions if (GetKeyword (ArgumentList, "prompt")) pStyle->iFlags |= ACTION_PROMPT; // prompt action else pStyle->iFlags |= ACTION_SEND; // send-to action if (m_bUnderlineHyperlinks) pStyle->iFlags |= UNDERLINE; // underline it if (m_bUseCustomLinkColour) { // find current background RGB value pStyle->iForeColour = m_iHyperlinkColour; // use hyperlink colour pStyle->iBackColour = colour2; pStyle->iFlags &= ~COLOURTYPE; // clear bits, eg. custom pStyle->iFlags |= COLOUR_RGB; } strArgument = GetArgument (ArgumentList,"href", 1, false); // get link if (strArgument.IsEmpty ()) strArgument = GetArgument (ArgumentList,"xch_cmd", 1, false); // get link strAction = strArgument; // hyperlink strArgument = GetArgument (ArgumentList, "hint", 2, false); // get hints if (strArgument.IsEmpty ()) strArgument = GetArgument (ArgumentList,"xch_hint", 2, false); // get hint strHint = strArgument; // hints break; // end of MXP_ACTION_SEND case MXP_ACTION_HYPERLINK: // hyperlink strArgument = GetArgument (ArgumentList,"href", 1, false); // get link strAction = strArgument; // hyperlink pStyle->iFlags &= ~ACTIONTYPE; // cancel old actions pStyle->iFlags |= ACTION_HYPERLINK | UNDERLINE; // send-to action if (m_bUseCustomLinkColour) { pStyle->iForeColour = m_iHyperlinkColour; // use hyperlink colour pStyle->iBackColour = colour2; pStyle->iFlags &= ~COLOURTYPE; // clear bits, eg. custom pStyle->iFlags |= COLOUR_RGB; } break; // end of MXP_ACTION_HYPERLINK case MXP_ACTION_FONT: { pStyle->iForeColour = colour1; pStyle->iBackColour = colour2; // convert to RGB colour to start with in case only FORE or BACK supplied pStyle->iFlags &= ~COLOURTYPE; // clear bits, eg. custom pStyle->iFlags |= COLOUR_RGB; // eg. <FONT COLOR=Red,Blink> CStringList list; strArgument = GetArgument (ArgumentList,"color", 1, true); // get color etc. if (strArgument.IsEmpty () && PUEBLO_ACTIVE) strArgument = GetArgument (ArgumentList,"fgcolor", 1, true); // get color StringToList (strArgument, ",", list); // break into components for (POSITION pos = list.GetHeadPosition (); pos; ) { CString strItem = list.GetNext (pos); // get action item if (strItem == "blink") pStyle->iFlags |= BLINK; else if (strItem == "italic") pStyle->iFlags |= BLINK; else if (strItem == "underline") pStyle->iFlags |= UNDERLINE; else if (strItem == "bold") pStyle->iFlags |= HILITE; else if (strItem == "inverse") pStyle->iFlags |= INVERSE; else { // must be colour name, yes? // foreground colour if (!m_bIgnoreMXPcolourChanges) if (SetColour (strItem, pStyle->iForeColour)) MXP_error (DBG_ERROR, errMXP_UnknownColour, TFormat ("Unknown colour: \"%s\"" , (LPCTSTR) strItem)); } // end of colour } // end of handling each item in the list strArgument = GetArgument (ArgumentList,"back", 2, true); // get back color if (strArgument.IsEmpty () && PUEBLO_ACTIVE) strArgument = GetArgument (ArgumentList,"bgcolor", 2, true); // get back color // background colour if (!m_bIgnoreMXPcolourChanges) if (SetColour (strArgument, pStyle->iBackColour)) MXP_error (DBG_ERROR, errMXP_UnknownColour, TFormat ("Unknown colour: \"%s\"" , (LPCTSTR) strArgument)); // get font size argument to avoid warnings about unused arguments strArgument = GetArgument (ArgumentList,"size", 0, true); // get font size } break; // end of FONT case MXP_ACTION_VERSION: { CString strVersion = CFormat ("\x1B[1z<VERSION MXP=\"%s\" CLIENT=MUSHclient " "VERSION=\"%s\" REGISTERED=YES>%s", MXP_VERSION, MUSHCLIENT_VERSION, ENDLINE ); SendPacket (strVersion, strVersion.GetLength ()); // send version info back MXP_error (DBG_INFO, infoMXP_VersionSent, TFormat ("Sent version response: %s" , (LPCTSTR) strVersion.Mid (4))); } break; // end of VERSION case MXP_ACTION_AFK: if (m_bSendMXP_AFK_Response) // if player wants us to { strArgument = GetArgument (ArgumentList,"challenge", 1, false); // get challenge // find time since last player input CTimeSpan ts = CTime::GetCurrentTime() - m_tLastPlayerInput; CString strAFK = CFormat ("\x1B[1z<AFK %ld %s>%s", ts.GetTotalSeconds (), (LPCTSTR) strArgument, ENDLINE ); SendPacket (strAFK, strAFK.GetLength ()); // send AFK info back MXP_error (DBG_INFO, infoMXP_AFKSent, TFormat ("Sent AFK response: %s" , (LPCTSTR) strAFK.Mid (4))); } // end of AFK break; case MXP_ACTION_SUPPORT: { CString strSupports; CAtomicElement * pElement; CStringList list; CString strName; if (ArgumentList.IsEmpty ()) { for (POSITION pos = App.m_ElementMap.GetStartPosition(); pos; ) { App.m_ElementMap.GetNextAssoc (pos, strName, pElement); if ((pElement->iFlags & TAG_NOT_IMP) == 0) { strSupports += "+"; strSupports += pElement->strName; strSupports += " "; // now list the sub-items it supports StringToList (pElement->strArgs, ",", list); // break into components for (POSITION argpos = list.GetHeadPosition (); argpos; ) { CString strItem = list.GetNext (argpos); // get argument item strSupports += "+"; strSupports += pElement->strName; strSupports += "."; strSupports += strItem; strSupports += " "; } // end of doing each sub-item } // end of being implemented } // end of looping through all atomic elements } // end of wanting complete list else { for (POSITION pos = ArgumentList.GetHeadPosition (); pos; ) { CArgument * pArgument = ArgumentList.GetNext (pos); CStringList questionlist; StringToList (pArgument->strValue, ".", questionlist); // break into components // should be one or two words, eg. send.prompt or color if (questionlist.GetCount () > 2) { MXP_error (DBG_ERROR, errMXP_InvalidSupportArgument, TFormat ("Invalid <support> argument: %s" , (LPCTSTR) pArgument->strValue)); return; } CString strTag = questionlist.RemoveHead (); strTag.MakeLower (); // check valid name requested if (!IsValidName (strTag)) { MXP_error (DBG_ERROR, errMXP_InvalidSupportArgument, TFormat ("Invalid <support> argument: %s" , (LPCTSTR) strTag)); return; } // look up main element name if (!App.m_ElementMap.Lookup (strTag, pElement) || (pElement->iFlags & TAG_NOT_IMP) != 0) { // not supported strSupports += "-"; strSupports += strTag; strSupports += " "; continue; // all done for this argument } // only one word - they aren't looking for a suboption if (questionlist.IsEmpty ()) { // supported strSupports += "+"; strSupports += strTag; strSupports += " "; continue; // all done for this argument } CString strSubtag = questionlist.RemoveHead (); strSubtag.MakeLower (); if (strSubtag == "*") { // they want list of options for this tag // now list the sub-items it supports StringToList (pElement->strArgs, ",", list); // break into components for (POSITION argpos = list.GetHeadPosition (); argpos; ) { CString strItem = list.GetNext (argpos); // get argument item strSupports += "+"; strSupports += pElement->strName; strSupports += "."; strSupports += strItem; strSupports += " "; } // end of doing each sub-item } // end of wildcard else { // not wildcard - must be name // check valid name requested if (!IsValidName (strSubtag)) { MXP_error (DBG_ERROR, errMXP_InvalidSupportArgument, TFormat ("Invalid <support> argument: %s" , (LPCTSTR) strSubtag)); return; } // so, see if that word is in our arguments list StringToList (pElement->strArgs, ",", list); // break into components if (list.Find (strSubtag)) { strSupports += "+"; strSupports += pArgument->strValue; strSupports += " "; } else { strSupports += "-"; strSupports += pArgument->strValue; strSupports += " "; } } // end of not looking for wildcard } // end of doing each argument } // find individual items CString strMessage = CFormat ("\x1B[1z<SUPPORTS %s>%s", (LPCTSTR) strSupports, ENDLINE); SendPacket (strMessage, strMessage.GetLength ()); // send version info back MXP_error (DBG_INFO, infoMXP_SupportsSent, TFormat ("Sent supports response: %s" , (LPCTSTR) strMessage.Mid (4))); } bIgnoreUnusedArgs = true; break; // end of MXP_ACTION_SUPPORT case MXP_ACTION_OPTION: { CString strOptions; CStringList list; CString strName; if (ArgumentList.IsEmpty ()) { for (long i = 0; OptionsTable [i].pName; i++) { char * pName = OptionsTable [i].pName; strOptions += CFormat ("%s=%ld ", pName, (LPCTSTR) GetOptionItem (i)); } } // end of wanting complete list else { for (POSITION pos = ArgumentList.GetHeadPosition (); pos; ) { CArgument * pArgument = ArgumentList.GetNext (pos); strOptions += CFormat ("%s=%ld", (LPCTSTR) pArgument->strValue, (LPCTSTR) GetOption (pArgument->strValue)); } // end of doing each argument } // find individual items CString strMessage = CFormat ("\x1B[1z<OPTIONS %s>%s", (LPCTSTR) strOptions, ENDLINE); SendPacket (strMessage, strMessage.GetLength ()); // send version info back MXP_error (DBG_INFO, infoMXP_OptionsSent, TFormat ("Sent options response: %s" , (LPCTSTR) strMessage.Mid (4))); } bIgnoreUnusedArgs = true; break; // end of MXP_ACTION_OPTION case MXP_ACTION_RECOMMEND_OPTION: if (m_bMudCanChangeOptions) { CString strOptions; CStringList list; CString strName; for (POSITION pos = ArgumentList.GetHeadPosition (); pos; ) { CArgument * pArgument = ArgumentList.GetNext (pos); int iItem; int iResult = FindBaseOption (pArgument->strName, OptionsTable, iItem); if (iResult != eOK) MXP_error (DBG_ERROR, errMXP_InvalidOptionArgument, TFormat ("Option named '%s' not known.", (LPCTSTR) pArgument->strName)); else if (!(OptionsTable [iItem].iFlags & OPT_SERVER_CAN_WRITE)) MXP_error (DBG_ERROR, errMXP_CannotChangeOption, TFormat ("Option named '%s' cannot be changed.", (LPCTSTR) pArgument->strName)); else { iResult = SetOptionItem (iItem, atol (pArgument->strValue), true, false); if (iResult == eOK) MXP_error (DBG_INFO, infoMXP_OptionChanged, TFormat ("Option named '%s' changed to '%s'.", (LPCTSTR) pArgument->strName, (LPCTSTR) pArgument->strValue)); else MXP_error (DBG_ERROR, errMXP_OptionOutOfRange, TFormat ("Option named '%s' could not be changed to '%s' (out of range).", (LPCTSTR) pArgument->strName, (LPCTSTR) pArgument->strValue)); } } // end of doing each argument } bIgnoreUnusedArgs = true; break; // end of MXP_ACTION_RECOMMEND_OPTION case MXP_ACTION_USER: if (!m_name.IsEmpty () && m_connect_now == eConnectMXP) { CString strPacket = m_name + ENDLINE; SendPacket (strPacket, strPacket.GetLength ()); // send name to MUD MXP_error (DBG_INFO, infoMXP_CharacterNameSent, TFormat ("Sent character name: %s" , (LPCTSTR) m_name)); } else if (m_connect_now != eConnectMXP) MXP_error (DBG_WARNING, wrnMXP_CharacterNameRequestedButNotDefined, Translate ("Character name requested but auto-connect not set to MXP.")); else MXP_error (DBG_WARNING, wrnMXP_CharacterNameRequestedButNotDefined, Translate ("Character name requested but none defined.")); break; // end of USER case MXP_ACTION_PASSWORD: if (m_nTotalLinesSent > 10) // security check MXP_error (DBG_WARNING, wrnMXP_PasswordNotSent, "Too many lines sent to MUD - password not sent."); else if (!m_password.IsEmpty () && m_connect_now == eConnectMXP) { CString strPacket = m_password + ENDLINE; SendPacket (strPacket, strPacket.GetLength ()); // send password to MUD MXP_error (DBG_INFO, infoMXP_PasswordSent, "Sent password to world."); } else if (m_connect_now != eConnectMXP) MXP_error (DBG_WARNING, wrnMXP_PasswordRequestedButNotDefined, "Password requested but auto-connect not set to MXP."); else MXP_error (DBG_WARNING, wrnMXP_PasswordRequestedButNotDefined, "Password requested but none defined."); break; // end of PASSWORD // new para case MXP_ACTION_P: // experimental m_cLastChar = 0; m_bInParagraph = true; break; // end of MXP_ACTION_P // new line case MXP_ACTION_BR: bIgnoreUnusedArgs = true; // don't worry about args for now :) StartNewLine (true, 0); SetNewLineColour (0); break; // end of MXP_ACTION_BR // reset case MXP_ACTION_RESET: MXP_Off (); break; // end of MXP_ACTION_RESET // MXP options (MXP OFF, MXP DEFAULT_OPEN, MXP DEFAULT_SECURE etc. case MXP_ACTION_MXP: if (GetKeyword (ArgumentList, "off")) MXP_Off (true); /* if (GetKeyword (ArgumentList, "default_open")) { MXP_error (DBG_INFO, "MXP default mode now OPEN."); m_iMXP_defaultMode = eMXP_open; } // end of DEFAULT_OPEN if (GetKeyword (ArgumentList, "default_secure")) { MXP_error (DBG_INFO, "MXP default mode now SECURE."); m_iMXP_defaultMode = eMXP_secure; } // end of DEFAULT_SECURE if (GetKeyword (ArgumentList, "default_locked")) { MXP_error (DBG_INFO, "MXP default mode now LOCKED."); m_iMXP_defaultMode = eMXP_locked; } // end of DEFAULT_LOCKED if (GetKeyword (ArgumentList, "use_newlines")) { MXP_error (DBG_INFO, "Now interpreting newlines as normal."); m_bInParagraph = false; } // end of USE_NEWLINES if (GetKeyword (ArgumentList, "ignore_newlines")) { MXP_error (DBG_INFO, "Now ignoring newlines."); m_bInParagraph = true; } // end of IGNORE_NEWLINES */ break; // end of MXP_ACTION_MXP case MXP_ACTION_SCRIPT: MXP_error (DBG_INFO, infoMXP_ScriptCollectionStarted, "Script collection mode entered (discarding script)."); m_bMXP_script = true; break; // end of MXP_ACTION_SCRIPT case MXP_ACTION_HR: { // wrap up previous line if necessary if (m_pCurrentLine->len > 0) StartNewLine (true, 0); /* CString strLine; char * p = strLine.GetBuffer (m_nWrapColumn); memset (p, 175, m_nWrapColumn); strLine.ReleaseBuffer (m_nWrapColumn); AddToLine (strLine, 0); */ // mark line as HR line m_pCurrentLine->flags = HORIZ_RULE; StartNewLine (true, 0); // now finish this line } break; // end of MXP_ACTION_HR case MXP_ACTION_PRE: m_bPreMode = true; break; // end of MXP_ACTION_PRE case MXP_ACTION_UL: m_iListMode = eUnorderedList; m_iListCount = 0; break; // end of MXP_ACTION_UL case MXP_ACTION_OL: m_iListMode = eOrderedList; m_iListCount = 0; break; // end of MXP_ACTION_OL case MXP_ACTION_LI: { // wrap up previous line if necessary if (m_pCurrentLine->len > 0) StartNewLine (true, 0); CString strListItem = " * "; if (m_iListMode == eOrderedList) strListItem.Format (" %i. ", ++m_iListCount); AddToLine (strListItem, 0); } break; // end of MXP_ACTION_LI // pueblo tags we put here so we don't get warnings case MXP_ACTION_BODY : bIgnoreUnusedArgs = true; break; // just ignore it case MXP_ACTION_HEAD : bIgnoreUnusedArgs = true; break; // just ignore it case MXP_ACTION_HTML : bIgnoreUnusedArgs = true; break; // just ignore it case MXP_ACTION_TITLE: bIgnoreUnusedArgs = true; break; // just ignore it case MXP_ACTION_SAMP : bIgnoreUnusedArgs = true; break; // just ignore it case MXP_ACTION_CENTER : bIgnoreUnusedArgs = true; break; // just ignore it case MXP_ACTION_XCH_PANE : bIgnoreUnusedArgs = true; break; // just ignore it case MXP_ACTION_IMG : case MXP_ACTION_IMAGE: { GetKeyword (ArgumentList, "ismap"); // make sure we realise it is a keyword // detect newline treatment strArgument = GetArgument (ArgumentList,"xch_mode", 0, false); // get mode if (!strArgument.IsEmpty ()) { m_bPuebloActive = true; // for correct newline processing if (strArgument.CompareNoCase ("purehtml") == 0) m_bSuppressNewline = true; else if (strArgument.CompareNoCase ("html") == 0) m_bSuppressNewline = false; } // end of some sort of Pueblo strArgument = GetArgument (ArgumentList,"url", 0, false); // get link if (strArgument.IsEmpty () && PUEBLO_ACTIVE) strArgument = GetArgument (ArgumentList,"src", 0, false); // get link CString strFilename = GetArgument (ArgumentList,"fname", 0, false); // and file name if (!strArgument.IsEmpty ()) { CString strOldAction = strAction; int iFlags = pStyle->iFlags; COLORREF iForeColour = pStyle->iForeColour; COLORREF iBackColour = pStyle->iBackColour; // ensure on new line if (m_pCurrentLine->len > 0) StartNewLine (true, 0); // starting a new line may have deleted pStyle pStyle = m_pCurrentLine->styleList.GetTail (); if (m_bUseCustomLinkColour) { pStyle->iForeColour = m_iHyperlinkColour; // use hyperlink colour pStyle->iBackColour = colour2; pStyle->iFlags &= ~COLOURTYPE; // clear bits, eg. custom pStyle->iFlags |= COLOUR_RGB; } strArgument += strFilename; // append filename to URL strAction = strArgument; // hyperlink pStyle->iFlags &= ~ACTIONTYPE; // cancel old actions pStyle->iFlags |= ACTION_HYPERLINK; // send-to action if (m_bUnderlineHyperlinks) pStyle->iFlags |= UNDERLINE; // send-to action AddToLine ("[", 0); AddToLine (strArgument, 0); AddToLine ("]", 0); // have to add the action now, before we start a new line pStyle->pAction = GetAction (strAction, strHint, strVariable); strAction.Empty (); StartNewLine (true, 0); // new line after image tag // go back to old style (ie. lose the underlining) AddStyle (iFlags, iForeColour, iBackColour, 0, strOldAction); } } break; // end of MXP_ACTION_IMG case MXP_ACTION_XCH_PAGE: bIgnoreUnusedArgs = true; m_bPuebloActive = true; // for correct newline processing MXP_Off (); // same as <reset>? break; // end of MXP_ACTION_XCH_PAGE case MXP_ACTION_VAR: // set variable strVariable = GetArgument (ArgumentList,"", 1, false); // get name // case insensitive strVariable.MakeLower (); if (!IsValidName (strVariable)) { MXP_error (DBG_ERROR, errMXP_InvalidDefinition, TFormat ("Invalid MXP entity name: <!%s>", (LPCTSTR) strVariable)); strVariable.Empty (); return; } { // protect local variable CString strEntityContents; if (App.m_EntityMap.Lookup (strVariable, strEntityContents)) { MXP_error (DBG_ERROR, errMXP_CannotRedefineEntity, TFormat ("Cannot redefine entity: &%s;", (LPCTSTR) strVariable)); strVariable.Empty (); return; } } break; // end of MXP_ACTION_VAR default: { // warn them it is not implemented MXP_error (DBG_WARNING, wrnMXP_TagNotImplemented, TFormat ("MXP tag <%s> is not implemented" , (LPCTSTR) strTag)); } // end of default } // end of switch on iAction if (!bIgnoreUnusedArgs) CheckArgumentsUsed (strTag, ArgumentList); } // end of CMUSHclientDoc::MXP_OpenAtomicTag
void Importer::ReadImportItems() { int item_counter = 0; wxStringTokenizer toker; wxString item_name; wxString item_value; ExtImportItem *new_item; ImportPluginList::compatibility_iterator importPluginNode; if (this->mExtImportItems != NULL) delete this->mExtImportItems; this->mExtImportItems = new ExtImportItems(); /* Rule string format is: * extension1:extension2:extension3\mime_type1:mime_type2:mime_type3|filter1:filter2:filter3\unusedfilter1:unusedfilter2 * backslashes are escaped and unescaped internally */ for (item_counter = 0; true; item_counter++) { wxString condition, filters, used_filters, unused_filters = wxEmptyString, extensions, mime_types = wxEmptyString; item_name.Printf (wxT("/ExtImportItems/Item%d"), item_counter); /* Break at first non-existent item */ if (!gPrefs->Read(item_name, &item_value)) break; toker.SetString(item_value, wxT("|"), wxTOKEN_RET_EMPTY_ALL); /* Break at first broken item */ if (toker.CountTokens() != 2) break; new_item = new ExtImportItem(); /* First token is the filtering condition, second - the filter list */ condition = toker.GetNextToken(); filters = toker.GetNextToken(); /* Condition token consists of extension list and mime type list * mime type list can be omitted entirely (complete with '\' separator)*/ toker.SetString(condition, wxT("\\"), wxTOKEN_RET_EMPTY_ALL); extensions = toker.GetNextToken(); if (toker.HasMoreTokens()) mime_types = toker.GetNextToken(); wxString delims(wxT(":")); StringToList (extensions, delims, new_item->extensions); if (mime_types != wxEmptyString) StringToList (mime_types, delims, new_item->mime_types); /* Filter token consists of used and unused filter lists */ toker.SetString(filters, wxT("\\"), wxTOKEN_RET_EMPTY_ALL); used_filters = toker.GetNextToken(); if (toker.HasMoreTokens()) unused_filters = toker.GetNextToken(); StringToList (used_filters, delims, new_item->filters); if (unused_filters != wxEmptyString) { /* Filters are stored in one list, but the position at which * unused filters start is remembered */ new_item->divider = new_item->filters.Count(); StringToList (unused_filters, delims, new_item->filters); } else new_item->divider = -1; /* Find corresponding filter object for each filter ID */ for (size_t i = 0; i < new_item->filters.Count(); i++) { for (importPluginNode = mImportPluginList->GetFirst(); importPluginNode; importPluginNode = importPluginNode->GetNext()) { ImportPlugin *importPlugin = importPluginNode->GetData(); if (importPlugin->GetPluginStringID().Cmp(new_item->filters[i]) == 0) { new_item->filter_objects.Add (importPlugin); break; } } /* IDs that do not have corresponding filters, will be shown as-is */ if (!importPluginNode) new_item->filter_objects.Add (NULL); } /* Find all filter objects that are not present in the filter list */ for (importPluginNode = mImportPluginList->GetFirst(); importPluginNode; importPluginNode = importPluginNode->GetNext()) { bool found = false; ImportPlugin *importPlugin = importPluginNode->GetData(); for (size_t i = 0; i < new_item->filter_objects.Count(); i++) { if (importPlugin == new_item->filter_objects[i]) { found = true; break; } } /* Add these filters at the bottom of used filter list */ if (!found) { int index = new_item->divider; if (new_item->divider < 0) index = new_item->filters.Count(); new_item->filters.Insert(importPlugin->GetPluginStringID(),index); new_item->filter_objects.Insert (importPlugin, index); if (new_item->divider >= 0) new_item->divider++; } } this->mExtImportItems->Add (new_item); } }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % L i s t D e l e g a t e I n f o % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Method ListDelegateInfo lists the image formats to a file. % % The format of the ListDelegateInfo method is: % % unsigned int ListDelegateInfo(FILE *file,ExceptionInfo *exception) % % A description of each parameter follows. % % o file: An pointer to a FILE. % % o exception: Return any errors or warnings in this structure. % % */ MagickExport unsigned int ListDelegateInfo(FILE *file,ExceptionInfo *exception) { char **commands, delegate[MaxTextExtent]; register long i; register const DelegateInfo *p; if (file == (const FILE *) NULL) file=stdout; (void) GetDelegateInfo("*","*",exception); LockSemaphoreInfo(delegate_semaphore); for (p=delegate_list; p != (const DelegateInfo *) NULL; p=p->next) { if ((p->previous == (DelegateInfo *) NULL) || (LocaleCompare(p->path,p->previous->path) != 0)) { if (p->previous != (DelegateInfo *) NULL) (void) fprintf(file,"\n"); if (p->path != (char *) NULL) (void) fprintf(file,"Path: %.1024s\n\n",p->path); (void) fprintf(file,"Delegate Command\n"); (void) fprintf(file,"-------------------------------------------------" "------------------------------\n"); } if (p->stealth) continue; *delegate='\0'; if (p->encode != (char *) NULL) (void) strlcpy(delegate,p->encode,MaxTextExtent); (void) strcat(delegate," "); delegate[8]='\0'; commands=StringToList(p->commands); if (commands == (char **) NULL) continue; { int command_start_column, command_length, formatted_chars=0, length=0, screen_width=79, strip_length; char *s; /* Format output so that command spans multiple lines if necessary */ if (getenv("COLUMNS")) screen_width=atoi(getenv("COLUMNS"))-1; command_length=strlen(commands[0]); command_start_column=fprintf(file,"%8s%c=%c%s ",p->decode ? p->decode : "", p->mode <= 0 ? '<' : ' ',p->mode >= 0 ? '>' : ' ',delegate); for (s=commands[0]; length < command_length; s+=formatted_chars) { if (s != commands[0]) (void) fprintf(file,"%*s",command_start_column,""); strip_length=screen_width-command_start_column; if (length+strip_length < command_length) { char *e; for(e=s+strip_length; (*e != ' ') && (e > s) ; e--); strip_length=e-s; } formatted_chars=fprintf(file,"%.*s",strip_length,s); length+=formatted_chars; (void) fprintf(file,"\n"); if (formatted_chars <= 0) break; } } for (i=0; commands[i] != (char *) NULL; i++) MagickFreeMemory(commands[i]); MagickFreeMemory(commands); } (void) fflush(file); UnlockSemaphoreInfo(delegate_semaphore); return(True); }
MagickExport unsigned int InvokeDelegate(ImageInfo *image_info,Image *image, const char *decode,const char *encode,ExceptionInfo *exception) { char *command, **commands, filename[MaxTextExtent]; const DelegateInfo *delegate_info; register long i; unsigned int status, temporary_image_filename; /* Get delegate. */ assert(image_info != (ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(image != (Image *) NULL); assert(image->signature == MagickSignature); temporary_image_filename=(*image->filename == '\0'); if (temporary_image_filename) { /* Allocate a temporary filename if image is unnamed. */ if(!AcquireTemporaryFileName(image->filename)) { (void) ThrowException(exception,FileOpenError,UnableToCreateTemporaryFile,image->filename); return(False); } } (void) strlcpy(filename,image->filename,MaxTextExtent); delegate_info=GetDelegateInfo(decode,encode,exception); if (delegate_info == (DelegateInfo *) NULL) { if (temporary_image_filename) (void) LiberateTemporaryFile(image->filename); (void) ThrowException(exception,DelegateError,NoTagFound, decode ? decode : encode); return(False); } if (*image_info->filename == '\0') { /* ReadImage will normally have already set image_info->filename to the name of a temporary file. If not, then assign one. Setting image_info->temporary to True indicates that there is a temporary file to be removed later. */ if(!AcquireTemporaryFileName(image_info->filename)) { if (temporary_image_filename) (void) LiberateTemporaryFile(image->filename); (void) ThrowException(exception,FileOpenError,UnableToCreateTemporaryFile,image_info->filename); return(False); } image_info->temporary=True; } if (delegate_info->mode != 0) if ((decode && (delegate_info->encode != (char *) NULL)) || (encode && (delegate_info->decode != (char *) NULL))) { char decode_filename[MaxTextExtent], *magick; ImageInfo *clone_info; register Image *p; /* Delegate requires a particular image format. */ if (!AcquireTemporaryFileName(image_info->unique)) { if (temporary_image_filename) (void) LiberateTemporaryFile(image->filename); (void) ThrowException(exception,FileOpenError,UnableToCreateTemporaryFile,image_info->unique); return(False); } if (!AcquireTemporaryFileName(image_info->zero)) { if (temporary_image_filename) (void) LiberateTemporaryFile(image->filename); (void) LiberateTemporaryFile(image_info->unique); (void) ThrowException(exception,FileOpenError,UnableToCreateTemporaryFile,image_info->zero); return(False); } /* Expand sprintf-style codes in delegate command to command string */ magick=TranslateText(image_info,image,decode != (char *) NULL ? delegate_info->encode : delegate_info->decode); if (magick == (char *) NULL) { (void) LiberateTemporaryFile(image_info->unique); (void) LiberateTemporaryFile(image_info->zero); if (temporary_image_filename) (void) LiberateTemporaryFile(image->filename); (void) ThrowException(exception,DelegateError,DelegateFailed, decode ? decode : encode); return(False); } LocaleUpper(magick); clone_info=CloneImageInfo(image_info); (void) strlcpy((char *) clone_info->magick,magick,MaxTextExtent); (void) strlcpy(image->magick,magick,MaxTextExtent); MagickFreeMemory(magick); (void) strlcpy(decode_filename,image->filename,MaxTextExtent); FormatString(clone_info->filename,"%.1024s:",delegate_info->decode); (void) SetImageInfo(clone_info,True,exception); (void) strlcpy(clone_info->filename,image_info->filename, MaxTextExtent); for (p=image; p != (Image *) NULL; p=p->next) { FormatString(p->filename,"%.1024s:%.1024s",delegate_info->decode, decode_filename); status=WriteImage(clone_info,p); if (status == False) { (void) LiberateTemporaryFile(image_info->unique); (void) LiberateTemporaryFile(image_info->zero); if (temporary_image_filename) (void) LiberateTemporaryFile(image->filename); DestroyImageInfo(clone_info); (void) ThrowException(exception,DelegateError,DelegateFailed, decode ? decode : encode); return(False); } if (clone_info->adjoin) break; } (void) LiberateTemporaryFile(image_info->unique); (void) LiberateTemporaryFile(image_info->zero); DestroyImageInfo(clone_info); } /* Invoke delegate. */ (void) strlcpy(image->filename,filename,MaxTextExtent); commands=StringToList(delegate_info->commands); if (commands == (char **) NULL) { if (temporary_image_filename) (void) LiberateTemporaryFile(image->filename); (void) ThrowException(exception,ResourceLimitError,MemoryAllocationFailed,decode ? decode : encode); return(False); } command=(char *) NULL; status=True; /* For each delegate command ... */ for (i=0; commands[i] != (char *) NULL; i++) { status=True; /* Allocate convenience temporary files */ if (!AcquireTemporaryFileName(image_info->unique)) { (void) ThrowException(exception,FileOpenError,UnableToCreateTemporaryFile,image_info->unique); status=False; goto error_exit; } if (!AcquireTemporaryFileName(image_info->zero)) { (void) ThrowException(exception,FileOpenError,UnableToCreateTemporaryFile,image_info->zero); (void) LiberateTemporaryFile(image_info->unique); status=False; goto error_exit; } #if defined(POSIX) { MagickBool needs_shell; /* Check to see if command template must be executed via shell due to using constructs requiring multiple processes or I/O redirection. */ needs_shell = MagickFalse; { char * p; p = commands[i]; for (p = commands[i]; *p; p++) { if (('&' == *p) || (';' == *p) || ('<' == *p) || ('>' == *p) || ('|' == *p)) { needs_shell = MagickTrue; break; } } } if (MagickFalse == needs_shell) { int arg_count, j; char **arg_array; /* Convert command template into an argument array. Translate each argument array element individually in order to absolutely avoid any possibility that the number of arguments may be altered due to substituted data. */ arg_array = StringToArgv(commands[i],&arg_count); for (j = 0; arg_array[j] != (const char*) NULL; j++) { if (strchr(arg_array[j], '%') != (const char*) NULL) { char *expanded = TranslateText(image_info,image,arg_array[j]); if (expanded != (char *) NULL) { MagickFreeMemory(arg_array[j]); arg_array[j] = expanded; } } } /* Execute delegate using our secure "spawn" facility. */ status = MagickSpawnVP(image_info->verbose,arg_array[1],arg_array+1); } else { /* Expand sprintf-style codes in delegate command to command string, escaping replacement text appropriately */ command=TranslateTextEx(image_info,image,commands[i],UnixShellTextEscape); if (command == (char *) NULL) break; /* Execute delegate using command shell. */ status=SystemCommand(image_info->verbose,command); } } #else { /* Expand sprintf-style codes in delegate command to command string */ command=TranslateText(image_info,image,commands[i]); if (command == (char *) NULL) break; /* Execute delegate using command shell. */ status=SystemCommand(image_info->verbose,command); } #endif MagickFreeMemory(command); /* Liberate convenience temporary files */ (void) LiberateTemporaryFile(image_info->unique); (void) LiberateTemporaryFile(image_info->zero); if (status != False) { (void) ThrowException(exception,DelegateError,DelegateFailed, commands[i]); goto error_exit; } MagickFreeMemory(commands[i]); } /* Free resources. */ error_exit: if (temporary_image_filename) (void) LiberateTemporaryFile(image->filename); for ( ; commands[i] != (char *) NULL; i++) MagickFreeMemory(commands[i]); MagickFreeMemory(commands); return(status != False); }
bool Get_XML_date (CXMLelement & node, const char * sName, CTime & tValue, const bool bUseDefault) { CString strValue; if (!Get_XML_string (node, sName, strValue, true, true)) if (bUseDefault) return false; else { tValue = 0; // default is no time return false; } if (strValue.IsEmpty ()) ThrowErrorException ("No time supplied for attribute named '%s'" , sName); // break up date into date portion / time portion CStringList strDateTime; StringToList (strValue, " ", strDateTime); if (strDateTime.GetCount () < 1 || strDateTime.GetCount () > 2) ThrowErrorException ("Date/time must consist of YYYY-MM-DD [ HH:MM:SS ]"); CString strDate = strDateTime.RemoveHead (); CString strTime; if (!strDateTime.IsEmpty ()) strTime = strDateTime.RemoveHead (); CString strYear, strMonth, strDay; CStringList strDateList; StringToList (strDate, "-", strDateList); if (strDateList.GetCount () != 3) ThrowErrorException ("Date must consist of YYYY-MM-DD"); strYear = strDateList.RemoveHead (); strMonth = strDateList.RemoveHead (); strDay = strDateList.RemoveHead (); if (!IsNumber (strYear)) ThrowErrorException ("Year is not numeric"); if (!IsNumber (strMonth)) ThrowErrorException ("Month is not numeric"); if (!IsNumber (strDay)) ThrowErrorException ("Day is not numeric"); int iYear, iMonth, iDay; iYear = atoi (strYear); iMonth = atoi (strMonth); iDay = atoi (strDay); if (iYear < 1900 || iYear > 2100) ThrowErrorException ("Year must be in range 1900 to 2100"); if (iMonth < 1 || iMonth > 12) ThrowErrorException ("Month must be in range 1 to 12"); if (iDay < 1 || iDay > 31) ThrowErrorException ("Month must be in range 1 to 31"); int iHour = 0, iMinute = 0, iSecond = 0; if (!strTime.IsEmpty ()) { CString strHour, strMinute, strSecond; CStringList strTimeList; StringToList (strTime, ":", strTimeList); if (strTimeList.GetCount () > 3) ThrowErrorException ("Time must consist of HH, HH:MM, or HH:MM:SS"); strHour = strTimeList.RemoveHead (); strMinute = "0"; strSecond = "0"; if (!strTimeList.IsEmpty ()) { strMinute = strTimeList.RemoveHead (); if (!strTimeList.IsEmpty ()) strSecond = strTimeList.RemoveHead (); } if (!IsNumber (strHour)) ThrowErrorException ("Hour is not numeric"); if (!IsNumber (strMinute)) ThrowErrorException ("Minute is not numeric"); if (!IsNumber (strSecond)) ThrowErrorException ("Second is not numeric"); iHour = atoi (strHour); iMinute = atoi (strMinute); iSecond = atoi (strSecond); if (iHour < 0 || iHour > 23) ThrowErrorException ("Hour must be in range 0 to 23"); if (iMinute < 0 || iMinute > 59) ThrowErrorException ("Minute must be in range 0 to 59"); if (iSecond < 0 || iSecond > 59) ThrowErrorException ("Minute must be in range 0 to 59"); } // end of having a time tValue = CTime (iYear, iMonth, iDay, iHour, iMinute, iSecond, 0); return true; } // end of Get_XML_date
bool GetFileFormat(api::File& file, uintptr_t& nCodePage, bool* pSignatureFound, bool bUseHeuristics) { DWORD dwTemp=0; bool bSignatureFound = false; bool bDetect=false; DWORD Readed = 0; if (file.Read(&dwTemp, sizeof(dwTemp), Readed) && Readed > 1 ) // minimum signature size is 2 bytes { if (LOWORD(dwTemp) == SIGN_UNICODE) { nCodePage = CP_UNICODE; file.SetPointer(2, nullptr, FILE_BEGIN); bSignatureFound = true; } else if (LOWORD(dwTemp) == SIGN_REVERSEBOM) { nCodePage = CP_REVERSEBOM; file.SetPointer(2, nullptr, FILE_BEGIN); bSignatureFound = true; } else if ((dwTemp & 0x00FFFFFF) == SIGN_UTF8) { nCodePage = CP_UTF8; file.SetPointer(3, nullptr, FILE_BEGIN); bSignatureFound = true; } else { file.SetPointer(0, nullptr, FILE_BEGIN); } } if (bSignatureFound) { bDetect = true; } else if (bUseHeuristics) { file.SetPointer(0, nullptr, FILE_BEGIN); DWORD Size=0x8000; // BUGBUG. TODO: configurable char_ptr Buffer(Size); DWORD ReadSize = 0; bool ReadResult = file.Read(Buffer.get(), Size, ReadSize); file.SetPointer(0, nullptr, FILE_BEGIN); if (ReadResult && ReadSize) { int test= IS_TEXT_UNICODE_STATISTICS| IS_TEXT_UNICODE_REVERSE_STATISTICS| IS_TEXT_UNICODE_CONTROLS| IS_TEXT_UNICODE_REVERSE_CONTROLS| IS_TEXT_UNICODE_ILLEGAL_CHARS| IS_TEXT_UNICODE_ODD_LENGTH| IS_TEXT_UNICODE_NULL_BYTES; if (IsTextUnicode(Buffer.get(), ReadSize, &test)) { if (!(test&IS_TEXT_UNICODE_ODD_LENGTH) && !(test&IS_TEXT_UNICODE_ILLEGAL_CHARS)) { if ((test&IS_TEXT_UNICODE_NULL_BYTES) || (test&IS_TEXT_UNICODE_CONTROLS) || (test&IS_TEXT_UNICODE_REVERSE_CONTROLS)) { if ((test&IS_TEXT_UNICODE_CONTROLS) || (test&IS_TEXT_UNICODE_STATISTICS)) { nCodePage=CP_UNICODE; bDetect=true; } else if ((test&IS_TEXT_UNICODE_REVERSE_CONTROLS) || (test&IS_TEXT_UNICODE_REVERSE_STATISTICS)) { nCodePage=CP_REVERSEBOM; bDetect=true; } } } } else if (IsTextUTF8(Buffer.get(), ReadSize)) { nCodePage=CP_UTF8; bDetect=true; } else { int cp = GetCpUsingUniversalDetector(Buffer.get(), ReadSize); if ( cp >= 0 ) { if (Global->Opt->strNoAutoDetectCP.Get() == L"-1") { if ( Global->Opt->CPMenuMode ) { if ( static_cast<UINT>(cp) != GetACP() && static_cast<UINT>(cp) != GetOEMCP() ) { long long selectType = Global->CodePages->GetFavorite(cp); if (0 == (selectType & CPST_FAVORITE)) cp = -1; } } } else { const auto BannedCpList = StringToList(Global->Opt->strNoAutoDetectCP, STLF_UNIQUE); if (std::find(ALL_CONST_RANGE(BannedCpList), std::to_wstring(cp)) != BannedCpList.cend()) { cp = -1; } } } if (cp != -1) { nCodePage = cp; bDetect = true; } } } } if (pSignatureFound) { *pSignatureFound = bSignatureFound; } return bDetect; }
static MagickBooleanType WritePS3Image(const ImageInfo *image_info,Image *image) { static const char *PostscriptProlog[]= { "/ByteStreamDecodeFilter", "{", " /z exch def", " /r exch def", " /c exch def", " z "PS3_NoCompression" eq { /ASCII85Decode filter } if", " z "PS3_FaxCompression" eq", " {", " <<", " /K "CCITTParam, " /Columns c", " /Rows r", " >>", " /CCITTFaxDecode filter", " } if", " z "PS3_JPEGCompression" eq { /DCTDecode filter } if", " z "PS3_LZWCompression" eq { /LZWDecode filter } if", " z "PS3_RLECompression" eq { /RunLengthDecode filter } if", " z "PS3_ZipCompression" eq { /FlateDecode filter } if", "} bind def", "", "/DirectClassImageDict", "{", " colorspace "PS3_RGBColorspace" eq", " {", " /DeviceRGB setcolorspace", " <<", " /ImageType 1", " /Width columns", " /Height rows", " /BitsPerComponent 8", " /DataSource pixel_stream", " /MultipleDataSources false", " /ImageMatrix [columns 0 0 rows neg 0 rows]", " /Decode [0 1 0 1 0 1]", " >>", " }", " {", " /DeviceCMYK setcolorspace", " <<", " /ImageType 1", " /Width columns", " /Height rows", " /BitsPerComponent 8", " /DataSource pixel_stream", " /MultipleDataSources false", " /ImageMatrix [columns 0 0 rows neg 0 rows]", " /Decode", " compression "PS3_JPEGCompression" eq", " { [1 0 1 0 1 0 1 0] }", " { [0 1 0 1 0 1 0 1] }", " ifelse", " >>", " }", " ifelse", "} bind def", "", "/PseudoClassImageDict", "{", " % Colors in colormap image.", " currentfile buffer readline pop", " token pop /colors exch def pop", " colors 0 eq", " {", " % Depth of grayscale image.", " currentfile buffer readline pop", " token pop /bits exch def pop", " /DeviceGray setcolorspace", " <<", " /ImageType 1", " /Width columns", " /Height rows", " /BitsPerComponent bits", " /Decode [0 1]", " /ImageMatrix [columns 0 0 rows neg 0 rows]", " /DataSource pixel_stream", " >>", " }", " {", " % RGB colormap.", " /colormap colors 3 mul string def", " compression "PS3_NoCompression" eq", " { currentfile /ASCII85Decode filter colormap readstring pop pop }", " { currentfile colormap readstring pop pop }", " ifelse", " [ /Indexed /DeviceRGB colors 1 sub colormap ] setcolorspace", " <<", " /ImageType 1", " /Width columns", " /Height rows", " /BitsPerComponent 8", " /Decode [0 255]", " /ImageMatrix [columns 0 0 rows neg 0 rows]", " /DataSource pixel_stream", " >>", " }", " ifelse", "} bind def", "", "/NonMaskedImageDict", "{", " class "PS3_PseudoClass" eq", " { PseudoClassImageDict }", " { DirectClassImageDict }", " ifelse", "} bind def", "", "/MaskedImageDict", "{", " <<", " /ImageType 3", " /InterleaveType 3", " /DataDict NonMaskedImageDict", " /MaskDict", " <<", " /ImageType 1", " /Width columns", " /Height rows", " /BitsPerComponent 1", " /DataSource mask_stream", " /MultipleDataSources false", " /ImageMatrix [ columns 0 0 rows neg 0 rows]", " /Decode [ 0 1 ]", " >>", " >>", "} bind def", "", "/ClipImage", "{} def", "", "/DisplayImage", "{", " /buffer 512 string def", " % Translation.", " currentfile buffer readline pop", " token pop /x exch def", " token pop /y exch def pop", " x y translate", " % Image size and font size.", " currentfile buffer readline pop", " token pop /x exch def", " token pop /y exch def pop", " currentfile buffer readline pop", " token pop /pointsize exch def pop", (char *) NULL }, *PostscriptEpilog[]= { " x y scale", " % Clipping path.", " currentfile buffer readline pop", " token pop /clipped exch def pop", " % Showpage.", " currentfile buffer readline pop", " token pop /sp exch def pop", " % Image pixel size.", " currentfile buffer readline pop", " token pop /columns exch def", " token pop /rows exch def pop", " % Colorspace (RGB/CMYK).", " currentfile buffer readline pop", " token pop /colorspace exch def pop", " % Transparency.", " currentfile buffer readline pop", " token pop /alpha exch def pop", " % Stencil mask?", " currentfile buffer readline pop", " token pop /stencil exch def pop", " % Image class (direct/pseudo).", " currentfile buffer readline pop", " token pop /class exch def pop", " % Compression type.", " currentfile buffer readline pop", " token pop /compression exch def pop", " % Clip and render.", " /pixel_stream currentfile columns rows compression ByteStreamDecodeFilter def", " clipped { ClipImage } if", " alpha stencil not and", " { MaskedImageDict mask_stream resetfile }", " { NonMaskedImageDict }", " ifelse", " stencil { 0 setgray imagemask } { image } ifelse", " sp { showpage } if", "} bind def", (char *) NULL }; char buffer[MaxTextExtent], date[MaxTextExtent], **labels, page_geometry[MaxTextExtent]; CompressionType compression; const char *option, **q, *value; double pointsize; GeometryInfo geometry_info; long j; MagickBooleanType status; MagickOffsetType offset, scene, start, stop; MagickStatusType flags; PointInfo delta, resolution, scale; RectangleInfo geometry, media_info, page_info; register long i; SegmentInfo bounds; size_t length; time_t timer; unsigned char *pixels; unsigned long page, pixel, text_size; /* Open output image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(image != (Image *) NULL); assert(image->signature == MagickSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == MagickFalse) return(MagickFalse); compression=image->compression; if (image_info->compression != UndefinedCompression) compression=image_info->compression; switch (compression) { case FaxCompression: case Group4Compression: { if ((IsMonochromeImage(image,&image->exception) == MagickFalse) || (image->matte != MagickFalse)) compression=RLECompression; break; } #if !defined(MAGICKCORE_JPEG_DELEGATE) case JPEGCompression: { compression=RLECompression; (void) ThrowMagickException(&image->exception,GetMagickModule(), MissingDelegateError,"DelegateLibrarySupportNotBuiltIn","`%s' (JPEG)", image->filename); break; } #endif #if !defined(MAGICKCORE_ZLIB_DELEGATE) case ZipCompression: { compression=RLECompression; (void) ThrowMagickException(&image->exception,GetMagickModule(), MissingDelegateError,"DelegateLibrarySupportNotBuiltIn","`%s' (ZLIB)", image->filename); break; } #endif default: break; } (void) ResetMagickMemory(&bounds,0,sizeof(bounds)); page=0; scene=0; do { /* Scale relative to dots-per-inch. */ delta.x=DefaultResolution; delta.y=DefaultResolution; resolution.x=image->x_resolution; resolution.y=image->y_resolution; if ((resolution.x == 0.0) || (resolution.y == 0.0)) { flags=ParseGeometry(PSDensityGeometry,&geometry_info); resolution.x=geometry_info.rho; resolution.y=geometry_info.sigma; if ((flags & SigmaValue) == 0) resolution.y=resolution.x; } if (image_info->density != (char *) NULL) { flags=ParseGeometry(image_info->density,&geometry_info); resolution.x=geometry_info.rho; resolution.y=geometry_info.sigma; if ((flags & SigmaValue) == 0) resolution.y=resolution.x; } if (image->units == PixelsPerCentimeterResolution) { resolution.x*=2.54; resolution.y*=2.54; } SetGeometry(image,&geometry); (void) FormatMagickString(page_geometry,MaxTextExtent,"%lux%lu", image->columns,image->rows); if (image_info->page != (char *) NULL) (void) CopyMagickString(page_geometry,image_info->page,MaxTextExtent); else if ((image->page.width != 0) && (image->page.height != 0)) (void) FormatMagickString(page_geometry,MaxTextExtent,"%lux%lu%+ld%+ld", image->page.width,image->page.height,image->page.x,image->page.y); else if ((image->gravity != UndefinedGravity) && (LocaleCompare(image_info->magick,"PS") == 0)) (void) CopyMagickString(page_geometry,PSPageGeometry,MaxTextExtent); (void) ConcatenateMagickString(page_geometry,">",MaxTextExtent); (void) ParseMetaGeometry(page_geometry,&geometry.x,&geometry.y, &geometry.width,&geometry.height); scale.x=(double) (geometry.width*delta.x)/resolution.x; geometry.width=(unsigned long) (scale.x+0.5); scale.y=(double) (geometry.height*delta.y)/resolution.y; geometry.height=(unsigned long) (scale.y+0.5); (void) ParseAbsoluteGeometry(page_geometry,&media_info); (void) ParseGravityGeometry(image,page_geometry,&page_info, &image->exception); if (image->gravity != UndefinedGravity) { geometry.x=(-page_info.x); geometry.y=(long) (media_info.height+page_info.y-image->rows); } pointsize=12.0; if (image_info->pointsize != 0.0) pointsize=image_info->pointsize; text_size=0; value=GetImageProperty(image,"label"); if (value != (const char *) NULL) text_size=(unsigned long) (MultilineCensus(value)*pointsize+12); page++; if (page == 1) { /* Postscript header on the first page. */ if (LocaleCompare(image_info->magick,"PS3") == 0) (void) CopyMagickString(buffer,"%!PS-Adobe-3.0\n",MaxTextExtent); else (void) CopyMagickString(buffer,"%!PS-Adobe-3.0 EPSF-3.0\n", MaxTextExtent); (void) WriteBlobString(image,buffer); (void) FormatMagickString(buffer,MaxTextExtent, "%%%%Creator: ImageMagick %s\n",MagickLibVersionText); (void) WriteBlobString(image,buffer); (void) FormatMagickString(buffer,MaxTextExtent,"%%%%Title: %s\n", image->filename); (void) WriteBlobString(image,buffer); timer=time((time_t *) NULL); (void) FormatMagickTime(timer,MaxTextExtent,date); (void) FormatMagickString(buffer,MaxTextExtent, "%%%%CreationDate: %s\n",date); (void) WriteBlobString(image,buffer); bounds.x1=(double) geometry.x; bounds.y1=(double) geometry.y; bounds.x2=(double) geometry.x+scale.x; bounds.y2=(double) geometry.y+scale.y+text_size; if ((image_info->adjoin != MagickFalse) && (GetNextImageInList(image) != (Image *) NULL)) { (void) WriteBlobString(image,"%%BoundingBox: (atend)\n"); (void) WriteBlobString(image,"%%HiResBoundingBox: (atend)\n"); } else { (void) FormatMagickString(buffer,MaxTextExtent, "%%%%BoundingBox: %g %g %g %g\n",floor(bounds.x1+0.5), floor(bounds.y1+0.5),ceil(bounds.x2-0.5),ceil(bounds.y2-0.5)); (void) WriteBlobString(image,buffer); (void) FormatMagickString(buffer,MaxTextExtent, "%%%%HiResBoundingBox: %g %g %g %g\n",bounds.x1,bounds.y1, bounds.x2,bounds.y2); (void) WriteBlobString(image,buffer); if (image->colorspace == CMYKColorspace) (void) WriteBlobString(image, "%%DocumentProcessColors: Cyan Magenta Yellow Black\n"); else if (IsGrayImage(image,&image->exception) != MagickFalse) (void) WriteBlobString(image, "%%DocumentProcessColors: Black\n"); } /* Font resources */ value=GetImageProperty(image,"label"); if (value != (const char *) NULL) (void) WriteBlobString(image, "%%DocumentNeededResources: font Helvetica\n"); (void) WriteBlobString(image,"%%LanguageLevel: 3\n"); /* Pages, orientation and order. */ if (LocaleCompare(image_info->magick,"PS3") != 0) (void) WriteBlobString(image,"%%Pages: 1\n"); else { (void) WriteBlobString(image,"%%Orientation: Portrait\n"); (void) WriteBlobString(image,"%%PageOrder: Ascend\n"); if (image_info->adjoin == MagickFalse) (void) CopyMagickString(buffer,"%%Pages: 1\n",MaxTextExtent); else (void) FormatMagickString(buffer,MaxTextExtent,"%%%%Pages: %lu\n", (unsigned long) GetImageListLength(image)); (void) WriteBlobString(image,buffer); } (void) WriteBlobString(image,"%%EndComments\n"); /* The static postscript procedures prolog. */ (void)WriteBlobString(image,"%%BeginProlog\n"); for (q=PostscriptProlog; *q; q++) { (void) WriteBlobString(image,*q); (void) WriteBlobByte(image,'\n'); } /* One label line for each line in label string. */ value=GetImageProperty(image,"label"); if (value != (const char *) NULL) { (void) WriteBlobString(image,"\n %% Labels.\n /Helvetica " " findfont pointsize scalefont setfont\n"); for (i=(long) MultilineCensus(value)-1; i >= 0; i--) { (void) WriteBlobString(image, " currentfile buffer readline pop token pop\n"); (void) FormatMagickString(buffer,MaxTextExtent, " 0 y %g add moveto show pop\n",i*pointsize+12); (void) WriteBlobString(image,buffer); } } /* The static postscript procedures epilog. */ for (q=PostscriptEpilog; *q; q++) { (void) WriteBlobString(image,*q); (void) WriteBlobByte(image,'\n'); } (void)WriteBlobString(image,"%%EndProlog\n"); } (void) FormatMagickString(buffer,MaxTextExtent,"%%%%Page: 1 %lu\n",page); (void) WriteBlobString(image,buffer); /* Page bounding box. */ (void) FormatMagickString(buffer,MaxTextExtent, "%%%%PageBoundingBox: %ld %ld %ld %ld\n",geometry.x,geometry.y,geometry.x+ (long) geometry.width,geometry.y+(long) (geometry.height+text_size)); (void) WriteBlobString(image,buffer); /* Page process colors if not RGB. */ if (image->colorspace == CMYKColorspace) (void) WriteBlobString(image, "%%PageProcessColors: Cyan Magenta Yellow Black\n"); else if (IsGrayImage(image,&image->exception) != MagickFalse) (void) WriteBlobString(image,"%%PageProcessColors: Black\n"); /* Adjust document bounding box to bound page bounding box. */ if ((double) geometry.x < bounds.x1) bounds.x1=(double) geometry.x; if ((double) geometry.y < bounds.y1) bounds.y1=(double) geometry.y; if ((double) (geometry.x+scale.x) > bounds.x2) bounds.x2=(double) geometry.x+scale.x; if ((double) (geometry.y+scale.y+text_size) > bounds.y2) bounds.y2=(double) geometry.y+scale.y+text_size; /* Page font resource if there's a label. */ value=GetImageProperty(image,"label"); if (value != (const char *) NULL) (void) WriteBlobString(image,"%%PageResources: font Helvetica\n"); /* PS clipping path from Photoshop clipping path. */ if ((image->clip_mask == (Image *) NULL) || (LocaleNCompare("8BIM:",image->clip_mask->magick_filename,5) != 0)) (void) WriteBlobString(image,"/ClipImage {} def\n"); else { const char *value; value=GetImageProperty(image,image->clip_mask->magick_filename); if (value == (const char *) NULL) return(MagickFalse); (void) WriteBlobString(image,value); (void) WriteBlobByte(image,'\n'); } /* Push a dictionary for our own def's if this an EPS. */ if (LocaleCompare(image_info->magick,"PS3") != 0) (void) WriteBlobString(image,"userdict begin\n"); /* Image mask. */ if ((image->matte != MagickFalse) && (WritePS3MaskImage(image_info,image,compression) == MagickFalse)) { (void) CloseBlob(image); return(MagickFalse); } /* Remember position of BeginData comment so we can update it. */ start=TellBlob(image); (void) FormatMagickString(buffer,MaxTextExtent, "%%%%BeginData:%13ld %s Bytes\n",0L, compression == NoCompression ? "ASCII" : "BINARY"); (void) WriteBlobString(image,buffer); stop=TellBlob(image); (void) WriteBlobString(image,"DisplayImage\n"); /* Translate, scale, and font point size. */ (void) FormatMagickString(buffer,MaxTextExtent,"%ld %ld\n%g %g\n%f\n", geometry.x,geometry.y,scale.x,scale.y,pointsize); (void) WriteBlobString(image,buffer); /* Output labels. */ labels=(char **) NULL; value=GetImageProperty(image,"label"); if (value != (const char *) NULL) labels=StringToList(value); if (labels != (char **) NULL) { for (i=0; labels[i] != (char *) NULL; i++) { if (compression != NoCompression) { for (j=0; labels[i][j] != '\0'; j++) (void) WriteBlobByte(image,(unsigned char) labels[i][j]); (void) WriteBlobByte(image,'\n'); } else { (void) WriteBlobString(image,"<~"); Ascii85Initialize(image); for (j=0; labels[i][j] != '\0'; j++) Ascii85Encode(image,(unsigned char) labels[i][j]); Ascii85Flush(image); } labels[i]=DestroyString(labels[i]); } labels=(char **) RelinquishMagickMemory(labels); } /* Photoshop clipping path active? */ if ((image->clip_mask != (Image *) NULL) && (LocaleNCompare("8BIM:",image->clip_mask->magick_filename,5) == 0)) (void) WriteBlobString(image,"true\n"); else (void) WriteBlobString(image,"false\n"); /* Showpage for non-EPS. */ (void) WriteBlobString(image, LocaleCompare(image_info->magick,"PS3") == 0 ? "true\n" : "false\n"); /* Image columns, rows, and color space. */ (void) FormatMagickString(buffer,MaxTextExtent,"%lu %lu\n%s\n", image->columns,image->rows,image->colorspace == CMYKColorspace ? PS3_CMYKColorspace : PS3_RGBColorspace); (void) WriteBlobString(image,buffer); /* Masked image? */ (void) WriteBlobString(image,image->matte != MagickFalse ? "true\n" : "false\n"); /* Render with imagemask operator? */ option=GetImageOption(image_info,"ps3:imagemask"); (void) WriteBlobString(image,((option != (const char *) NULL) && (IsMonochromeImage(image,&image->exception) != MagickFalse)) ? "true\n" : "false\n"); /* Output pixel data. */ pixels=(unsigned char *) NULL; length=0; if ((image_info->type != TrueColorType) && (image_info->type != TrueColorMatteType) && (image_info->type != ColorSeparationType) && (image_info->type != ColorSeparationMatteType) && (image->colorspace != CMYKColorspace) && ((IsGrayImage(image,&image->exception) != MagickFalse) || (IsMonochromeImage(image,&image->exception) != MagickFalse))) { /* Gray images. */ (void) WriteBlobString(image,PS3_PseudoClass"\n"); switch (compression) { case NoCompression: default: { (void) WriteBlobString(image,PS3_NoCompression"\n"); break; } case FaxCompression: case Group4Compression: { (void) WriteBlobString(image,PS3_FaxCompression"\n"); break; } case JPEGCompression: { (void) WriteBlobString(image,PS3_JPEGCompression"\n"); break; } case LZWCompression: { (void) WriteBlobString(image,PS3_LZWCompression"\n"); break; } case RLECompression: { (void) WriteBlobString(image,PS3_RLECompression"\n"); break; } case ZipCompression: { (void) WriteBlobString(image,PS3_ZipCompression"\n"); break; } } /* Number of colors -- 0 for single component non-color mapped data. */ (void) WriteBlobString(image,"0\n"); /* 1 bit or 8 bit components? */ (void) FormatMagickString(buffer,MaxTextExtent,"%d\n", IsMonochromeImage(image,&image->exception) != MagickFalse ? 1 : 8); (void) WriteBlobString(image,buffer); /* Image data. */ if (compression == JPEGCompression) status=InjectImageBlob(image_info,image,image,"jpeg", &image->exception); else if ((compression == FaxCompression) || (compression == Group4Compression)) { if (LocaleCompare(CCITTParam,"0") == 0) status=HuffmanEncodeImage(image_info,image,image); else status=Huffman2DEncodeImage(image_info,image,image); } else { status=SerializeImageChannel(image_info,image,&pixels,&length); if (status == MagickFalse) { (void) CloseBlob(image); return(MagickFalse); } switch (compression) { case NoCompression: default: { Ascii85Initialize(image); for (i=0; i < (long) length; i++) Ascii85Encode(image,pixels[i]); Ascii85Flush(image); status=MagickTrue; break; } case LZWCompression: { status=LZWEncodeImage(image,length,pixels); break; } case RLECompression: { status=PackbitsEncodeImage(image,length,pixels); break; } case ZipCompression: { status=ZLIBEncodeImage(image,length,pixels); break; } } pixels=(unsigned char *) RelinquishMagickMemory(pixels); } } else if ((image->storage_class == DirectClass) || (image->colors > 256) || (compression == JPEGCompression)) { /* Truecolor image. */ (void) WriteBlobString(image,PS3_DirectClass"\n"); switch (compression) { case NoCompression: default: { (void) WriteBlobString(image,PS3_NoCompression"\n"); break; } case RLECompression: { (void) WriteBlobString(image,PS3_RLECompression"\n"); break; } case JPEGCompression: { (void) WriteBlobString(image,PS3_JPEGCompression"\n"); break; } case LZWCompression: { (void) WriteBlobString(image,PS3_LZWCompression"\n"); break; } case ZipCompression: { (void) WriteBlobString(image,PS3_ZipCompression"\n"); break; } } /* Image data. */ if (compression == JPEGCompression) status=InjectImageBlob(image_info,image,image,"jpeg", &image->exception); else { /* Stream based compressions. */ status=SerializeImage(image_info,image,&pixels,&length); if (status == MagickFalse) { (void) CloseBlob(image); return(MagickFalse); } switch (compression) { case NoCompression: default: { Ascii85Initialize(image); for (i=0; i < (long) length; i++) Ascii85Encode(image,pixels[i]); Ascii85Flush(image); status=MagickTrue; break; } case RLECompression: { status=PackbitsEncodeImage(image,length,pixels); break; } case LZWCompression: { status=LZWEncodeImage(image,length,pixels); break; } case ZipCompression: { status=ZLIBEncodeImage(image,length,pixels); break; } } pixels=(unsigned char *) RelinquishMagickMemory(pixels); } } else { /* Colormapped images. */ (void) WriteBlobString(image,PS3_PseudoClass"\n"); switch (compression) { case NoCompression: default: { (void) WriteBlobString(image,PS3_NoCompression"\n"); break; } case JPEGCompression: { (void) WriteBlobString(image,PS3_JPEGCompression"\n"); break; } case RLECompression: { (void) WriteBlobString(image,PS3_RLECompression"\n"); break; } case LZWCompression: { (void) WriteBlobString(image,PS3_LZWCompression"\n"); break; } case ZipCompression: { (void) WriteBlobString(image,PS3_ZipCompression"\n"); break; } } /* Number of colors in color map. */ (void) FormatMagickString(buffer,MaxTextExtent,"%lu\n", image->colors); (void) WriteBlobString(image,buffer); /* Color map - uncompressed. */ if ((compression != NoCompression) && (compression != UndefinedCompression)) { for (i=0; i < (long) image->colors; i++) { pixel=ScaleQuantumToChar(image->colormap[i].red); (void) WriteBlobByte(image,(unsigned char) pixel); pixel=ScaleQuantumToChar(image->colormap[i].green); (void) WriteBlobByte(image,(unsigned char) pixel); pixel=ScaleQuantumToChar(image->colormap[i].blue); (void) WriteBlobByte(image,(unsigned char) pixel); } } else { Ascii85Initialize(image); for (i=0; i < (long) image->colors; i++) { pixel=ScaleQuantumToChar(image->colormap[i].red); Ascii85Encode(image,(unsigned char) pixel); pixel=ScaleQuantumToChar(image->colormap[i].green); Ascii85Encode(image,(unsigned char) pixel); pixel=ScaleQuantumToChar(image->colormap[i].blue); Ascii85Encode(image,(unsigned char) pixel); } Ascii85Flush(image); } status=SerializeImageIndexes(image_info,image,&pixels,&length); if (status == MagickFalse) { (void) CloseBlob(image); return(MagickFalse); } switch (compression) { case NoCompression: default: { Ascii85Initialize(image); for (i=0; i < (long) length; i++) Ascii85Encode(image,pixels[i]); Ascii85Flush(image); status=MagickTrue; break; } case JPEGCompression: { status=InjectImageBlob(image_info,image,image,"jpeg", &image->exception); break; } case RLECompression: { status=PackbitsEncodeImage(image,length,pixels); break; } case LZWCompression: { status=LZWEncodeImage(image,length,pixels); break; } case ZipCompression: { status=ZLIBEncodeImage(image,length,pixels); break; } } pixels=(unsigned char *) RelinquishMagickMemory(pixels); } (void) WriteBlobByte(image,'\n'); if (status == MagickFalse) { (void) CloseBlob(image); return(MagickFalse); } /* Update BeginData now that we know the data size. */ length=(size_t) (TellBlob(image)-stop); stop=TellBlob(image); offset=SeekBlob(image,start,SEEK_SET); if (offset < 0) ThrowWriterException(CorruptImageError,"ImproperImageHeader"); (void) FormatMagickString(buffer,MaxTextExtent, "%%%%BeginData:%13ld %s Bytes\n",(long) length, compression == NoCompression ? "ASCII" : "BINARY"); (void) WriteBlobString(image,buffer); offset=SeekBlob(image,stop,SEEK_SET); (void) WriteBlobString(image,"%%EndData\n"); /* End private dictionary if this an EPS. */ if (LocaleCompare(image_info->magick,"PS3") != 0) (void) WriteBlobString(image,"end\n"); (void) WriteBlobString(image,"%%PageTrailer\n"); if (GetNextImageInList(image) == (Image *) NULL) break; image=SyncNextImageInList(image); status=SetImageProgress(image,SaveImagesTag,scene++, GetImageListLength(image)); if (status == MagickFalse) break; } while (image_info->adjoin != MagickFalse); (void) WriteBlobString(image,"%%Trailer\n"); if (page > 1) { (void) FormatMagickString(buffer,MaxTextExtent, "%%%%BoundingBox: %g %g %g %g\n",floor(bounds.x1+0.5), floor(bounds.y1+0.5),ceil(bounds.x2-0.5),ceil(bounds.y2-0.5)); (void) WriteBlobString(image,buffer); (void) FormatMagickString(buffer,MaxTextExtent, "%%%%HiResBoundingBox: %g %g %g %g\n",bounds.x1,bounds.y1, bounds.x2,bounds.y2); (void) WriteBlobString(image,buffer); } (void) WriteBlobString(image,"%%EOF\n"); (void) CloseBlob(image); return(MagickTrue); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % L i s t M a g i c k I n f o % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ListMagickInfo() lists the image formats to a file. % % The format of the ListMagickInfo method is: % % MagickPassFail ListMagickInfo(FILE *file,ExceptionInfo *exception) % % A description of each parameter follows. % % o file: A file handle. % % o exception: Return any errors or warnings in this structure. % % */ MagickExport MagickPassFail ListMagickInfo(FILE *file,ExceptionInfo *exception) { MagickInfo **magick_array; int i; if (file == (FILE *) NULL) file=stdout; magick_array=GetMagickInfoArray(exception); if (!magick_array) return False; (void) fprintf(file," Format L Mode Description\n"); (void) fprintf(file,"--------------------------------------------------------" "------------------------\n"); for (i=0; magick_array[i] != 0; i++) { if (magick_array[i]->stealth) continue; (void) fprintf(file,"%9s %c %c%c%c", magick_array[i]->name ? magick_array[i]->name : "", (magick_array[i]->coder_class == PrimaryCoderClass ? 'P' : (magick_array[i]->coder_class == StableCoderClass ? 'S' : 'U')), (magick_array[i]->decoder ? 'r' : '-'), (magick_array[i]->encoder ? 'w' : '-'), ((magick_array[i]->encoder && magick_array[i]->adjoin) ? '+' : '-')); if (magick_array[i]->description != (char *) NULL) (void) fprintf(file," %.1024s",magick_array[i]->description); if (magick_array[i]->version != (char *) NULL) (void) fprintf(file," (%.1024s)",magick_array[i]->version); (void) fprintf(file,"\n"); if (magick_array[i]->note != (char *) NULL) { char **text; text=StringToList(magick_array[i]->note); if (text != (char **) NULL) { register long j; for (j=0; text[j] != (char *) NULL; j++) { (void) fprintf(file," %.1024s\n",text[j]); MagickFreeMemory(text[j]); } MagickFreeMemory(text); } } } (void) fprintf(file,"\n Meaning of 'L': P=Primary, S=Stable, U=Unstable\n"); (void) fflush(file); MagickFreeMemory(magick_array); return(MagickPass); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % D e s c r i b e I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % DescribeImage() describes an image by printing its attributes to the file. % Attributes include the image width, height, size, and others. % % The format of the DescribeImage method is: % % void DescribeImage(Image *image,FILE *file,const MagickBool verbose) % % A description of each parameter follows: % % o image: The image. % % o file: The file, typically stdout. % % o verbose: A value other than zero prints more detailed information % about the image. Values greater than one enable counting the number of % colors in the image. % % */ MagickExport MagickPassFail DescribeImage(Image *image,FILE *file, const MagickBool verbose) { char color[MaxTextExtent], format[MaxTextExtent]; const unsigned char *profile; size_t profile_length; const ImageAttribute *attribute; const MagickInfo *magick_info; double elapsed_time, user_time; unsigned long columns, rows; magick_int64_t pixels_per_second; Image *p; long y; register long i, x; unsigned long count; assert(image != (Image *) NULL); assert(image->signature == MagickSignature); assert(file != (FILE *) NULL); elapsed_time=GetElapsedTime(&image->timer); user_time=GetUserTime(&image->timer); GetTimerInfo(&image->timer); if (!verbose) { /* Display summary info about the image. */ if (*image->magick_filename != '\0') if (LocaleCompare(image->magick_filename,image->filename) != 0) (void) fprintf(file,"%.1024s=>",image->magick_filename); if ((image->previous == (Image *) NULL) && (image->next == (Image *) NULL) && (image->scene == 0)) (void) fprintf(file,"%.1024s ",image->filename); else (void) fprintf(file,"%.1024s[%lu] ",image->filename,image->scene); (void) fprintf(file,"%.1024s ",image->magick); columns=image->columns; rows=image->rows; if ((image->magick_columns != 0) || (image->magick_rows != 0)) if ((image->magick_columns != image->columns) || (image->magick_rows != image->rows)) { columns=image->magick_columns; rows=image->magick_rows; (void) fprintf(file,"%lux%lu=>",image->magick_columns, image->magick_rows); } (void) fprintf(file,"%lux%lu%+ld%+ld ",image->columns,image->rows, image->page.x,image->page.y); if (image->storage_class == DirectClass) { (void) fprintf(file,"DirectClass "); if (image->total_colors != 0) { FormatSize(image->total_colors,format); (void) fprintf(file,"%.1024s ",format); } } else if (image->total_colors <= image->colors) (void) fprintf(file,"PseudoClass %uc ",image->colors); else { (void) fprintf(file,"PseudoClass %lu=>%uc ",image->total_colors, image->colors); (void) fprintf(file,"%ld/%.6f/%.6fe ", (long) image->error.mean_error_per_pixel, image->error.normalized_mean_error, image->error.normalized_maximum_error); } (void) fprintf(file,"%u-bit ",image->depth); if (GetBlobSize(image) != 0) { FormatSize(GetBlobSize(image),format); (void) fprintf(file,"%.1024s ",format); } (void) fprintf(file,"%0.3fu %ld:%02ld",user_time, (long) (elapsed_time/60.0), (long) ceil(fmod(elapsed_time,60.0))); /* Only display pixel read rate if the time accumulated is at least six times the timer's resolution (typically 0.01 on Unix). */ if (elapsed_time >= GetTimerResolution()*6) { pixels_per_second=(magick_int64_t) ((double) rows*columns/ elapsed_time); FormatSize(pixels_per_second,format); (void) fprintf(file," (%s pixels/s)",format); } (void) fprintf(file,"\n"); return (ferror(file) ? MagickFail : MagickPass); } /* Display verbose info about the image. */ (void) SignatureImage(image); if (verbose > 1) image->total_colors=GetNumberColors(image,(FILE *) NULL,&image->exception); (void) fprintf(file,"Image: %.1024s\n",image->filename); magick_info=GetMagickInfo(image->magick,&image->exception); if ((magick_info == (const MagickInfo *) NULL) || (*magick_info->description == '\0')) (void) fprintf(file," Format: %.1024s\n",image->magick); else (void) fprintf(file," Format: %.1024s (%.1024s)\n",image->magick, magick_info->description); (void) fprintf(file," Geometry: %lux%lu\n",image->columns,image->rows); if (image->storage_class == DirectClass) (void) fprintf(file," Class: DirectClass\n"); else (void) fprintf(file," Class: PseudoClass\n"); if ((image->magick_columns != 0) || (image->magick_rows != 0)) if ((image->magick_columns != image->columns) || (image->magick_rows != image->rows)) (void) fprintf(file," Base geometry: %lux%lu\n",image->magick_columns, image->magick_rows); (void) fprintf(file," Type: "); switch (GetImageType(image,&image->exception)) { case BilevelType: (void) fprintf(file,"bilevel"); break; case GrayscaleType: (void) fprintf(file,"grayscale"); break; case GrayscaleMatteType: (void) fprintf(file,"grayscale with transparency"); break; case PaletteType: (void) fprintf(file,"palette"); break; case PaletteMatteType: (void) fprintf(file,"palette with transparency"); break; case TrueColorType: (void) fprintf(file,"true color"); break; case TrueColorMatteType: (void) fprintf(file,"true color with transparency"); break; case ColorSeparationType: (void) fprintf(file,"color separated"); break; case ColorSeparationMatteType: (void) fprintf(file,"color separated with transparency"); break; default: (void) fprintf(file,"undefined"); break; } (void) fprintf(file,"\n"); (void) fprintf(file," Depth: %lu bits-per-pixel component\n", GetImageDepth(image,&image->exception)); (void) fprintf(file," Channel Depths:\n"); if (image->colorspace == CMYKColorspace) { (void) fprintf(file," Cyan: %u bits\n", GetImageChannelDepth(image,CyanChannel,&image->exception)); (void) fprintf(file," Magenta: %u bits\n", GetImageChannelDepth(image,MagentaChannel,&image->exception)); (void) fprintf(file," Yellow: %u bits\n", GetImageChannelDepth(image,YellowChannel,&image->exception)); (void) fprintf(file," Black: %u bits\n", GetImageChannelDepth(image,BlackChannel,&image->exception)); } else if ((IsGrayColorspace(image->colorspace)) || (image->is_grayscale == True)) { (void) fprintf(file," Gray: %u bits\n", GetImageChannelDepth(image,RedChannel,&image->exception)); } else { (void) fprintf(file," Red: %u bits\n", GetImageChannelDepth(image,RedChannel,&image->exception)); (void) fprintf(file," Green: %u bits\n", GetImageChannelDepth(image,GreenChannel,&image->exception)); (void) fprintf(file," Blue: %u bits\n", GetImageChannelDepth(image,BlueChannel,&image->exception)); } if (image->matte) (void) fprintf(file," Opacity: %u bits\n", GetImageChannelDepth(image,OpacityChannel,&image->exception)); (void) fprintf(file," Channel Statistics:\n"); { ImageStatistics statistics; (void) GetImageStatistics(image,&statistics,&image->exception); if (image->colorspace == CMYKColorspace) { (void) fprintf(file," Cyan:\n"); (void) fprintf(file," Minimum: %13.02lf (%1.4f)\n", MaxRGB*statistics.red.minimum, statistics.red.minimum); (void) fprintf(file," Maximum: %13.02lf (%1.4f)\n", MaxRGB*statistics.red.maximum, statistics.red.maximum); (void) fprintf(file," Mean: %13.02lf (%1.4f)\n", MaxRGB*statistics.red.mean, statistics.red.mean); (void) fprintf(file," Standard Deviation: %13.02lf (%1.4f)\n", MaxRGB*statistics.red.standard_deviation, statistics.red.standard_deviation); (void) fprintf(file," Magenta:\n"); (void) fprintf(file," Minimum: %13.02lf (%1.4f)\n", MaxRGB*statistics.green.minimum, statistics.green.minimum); (void) fprintf(file," Maximum: %13.02lf (%1.4f)\n", MaxRGB*statistics.green.maximum, statistics.green.maximum); (void) fprintf(file," Mean: %13.02lf (%1.4f)\n", MaxRGB*statistics.green.mean, statistics.green.mean); (void) fprintf(file," Standard Deviation: %13.02lf (%1.4f)\n", MaxRGB*statistics.green.standard_deviation, statistics.green.standard_deviation); (void) fprintf(file," Yellow:\n"); (void) fprintf(file," Minimum: %13.02lf (%1.4f)\n", MaxRGB*statistics.blue.minimum, statistics.blue.minimum); (void) fprintf(file," Maximum: %13.02lf (%1.4f)\n", MaxRGB*statistics.blue.maximum, statistics.blue.maximum); (void) fprintf(file," Mean: %13.02lf (%1.4f)\n", MaxRGB*statistics.blue.mean, statistics.blue.mean); (void) fprintf(file," Standard Deviation: %13.02lf (%1.4f)\n", MaxRGB*statistics.blue.standard_deviation, statistics.blue.standard_deviation); (void) fprintf(file," Black:\n"); (void) fprintf(file," Minimum: %13.02lf (%1.4f)\n", MaxRGB*statistics.opacity.minimum, statistics.opacity.minimum); (void) fprintf(file," Maximum: %13.02lf (%1.4f)\n", MaxRGB*statistics.opacity.maximum, statistics.opacity.maximum); (void) fprintf(file," Mean: %13.02lf (%1.4f)\n", MaxRGB*statistics.opacity.mean, statistics.opacity.mean); (void) fprintf(file," Standard Deviation: %13.02lf (%1.4f)\n", MaxRGB*statistics.opacity.standard_deviation, statistics.opacity.standard_deviation); /* if (image->matte) (void) fprintf(file," Opacity:\n"); */ } else if ((IsGrayColorspace(image->colorspace)) || (image->is_grayscale == True)) { (void) fprintf(file," Gray:\n"); (void) fprintf(file," Minimum: %13.02lf (%1.4f)\n", MaxRGB*statistics.red.minimum, statistics.red.minimum); (void) fprintf(file," Maximum: %13.02lf (%1.4f)\n", MaxRGB*statistics.red.maximum, statistics.red.maximum); (void) fprintf(file," Mean: %13.02lf (%1.4f)\n", MaxRGB*statistics.red.mean, statistics.red.mean); (void) fprintf(file," Standard Deviation: %13.02lf (%1.4f)\n", MaxRGB*statistics.red.standard_deviation, statistics.red.standard_deviation); if (image->matte) { (void) fprintf(file," Opacity:\n"); (void) fprintf(file," Minimum: %13.02lf (%1.4f)\n", MaxRGB*statistics.opacity.minimum, statistics.opacity.minimum); (void) fprintf(file," Maximum: %13.02lf (%1.4f)\n", MaxRGB*statistics.opacity.maximum, statistics.opacity.maximum); (void) fprintf(file," Mean: %13.02lf (%1.4f)\n", MaxRGB*statistics.opacity.mean, statistics.opacity.mean); (void) fprintf(file," Standard Deviation: %13.02lf (%1.4f)\n", MaxRGB*statistics.opacity.standard_deviation, statistics.opacity.standard_deviation); } } else { (void) fprintf(file," Red:\n"); (void) fprintf(file," Minimum: %13.02lf (%1.4f)\n", MaxRGB*statistics.red.minimum, statistics.red.minimum); (void) fprintf(file," Maximum: %13.02lf (%1.4f)\n", MaxRGB*statistics.red.maximum, statistics.red.maximum); (void) fprintf(file," Mean: %13.02lf (%1.4f)\n", MaxRGB*statistics.red.mean, statistics.red.mean); (void) fprintf(file," Standard Deviation: %13.02lf (%1.4f)\n", MaxRGB*statistics.red.standard_deviation, statistics.red.standard_deviation); (void) fprintf(file," Green:\n"); (void) fprintf(file," Minimum: %13.02lf (%1.4f)\n", MaxRGB*statistics.green.minimum, statistics.green.minimum); (void) fprintf(file," Maximum: %13.02lf (%1.4f)\n", MaxRGB*statistics.green.maximum, statistics.green.maximum); (void) fprintf(file," Mean: %13.02lf (%1.4f)\n", MaxRGB*statistics.green.mean, statistics.green.mean); (void) fprintf(file," Standard Deviation: %13.02lf (%1.4f)\n", MaxRGB*statistics.green.standard_deviation, statistics.green.standard_deviation); (void) fprintf(file," Blue:\n"); (void) fprintf(file," Minimum: %13.02lf (%1.4f)\n", MaxRGB*statistics.blue.minimum, statistics.blue.minimum); (void) fprintf(file," Maximum: %13.02lf (%1.4f)\n", MaxRGB*statistics.blue.maximum, statistics.blue.maximum); (void) fprintf(file," Mean: %13.02lf (%1.4f)\n", MaxRGB*statistics.blue.mean, statistics.blue.mean); (void) fprintf(file," Standard Deviation: %13.02lf (%1.4f)\n", MaxRGB*statistics.blue.standard_deviation, statistics.blue.standard_deviation); if (image->matte) { (void) fprintf(file," Opacity:\n"); (void) fprintf(file," Minimum: %13.02lf (%1.4f)\n", MaxRGB*statistics.opacity.minimum, statistics.opacity.minimum); (void) fprintf(file," Maximum: %13.02lf (%1.4f)\n", MaxRGB*statistics.opacity.maximum, statistics.opacity.maximum); (void) fprintf(file," Mean: %13.02lf (%1.4f)\n", MaxRGB*statistics.opacity.mean, statistics.opacity.mean); (void) fprintf(file," Standard Deviation: %13.02lf (%1.4f)\n", MaxRGB*statistics.opacity.standard_deviation, statistics.opacity.standard_deviation); } } } x=0; p=(Image *) NULL; if ((image->matte && (strcmp(image->magick,"GIF") != 0)) || image->taint) { char tuple[MaxTextExtent]; register const PixelPacket *p; p=(PixelPacket *) NULL; for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; for (x=0; x < (long) image->columns; x++) { if (p->opacity == TransparentOpacity) break; p++; } if (x < (long) image->columns) break; } if ((x < (long) image->columns) || (y < (long) image->rows)) { GetColorTuple(p,image->depth,image->matte,False,tuple); (void) fprintf(file," Opacity: %.1024s\t",tuple); GetColorTuple(p,image->depth,image->matte,True,tuple); (void) fprintf(file," %.1024s\n",tuple); } } if (image->storage_class == DirectClass) { if (image->total_colors != 0) (void) fprintf(file," Colors: %lu\n",image->total_colors); } else { if (image->total_colors <= image->colors) (void) fprintf(file," Colors: %u\n",image->colors); else (void) fprintf(file," Colors: %lu=>%u\n",image->total_colors, image->colors); } if (image->storage_class == DirectClass) { if (image->total_colors < 1024) if (verbose > 1) (void) GetNumberColors(image,file,&image->exception); } else { char name[MaxTextExtent]; register PixelPacket *p; /* Display image colormap. */ p=image->colormap; for (i=0; i < (long) image->colors; i++) { char tuple[MaxTextExtent]; GetColorTuple(p,image->depth,image->matte,False,tuple); (void) fprintf(file," %lu: %.1024s",i,tuple); (void) fprintf(file,"\t"); (void) QueryColorname(image,p,SVGCompliance,name,&image->exception); (void) fprintf(file," %.1024s",name); (void) fprintf(file,"\n"); p++; } } if (image->error.mean_error_per_pixel != 0.0) (void) fprintf(file," Mean Exception Per Pixel: %ld\n", (long) image->error.mean_error_per_pixel); if (image->error.normalized_mean_error != 0.0) (void) fprintf(file," Normalized Mean Exception: %g\n", image->error.normalized_mean_error); if (image->error.normalized_maximum_error != 0.0) (void) fprintf(file," Normalized Maximum Exception: %gn", image->error.normalized_maximum_error); if (image->rendering_intent == SaturationIntent) (void) fprintf(file," Rendering-Intent: saturation\n"); else if (image->rendering_intent == PerceptualIntent) (void) fprintf(file," Rendering-Intent: perceptual\n"); else if (image->rendering_intent == AbsoluteIntent) (void) fprintf(file," Rendering-Intent: absolute\n"); else if (image->rendering_intent == RelativeIntent) (void) fprintf(file," Rendering-Intent: relative\n"); if (image->gamma != 0.0) (void) fprintf(file," Gamma: %g\n",image->gamma); if ((image->chromaticity.red_primary.x != 0.0) || (image->chromaticity.green_primary.x != 0.0) || (image->chromaticity.blue_primary.x != 0.0) || (image->chromaticity.white_point.x != 0.0)) { /* Display image chromaticity. */ (void) fprintf(file," Chromaticity:\n"); (void) fprintf(file," red primary: (%g,%g)\n", image->chromaticity.red_primary.x,image->chromaticity.red_primary.y); (void) fprintf(file," green primary: (%g,%g)\n", image->chromaticity.green_primary.x, image->chromaticity.green_primary.y); (void) fprintf(file," blue primary: (%g,%g)\n", image->chromaticity.blue_primary.x,image->chromaticity.blue_primary.y); (void) fprintf(file," white point: (%g,%g)\n", image->chromaticity.white_point.x,image->chromaticity.white_point.y); } if ((image->tile_info.width*image->tile_info.height) != 0) (void) fprintf(file," Tile geometry: %lux%lu%+ld%+ld\n", image->tile_info.width,image->tile_info.height,image->tile_info.x, image->tile_info.y); if ((image->x_resolution != 0.0) && (image->y_resolution != 0.0)) { /* Display image resolution. */ (void) fprintf(file," Resolution: %gx%g",image->x_resolution, image->y_resolution); if (image->units == UndefinedResolution) (void) fprintf(file," pixels\n"); else if (image->units == PixelsPerInchResolution) (void) fprintf(file," pixels/inch\n"); else if (image->units == PixelsPerCentimeterResolution) (void) fprintf(file," pixels/centimeter\n"); else (void) fprintf(file,"\n"); } FormatSize(GetBlobSize(image),format); (void) fprintf(file," Filesize: %.1024s\n",format); fprintf(file," Interlace: %s\n", InterlaceTypeToString(image->interlace == UndefinedInterlace ? NoInterlace : image->interlace)); (void) fprintf(file," Orientation: %s\n", OrientationTypeToString(image->orientation)); (void) QueryColorname(image,&image->background_color,SVGCompliance,color, &image->exception); (void) fprintf(file," Background Color: %.1024s\n",color); (void) QueryColorname(image,&image->border_color,SVGCompliance,color, &image->exception); (void) fprintf(file," Border Color: %.1024s\n",color); (void) QueryColorname(image,&image->matte_color,SVGCompliance,color, &image->exception); (void) fprintf(file," Matte Color: %.1024s\n",color); if ((image->page.width != 0) && (image->page.height != 0)) (void) fprintf(file," Page geometry: %lux%lu%+ld%+ld\n",image->page.width, image->page.height,image->page.x,image->page.y); (void) fprintf(file," Compose: %s\n", CompositeOperatorToString(image->compose)); (void) fprintf(file," Dispose: "); switch (image->dispose) { case UndefinedDispose: (void) fprintf(file,"Undefined\n"); break; case NoneDispose: (void) fprintf(file,"None\n"); break; case BackgroundDispose: (void) fprintf(file,"Background\n"); break; case PreviousDispose: (void) fprintf(file,"Previous\n"); break; default: (void) fprintf(file,"\n"); break; } if (image->delay != 0) (void) fprintf(file," Delay: %lu\n",image->delay); if (image->iterations != 1) (void) fprintf(file," Iterations: %lu\n",image->iterations); p=image; while (p->previous != (Image *) NULL) p=p->previous; for (count=1; p->next != (Image *) NULL; count++) p=p->next; if (count > 1) (void) fprintf(file," Scene: %lu of %lu\n",image->scene,count); else if (image->scene != 0) (void) fprintf(file," Scene: %lu\n",image->scene); (void) fprintf(file," Compression: %s\n", CompressionTypeToString(image->compression)); /* Display formatted image attributes. This must happen before we access any pseudo attributes like EXIF since doing so causes real attributes to be created and we would get duplicates in the output. */ attribute=GetImageAttribute(image,(char *) NULL); { for ( ; attribute != (const ImageAttribute *) NULL; attribute=attribute->next) { if (LocaleNCompare("EXIF",attribute->key,4) != 0) { (void) fprintf(file," %c", toupper((int)attribute->key[0])); if (strlen(attribute->key) > 1) (void) fprintf(file,"%.1024s",attribute->key+1); (void) fprintf(file,": "); (void) fprintf(file,"%s\n",attribute->value); } } } if((profile=GetImageProfile(image,"ICM",&profile_length)) != 0) (void) fprintf(file," Profile-color: %lu bytes\n",(unsigned long) profile_length); if((profile=GetImageProfile(image,"IPTC",&profile_length)) != 0) { char *tag, *text; size_t length; /* Describe IPTC data. */ (void) fprintf(file," Profile-iptc: %lu bytes\n",(unsigned long) profile_length); for (i=0; i < (long) profile_length; ) { if (profile[i] != 0x1c) { i++; continue; } i++; /* skip file separator */ i++; /* skip record number */ switch (profile[i]) { case 5: tag=(char *) "Image Name"; break; case 7: tag=(char *) "Edit Status"; break; case 10: tag=(char *) "Priority"; break; case 15: tag=(char *) "Category"; break; case 20: tag=(char *) "Supplemental Category"; break; case 22: tag=(char *) "Fixture Identifier"; break; case 25: tag=(char *) "Keyword"; break; case 30: tag=(char *) "Release Date"; break; case 35: tag=(char *) "Release Time"; break; case 40: tag=(char *) "Special Instructions"; break; case 45: tag=(char *) "Reference Service"; break; case 47: tag=(char *) "Reference Date"; break; case 50: tag=(char *) "Reference Number"; break; case 55: tag=(char *) "Created Date"; break; case 60: tag=(char *) "Created Time"; break; case 65: tag=(char *) "Originating Program"; break; case 70: tag=(char *) "Program Version"; break; case 75: tag=(char *) "Object Cycle"; break; case 80: tag=(char *) "Byline"; break; case 85: tag=(char *) "Byline Title"; break; case 90: tag=(char *) "City"; break; case 95: tag=(char *) "Province State"; break; case 100: tag=(char *) "Country Code"; break; case 101: tag=(char *) "Country"; break; case 103: tag=(char *) "Original Transmission Reference"; break; case 105: tag=(char *) "Headline"; break; case 110: tag=(char *) "Credit"; break; case 115: tag=(char *) "Source"; break; case 116: tag=(char *) "Copyright String"; break; case 120: tag=(char *) "Caption"; break; case 121: tag=(char *) "Local Caption"; break; case 122: tag=(char *) "Caption Writer"; break; case 200: tag=(char *) "Custom Field 1"; break; case 201: tag=(char *) "Custom Field 2"; break; case 202: tag=(char *) "Custom Field 3"; break; case 203: tag=(char *) "Custom Field 4"; break; case 204: tag=(char *) "Custom Field 5"; break; case 205: tag=(char *) "Custom Field 6"; break; case 206: tag=(char *) "Custom Field 7"; break; case 207: tag=(char *) "Custom Field 8"; break; case 208: tag=(char *) "Custom Field 9"; break; case 209: tag=(char *) "Custom Field 10"; break; case 210: tag=(char *) "Custom Field 11"; break; case 211: tag=(char *) "Custom Field 12"; break; case 212: tag=(char *) "Custom Field 13"; break; case 213: tag=(char *) "Custom Field 14"; break; case 214: tag=(char *) "Custom Field 15"; break; case 215: tag=(char *) "Custom Field 16"; break; case 216: tag=(char *) "Custom Field 17"; break; case 217: tag=(char *) "Custom Field 18"; break; case 218: tag=(char *) "Custom Field 19"; break; case 219: tag=(char *) "Custom Field 20"; break; default: tag=(char *) "unknown"; break; } i++; (void) fprintf(file," %.1024s:\n",tag); length=profile[i++] << 8; length|=profile[i++]; text=MagickAllocateMemory(char *,length+1); if (text != (char *) NULL) { char **textlist; register long j; (void) strncpy(text,(char *) profile+i,length); text[length]='\0'; textlist=StringToList(text); if (textlist != (char **) NULL) { for (j=0; textlist[j] != (char *) NULL; j++) { (void) fprintf(file," %s\n",textlist[j]); MagickFreeMemory(textlist[j]); } MagickFreeMemory(textlist); } MagickFreeMemory(text); } i+=length; } }