X-Git-Url: https://granicus.if.org/sourcecode?a=blobdiff_plain;f=coders%2Fpdf.c;h=61535ba72488428cee3f045e47d15a2514b47c6c;hb=77b33baacfae08c3794dd19df1862fb645ebe265;hp=850994027a852db5edce55bbf69a2972b0036c42;hpb=48853f123c49f159ce4f5b20f0768a8987800bd0;p=imagemagick diff --git a/coders/pdf.c b/coders/pdf.c index 850994027..61535ba72 100644 --- a/coders/pdf.c +++ b/coders/pdf.c @@ -17,7 +17,7 @@ % July 1992 % % % % % -% Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization % +% Copyright 1999-2013 ImageMagick Studio LLC, a non-profit organization % % dedicated to making software imaging solutions freely available. % % % % You may not use this file except in compliance with the License. You may % @@ -70,9 +70,11 @@ #include "MagickCore/quantum-private.h" #include "MagickCore/resource_.h" #include "MagickCore/resize.h" +#include "MagickCore/signature.h" #include "MagickCore/static.h" #include "MagickCore/string_.h" #include "MagickCore/module.h" +#include "MagickCore/token.h" #include "MagickCore/transform.h" #include "MagickCore/utility.h" #include "MagickCore/module.h" @@ -180,6 +182,8 @@ static MagickBooleanType InvokePDFDelegate(const MagickBooleanType verbose, } code=0; argv=StringToArgv(command,&argc); + if (argv == (char **) NULL) + return(MagickFalse); status=(ghost_info->init_with_args)(interpreter,argc-1,argv+1); if (status == 0) status=(ghost_info->run_string)(interpreter,"systemdict /start get exec\n", @@ -292,7 +296,9 @@ static MagickBooleanType IsPDFRendered(const char *path) static Image *ReadPDFImage(const ImageInfo *image_info,ExceptionInfo *exception) { +#define CMYKProcessColor "CMYKProcessColor" #define CropBox "CropBox" +#define DefaultCMYK "DefaultCMYK" #define DeviceCMYK "DeviceCMYK" #define MediaBox "MediaBox" #define RenderPostscriptText "Rendering Postscript... " @@ -405,24 +411,32 @@ static Image *ReadPDFImage(const ImageInfo *image_info,ExceptionInfo *exception) if ((flags & SigmaValue) == 0) image->resolution.y=image->resolution.x; } + if (image_info->density != (char *) NULL) + { + flags=ParseGeometry(image_info->density,&geometry_info); + image->resolution.x=geometry_info.rho; + image->resolution.y=geometry_info.sigma; + if ((flags & SigmaValue) == 0) + image->resolution.y=image->resolution.x; + } + (void) ParseAbsoluteGeometry(PSPageGeometry,&page); + if (image_info->page != (char *) NULL) + (void) ParseAbsoluteGeometry(image_info->page,&page); + page.width=(size_t) ceil((double) (page.width*image->resolution.x/delta.x)- + 0.5); + page.height=(size_t) ceil((double) (page.height*image->resolution.y/delta.y)- + 0.5); /* Determine page geometry from the PDF media box. */ cmyk=image_info->colorspace == CMYKColorspace ? MagickTrue : MagickFalse; - cropbox=MagickFalse; - option=GetImageOption(image_info,"pdf:use-cropbox"); - if (option != (const char *) NULL) - cropbox=IsMagickTrue(option); - trimbox=MagickFalse; - option=GetImageOption(image_info,"pdf:use-trimbox"); - if (option != (const char *) NULL) - trimbox=IsMagickTrue(option); + cropbox=IsStringTrue(GetImageOption(image_info,"pdf:use-cropbox")); + trimbox=IsStringTrue(GetImageOption(image_info,"pdf:use-trimbox")); count=0; spotcolor=0; (void) ResetMagickMemory(&bounding_box,0,sizeof(bounding_box)); (void) ResetMagickMemory(&bounds,0,sizeof(bounds)); (void) ResetMagickMemory(&hires_bounds,0,sizeof(hires_bounds)); - (void) ResetMagickMemory(&page,0,sizeof(page)); (void) ResetMagickMemory(command,0,sizeof(command)); angle=0.0; p=command; @@ -444,8 +458,12 @@ static Image *ReadPDFImage(const ImageInfo *image_info,ExceptionInfo *exception) /* Is this a CMYK document? */ + if (LocaleNCompare(DefaultCMYK,command,strlen(DefaultCMYK)) == 0) + cmyk=MagickTrue; if (LocaleNCompare(DeviceCMYK,command,strlen(DeviceCMYK)) == 0) cmyk=MagickTrue; + if (LocaleNCompare(CMYKProcessColor,command,strlen(CMYKProcessColor)) == 0) + cmyk=MagickTrue; if (LocaleNCompare(SpotColor,command,strlen(SpotColor)) == 0) { char @@ -477,6 +495,8 @@ static Image *ReadPDFImage(const ImageInfo *image_info,ExceptionInfo *exception) } if (LocaleNCompare(PDFVersion,command,strlen(PDFVersion)) == 0) (void) SetImageProperty(image,"pdf:Version",command,exception); + if (image_info->page != (char *) NULL) + continue; count=0; if (cropbox != MagickFalse) { @@ -521,9 +541,13 @@ static Image *ReadPDFImage(const ImageInfo *image_info,ExceptionInfo *exception) } if (count != 4) continue; + if ((fabs(bounds.x2-bounds.x1) <= fabs(hires_bounds.x2-hires_bounds.x1)) || + (fabs(bounds.y2-bounds.y1) <= fabs(hires_bounds.y2-hires_bounds.y1))) + continue; hires_bounds=bounds; } - if ((hires_bounds.x2 != 0.0) && (hires_bounds.y2 != 0.0)) + if ((fabs(hires_bounds.x2-hires_bounds.x1) >= MagickEpsilon) && + (fabs(hires_bounds.y2-hires_bounds.y1) >= MagickEpsilon)) { /* Set PDF render geometry. @@ -532,8 +556,10 @@ static Image *ReadPDFImage(const ImageInfo *image_info,ExceptionInfo *exception) hires_bounds.x2-bounds.x1,hires_bounds.y2-hires_bounds.y1, hires_bounds.x1,hires_bounds.y1); (void) SetImageProperty(image,"pdf:HiResBoundingBox",geometry,exception); - page.width=(size_t) floor(hires_bounds.x2-hires_bounds.x1+0.5); - page.height=(size_t) floor(hires_bounds.y2-hires_bounds.y1+0.5); + page.width=(size_t) ceil((double) ((hires_bounds.x2-hires_bounds.x1)* + image->resolution.x/delta.x)-0.5); + page.height=(size_t) ceil((double) ((hires_bounds.y2-hires_bounds.y1)* + image->resolution.y/delta.y)-0.5); } (void) CloseBlob(image); if ((fabs(angle) == 90.0) || (fabs(angle) == 270.0)) @@ -545,7 +571,7 @@ static Image *ReadPDFImage(const ImageInfo *image_info,ExceptionInfo *exception) page.width=page.height; page.height=swap; } - if (IsRGBColorspace(image_info->colorspace) != MagickFalse) + if (IssRGBCompatibleColorspace(image_info->colorspace) != MagickFalse) cmyk=MagickFalse; /* Create Ghostscript control file. @@ -578,26 +604,11 @@ static Image *ReadPDFImage(const ImageInfo *image_info,ExceptionInfo *exception) return((Image *) NULL); } *options='\0'; - if (image_info->density != (char *) NULL) - { - flags=ParseGeometry(image_info->density,&geometry_info); - image->resolution.x=geometry_info.rho; - image->resolution.y=geometry_info.sigma; - if ((flags & SigmaValue) == 0) - image->resolution.y=image->resolution.x; - } (void) FormatLocaleString(density,MaxTextExtent,"%gx%g",image->resolution.x, image->resolution.y); if (image_info->page != (char *) NULL) - { - (void) ParseAbsoluteGeometry(image_info->page,&page); - page.width=(size_t) floor((double) (page.width*image->resolution.x/ - delta.x)+0.5); - page.height=(size_t) floor((double) (page.height*image->resolution.y/ - delta.y)+0.5); - (void) FormatLocaleString(options,MaxTextExtent,"-g%.20gx%.20g ",(double) - page.width,(double) page.height); - } + (void) FormatLocaleString(options,MaxTextExtent,"-g%.20gx%.20g ",(double) + page.width,(double) page.height); if (cmyk != MagickFalse) (void) ConcatenateMagickString(options,"-dUseCIEColor ",MaxTextExtent); if (cropbox != MagickFalse) @@ -625,7 +636,7 @@ static Image *ReadPDFImage(const ImageInfo *image_info,ExceptionInfo *exception) " -sPCLPassword=%s",option); (void) CopyMagickString(filename,read_info->filename,MaxTextExtent); (void) AcquireUniqueFilename(filename); - (void) ConcatenateMagickString(filename,"-%08d",MaxTextExtent); + (void) ConcatenateMagickString(filename,"%d",MaxTextExtent); (void) FormatLocaleString(command,MaxTextExtent, GetDelegateCommands(delegate_info), read_info->antialias != MagickFalse ? 4 : 1, @@ -651,6 +662,8 @@ static Image *ReadPDFImage(const ImageInfo *image_info,ExceptionInfo *exception) read_info->filename,exception); if (IsPDFRendered(read_info->filename) == MagickFalse) break; + read_info->blob=NULL; + read_info->length=0; next=ReadImage(read_info,exception); (void) RelinquishUniqueFileResource(read_info->filename); if (next == (Image *) NULL) @@ -749,7 +762,6 @@ ModuleExport size_t RegisterPDFImage(void) entry->adjoin=MagickFalse; entry->blob_support=MagickFalse; entry->seekable_stream=MagickTrue; - entry->thread_support=EncoderThreadSupport; entry->description=ConstantString("Adobe Illustrator CS2"); entry->module=ConstantString("PDF"); (void) RegisterMagickInfo(entry); @@ -759,7 +771,6 @@ ModuleExport size_t RegisterPDFImage(void) entry->adjoin=MagickFalse; entry->blob_support=MagickFalse; entry->seekable_stream=MagickTrue; - entry->thread_support=EncoderThreadSupport; entry->description=ConstantString("Encapsulated Portable Document Format"); entry->module=ConstantString("PDF"); (void) RegisterMagickInfo(entry); @@ -769,7 +780,6 @@ ModuleExport size_t RegisterPDFImage(void) entry->magick=(IsImageFormatHandler *) IsPDF; entry->blob_support=MagickFalse; entry->seekable_stream=MagickTrue; - entry->thread_support=EncoderThreadSupport; entry->description=ConstantString("Portable Document Format"); entry->module=ConstantString("PDF"); (void) RegisterMagickInfo(entry); @@ -779,7 +789,6 @@ ModuleExport size_t RegisterPDFImage(void) entry->magick=(IsImageFormatHandler *) IsPDF; entry->blob_support=MagickFalse; entry->seekable_stream=MagickTrue; - entry->thread_support=EncoderThreadSupport; entry->description=ConstantString("Portable Document Archive Format"); entry->module=ConstantString("PDF"); (void) RegisterMagickInfo(entry); @@ -944,6 +953,11 @@ static MagickBooleanType WritePDFImage(const ImageInfo *image_info,Image *image, " \n" " application/pdf\n" + " \n" + " \n" + " %s\n" + " \n" + " \n" " \n" " \n" @@ -956,7 +970,7 @@ static MagickBooleanType WritePDFImage(const ImageInfo *image_info,Image *image, " \n" " \n" - " 1\n" + " 2\n" " B\n" " \n" " \n" @@ -1073,12 +1087,12 @@ static MagickBooleanType WritePDFImage(const ImageInfo *image_info,Image *image, if (image_info->compression == JPEG2000Compression) version=(size_t) MagickMax(version,5); for (next=image; next != (Image *) NULL; next=GetNextImageInList(next)) - if (next->matte != MagickFalse) + if (next->alpha_trait == BlendPixelTrait) version=(size_t) MagickMax(version,4); if (LocaleCompare(image_info->magick,"PDFA") == 0) version=(size_t) MagickMax(version,6); - (void) FormatLocaleString(buffer,MaxTextExtent,"%%PDF-1.%.20g \n", - (double) version); + (void) FormatLocaleString(buffer,MaxTextExtent,"%%PDF-1.%.20g \n",(double) + version); (void) WriteBlobString(image,buffer); if (LocaleCompare(image_info->magick,"PDFA") == 0) (void) WriteBlobString(image,"%âãÏÓ\n"); @@ -1092,8 +1106,8 @@ static MagickBooleanType WritePDFImage(const ImageInfo *image_info,Image *image, (void) WriteBlobString(image,buffer); (void) WriteBlobString(image,"<<\n"); if (LocaleCompare(image_info->magick,"PDFA") != 0) - (void) FormatLocaleString(buffer,MaxTextExtent,"/Pages %.20g 0 R\n", - (double) object+1); + (void) FormatLocaleString(buffer,MaxTextExtent,"/Pages %.20g 0 R\n",(double) + object+1); else { (void) FormatLocaleString(buffer,MaxTextExtent,"/Metadata %.20g 0 R\n", @@ -1106,6 +1120,7 @@ static MagickBooleanType WritePDFImage(const ImageInfo *image_info,Image *image, (void) WriteBlobString(image,"/Type /Catalog\n"); (void) WriteBlobString(image,">>\n"); (void) WriteBlobString(image,"endobj\n"); + GetPathComponent(image->filename,BasePath,basename); if (LocaleCompare(image_info->magick,"PDFA") == 0) { char @@ -1121,8 +1136,8 @@ static MagickBooleanType WritePDFImage(const ImageInfo *image_info,Image *image, Write XMP object. */ xref[object++]=TellBlob(image); - (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g 0 obj\n", - (double) object); + (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g 0 obj\n",(double) + object); (void) WriteBlobString(image,buffer); (void) WriteBlobString(image,"<<\n"); (void) WriteBlobString(image,"/Subtype /XML\n"); @@ -1137,14 +1152,15 @@ static MagickBooleanType WritePDFImage(const ImageInfo *image_info,Image *image, (void) FormatMagickTime(time((time_t *) NULL),MaxTextExtent,timestamp); i=FormatLocaleString(xmp_profile,MaxTextExtent,XMPProfile, XMPProfileMagick,modify_date,create_date,timestamp, - GetMagickVersion(&version),GetMagickVersion(&version)); - (void) FormatLocaleString(buffer,MaxTextExtent,"/Length %.20g\n", - (double) i); + GetMagickVersion(&version),EscapeParenthesis(basename), + GetMagickVersion(&version)); + (void) FormatLocaleString(buffer,MaxTextExtent,"/Length %.20g\n",(double) + i); (void) WriteBlobString(image,buffer); (void) WriteBlobString(image,"/Type /Metadata\n"); (void) WriteBlobString(image,">>\nstream\n"); (void) WriteBlobString(image,xmp_profile); - (void) WriteBlobString(image,"endstream\n"); + (void) WriteBlobString(image,"\nendstream\n"); (void) WriteBlobString(image,"endobj\n"); } /* @@ -1157,8 +1173,8 @@ static MagickBooleanType WritePDFImage(const ImageInfo *image_info,Image *image, (void) WriteBlobString(image,buffer); (void) WriteBlobString(image,"<<\n"); (void) WriteBlobString(image,"/Type /Pages\n"); - (void) FormatLocaleString(buffer,MaxTextExtent,"/Kids [ %.20g 0 R ", - (double) object+1); + (void) FormatLocaleString(buffer,MaxTextExtent,"/Kids [ %.20g 0 R ",(double) + object+1); (void) WriteBlobString(image,buffer); count=(ssize_t) (pages_id+ObjectsPerImage+1); if (image_info->adjoin != MagickFalse) @@ -1183,8 +1199,8 @@ static MagickBooleanType WritePDFImage(const ImageInfo *image_info,Image *image, ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); } (void) WriteBlobString(image,"]\n"); - (void) FormatLocaleString(buffer,MaxTextExtent,"/Count %.20g\n", - (double) ((count-pages_id)/ObjectsPerImage)); + (void) FormatLocaleString(buffer,MaxTextExtent,"/Count %.20g\n",(double) + ((count-pages_id)/ObjectsPerImage)); (void) WriteBlobString(image,buffer); (void) WriteBlobString(image,">>\n"); (void) WriteBlobString(image,"endobj\n"); @@ -1200,7 +1216,7 @@ static MagickBooleanType WritePDFImage(const ImageInfo *image_info,Image *image, case Group4Compression: { if ((IsImageMonochrome(image,exception) == MagickFalse) || - (image->matte != MagickFalse)) + (image->alpha_trait == BlendPixelTrait)) compression=RLECompression; break; } @@ -1251,8 +1267,8 @@ static MagickBooleanType WritePDFImage(const ImageInfo *image_info,Image *image, } if (compression == JPEG2000Compression) { - if (IsRGBColorspace(image->colorspace) == MagickFalse) - (void) TransformImageColorspace(image,RGBColorspace,exception); + if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse) + (void) TransformImageColorspace(image,sRGBColorspace,exception); } /* Scale relative to dots-per-inch. @@ -1283,16 +1299,15 @@ static MagickBooleanType WritePDFImage(const ImageInfo *image_info,Image *image, resolution.y=(double) ((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); + (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); + "%.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,"PDF") == 0)) @@ -1361,8 +1376,8 @@ static MagickBooleanType WritePDFImage(const ImageInfo *image_info,Image *image, (void) FormatLocaleString(buffer,MaxTextExtent,"/Contents %.20g 0 R\n", (double) object+1); (void) WriteBlobString(image,buffer); - (void) FormatLocaleString(buffer,MaxTextExtent,"/Thumb %.20g 0 R\n", - (double) object+8); + (void) FormatLocaleString(buffer,MaxTextExtent,"/Thumb %.20g 0 R\n",(double) + object+8); (void) WriteBlobString(image,buffer); (void) WriteBlobString(image,">>\n"); (void) WriteBlobString(image,"endobj\n"); @@ -1400,12 +1415,12 @@ static MagickBooleanType WritePDFImage(const ImageInfo *image_info,Image *image, (void) FormatLocaleString(buffer,MaxTextExtent,"%g 0 0 %g %.20g %.20g cm\n", scale.x,scale.y,(double) geometry.x,(double) geometry.y); (void) WriteBlobString(image,buffer); - (void) FormatLocaleString(buffer,MaxTextExtent,"/Im%.20g Do\n", - (double) image->scene); + (void) FormatLocaleString(buffer,MaxTextExtent,"/Im%.20g Do\n",(double) + image->scene); (void) WriteBlobString(image,buffer); (void) WriteBlobString(image,"Q\n"); offset=TellBlob(image)-offset; - (void) WriteBlobString(image,"endstream\n"); + (void) WriteBlobString(image,"\nendstream\n"); (void) WriteBlobString(image,"endobj\n"); /* Write Length object. @@ -1421,8 +1436,8 @@ static MagickBooleanType WritePDFImage(const ImageInfo *image_info,Image *image, Write Procset object. */ xref[object++]=TellBlob(image); - (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g 0 obj\n", - (double) object); + (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g 0 obj\n",(double) + object); (void) WriteBlobString(image,buffer); if ((image->storage_class == DirectClass) || (image->colors > 256)) (void) CopyMagickString(buffer,"[ /PDF /Text /ImageC",MaxTextExtent); @@ -1438,8 +1453,8 @@ static MagickBooleanType WritePDFImage(const ImageInfo *image_info,Image *image, Write Font object. */ xref[object++]=TellBlob(image); - (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g 0 obj\n", - (double) object); + (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g 0 obj\n",(double) + object); (void) WriteBlobString(image,buffer); (void) WriteBlobString(image,"<<\n"); if (labels != (char **) NULL) @@ -1465,8 +1480,8 @@ static MagickBooleanType WritePDFImage(const ImageInfo *image_info,Image *image, (void) WriteBlobString(image,"<<\n"); (void) WriteBlobString(image,"/Type /XObject\n"); (void) WriteBlobString(image,"/Subtype /Image\n"); - (void) FormatLocaleString(buffer,MaxTextExtent,"/Name /Im%.20g\n", - (double) image->scene); + (void) FormatLocaleString(buffer,MaxTextExtent,"/Name /Im%.20g\n",(double) + image->scene); (void) WriteBlobString(image,buffer); switch (compression) { @@ -1537,7 +1552,7 @@ static MagickBooleanType WritePDFImage(const ImageInfo *image_info,Image *image, (compression == FaxCompression) || (compression == Group4Compression) ? 1 : 8); (void) WriteBlobString(image,buffer); - if (image->matte != MagickFalse) + if (image->alpha_trait == BlendPixelTrait) { (void) FormatLocaleString(buffer,MaxTextExtent,"/SMask %.20g 0 R\n", (double) object+7); @@ -1880,8 +1895,7 @@ static MagickBooleanType WritePDFImage(const ImageInfo *image_info,Image *image, (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g 0 obj\n",(double) object); (void) WriteBlobString(image,buffer); - (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g\n", - (double) offset); + (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g\n",(double) offset); (void) WriteBlobString(image,buffer); (void) WriteBlobString(image,"endobj\n"); /* @@ -2257,7 +2271,7 @@ static MagickBooleanType WritePDFImage(const ImageInfo *image_info,Image *image, for (x=0; x < (ssize_t) tile_image->columns; x++) { *q++=(unsigned char) GetPixelIndex(tile_image,p); - q+=GetPixelChannels(image); + p+=GetPixelChannels(tile_image); } } #if defined(MAGICKCORE_ZLIB_DELEGATE) @@ -2319,13 +2333,15 @@ static MagickBooleanType WritePDFImage(const ImageInfo *image_info,Image *image, (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g 0 obj\n",(double) object); (void) WriteBlobString(image,buffer); - if ((image->storage_class != DirectClass) && (image->colors <= 256) && - (compression != FaxCompression) && (compression != Group4Compression)) + (void) WriteBlobString(image,"<<\n"); + if ((image->storage_class == DirectClass) || (image->colors > 256) || + (compression == FaxCompression) || (compression == Group4Compression)) + (void) WriteBlobString(image,">>\n"); + else { /* Write Colormap object. */ - (void) WriteBlobString(image,"<<\n"); if (compression == NoCompression) (void) WriteBlobString(image,"/Filter [ /ASCII85Decode ]\n"); (void) FormatLocaleString(buffer,MaxTextExtent,"/Length %.20g 0 R\n", @@ -2377,7 +2393,7 @@ static MagickBooleanType WritePDFImage(const ImageInfo *image_info,Image *image, object); (void) WriteBlobString(image,buffer); (void) WriteBlobString(image,"<<\n"); - if (image->matte == MagickFalse) + if (image->alpha_trait != BlendPixelTrait) (void) WriteBlobString(image,">>\n"); else { @@ -2413,8 +2429,8 @@ static MagickBooleanType WritePDFImage(const ImageInfo *image_info,Image *image, } } (void) WriteBlobString(image,buffer); - (void) FormatLocaleString(buffer,MaxTextExtent,"/Width %.20g\n", - (double) image->columns); + (void) FormatLocaleString(buffer,MaxTextExtent,"/Width %.20g\n",(double) + image->columns); (void) WriteBlobString(image,buffer); (void) FormatLocaleString(buffer,MaxTextExtent,"/Height %.20g\n", (double) image->rows); @@ -2532,7 +2548,6 @@ static MagickBooleanType WritePDFImage(const ImageInfo *image_info,Image *image, object); (void) WriteBlobString(image,buffer); (void) WriteBlobString(image,"<<\n"); - GetPathComponent(image->filename,BasePath,basename); (void) FormatLocaleString(buffer,MaxTextExtent,"/Title (%s)\n", EscapeParenthesis(basename)); (void) WriteBlobString(image,buffer); @@ -2557,7 +2572,8 @@ static MagickBooleanType WritePDFImage(const ImageInfo *image_info,Image *image, /* Write Xref object. */ - offset=TellBlob(image)-xref[0]+10; + offset=TellBlob(image)-xref[0]+ + (LocaleCompare(image_info->magick,"PDFA") == 0 ? 6 : 0)+10; (void) WriteBlobString(image,"xref\n"); (void) FormatLocaleString(buffer,MaxTextExtent,"0 %.20g\n",(double) object+1); @@ -2580,6 +2596,11 @@ static MagickBooleanType WritePDFImage(const ImageInfo *image_info,Image *image, (void) FormatLocaleString(buffer,MaxTextExtent,"/Root %.20g 0 R\n",(double) root_id); (void) WriteBlobString(image,buffer); + (void) SignatureImage(image,exception); + (void) FormatLocaleString(buffer,MaxTextExtent,"/ID [<%s> <%s>]\n", + GetImageProperty(image,"signature",exception), + GetImageProperty(image,"signature",exception)); + (void) WriteBlobString(image,buffer); (void) WriteBlobString(image,">>\n"); (void) WriteBlobString(image,"startxref\n"); (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g\n",(double) offset);