2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13 % Read/Write Portable Document Format %
20 % Copyright 1999-2010 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
26 % http://www.imagemagick.org/script/license.php %
28 % Unless required by applicable law or agreed to in writing, software %
29 % distributed under the License is distributed on an "AS IS" BASIS, %
30 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31 % See the License for the specific language governing permissions and %
32 % limitations under the License. %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
42 #include "magick/studio.h"
43 #include "magick/blob.h"
44 #include "magick/blob-private.h"
45 #include "magick/cache.h"
46 #include "magick/color.h"
47 #include "magick/color-private.h"
48 #include "magick/colorspace.h"
49 #include "magick/compress.h"
50 #include "magick/constitute.h"
51 #include "magick/delegate.h"
52 #include "magick/delegate-private.h"
53 #include "magick/draw.h"
54 #include "magick/exception.h"
55 #include "magick/exception-private.h"
56 #include "magick/geometry.h"
57 #include "magick/image.h"
58 #include "magick/image-private.h"
59 #include "magick/list.h"
60 #include "magick/magick.h"
61 #include "magick/memory_.h"
62 #include "magick/monitor.h"
63 #include "magick/monitor-private.h"
64 #include "magick/option.h"
65 #include "magick/profile.h"
66 #include "magick/property.h"
67 #include "magick/quantum-private.h"
68 #include "magick/resource_.h"
69 #include "magick/resize.h"
70 #include "magick/static.h"
71 #include "magick/string_.h"
72 #include "magick/module.h"
73 #include "magick/transform.h"
74 #include "magick/utility.h"
75 #include "magick/module.h"
80 #if defined(MAGICKCORE_TIFF_DELEGATE)
81 #define CCITTParam "-1"
83 #define CCITTParam "0"
89 static MagickBooleanType
90 WritePDFImage(const ImageInfo *,Image *);
93 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
97 % I n v o k e P D F D e l e g a t e %
101 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
103 % InvokePDFDelegate() executes the PDF interpreter with the specified command.
105 % The format of the InvokePDFDelegate method is:
107 % MagickBooleanType InvokePDFDelegate(const MagickBooleanType verbose,
108 % const char *command,ExceptionInfo *exception)
110 % A description of each parameter follows:
112 % o verbose: A value other than zero displays the command prior to
115 % o command: the address of a character string containing the command to
118 % o exception: return any errors or warnings in this structure.
121 static MagickBooleanType InvokePDFDelegate(const MagickBooleanType verbose,
122 const char *command,ExceptionInfo *exception)
127 #if defined(MAGICKCORE_GS_DELEGATE) || defined(__WINDOWS__)
144 #if defined(__WINDOWS__)
145 ghost_info=NTGhostscriptDLLVectors();
150 ghost_info=(&ghost_info_struct);
151 (void) ResetMagickMemory(&ghost_info,0,sizeof(ghost_info));
152 ghost_info_struct.new_instance=(int (*)(gs_main_instance **,void *))
154 ghost_info_struct.init_with_args=(int (*)(gs_main_instance *,int,char **))
155 gsapi_init_with_args;
156 ghost_info_struct.run_string=(int (*)(gs_main_instance *,const char *,int,
157 int *)) gsapi_run_string;
158 ghost_info_struct.delete_instance=(void (*)(gs_main_instance *))
159 gsapi_delete_instance;
160 ghost_info_struct.exit=(int (*)(gs_main_instance *)) gsapi_exit;
162 if (ghost_info == (GhostInfo *) NULL)
164 status=SystemCommand(MagickFalse,verbose,command,exception);
165 return(status == 0 ? MagickTrue : MagickFalse);
167 if (verbose != MagickFalse)
169 (void) fputs("[ghostscript library]",stdout);
170 (void) fputs(strchr(command,' '),stdout);
172 status=(ghost_info->new_instance)(&interpreter,(void *) NULL);
175 status=SystemCommand(MagickFalse,verbose,command,exception);
176 return(status == 0 ? MagickTrue : MagickFalse);
178 argv=StringToArgv(command,&argc);
179 status=(ghost_info->init_with_args)(interpreter,argc-1,argv+1);
181 status=(ghost_info->run_string)(interpreter,"systemdict /start get exec\n",
183 (ghost_info->exit)(interpreter);
184 (ghost_info->delete_instance)(interpreter);
185 #if defined(__WINDOWS__)
186 NTGhostscriptUnLoadDLL();
188 for (i=0; i < (long) argc; i++)
189 argv[i]=DestroyString(argv[i]);
190 argv=(char **) RelinquishMagickMemory(argv);
191 if ((status != 0) && (status != -101))
196 message=GetExceptionMessage(errno);
197 (void) ThrowMagickException(exception,GetMagickModule(),DelegateError,
198 "`%s': %s",command,message);
199 message=DestroyString(message);
200 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
201 "Ghostscript returns status %d, exit code %d",status,code);
206 status=SystemCommand(MagickFalse,verbose,command,exception);
207 return(status == 0 ? MagickTrue : MagickFalse);
212 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
220 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
222 % IsPDF() returns MagickTrue if the image format type, identified by the
223 % magick string, is PDF.
225 % The format of the IsPDF method is:
227 % MagickBooleanType IsPDF(const unsigned char *magick,const size_t offset)
229 % A description of each parameter follows:
231 % o magick: compare image format pattern against these bytes.
233 % o offset: Specifies the offset of the magick string.
236 static MagickBooleanType IsPDF(const unsigned char *magick,const size_t offset)
240 if (LocaleNCompare((const char *) magick,"%PDF-",5) == 0)
246 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
250 % R e a d P D F I m a g e %
254 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
256 % ReadPDFImage() reads a Portable Document Format image file and
257 % returns it. It allocates the memory necessary for the new Image structure
258 % and returns a pointer to the new image.
260 % The format of the ReadPDFImage method is:
262 % Image *ReadPDFImage(const ImageInfo *image_info,ExceptionInfo *exception)
264 % A description of each parameter follows:
266 % o image_info: the image info.
268 % o exception: return any errors or warnings in this structure.
272 static MagickBooleanType IsPDFRendered(const char *path)
280 if ((path == (const char *) NULL) || (*path == '\0'))
282 status=GetPathAttributes(path,&attributes);
283 if ((status != MagickFalse) && S_ISREG(attributes.st_mode) &&
284 (attributes.st_size > 0))
289 static Image *ReadPDFImage(const ImageInfo *image_info,ExceptionInfo *exception)
291 #define CropBox "CropBox"
292 #define DeviceCMYK "DeviceCMYK"
293 #define ICCBased "ICCBased"
294 #define MediaBox "MediaBox"
295 #define RenderPostscriptText "Rendering Postscript... "
296 #define PDFRotate "Rotate"
297 #define SpotColor "Separation"
298 #define TrimBox "TrimBox"
299 #define PDFVersion "PDF-"
302 command[MaxTextExtent],
303 density[MaxTextExtent],
304 filename[MaxTextExtent],
305 geometry[MaxTextExtent],
306 options[MaxTextExtent],
307 input_filename[MaxTextExtent],
308 postscript_filename[MaxTextExtent];
366 assert(image_info != (const ImageInfo *) NULL);
367 assert(image_info->signature == MagickSignature);
368 if (image_info->debug != MagickFalse)
369 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
370 image_info->filename);
371 assert(exception != (ExceptionInfo *) NULL);
372 assert(exception->signature == MagickSignature);
376 image=AcquireImage(image_info);
377 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
378 if (status == MagickFalse)
380 image=DestroyImageList(image);
381 return((Image *) NULL);
383 status=AcquireUniqueSymbolicLink(image_info->filename,input_filename);
384 if (status == MagickFalse)
386 ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
387 image_info->filename);
388 image=DestroyImageList(image);
389 return((Image *) NULL);
392 Set the page density.
394 delta.x=DefaultResolution;
395 delta.y=DefaultResolution;
396 if ((image->x_resolution == 0.0) || (image->y_resolution == 0.0))
398 flags=ParseGeometry(PSDensityGeometry,&geometry_info);
399 image->x_resolution=geometry_info.rho;
400 image->y_resolution=geometry_info.sigma;
401 if ((flags & SigmaValue) == 0)
402 image->y_resolution=image->x_resolution;
405 Determine page geometry from the PDF media box.
407 cmyk=image_info->colorspace == CMYKColorspace ? MagickTrue : MagickFalse;
409 option=GetImageOption(image_info,"pdf:use-cropbox");
410 if (option != (const char *) NULL)
411 cropbox=IsMagickTrue(option);
413 option=GetImageOption(image_info,"pdf:use-trimbox");
414 if (option != (const char *) NULL)
415 trimbox=IsMagickTrue(option);
418 (void) ResetMagickMemory(&bounding_box,0,sizeof(bounding_box));
419 (void) ResetMagickMemory(&bounds,0,sizeof(bounds));
420 (void) ResetMagickMemory(&hires_bounds,0,sizeof(hires_bounds));
421 (void) ResetMagickMemory(&page,0,sizeof(page));
422 (void) ResetMagickMemory(command,0,sizeof(command));
427 for (c=ReadBlobByte(image); c != EOF; c=ReadBlobByte(image))
435 if ((c != (int) '/') && (c != (int) '%') &&
436 ((size_t) (p-command) < (MaxTextExtent-1)))
440 if (LocaleNCompare(PDFRotate,command,strlen(PDFRotate)) == 0)
441 count=(ssize_t) sscanf(command,"Rotate %lf",&angle);
443 Is this a CMYK document?
445 if (LocaleNCompare(DeviceCMYK,command,strlen(DeviceCMYK)) == 0)
447 if (LocaleNCompare(ICCBased,command,strlen(ICCBased)) == 0)
449 if (LocaleNCompare(SpotColor,command,strlen(SpotColor)) == 0)
453 property[MaxTextExtent],
462 (void) FormatMagickString(property,MaxTextExtent,"pdf:SpotColor-%lu",
465 for (c=ReadBlobByte(image); c != EOF; c=ReadBlobByte(image))
467 if ((isspace(c) != 0) || (c == '/') || ((i+1) == MaxTextExtent))
472 value=AcquireString(name);
473 (void) SubstituteString(&value,"#20"," ");
474 (void) SetImageProperty(image,property,value);
475 value=DestroyString(value);
478 if (LocaleNCompare(PDFVersion,command,strlen(PDFVersion)) == 0)
479 (void) SetImageProperty(image,"pdf:Version",command);
481 if (cropbox != MagickFalse)
483 if (LocaleNCompare(CropBox,command,strlen(CropBox)) == 0)
486 Note region defined by crop box.
488 count=(ssize_t) sscanf(command,"CropBox [%lf %lf %lf %lf",
489 &bounds.x1,&bounds.y1,&bounds.x2,&bounds.y2);
491 count=(ssize_t) sscanf(command,"CropBox[%lf %lf %lf %lf",
492 &bounds.x1,&bounds.y1,&bounds.x2,&bounds.y2);
496 if (trimbox != MagickFalse)
498 if (LocaleNCompare(TrimBox,command,strlen(TrimBox)) == 0)
501 Note region defined by trim box.
503 count=(ssize_t) sscanf(command,"TrimBox [%lf %lf %lf %lf",
504 &bounds.x1,&bounds.y1,&bounds.x2,&bounds.y2);
506 count=(ssize_t) sscanf(command,"TrimBox[%lf %lf %lf %lf",
507 &bounds.x1,&bounds.y1,&bounds.x2,&bounds.y2);
511 if (LocaleNCompare(MediaBox,command,strlen(MediaBox)) == 0)
514 Note region defined by media box.
516 count=(ssize_t) sscanf(command,"MediaBox [%lf %lf %lf %lf",
517 &bounds.x1,&bounds.y1,&bounds.x2,&bounds.y2);
519 count=(ssize_t) sscanf(command,"MediaBox[%lf %lf %lf %lf",
520 &bounds.x1,&bounds.y1,&bounds.x2,&bounds.y2);
524 if (((bounds.x2 > hires_bounds.x2) && (bounds.y2 > hires_bounds.y2)) ||
525 ((hires_bounds.x2 == 0.0) && (hires_bounds.y2 == 0.0)))
528 Set PDF render geometry.
530 (void) FormatMagickString(geometry,MaxTextExtent,
531 "%gx%g%+.15g%+.15g",bounds.x2-bounds.x1,bounds.y2-bounds.y1,
532 bounds.x1,bounds.y1);
533 (void) SetImageProperty(image,"pdf:HiResBoundingBox",geometry);
534 page.width=(unsigned long) floor(bounds.x2-bounds.x1+0.5);
535 page.height=(unsigned long) floor(bounds.y2-bounds.y1+0.5);
539 (void) CloseBlob(image);
540 if ((fabs(angle) == 90.0) || (fabs(angle) == 270.0))
546 page.width=page.height;
549 if (image_info->colorspace == RGBColorspace)
552 Create Ghostscript control file.
554 file=AcquireUniqueFileResource(postscript_filename);
557 ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
558 image_info->filename);
559 image=DestroyImage(image);
560 return((Image *) NULL);
562 count=write(file," ",1);
565 Render Postscript with the Ghostscript delegate.
567 if ((image_info->ping != MagickFalse) ||
568 (image_info->monochrome != MagickFalse))
569 delegate_info=GetDelegateInfo("ps:mono",(char *) NULL,exception);
571 if (cmyk != MagickFalse)
572 delegate_info=GetDelegateInfo("ps:cmyk",(char *) NULL,exception);
574 if (LocaleCompare(image_info->magick,"AI") == 0)
575 delegate_info=GetDelegateInfo("ps:alpha",(char *) NULL,exception);
577 delegate_info=GetDelegateInfo("ps:color",(char *) NULL,exception);
578 if (delegate_info == (const DelegateInfo *) NULL)
580 (void) RelinquishUniqueFileResource(postscript_filename);
581 image=DestroyImage(image);
582 return((Image *) NULL);
585 if (image_info->density != (char *) NULL)
587 flags=ParseGeometry(image_info->density,&geometry_info);
588 image->x_resolution=geometry_info.rho;
589 image->y_resolution=geometry_info.sigma;
590 if ((flags & SigmaValue) == 0)
591 image->y_resolution=image->x_resolution;
593 (void) FormatMagickString(density,MaxTextExtent,"%gx%g",
594 image->x_resolution,image->y_resolution);
595 if (image_info->page != (char *) NULL)
597 (void) ParseAbsoluteGeometry(image_info->page,&page);
598 page.width=(unsigned long) floor(page.width*image->x_resolution/delta.x+
600 page.height=(unsigned long) floor(page.height*image->y_resolution/delta.y+
602 (void) FormatMagickString(options,MaxTextExtent,"-g%lux%lu ",page.width,
605 if (cmyk != MagickFalse)
606 (void) ConcatenateMagickString(options,"-dUseCIEColor ",MaxTextExtent);
607 if (cropbox != MagickFalse)
608 (void) ConcatenateMagickString(options,"-dUseCropBox ",MaxTextExtent);
609 if (trimbox != MagickFalse)
610 (void) ConcatenateMagickString(options,"-dUseTrimBox ",MaxTextExtent);
611 read_info=CloneImageInfo(image_info);
612 *read_info->magick='\0';
613 if (read_info->number_scenes != 0)
616 pages[MaxTextExtent];
618 (void) FormatMagickString(pages,MaxTextExtent,"-dFirstPage=%lu "
619 "-dLastPage=%lu",read_info->scene+1,read_info->scene+
620 read_info->number_scenes);
621 (void) ConcatenateMagickString(options,pages,MaxTextExtent);
622 read_info->number_scenes=0;
623 if (read_info->scenes != (char *) NULL)
624 *read_info->scenes='\0';
626 if (read_info->authenticate != (char *) NULL)
627 (void) FormatMagickString(options+strlen(options),MaxTextExtent,
628 " -sPDFPassword=%s",read_info->authenticate);
629 (void) CopyMagickString(filename,read_info->filename,MaxTextExtent);
630 (void) AcquireUniqueFilename(read_info->filename);
631 (void) FormatMagickString(command,MaxTextExtent,
632 GetDelegateCommands(delegate_info),
633 read_info->antialias != MagickFalse ? 4 : 1,
634 read_info->antialias != MagickFalse ? 4 : 1,density,options,
635 read_info->filename,postscript_filename,input_filename);
636 status=InvokePDFDelegate(read_info->verbose,command,exception);
637 pdf_image=(Image *) NULL;
638 if ((status != MagickFalse) &&
639 (IsPDFRendered(read_info->filename) != MagickFalse))
640 pdf_image=ReadImage(read_info,exception);
641 (void) RelinquishUniqueFileResource(postscript_filename);
642 (void) RelinquishUniqueFileResource(read_info->filename);
643 (void) RelinquishUniqueFileResource(input_filename);
644 read_info=DestroyImageInfo(read_info);
645 if (pdf_image == (Image *) NULL)
647 ThrowFileException(exception,DelegateError,"PostscriptDelegateFailed",
648 image_info->filename);
649 return((Image *) NULL);
651 if (LocaleCompare(pdf_image->magick,"BMP") == 0)
656 cmyk_image=ConsolidateCMYKImages(pdf_image,exception);
657 if (cmyk_image != (Image *) NULL)
659 pdf_image=DestroyImageList(pdf_image);
660 pdf_image=cmyk_image;
663 if (image_info->number_scenes != 0)
672 Add place holder images to meet the subimage specification requirement.
674 for (i=0; i < (long) image_info->scene; i++)
676 clone_image=CloneImage(pdf_image,1,1,MagickTrue,exception);
677 if (clone_image != (Image *) NULL)
678 PrependImageToList(&pdf_image,clone_image);
683 (void) CopyMagickString(pdf_image->filename,filename,MaxTextExtent);
684 pdf_image->page=page;
685 (void) CloneImageProfiles(pdf_image,image);
686 (void) CloneImageProperties(pdf_image,image);
687 next=SyncNextImageInList(pdf_image);
688 if (next != (Image *) NULL)
690 } while (next != (Image *) NULL);
691 image=DestroyImage(image);
693 for (next=GetFirstImageInList(pdf_image); next != (Image *) NULL; )
696 next=GetNextImageInList(next);
698 return(GetFirstImageInList(pdf_image));
702 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
706 % R e g i s t e r P D F I m a g e %
710 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
712 % RegisterPDFImage() adds properties for the PDF image format to
713 % the list of supported formats. The properties include the image format
714 % tag, a method to read and/or write the format, whether the format
715 % supports the saving of more than one frame to the same file or blob,
716 % whether the format supports native in-memory I/O, and a brief
717 % description of the format.
719 % The format of the RegisterPDFImage method is:
721 % unsigned long RegisterPDFImage(void)
724 ModuleExport unsigned long RegisterPDFImage(void)
729 entry=SetMagickInfo("AI");
730 entry->decoder=(DecodeImageHandler *) ReadPDFImage;
731 entry->encoder=(EncodeImageHandler *) WritePDFImage;
732 entry->adjoin=MagickFalse;
733 entry->blob_support=MagickFalse;
734 entry->seekable_stream=MagickTrue;
735 entry->thread_support=EncoderThreadSupport;
736 entry->description=ConstantString("Adobe Illustrator CS2");
737 entry->module=ConstantString("PDF");
738 (void) RegisterMagickInfo(entry);
739 entry=SetMagickInfo("EPDF");
740 entry->decoder=(DecodeImageHandler *) ReadPDFImage;
741 entry->encoder=(EncodeImageHandler *) WritePDFImage;
742 entry->adjoin=MagickFalse;
743 entry->blob_support=MagickFalse;
744 entry->seekable_stream=MagickTrue;
745 entry->thread_support=EncoderThreadSupport;
746 entry->description=ConstantString("Encapsulated Portable Document Format");
747 entry->module=ConstantString("PDF");
748 (void) RegisterMagickInfo(entry);
749 entry=SetMagickInfo("PDF");
750 entry->decoder=(DecodeImageHandler *) ReadPDFImage;
751 entry->encoder=(EncodeImageHandler *) WritePDFImage;
752 entry->magick=(IsImageFormatHandler *) IsPDF;
753 entry->blob_support=MagickFalse;
754 entry->seekable_stream=MagickTrue;
755 entry->thread_support=EncoderThreadSupport;
756 entry->description=ConstantString("Portable Document Format");
757 entry->module=ConstantString("PDF");
758 (void) RegisterMagickInfo(entry);
759 entry=SetMagickInfo("PDFA");
760 entry->decoder=(DecodeImageHandler *) ReadPDFImage;
761 entry->encoder=(EncodeImageHandler *) WritePDFImage;
762 entry->magick=(IsImageFormatHandler *) IsPDF;
763 entry->blob_support=MagickFalse;
764 entry->seekable_stream=MagickTrue;
765 entry->thread_support=EncoderThreadSupport;
766 entry->description=ConstantString("Portable Document Archive Format");
767 entry->module=ConstantString("PDF");
768 (void) RegisterMagickInfo(entry);
769 return(MagickImageCoderSignature);
773 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
777 % U n r e g i s t e r P D F I m a g e %
781 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
783 % UnregisterPDFImage() removes format registrations made by the
784 % PDF module from the list of supported formats.
786 % The format of the UnregisterPDFImage method is:
788 % UnregisterPDFImage(void)
791 ModuleExport void UnregisterPDFImage(void)
793 (void) UnregisterMagickInfo("AI");
794 (void) UnregisterMagickInfo("EPDF");
795 (void) UnregisterMagickInfo("PDF");
796 (void) UnregisterMagickInfo("PDFA");
800 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
804 % W r i t e P D F I m a g e %
808 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
810 % WritePDFImage() writes an image in the Portable Document image
813 % The format of the WritePDFImage method is:
815 % MagickBooleanType WritePDFImage(const ImageInfo *image_info,Image *image)
817 % A description of each parameter follows.
819 % o image_info: the image info.
821 % o image: The image.
825 static inline size_t MagickMax(const size_t x,const size_t y)
832 static inline size_t MagickMin(const size_t x,const size_t y)
839 static char *EscapeParenthesis(const char *text)
848 buffer[MaxTextExtent];
855 for (i=0; i < (long) MagickMin(strlen(text),(MaxTextExtent-escapes-1)); i++)
857 if ((text[i] == '(') || (text[i] == ')'))
868 static MagickBooleanType Huffman2DEncodeImage(const ImageInfo *image_info,
869 Image *image,Image *inject_image)
887 write_info=CloneImageInfo(image_info);
888 (void) CopyMagickString(write_info->filename,"GROUP4:",MaxTextExtent);
889 (void) CopyMagickString(write_info->magick,"GROUP4",MaxTextExtent);
890 group4_image=CloneImage(inject_image,0,0,MagickTrue,&image->exception);
891 if (group4_image == (Image *) NULL)
893 group4=(unsigned char *) ImageToBlob(write_info,group4_image,&length,
895 group4_image=DestroyImage(group4_image);
896 if (group4 == (unsigned char *) NULL)
898 write_info=DestroyImageInfo(write_info);
899 if (WriteBlob(image,length,group4) != (ssize_t) length)
901 group4=(unsigned char *) RelinquishMagickMemory(group4);
905 static MagickBooleanType WritePDFImage(const ImageInfo *image_info,Image *image)
907 #define CFormat "/Filter [ /%s ]\n"
908 #define ObjectsPerImage 14
913 "<?xpacket begin=\"%s\" id=\"W5M0MpCehiHzreSzNTczkc9d\"?>\n"
914 "<x:xmpmeta xmlns:x=\"adobe:ns:meta/\" x:xmptk=\"Adobe XMP Core 4.0-c316 44.253921, Sun Oct 01 2006 17:08:23\">\n"
915 " <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\n"
916 " <rdf:Description rdf:about=\"\"\n"
917 " xmlns:xap=\"http://ns.adobe.com/xap/1.0/\">\n"
918 " <xap:ModifyDate>%s</xap:ModifyDate>\n"
919 " <xap:CreateDate>%s</xap:CreateDate>\n"
920 " <xap:MetadataDate>%s</xap:MetadataDate>\n"
921 " <xap:CreatorTool>%s</xap:CreatorTool>\n"
922 " </rdf:Description>\n"
923 " <rdf:Description rdf:about=\"\"\n"
924 " xmlns:dc=\"http://purl.org/dc/elements/1.1/\">\n"
925 " <dc:format>application/pdf</dc:format>\n"
926 " </rdf:Description>\n"
927 " <rdf:Description rdf:about=\"\"\n"
928 " xmlns:xapMM=\"http://ns.adobe.com/xap/1.0/mm/\">\n"
929 " <xapMM:DocumentID>uuid:6ec119d7-7982-4f56-808d-dfe64f5b35cf</xapMM:DocumentID>\n"
930 " <xapMM:InstanceID>uuid:a79b99b4-6235-447f-9f6c-ec18ef7555cb</xapMM:InstanceID>\n"
931 " </rdf:Description>\n"
932 " <rdf:Description rdf:about=\"\"\n"
933 " xmlns:pdf=\"http://ns.adobe.com/pdf/1.3/\">\n"
934 " <pdf:Producer>%s</pdf:Producer>\n"
935 " </rdf:Description>\n"
936 " <rdf:Description rdf:about=\"\"\n"
937 " xmlns:pdfaid=\"http://www.aiim.org/pdfa/ns/id/\">\n"
938 " <pdfaid:part>1</pdfaid:part>\n"
939 " <pdfaid:conformance>B</pdfaid:conformance>\n"
940 " </rdf:Description>\n"
943 "<?xpacket end=\"w\"?>\n"
945 XMPProfileMagick[4]= { (char) 0xef, (char) 0xbb, (char) 0xbf, (char) 0x00 };
948 buffer[MaxTextExtent],
951 page_geometry[MaxTextExtent];
997 register const IndexPacket
1000 register const PixelPacket
1003 register unsigned char
1031 Open output image file.
1033 assert(image_info != (const ImageInfo *) NULL);
1034 assert(image_info->signature == MagickSignature);
1035 assert(image != (Image *) NULL);
1036 assert(image->signature == MagickSignature);
1037 if (image->debug != MagickFalse)
1038 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1039 status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
1040 if (status == MagickFalse)
1043 Allocate X ref memory.
1045 xref=(MagickOffsetType *) AcquireQuantumMemory(2048UL,sizeof(*xref));
1046 if (xref == (MagickOffsetType *) NULL)
1047 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1048 (void) ResetMagickMemory(xref,0,2048UL*sizeof(*xref));
1054 if (image_info->compression == JPEG2000Compression)
1055 version=(unsigned long) MagickMax(version,5);
1056 for (next=image; next != (Image *) NULL; next=GetNextImageInList(next))
1057 if (next->matte != MagickFalse)
1058 version=(unsigned long) MagickMax(version,4);
1059 if (LocaleCompare(image_info->magick,"PDFA") == 0)
1060 version=(unsigned long) MagickMax(version,6);
1061 (void) FormatMagickString(buffer,MaxTextExtent,"%%PDF-1.%lu \n",version);
1062 (void) WriteBlobString(image,buffer);
1063 if (LocaleCompare(image_info->magick,"PDFA") == 0)
1064 (void) WriteBlobString(image,"%âãÏÓ\n");
1066 Write Catalog object.
1068 xref[object++]=TellBlob(image);
1070 (void) FormatMagickString(buffer,MaxTextExtent,"%lu 0 obj\n",object);
1071 (void) WriteBlobString(image,buffer);
1072 (void) WriteBlobString(image,"<<\n");
1073 if (LocaleCompare(image_info->magick,"PDFA") != 0)
1074 (void) FormatMagickString(buffer,MaxTextExtent,"/Pages %lu 0 R\n",
1078 (void) FormatMagickString(buffer,MaxTextExtent,"/Metadata %lu 0 R\n",
1080 (void) WriteBlobString(image,buffer);
1081 (void) FormatMagickString(buffer,MaxTextExtent,"/Pages %lu 0 R\n",
1084 (void) WriteBlobString(image,buffer);
1085 (void) WriteBlobString(image,"/Type /Catalog\n");
1086 (void) WriteBlobString(image,">>\n");
1087 (void) WriteBlobString(image,"endobj\n");
1088 if (LocaleCompare(image_info->magick,"PDFA") == 0)
1091 create_date[MaxTextExtent],
1092 modify_date[MaxTextExtent],
1093 timestamp[MaxTextExtent],
1094 xmp_profile[MaxTextExtent];
1102 xref[object++]=TellBlob(image);
1103 (void) FormatMagickString(buffer,MaxTextExtent,"%lu 0 obj\n",object);
1104 (void) WriteBlobString(image,buffer);
1105 (void) WriteBlobString(image,"<<\n");
1106 (void) WriteBlobString(image,"/Subtype /XML\n");
1108 value=GetImageProperty(image,"date:modify");
1109 if (value != (const char *) NULL)
1110 (void) CopyMagickString(modify_date,value,MaxTextExtent);
1112 value=GetImageProperty(image,"date:create");
1113 if (value != (const char *) NULL)
1114 (void) CopyMagickString(create_date,value,MaxTextExtent);
1115 (void) FormatMagickTime(time((time_t *) NULL),MaxTextExtent,timestamp);
1116 i=FormatMagickString(xmp_profile,MaxTextExtent,XMPProfile,
1117 XMPProfileMagick,modify_date,create_date,timestamp,
1118 GetMagickVersion(&version),GetMagickVersion(&version));
1119 (void) FormatMagickString(buffer,MaxTextExtent,"/Length %lu\n",1UL*i);
1120 (void) WriteBlobString(image,buffer);
1121 (void) WriteBlobString(image,"/Type /Metadata\n");
1122 (void) WriteBlobString(image,">>\nstream\n");
1123 (void) WriteBlobString(image,xmp_profile);
1124 (void) WriteBlobString(image,"endstream\n");
1125 (void) WriteBlobString(image,"endobj\n");
1130 xref[object++]=TellBlob(image);
1132 (void) FormatMagickString(buffer,MaxTextExtent,"%lu 0 obj\n",object);
1133 (void) WriteBlobString(image,buffer);
1134 (void) WriteBlobString(image,"<<\n");
1135 (void) WriteBlobString(image,"/Type /Pages\n");
1136 (void) FormatMagickString(buffer,MaxTextExtent,"/Kids [ %lu 0 R ",object+1);
1137 (void) WriteBlobString(image,buffer);
1138 count=(long) (pages_id+ObjectsPerImage+1);
1139 if (image_info->adjoin != MagickFalse)
1145 Predict page object id's.
1148 for ( ; GetNextImageInList(kid_image) != (Image *) NULL; count+=ObjectsPerImage)
1150 (void) FormatMagickString(buffer,MaxTextExtent,"%ld 0 R ",count);
1151 (void) WriteBlobString(image,buffer);
1152 kid_image=GetNextImageInList(kid_image);
1154 xref=(MagickOffsetType *) ResizeQuantumMemory(xref,(size_t) count+2048UL,
1156 if (xref == (MagickOffsetType *) NULL)
1157 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1159 (void) WriteBlobString(image,"]\n");
1160 (void) FormatMagickString(buffer,MaxTextExtent,"/Count %lu\n",
1161 (count-pages_id)/ObjectsPerImage);
1162 (void) WriteBlobString(image,buffer);
1163 (void) WriteBlobString(image,">>\n");
1164 (void) WriteBlobString(image,"endobj\n");
1168 compression=image->compression;
1169 if (image_info->compression != UndefinedCompression)
1170 compression=image_info->compression;
1171 switch (compression)
1173 case FaxCompression:
1174 case Group4Compression:
1176 if ((IsMonochromeImage(image,&image->exception) == MagickFalse) ||
1177 (image->matte != MagickFalse))
1178 compression=RLECompression;
1181 #if !defined(MAGICKCORE_JPEG_DELEGATE)
1182 case JPEGCompression:
1184 compression=RLECompression;
1185 (void) ThrowMagickException(&image->exception,GetMagickModule(),
1186 MissingDelegateError,"DelegateLibrarySupportNotBuiltIn","`%s' (JPEG)",
1191 #if !defined(MAGICKCORE_JP2_DELEGATE)
1192 case JPEG2000Compression:
1194 compression=RLECompression;
1195 (void) ThrowMagickException(&image->exception,GetMagickModule(),
1196 MissingDelegateError,"DelegateLibrarySupportNotBuiltIn","`%s' (JP2)",
1201 #if !defined(MAGICKCORE_ZLIB_DELEGATE)
1202 case ZipCompression:
1204 compression=RLECompression;
1205 (void) ThrowMagickException(&image->exception,GetMagickModule(),
1206 MissingDelegateError,"DelegateLibrarySupportNotBuiltIn","`%s' (ZLIB)",
1211 case LZWCompression:
1213 if (LocaleCompare(image_info->magick,"PDFA") == 0)
1214 compression=RLECompression; /* LZW compression is forbidden */
1219 if (LocaleCompare(image_info->magick,"PDFA") == 0)
1220 compression=RLECompression; /* ASCII 85 compression is forbidden */
1226 if (compression == JPEG2000Compression)
1228 if (image->colorspace != RGBColorspace)
1229 (void) TransformImageColorspace(image,RGBColorspace);
1232 Scale relative to dots-per-inch.
1234 delta.x=DefaultResolution;
1235 delta.y=DefaultResolution;
1236 resolution.x=image->x_resolution;
1237 resolution.y=image->y_resolution;
1238 if ((resolution.x == 0.0) || (resolution.y == 0.0))
1240 flags=ParseGeometry(PSDensityGeometry,&geometry_info);
1241 resolution.x=geometry_info.rho;
1242 resolution.y=geometry_info.sigma;
1243 if ((flags & SigmaValue) == 0)
1244 resolution.y=resolution.x;
1246 if (image_info->density != (char *) NULL)
1248 flags=ParseGeometry(image_info->density,&geometry_info);
1249 resolution.x=geometry_info.rho;
1250 resolution.y=geometry_info.sigma;
1251 if ((flags & SigmaValue) == 0)
1252 resolution.y=resolution.x;
1254 if (image->units == PixelsPerCentimeterResolution)
1259 SetGeometry(image,&geometry);
1260 (void) FormatMagickString(page_geometry,MaxTextExtent,"%lux%lu",
1261 image->columns,image->rows);
1262 if (image_info->page != (char *) NULL)
1263 (void) CopyMagickString(page_geometry,image_info->page,MaxTextExtent);
1265 if ((image->page.width != 0) && (image->page.height != 0))
1266 (void) FormatMagickString(page_geometry,MaxTextExtent,"%lux%lu%+ld%+ld",
1267 image->page.width,image->page.height,image->page.x,image->page.y);
1269 if ((image->gravity != UndefinedGravity) &&
1270 (LocaleCompare(image_info->magick,"PDF") == 0))
1271 (void) CopyMagickString(page_geometry,PSPageGeometry,MaxTextExtent);
1272 (void) ConcatenateMagickString(page_geometry,">",MaxTextExtent);
1273 (void) ParseMetaGeometry(page_geometry,&geometry.x,&geometry.y,
1274 &geometry.width,&geometry.height);
1275 scale.x=(double) (geometry.width*delta.x)/resolution.x;
1276 geometry.width=(unsigned long) floor(scale.x+0.5);
1277 scale.y=(double) (geometry.height*delta.y)/resolution.y;
1278 geometry.height=(unsigned long) floor(scale.y+0.5);
1279 (void) ParseAbsoluteGeometry(page_geometry,&media_info);
1280 (void) ParseGravityGeometry(image,page_geometry,&page_info,
1282 if (image->gravity != UndefinedGravity)
1284 geometry.x=(-page_info.x);
1285 geometry.y=(long) (media_info.height+page_info.y-image->rows);
1288 if (image_info->pointsize != 0.0)
1289 pointsize=image_info->pointsize;
1291 value=GetImageProperty(image,"Label");
1292 if (value != (const char *) NULL)
1293 text_size=(unsigned long) (MultilineCensus(value)*pointsize+12);
1297 xref[object++]=TellBlob(image);
1298 (void) FormatMagickString(buffer,MaxTextExtent,"%lu 0 obj\n",object);
1299 (void) WriteBlobString(image,buffer);
1300 (void) WriteBlobString(image,"<<\n");
1301 (void) WriteBlobString(image,"/Type /Page\n");
1302 (void) FormatMagickString(buffer,MaxTextExtent,"/Parent %lu 0 R\n",
1304 (void) WriteBlobString(image,buffer);
1305 (void) WriteBlobString(image,"/Resources <<\n");
1306 labels=(char **) NULL;
1307 value=GetImageProperty(image,"Label");
1308 if (value != (const char *) NULL)
1309 labels=StringToList(value);
1310 if (labels != (char **) NULL)
1312 (void) FormatMagickString(buffer,MaxTextExtent,
1313 "/Font << /F%lu %lu 0 R >>\n",image->scene,object+4);
1314 (void) WriteBlobString(image,buffer);
1316 (void) FormatMagickString(buffer,MaxTextExtent,
1317 "/XObject << /Im%lu %lu 0 R >>\n",image->scene,object+5);
1318 (void) WriteBlobString(image,buffer);
1319 (void) FormatMagickString(buffer,MaxTextExtent,"/ProcSet %lu 0 R >>\n",
1321 (void) WriteBlobString(image,buffer);
1322 (void) FormatMagickString(buffer,MaxTextExtent,
1323 "/MediaBox [0 0 %g %g]\n",72.0*media_info.width/resolution.x,
1324 72.0*media_info.height/resolution.y);
1325 (void) WriteBlobString(image,buffer);
1326 (void) FormatMagickString(buffer,MaxTextExtent,
1327 "/CropBox [0 0 %g %g]\n",72.0*media_info.width/resolution.x,
1328 72.0*media_info.height/resolution.y);
1329 (void) WriteBlobString(image,buffer);
1330 (void) FormatMagickString(buffer,MaxTextExtent,"/Contents %lu 0 R\n",
1332 (void) WriteBlobString(image,buffer);
1333 (void) FormatMagickString(buffer,MaxTextExtent,"/Thumb %lu 0 R\n",
1335 (void) WriteBlobString(image,buffer);
1336 (void) WriteBlobString(image,">>\n");
1337 (void) WriteBlobString(image,"endobj\n");
1339 Write Contents object.
1341 xref[object++]=TellBlob(image);
1342 (void) FormatMagickString(buffer,MaxTextExtent,"%lu 0 obj\n",object);
1343 (void) WriteBlobString(image,buffer);
1344 (void) WriteBlobString(image,"<<\n");
1345 (void) FormatMagickString(buffer,MaxTextExtent,"/Length %lu 0 R\n",
1347 (void) WriteBlobString(image,buffer);
1348 (void) WriteBlobString(image,">>\n");
1349 (void) WriteBlobString(image,"stream\n");
1350 offset=TellBlob(image);
1351 (void) WriteBlobString(image,"q\n");
1352 if (labels != (char **) NULL)
1353 for (i=0; labels[i] != (char *) NULL; i++)
1355 (void) WriteBlobString(image,"BT\n");
1356 (void) FormatMagickString(buffer,MaxTextExtent,"/F%lu %g Tf\n",
1357 image->scene,pointsize);
1358 (void) WriteBlobString(image,buffer);
1359 (void) FormatMagickString(buffer,MaxTextExtent,"%ld %ld Td\n",
1360 geometry.x,(long) (geometry.y+geometry.height+i*pointsize+12));
1361 (void) WriteBlobString(image,buffer);
1362 (void) FormatMagickString(buffer,MaxTextExtent,"(%s) Tj\n",labels[i]);
1363 (void) WriteBlobString(image,buffer);
1364 (void) WriteBlobString(image,"ET\n");
1365 labels[i]=DestroyString(labels[i]);
1367 (void) FormatMagickString(buffer,MaxTextExtent,
1368 "%g 0 0 %g %ld %ld cm\n",scale.x,scale.y,geometry.x,geometry.y);
1369 (void) WriteBlobString(image,buffer);
1370 (void) FormatMagickString(buffer,MaxTextExtent,"/Im%lu Do\n",image->scene);
1371 (void) WriteBlobString(image,buffer);
1372 (void) WriteBlobString(image,"Q\n");
1373 offset=TellBlob(image)-offset;
1374 (void) WriteBlobString(image,"endstream\n");
1375 (void) WriteBlobString(image,"endobj\n");
1377 Write Length object.
1379 xref[object++]=TellBlob(image);
1380 (void) FormatMagickString(buffer,MaxTextExtent,"%lu 0 obj\n",object);
1381 (void) WriteBlobString(image,buffer);
1382 (void) FormatMagickString(buffer,MaxTextExtent,"%lu\n",
1383 (unsigned long) offset);
1384 (void) WriteBlobString(image,buffer);
1385 (void) WriteBlobString(image,"endobj\n");
1387 Write Procset object.
1389 xref[object++]=TellBlob(image);
1390 (void) FormatMagickString(buffer,MaxTextExtent,"%lu 0 obj\n",object);
1391 (void) WriteBlobString(image,buffer);
1392 if ((image->storage_class == DirectClass) || (image->colors > 256))
1393 (void) CopyMagickString(buffer,"[ /PDF /Text /ImageC",MaxTextExtent);
1395 if ((compression == FaxCompression) || (compression == Group4Compression))
1396 (void) CopyMagickString(buffer,"[ /PDF /Text /ImageB",MaxTextExtent);
1398 (void) CopyMagickString(buffer,"[ /PDF /Text /ImageI",MaxTextExtent);
1399 (void) WriteBlobString(image,buffer);
1400 (void) WriteBlobString(image," ]\n");
1401 (void) WriteBlobString(image,"endobj\n");
1405 xref[object++]=TellBlob(image);
1406 (void) FormatMagickString(buffer,MaxTextExtent,"%lu 0 obj\n",object);
1407 (void) WriteBlobString(image,buffer);
1408 (void) WriteBlobString(image,"<<\n");
1409 if (labels != (char **) NULL)
1411 (void) WriteBlobString(image,"/Type /Font\n");
1412 (void) WriteBlobString(image,"/Subtype /Type1\n");
1413 (void) FormatMagickString(buffer,MaxTextExtent,"/Name /F%lu\n",
1415 (void) WriteBlobString(image,buffer);
1416 (void) WriteBlobString(image,"/BaseFont /Helvetica\n");
1417 (void) WriteBlobString(image,"/Encoding /MacRomanEncoding\n");
1418 labels=(char **) RelinquishMagickMemory(labels);
1420 (void) WriteBlobString(image,">>\n");
1421 (void) WriteBlobString(image,"endobj\n");
1423 Write XObject object.
1425 xref[object++]=TellBlob(image);
1426 (void) FormatMagickString(buffer,MaxTextExtent,"%lu 0 obj\n",object);
1427 (void) WriteBlobString(image,buffer);
1428 (void) WriteBlobString(image,"<<\n");
1429 (void) WriteBlobString(image,"/Type /XObject\n");
1430 (void) WriteBlobString(image,"/Subtype /Image\n");
1431 (void) FormatMagickString(buffer,MaxTextExtent,"/Name /Im%lu\n",
1433 (void) WriteBlobString(image,buffer);
1434 switch (compression)
1438 (void) FormatMagickString(buffer,MaxTextExtent,CFormat,"ASCII85Decode");
1441 case JPEGCompression:
1443 (void) FormatMagickString(buffer,MaxTextExtent,CFormat,"DCTDecode");
1444 if (image->colorspace != CMYKColorspace)
1446 (void) WriteBlobString(image,buffer);
1447 (void) CopyMagickString(buffer,"/Decode [1 0 1 0 1 0 1 0]\n",
1451 case JPEG2000Compression:
1453 (void) FormatMagickString(buffer,MaxTextExtent,CFormat,"JPXDecode");
1454 if (image->colorspace != CMYKColorspace)
1456 (void) WriteBlobString(image,buffer);
1457 (void) CopyMagickString(buffer,"/Decode [1 0 1 0 1 0 1 0]\n",
1461 case LZWCompression:
1463 (void) FormatMagickString(buffer,MaxTextExtent,CFormat,"LZWDecode");
1466 case ZipCompression:
1468 (void) FormatMagickString(buffer,MaxTextExtent,CFormat,"FlateDecode");
1471 case FaxCompression:
1472 case Group4Compression:
1474 (void) CopyMagickString(buffer,"/Filter [ /CCITTFaxDecode ]\n",
1476 (void) WriteBlobString(image,buffer);
1477 (void) FormatMagickString(buffer,MaxTextExtent,"/DecodeParms [ << "
1478 "/K %s /BlackIs1 false /Columns %ld /Rows %ld >> ]\n",CCITTParam,
1479 image->columns,image->rows);
1484 (void) FormatMagickString(buffer,MaxTextExtent,CFormat,
1489 (void) WriteBlobString(image,buffer);
1490 (void) FormatMagickString(buffer,MaxTextExtent,"/Width %lu\n",
1492 (void) WriteBlobString(image,buffer);
1493 (void) FormatMagickString(buffer,MaxTextExtent,"/Height %lu\n",image->rows);
1494 (void) WriteBlobString(image,buffer);
1495 (void) FormatMagickString(buffer,MaxTextExtent,"/ColorSpace %lu 0 R\n",
1497 (void) WriteBlobString(image,buffer);
1498 (void) FormatMagickString(buffer,MaxTextExtent,"/BitsPerComponent %d\n",
1499 (compression == FaxCompression) || (compression == Group4Compression) ?
1501 (void) WriteBlobString(image,buffer);
1502 if (image->matte != MagickFalse)
1504 (void) FormatMagickString(buffer,MaxTextExtent,"/SMask %lu 0 R\n",
1506 (void) WriteBlobString(image,buffer);
1508 (void) FormatMagickString(buffer,MaxTextExtent,"/Length %lu 0 R\n",
1510 (void) WriteBlobString(image,buffer);
1511 (void) WriteBlobString(image,">>\n");
1512 (void) WriteBlobString(image,"stream\n");
1513 offset=TellBlob(image);
1514 number_pixels=(MagickSizeType) image->columns*image->rows;
1515 if ((4*number_pixels) != (MagickSizeType) ((size_t) (4*number_pixels)))
1516 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1517 if ((compression == FaxCompression) || (compression == Group4Compression) ||
1518 ((image_info->type != TrueColorType) &&
1519 (IsGrayImage(image,&image->exception) != MagickFalse)))
1521 switch (compression)
1523 case FaxCompression:
1524 case Group4Compression:
1526 if (LocaleCompare(CCITTParam,"0") == 0)
1528 (void) HuffmanEncodeImage(image_info,image,image);
1531 (void) Huffman2DEncodeImage(image_info,image,image);
1534 case JPEGCompression:
1536 status=InjectImageBlob(image_info,image,image,"jpeg",
1538 if (status == MagickFalse)
1539 ThrowWriterException(CoderError,image->exception.reason);
1542 case JPEG2000Compression:
1544 status=InjectImageBlob(image_info,image,image,"jp2",
1546 if (status == MagickFalse)
1547 ThrowWriterException(CoderError,image->exception.reason);
1550 case RLECompression:
1554 Allocate pixel array.
1556 length=(size_t) number_pixels;
1557 pixels=(unsigned char *) AcquireQuantumMemory(length,
1559 if (pixels == (unsigned char *) NULL)
1560 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1562 Dump Runlength encoded pixels.
1565 for (y=0; y < (long) image->rows; y++)
1567 p=GetVirtualPixels(image,0,y,image->columns,1,
1569 if (p == (const PixelPacket *) NULL)
1571 for (x=0; x < (long) image->columns; x++)
1573 *q++=ScaleQuantumToChar(PixelIntensityToQuantum(p));
1576 if (image->previous == (Image *) NULL)
1578 status=SetImageProgress(image,SaveImageTag,y,image->rows);
1579 if (status == MagickFalse)
1583 #if defined(MAGICKCORE_ZLIB_DELEGATE)
1584 if (compression == ZipCompression)
1585 status=ZLIBEncodeImage(image,length,pixels);
1588 if (compression == LZWCompression)
1589 status=LZWEncodeImage(image,length,pixels);
1591 status=PackbitsEncodeImage(image,length,pixels);
1592 pixels=(unsigned char *) RelinquishMagickMemory(pixels);
1593 if (status == MagickFalse)
1595 (void) CloseBlob(image);
1596 return(MagickFalse);
1603 Dump uncompressed PseudoColor packets.
1605 Ascii85Initialize(image);
1606 for (y=0; y < (long) image->rows; y++)
1608 p=GetVirtualPixels(image,0,y,image->columns,1,
1610 if (p == (const PixelPacket *) NULL)
1612 for (x=0; x < (long) image->columns; x++)
1614 Ascii85Encode(image,
1615 ScaleQuantumToChar(PixelIntensityToQuantum(p)));
1618 if (image->previous == (Image *) NULL)
1620 status=SetImageProgress(image,SaveImageTag,y,image->rows);
1621 if (status == MagickFalse)
1625 Ascii85Flush(image);
1631 if ((image->storage_class == DirectClass) || (image->colors > 256) ||
1632 (compression == JPEGCompression) ||
1633 (compression == JPEG2000Compression))
1634 switch (compression)
1636 case JPEGCompression:
1638 status=InjectImageBlob(image_info,image,image,"jpeg",
1640 if (status == MagickFalse)
1641 ThrowWriterException(CoderError,image->exception.reason);
1644 case JPEG2000Compression:
1646 status=InjectImageBlob(image_info,image,image,"jp2",
1648 if (status == MagickFalse)
1649 ThrowWriterException(CoderError,image->exception.reason);
1652 case RLECompression:
1656 Allocate pixel array.
1658 length=(size_t) number_pixels;
1659 pixels=(unsigned char *) AcquireQuantumMemory(length,
1661 length*=image->colorspace == CMYKColorspace ? 4UL : 3UL;
1662 if (pixels == (unsigned char *) NULL)
1663 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1665 Dump runoffset encoded pixels.
1668 for (y=0; y < (long) image->rows; y++)
1670 p=GetVirtualPixels(image,0,y,image->columns,1,
1672 if (p == (const PixelPacket *) NULL)
1674 indexes=GetVirtualIndexQueue(image);
1675 for (x=0; x < (long) image->columns; x++)
1677 *q++=ScaleQuantumToChar(GetRedPixelComponent(p));
1678 *q++=ScaleQuantumToChar(GetGreenPixelComponent(p));
1679 *q++=ScaleQuantumToChar(GetBluePixelComponent(p));
1680 if (image->colorspace == CMYKColorspace)
1681 *q++=ScaleQuantumToChar(indexes[x]);
1684 if (image->previous == (Image *) NULL)
1686 status=SetImageProgress(image,SaveImageTag,y,image->rows);
1687 if (status == MagickFalse)
1691 #if defined(MAGICKCORE_ZLIB_DELEGATE)
1692 if (compression == ZipCompression)
1693 status=ZLIBEncodeImage(image,length,pixels);
1696 if (compression == LZWCompression)
1697 status=LZWEncodeImage(image,length,pixels);
1699 status=PackbitsEncodeImage(image,length,pixels);
1700 pixels=(unsigned char *) RelinquishMagickMemory(pixels);
1701 if (status == MagickFalse)
1703 (void) CloseBlob(image);
1704 return(MagickFalse);
1711 Dump uncompressed DirectColor packets.
1713 Ascii85Initialize(image);
1714 for (y=0; y < (long) image->rows; y++)
1716 p=GetVirtualPixels(image,0,y,image->columns,1,
1718 if (p == (const PixelPacket *) NULL)
1720 indexes=GetVirtualIndexQueue(image);
1721 for (x=0; x < (long) image->columns; x++)
1723 Ascii85Encode(image,ScaleQuantumToChar(GetRedPixelComponent(p)));
1724 Ascii85Encode(image,ScaleQuantumToChar(GetGreenPixelComponent(p)));
1725 Ascii85Encode(image,ScaleQuantumToChar(GetBluePixelComponent(p)));
1726 if (image->colorspace == CMYKColorspace)
1727 Ascii85Encode(image,ScaleQuantumToChar(indexes[x]));
1730 if (image->previous == (Image *) NULL)
1732 status=SetImageProgress(image,SaveImageTag,y,image->rows);
1733 if (status == MagickFalse)
1737 Ascii85Flush(image);
1744 Dump number of colors and colormap.
1746 switch (compression)
1748 case RLECompression:
1752 Allocate pixel array.
1754 length=(size_t) number_pixels;
1755 pixels=(unsigned char *) AcquireQuantumMemory(length,
1757 if (pixels == (unsigned char *) NULL)
1758 ThrowWriterException(ResourceLimitError,
1759 "MemoryAllocationFailed");
1761 Dump Runlength encoded pixels.
1764 for (y=0; y < (long) image->rows; y++)
1766 p=GetVirtualPixels(image,0,y,image->columns,1,
1768 if (p == (const PixelPacket *) NULL)
1770 indexes=GetVirtualIndexQueue(image);
1771 for (x=0; x < (long) image->columns; x++)
1772 *q++=(unsigned char) indexes[x];
1773 if (image->previous == (Image *) NULL)
1775 status=SetImageProgress(image,SaveImageTag,y,image->rows);
1776 if (status == MagickFalse)
1780 #if defined(MAGICKCORE_ZLIB_DELEGATE)
1781 if (compression == ZipCompression)
1782 status=ZLIBEncodeImage(image,length,pixels);
1785 if (compression == LZWCompression)
1786 status=LZWEncodeImage(image,length,pixels);
1788 status=PackbitsEncodeImage(image,length,pixels);
1789 pixels=(unsigned char *) RelinquishMagickMemory(pixels);
1790 if (status == MagickFalse)
1792 (void) CloseBlob(image);
1793 return(MagickFalse);
1800 Dump uncompressed PseudoColor packets.
1802 Ascii85Initialize(image);
1803 for (y=0; y < (long) image->rows; y++)
1805 p=GetVirtualPixels(image,0,y,image->columns,1,
1807 if (p == (const PixelPacket *) NULL)
1809 indexes=GetVirtualIndexQueue(image);
1810 for (x=0; x < (long) image->columns; x++)
1811 Ascii85Encode(image,(unsigned char) indexes[x]);
1812 if (image->previous == (Image *) NULL)
1814 status=SetImageProgress(image,SaveImageTag,y,image->rows);
1815 if (status == MagickFalse)
1819 Ascii85Flush(image);
1824 offset=TellBlob(image)-offset;
1825 (void) WriteBlobString(image,"\nendstream\n");
1826 (void) WriteBlobString(image,"endobj\n");
1828 Write Length object.
1830 xref[object++]=TellBlob(image);
1831 (void) FormatMagickString(buffer,MaxTextExtent,"%lu 0 obj\n",object);
1832 (void) WriteBlobString(image,buffer);
1833 (void) FormatMagickString(buffer,MaxTextExtent,"%lu\n",
1834 (unsigned long) offset);
1835 (void) WriteBlobString(image,buffer);
1836 (void) WriteBlobString(image,"endobj\n");
1838 Write Colorspace object.
1840 xref[object++]=TellBlob(image);
1841 (void) FormatMagickString(buffer,MaxTextExtent,"%lu 0 obj\n",object);
1842 (void) WriteBlobString(image,buffer);
1843 if (image->colorspace == CMYKColorspace)
1844 (void) CopyMagickString(buffer,"/DeviceCMYK\n",MaxTextExtent);
1846 if ((compression == FaxCompression) ||
1847 (compression == Group4Compression) ||
1848 ((image_info->type != TrueColorType) &&
1849 (IsGrayImage(image,&image->exception) != MagickFalse)))
1850 (void) CopyMagickString(buffer,"/DeviceGray\n",MaxTextExtent);
1852 if ((image->storage_class == DirectClass) || (image->colors > 256) ||
1853 (compression == JPEGCompression) ||
1854 (compression == JPEG2000Compression))
1855 (void) CopyMagickString(buffer,"/DeviceRGB\n",MaxTextExtent);
1857 (void) FormatMagickString(buffer,MaxTextExtent,
1858 "[ /Indexed /DeviceRGB %lu %lu 0 R ]\n",
1859 image->colors-1,object+3);
1860 (void) WriteBlobString(image,buffer);
1861 (void) WriteBlobString(image,"endobj\n");
1865 SetGeometry(image,&geometry);
1866 (void) ParseMetaGeometry("106x106+0+0>",&geometry.x,&geometry.y,
1867 &geometry.width,&geometry.height);
1868 tile_image=ThumbnailImage(image,geometry.width,geometry.height,
1870 if (tile_image == (Image *) NULL)
1871 ThrowWriterException(ResourceLimitError,image->exception.reason);
1872 xref[object++]=TellBlob(image);
1873 (void) FormatMagickString(buffer,MaxTextExtent,"%lu 0 obj\n",object);
1874 (void) WriteBlobString(image,buffer);
1875 (void) WriteBlobString(image,"<<\n");
1876 switch (compression)
1880 (void) FormatMagickString(buffer,MaxTextExtent,CFormat,"ASCII85Decode");
1883 case JPEGCompression:
1885 (void) FormatMagickString(buffer,MaxTextExtent,CFormat,"DCTDecode");
1886 if (image->colorspace != CMYKColorspace)
1888 (void) WriteBlobString(image,buffer);
1889 (void) CopyMagickString(buffer,"/Decode [1 0 1 0 1 0 1 0]\n",
1893 case JPEG2000Compression:
1895 (void) FormatMagickString(buffer,MaxTextExtent,CFormat,"JPXDecode");
1896 if (image->colorspace != CMYKColorspace)
1898 (void) WriteBlobString(image,buffer);
1899 (void) CopyMagickString(buffer,"/Decode [1 0 1 0 1 0 1 0]\n",
1903 case LZWCompression:
1905 (void) FormatMagickString(buffer,MaxTextExtent,CFormat,"LZWDecode");
1908 case ZipCompression:
1910 (void) FormatMagickString(buffer,MaxTextExtent,CFormat,"FlateDecode");
1913 case FaxCompression:
1914 case Group4Compression:
1916 (void) CopyMagickString(buffer,"/Filter [ /CCITTFaxDecode ]\n",
1918 (void) WriteBlobString(image,buffer);
1919 (void) FormatMagickString(buffer,MaxTextExtent,"/DecodeParms [ << "
1920 "/K %s /BlackIs1 false /Columns %lu /Rows %lu >> ]\n",CCITTParam,
1921 tile_image->columns,tile_image->rows);
1926 (void) FormatMagickString(buffer,MaxTextExtent,CFormat,
1931 (void) WriteBlobString(image,buffer);
1932 (void) FormatMagickString(buffer,MaxTextExtent,"/Width %lu\n",
1933 tile_image->columns);
1934 (void) WriteBlobString(image,buffer);
1935 (void) FormatMagickString(buffer,MaxTextExtent,"/Height %lu\n",
1937 (void) WriteBlobString(image,buffer);
1938 (void) FormatMagickString(buffer,MaxTextExtent,"/ColorSpace %lu 0 R\n",
1940 (void) WriteBlobString(image,buffer);
1941 (void) FormatMagickString(buffer,MaxTextExtent,"/BitsPerComponent %d\n",
1942 (compression == FaxCompression) || (compression == Group4Compression) ?
1944 (void) WriteBlobString(image,buffer);
1945 (void) FormatMagickString(buffer,MaxTextExtent,"/Length %lu 0 R\n",
1947 (void) WriteBlobString(image,buffer);
1948 (void) WriteBlobString(image,">>\n");
1949 (void) WriteBlobString(image,"stream\n");
1950 offset=TellBlob(image);
1951 number_pixels=(MagickSizeType) tile_image->columns*tile_image->rows;
1952 if ((compression == FaxCompression) ||
1953 (compression == Group4Compression) ||
1954 ((image_info->type != TrueColorType) &&
1955 (IsGrayImage(tile_image,&image->exception) != MagickFalse)))
1957 switch (compression)
1959 case FaxCompression:
1960 case Group4Compression:
1962 if (LocaleCompare(CCITTParam,"0") == 0)
1964 (void) HuffmanEncodeImage(image_info,image,tile_image);
1967 (void) Huffman2DEncodeImage(image_info,image,tile_image);
1970 case JPEGCompression:
1972 status=InjectImageBlob(image_info,image,tile_image,"jpeg",
1974 if (status == MagickFalse)
1975 ThrowWriterException(CoderError,tile_image->exception.reason);
1978 case JPEG2000Compression:
1980 status=InjectImageBlob(image_info,image,tile_image,"jp2",
1982 if (status == MagickFalse)
1983 ThrowWriterException(CoderError,tile_image->exception.reason);
1986 case RLECompression:
1990 Allocate pixel array.
1992 length=(size_t) number_pixels;
1993 pixels=(unsigned char *) AcquireQuantumMemory(length,
1995 if (pixels == (unsigned char *) NULL)
1997 tile_image=DestroyImage(tile_image);
1998 ThrowWriterException(ResourceLimitError,
1999 "MemoryAllocationFailed");
2002 Dump Runlength encoded pixels.
2005 for (y=0; y < (long) tile_image->rows; y++)
2007 p=GetVirtualPixels(tile_image,0,y,tile_image->columns,1,
2008 &tile_image->exception);
2009 if (p == (const PixelPacket *) NULL)
2011 for (x=0; x < (long) tile_image->columns; x++)
2013 *q++=ScaleQuantumToChar(PixelIntensityToQuantum(p));
2017 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2018 if (compression == ZipCompression)
2019 status=ZLIBEncodeImage(image,length,pixels);
2022 if (compression == LZWCompression)
2023 status=LZWEncodeImage(image,length,pixels);
2025 status=PackbitsEncodeImage(image,length,pixels);
2026 pixels=(unsigned char *) RelinquishMagickMemory(pixels);
2027 if (status == MagickFalse)
2029 (void) CloseBlob(image);
2030 return(MagickFalse);
2037 Dump uncompressed PseudoColor packets.
2039 Ascii85Initialize(image);
2040 for (y=0; y < (long) tile_image->rows; y++)
2042 p=GetVirtualPixels(tile_image,0,y,tile_image->columns,1,
2043 &tile_image->exception);
2044 if (p == (const PixelPacket *) NULL)
2046 for (x=0; x < (long) tile_image->columns; x++)
2048 Ascii85Encode(image,
2049 ScaleQuantumToChar(PixelIntensityToQuantum(p)));
2053 Ascii85Flush(image);
2059 if ((tile_image->storage_class == DirectClass) ||
2060 (tile_image->colors > 256) || (compression == JPEGCompression) ||
2061 (compression == JPEG2000Compression))
2062 switch (compression)
2064 case JPEGCompression:
2066 status=InjectImageBlob(image_info,image,tile_image,"jpeg",
2068 if (status == MagickFalse)
2069 ThrowWriterException(CoderError,tile_image->exception.reason);
2072 case JPEG2000Compression:
2074 status=InjectImageBlob(image_info,image,tile_image,"jp2",
2076 if (status == MagickFalse)
2077 ThrowWriterException(CoderError,tile_image->exception.reason);
2080 case RLECompression:
2084 Allocate pixel array.
2086 length=(size_t) number_pixels;
2087 pixels=(unsigned char *) AcquireQuantumMemory(length,4*
2089 length*=tile_image->colorspace == CMYKColorspace ? 4UL : 3UL;
2090 if (pixels == (unsigned char *) NULL)
2092 tile_image=DestroyImage(tile_image);
2093 ThrowWriterException(ResourceLimitError,
2094 "MemoryAllocationFailed");
2097 Dump runoffset encoded pixels.
2100 for (y=0; y < (long) tile_image->rows; y++)
2102 p=GetVirtualPixels(tile_image,0,y,tile_image->columns,1,
2103 &tile_image->exception);
2104 if (p == (const PixelPacket *) NULL)
2106 indexes=GetVirtualIndexQueue(tile_image);
2107 for (x=0; x < (long) tile_image->columns; x++)
2109 *q++=ScaleQuantumToChar(GetRedPixelComponent(p));
2110 *q++=ScaleQuantumToChar(GetGreenPixelComponent(p));
2111 *q++=ScaleQuantumToChar(GetBluePixelComponent(p));
2112 if (image->colorspace == CMYKColorspace)
2113 *q++=ScaleQuantumToChar(indexes[x]);
2117 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2118 if (compression == ZipCompression)
2119 status=ZLIBEncodeImage(image,length,pixels);
2122 if (compression == LZWCompression)
2123 status=LZWEncodeImage(image,length,pixels);
2125 status=PackbitsEncodeImage(image,length,pixels);
2126 pixels=(unsigned char *) RelinquishMagickMemory(pixels);
2127 if (status == MagickFalse)
2129 (void) CloseBlob(image);
2130 return(MagickFalse);
2137 Dump uncompressed DirectColor packets.
2139 Ascii85Initialize(image);
2140 for (y=0; y < (long) tile_image->rows; y++)
2142 p=GetVirtualPixels(tile_image,0,y,tile_image->columns,1,
2143 &tile_image->exception);
2144 if (p == (const PixelPacket *) NULL)
2146 indexes=GetVirtualIndexQueue(tile_image);
2147 for (x=0; x < (long) tile_image->columns; x++)
2149 Ascii85Encode(image,ScaleQuantumToChar(GetRedPixelComponent(p)));
2150 Ascii85Encode(image,ScaleQuantumToChar(GetGreenPixelComponent(p)));
2151 Ascii85Encode(image,ScaleQuantumToChar(GetBluePixelComponent(p)));
2152 if (image->colorspace == CMYKColorspace)
2153 Ascii85Encode(image,ScaleQuantumToChar(indexes[x]));
2157 Ascii85Flush(image);
2164 Dump number of colors and colormap.
2166 switch (compression)
2168 case RLECompression:
2172 Allocate pixel array.
2174 length=(size_t) number_pixels;
2175 pixels=(unsigned char *) AcquireQuantumMemory(length,
2177 if (pixels == (unsigned char *) NULL)
2179 tile_image=DestroyImage(tile_image);
2180 ThrowWriterException(ResourceLimitError,
2181 "MemoryAllocationFailed");
2184 Dump Runlength encoded pixels.
2187 for (y=0; y < (long) tile_image->rows; y++)
2189 p=GetVirtualPixels(tile_image,0,y,tile_image->columns,1,
2190 &tile_image->exception);
2191 if (p == (const PixelPacket *) NULL)
2193 indexes=GetVirtualIndexQueue(tile_image);
2194 for (x=0; x < (long) tile_image->columns; x++)
2195 *q++=(unsigned char) indexes[x];
2197 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2198 if (compression == ZipCompression)
2199 status=ZLIBEncodeImage(image,length,pixels);
2202 if (compression == LZWCompression)
2203 status=LZWEncodeImage(image,length,pixels);
2205 status=PackbitsEncodeImage(image,length,pixels);
2206 pixels=(unsigned char *) RelinquishMagickMemory(pixels);
2207 if (status == MagickFalse)
2209 (void) CloseBlob(image);
2210 return(MagickFalse);
2217 Dump uncompressed PseudoColor packets.
2219 Ascii85Initialize(image);
2220 for (y=0; y < (long) tile_image->rows; y++)
2222 p=GetVirtualPixels(tile_image,0,y,tile_image->columns,1,
2223 &tile_image->exception);
2224 if (p == (const PixelPacket *) NULL)
2226 indexes=GetVirtualIndexQueue(tile_image);
2227 for (x=0; x < (long) tile_image->columns; x++)
2228 Ascii85Encode(image,(unsigned char) indexes[x]);
2230 Ascii85Flush(image);
2235 tile_image=DestroyImage(tile_image);
2236 offset=TellBlob(image)-offset;
2237 (void) WriteBlobString(image,"\nendstream\n");
2238 (void) WriteBlobString(image,"endobj\n");
2240 Write Length object.
2242 xref[object++]=TellBlob(image);
2243 (void) FormatMagickString(buffer,MaxTextExtent,"%lu 0 obj\n",object);
2244 (void) WriteBlobString(image,buffer);
2245 (void) FormatMagickString(buffer,MaxTextExtent,"%lu\n",
2246 (unsigned long) offset);
2247 (void) WriteBlobString(image,buffer);
2248 (void) WriteBlobString(image,"endobj\n");
2249 xref[object++]=TellBlob(image);
2250 (void) FormatMagickString(buffer,MaxTextExtent,"%lu 0 obj\n",object);
2251 (void) WriteBlobString(image,buffer);
2252 if ((image->storage_class != DirectClass) && (image->colors <= 256) &&
2253 (compression != FaxCompression) && (compression != Group4Compression))
2256 Write Colormap object.
2258 (void) WriteBlobString(image,"<<\n");
2259 if (compression == NoCompression)
2260 (void) WriteBlobString(image,"/Filter [ /ASCII85Decode ]\n");
2261 (void) FormatMagickString(buffer,MaxTextExtent,"/Length %lu 0 R\n",
2263 (void) WriteBlobString(image,buffer);
2264 (void) WriteBlobString(image,">>\n");
2265 (void) WriteBlobString(image,"stream\n");
2266 offset=TellBlob(image);
2267 if (compression == NoCompression)
2268 Ascii85Initialize(image);
2269 for (i=0; i < (long) image->colors; i++)
2271 if (compression == NoCompression)
2273 Ascii85Encode(image,ScaleQuantumToChar(image->colormap[i].red));
2274 Ascii85Encode(image,ScaleQuantumToChar(image->colormap[i].green));
2275 Ascii85Encode(image,ScaleQuantumToChar(image->colormap[i].blue));
2278 (void) WriteBlobByte(image,
2279 ScaleQuantumToChar(image->colormap[i].red));
2280 (void) WriteBlobByte(image,
2281 ScaleQuantumToChar(image->colormap[i].green));
2282 (void) WriteBlobByte(image,
2283 ScaleQuantumToChar(image->colormap[i].blue));
2285 if (compression == NoCompression)
2286 Ascii85Flush(image);
2287 offset=TellBlob(image)-offset;
2288 (void) WriteBlobString(image,"\nendstream\n");
2290 (void) WriteBlobString(image,"endobj\n");
2292 Write Length object.
2294 xref[object++]=TellBlob(image);
2295 (void) FormatMagickString(buffer,MaxTextExtent,"%lu 0 obj\n",object);
2296 (void) WriteBlobString(image,buffer);
2297 (void) FormatMagickString(buffer,MaxTextExtent,"%lu\n",
2298 (unsigned long) offset);
2299 (void) WriteBlobString(image,buffer);
2300 (void) WriteBlobString(image,"endobj\n");
2302 Write softmask object.
2304 xref[object++]=TellBlob(image);
2305 (void) FormatMagickString(buffer,MaxTextExtent,"%lu 0 obj\n",object);
2306 (void) WriteBlobString(image,buffer);
2307 (void) WriteBlobString(image,"<<\n");
2308 if (image->matte == MagickFalse)
2309 (void) WriteBlobString(image,">>\n");
2312 (void) WriteBlobString(image,"/Type /XObject\n");
2313 (void) WriteBlobString(image,"/Subtype /Image\n");
2314 (void) FormatMagickString(buffer,MaxTextExtent,"/Name /Ma%lu\n",
2316 (void) WriteBlobString(image,buffer);
2317 switch (compression)
2321 (void) FormatMagickString(buffer,MaxTextExtent,CFormat,
2325 case LZWCompression:
2327 (void) FormatMagickString(buffer,MaxTextExtent,CFormat,"LZWDecode");
2330 case ZipCompression:
2332 (void) FormatMagickString(buffer,MaxTextExtent,CFormat,
2338 (void) FormatMagickString(buffer,MaxTextExtent,CFormat,
2343 (void) WriteBlobString(image,buffer);
2344 (void) FormatMagickString(buffer,MaxTextExtent,"/Width %lu\n",
2346 (void) WriteBlobString(image,buffer);
2347 (void) FormatMagickString(buffer,MaxTextExtent,"/Height %lu\n",
2349 (void) WriteBlobString(image,buffer);
2350 (void) WriteBlobString(image,"/ColorSpace /DeviceGray\n");
2351 (void) FormatMagickString(buffer,MaxTextExtent,"/BitsPerComponent %d\n",
2352 (compression == FaxCompression) || (compression == Group4Compression)
2354 (void) WriteBlobString(image,buffer);
2355 (void) FormatMagickString(buffer,MaxTextExtent,"/Length %lu 0 R\n",
2357 (void) WriteBlobString(image,buffer);
2358 (void) WriteBlobString(image,">>\n");
2359 (void) WriteBlobString(image,"stream\n");
2360 offset=TellBlob(image);
2361 number_pixels=(MagickSizeType) image->columns*image->rows;
2362 switch (compression)
2364 case RLECompression:
2368 Allocate pixel array.
2370 length=(size_t) number_pixels;
2371 pixels=(unsigned char *) AcquireQuantumMemory(length,
2373 if (pixels == (unsigned char *) NULL)
2375 image=DestroyImage(image);
2376 ThrowWriterException(ResourceLimitError,
2377 "MemoryAllocationFailed");
2380 Dump Runlength encoded pixels.
2383 for (y=0; y < (long) image->rows; y++)
2385 p=GetVirtualPixels(image,0,y,image->columns,1,
2387 if (p == (const PixelPacket *) NULL)
2389 for (x=0; x < (long) image->columns; x++)
2391 *q++=ScaleQuantumToChar((Quantum) (GetAlphaPixelComponent(p)));
2395 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2396 if (compression == ZipCompression)
2397 status=ZLIBEncodeImage(image,length,pixels);
2400 if (compression == LZWCompression)
2401 status=LZWEncodeImage(image,length,pixels);
2403 status=PackbitsEncodeImage(image,length,pixels);
2404 pixels=(unsigned char *) RelinquishMagickMemory(pixels);
2405 if (status == MagickFalse)
2407 (void) CloseBlob(image);
2408 return(MagickFalse);
2415 Dump uncompressed PseudoColor packets.
2417 Ascii85Initialize(image);
2418 for (y=0; y < (long) image->rows; y++)
2420 p=GetVirtualPixels(image,0,y,image->columns,1,
2422 if (p == (const PixelPacket *) NULL)
2424 for (x=0; x < (long) image->columns; x++)
2426 Ascii85Encode(image,ScaleQuantumToChar((Quantum) (QuantumRange-
2427 GetOpacityPixelComponent(p))));
2431 Ascii85Flush(image);
2435 offset=TellBlob(image)-offset;
2436 (void) WriteBlobString(image,"\nendstream\n");
2438 (void) WriteBlobString(image,"endobj\n");
2440 Write Length object.
2442 xref[object++]=TellBlob(image);
2443 (void) FormatMagickString(buffer,MaxTextExtent,"%lu 0 obj\n",object);
2444 (void) WriteBlobString(image,buffer);
2445 (void) FormatMagickString(buffer,MaxTextExtent,"%lu\n",(unsigned long)
2447 (void) WriteBlobString(image,buffer);
2448 (void) WriteBlobString(image,"endobj\n");
2449 if (GetNextImageInList(image) == (Image *) NULL)
2451 image=SyncNextImageInList(image);
2452 status=SetImageProgress(image,SaveImagesTag,scene++,
2453 GetImageListLength(image));
2454 if (status == MagickFalse)
2456 } while (image_info->adjoin != MagickFalse);
2458 Write Metadata object.
2460 xref[object++]=TellBlob(image);
2462 (void) FormatMagickString(buffer,MaxTextExtent,"%lu 0 obj\n",object);
2463 (void) WriteBlobString(image,buffer);
2464 (void) WriteBlobString(image,"<<\n");
2465 (void) FormatMagickString(buffer,MaxTextExtent,"/Title (%s)\n",
2466 EscapeParenthesis(image->filename));
2467 (void) WriteBlobString(image,buffer);
2468 seconds=time((time_t *) NULL);
2469 #if defined(MAGICKCORE_HAVE_LOCALTIME_R)
2470 (void) localtime_r(&seconds,&local_time);
2472 (void) memcpy(&local_time,localtime(&seconds),sizeof(local_time));
2474 (void) FormatMagickString(date,MaxTextExtent,"D:%04d%02d%02d%02d%02d%02d",
2475 local_time.tm_year+1900,local_time.tm_mon+1,local_time.tm_mday,
2476 local_time.tm_hour,local_time.tm_min,local_time.tm_sec);
2477 (void) FormatMagickString(buffer,MaxTextExtent,"/CreationDate (%s)\n",date);
2478 (void) WriteBlobString(image,buffer);
2479 (void) FormatMagickString(buffer,MaxTextExtent,"/ModDate (%s)\n",date);
2480 (void) WriteBlobString(image,buffer);
2481 (void) FormatMagickString(buffer,MaxTextExtent,"/Producer (%s)\n",
2482 EscapeParenthesis(GetMagickVersion((unsigned long *) NULL)));
2483 (void) WriteBlobString(image,buffer);
2484 (void) WriteBlobString(image,">>\n");
2485 (void) WriteBlobString(image,"endobj\n");
2489 offset=TellBlob(image)-xref[0]+10;
2490 (void) WriteBlobString(image,"xref\n");
2491 (void) FormatMagickString(buffer,MaxTextExtent,"0 %lu\n",object+1);
2492 (void) WriteBlobString(image,buffer);
2493 (void) WriteBlobString(image,"0000000000 65535 f \n");
2494 for (i=0; i < (long) object; i++)
2496 (void) FormatMagickString(buffer,MaxTextExtent,"%010lu 00000 n \n",
2497 (unsigned long) xref[i]);
2498 (void) WriteBlobString(image,buffer);
2500 (void) WriteBlobString(image,"trailer\n");
2501 (void) WriteBlobString(image,"<<\n");
2502 (void) FormatMagickString(buffer,MaxTextExtent,"/Size %lu\n",object+1);
2503 (void) WriteBlobString(image,buffer);
2504 (void) FormatMagickString(buffer,MaxTextExtent,"/Info %lu 0 R\n",info_id);
2505 (void) WriteBlobString(image,buffer);
2506 (void) FormatMagickString(buffer,MaxTextExtent,"/Root %lu 0 R\n",root_id);
2507 (void) WriteBlobString(image,buffer);
2508 (void) WriteBlobString(image,">>\n");
2509 (void) WriteBlobString(image,"startxref\n");
2510 (void) FormatMagickString(buffer,MaxTextExtent,"%lu\n",
2511 (unsigned long) offset);
2512 (void) WriteBlobString(image,buffer);
2513 (void) WriteBlobString(image,"%%EOF\n");
2514 xref=(MagickOffsetType *) RelinquishMagickMemory(xref);
2515 (void) CloseBlob(image);