pdf.c

Go to the documentation of this file.
00001 /*
00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00003 %                                                                             %
00004 %                                                                             %
00005 %                                                                             %
00006 %                            PPPP   DDDD   FFFFF                              %
00007 %                            P   P  D   D  F                                  %
00008 %                            PPPP   D   D  FFF                                %
00009 %                            P      D   D  F                                  %
00010 %                            P      DDDD   F                                  %
00011 %                                                                             %
00012 %                                                                             %
00013 %                   Read/Write Portable Document Format.                      %
00014 %                                                                             %
00015 %                              Software Design                                %
00016 %                                John Cristy                                  %
00017 %                                 July 1992                                   %
00018 %                                                                             %
00019 %                                                                             %
00020 %  Copyright 1999-2005 ImageMagick Studio LLC, a non-profit organization      %
00021 %  dedicated to making software imaging solutions freely available.           %
00022 %                                                                             %
00023 %  You may not use this file except in compliance with the License.  You may  %
00024 %  obtain a copy of the License at                                            %
00025 %                                                                             %
00026 %    http://www.imagemagick.org/www/Copyright.html                            %
00027 %                                                                             %
00028 %  Unless required by applicable law or agreed to in writing, software        %
00029 %  distributed under the License is distributed on an "AS IS" BASIS,          %
00030 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
00031 %  See the License for the specific language governing permissions and        %
00032 %  limitations under the License.                                             %
00033 %                                                                             %
00034 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00035 %
00036 %
00037 */
00038 
00039 /*
00040   Include declarations.
00041 */
00042 #include "magick/studio.h"
00043 #include "magick/attribute.h"
00044 #include "magick/blob.h"
00045 #include "magick/blob-private.h"
00046 #include "magick/color.h"
00047 #include "magick/color-private.h"
00048 #include "magick/compress.h"
00049 #include "magick/constitute.h"
00050 #include "magick/delegate.h"
00051 #include "magick/exception.h"
00052 #include "magick/exception-private.h"
00053 #include "magick/geometry.h"
00054 #include "magick/image.h"
00055 #include "magick/image-private.h"
00056 #include "magick/list.h"
00057 #include "magick/magick.h"
00058 #include "magick/memory_.h"
00059 #include "magick/monitor.h"
00060 #include "magick/resource_.h"
00061 #include "magick/resize.h"
00062 #include "magick/static.h"
00063 #include "magick/string_.h"
00064 #include "magick/transform.h"
00065 #include "magick/utility.h"
00066 #include "magick/version.h"
00067 #if defined(HasTIFF)
00068 #define CCITTParam  "-1"
00069 #else
00070 #define CCITTParam  "0"
00071 #endif
00072 
00073 /*
00074   Forward declarations.
00075 */
00076 static MagickBooleanType
00077   WritePDFImage(const ImageInfo *,Image *);
00078 
00079 /*
00080 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00081 %                                                                             %
00082 %                                                                             %
00083 %                                                                             %
00084 %   I s P D F                                                                 %
00085 %                                                                             %
00086 %                                                                             %
00087 %                                                                             %
00088 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00089 %
00090 %  IsPDF() returns MagickTrue if the image format type, identified by the
00091 %  magick string, is PDF.
00092 %
00093 %  The format of the IsPDF method is:
00094 %
00095 %      MagickBooleanType IsPDF(const unsigned char *magick,const size_t offset)
00096 %
00097 %  A description of each parameter follows:
00098 %
00099 %    o magick: This string is generally the first few bytes of an image file
00100 %      or blob.
00101 %
00102 %    o offset: Specifies the offset of the magick string.
00103 %
00104 %
00105 */
00106 static MagickBooleanType IsPDF(const unsigned char *magick,const size_t offset)
00107 {
00108   if (offset < 5)
00109     return(MagickFalse);
00110   if (LocaleNCompare((char *) magick,"%PDF-",5) == 0)
00111     return(MagickTrue);
00112   return(MagickFalse);
00113 }
00114 
00115 /*
00116 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00117 %                                                                             %
00118 %                                                                             %
00119 %                                                                             %
00120 %   R e a d P D F I m a g e                                                   %
00121 %                                                                             %
00122 %                                                                             %
00123 %                                                                             %
00124 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00125 %
00126 %  ReadPDFImage() reads a Portable Document Format image file and
00127 %  returns it.  It allocates the memory necessary for the new Image structure
00128 %  and returns a pointer to the new image.
00129 %
00130 %  The format of the ReadPDFImage method is:
00131 %
00132 %      Image *ReadPDFImage(const ImageInfo *image_info,ExceptionInfo *exception)
00133 %
00134 %  A description of each parameter follows:
00135 %
00136 %    o image_info: The image info.
00137 %
00138 %    o exception: return any errors or warnings in this structure.
00139 %
00140 %
00141 */
00142 static Image *ReadPDFImage(const ImageInfo *image_info,ExceptionInfo *exception)
00143 {
00144 #define CropBox  "CropBox"
00145 #define DeviceCMYK  "DeviceCMYK"
00146 #define MediaBox  "MediaBox"
00147 #define RenderPostscriptText  "  Rendering postscript...  "
00148 
00149   char
00150     command[MaxTextExtent],
00151     density[MaxTextExtent],
00152     filename[MaxTextExtent],
00153     geometry[MaxTextExtent],
00154     options[MaxTextExtent],
00155     postscript_filename[MaxTextExtent];
00156 
00157   const DelegateInfo
00158     *delegate_info;
00159 
00160   double
00161     dx_resolution,
00162     dy_resolution;
00163 
00164   Image
00165     *image,
00166     *next_image;
00167 
00168   ImageInfo
00169     *read_info;
00170 
00171   int
00172     file;
00173 
00174   MagickBooleanType
00175     cmyk,
00176     status;
00177 
00178   RectangleInfo
00179     bounding_box,
00180     page;
00181 
00182   register char
00183     *p;
00184 
00185   register long
00186     c;
00187 
00188   SegmentInfo
00189     bounds;
00190 
00191   ssize_t
00192     count;
00193 
00194   unsigned long
00195     height,
00196     width;
00197 
00198   assert(image_info != (const ImageInfo *) NULL);
00199   assert(image_info->signature == MagickSignature);
00200   if (image_info->debug != MagickFalse)
00201     (void) LogMagickEvent(TraceEvent,GetMagickModule(),image_info->filename);
00202   assert(exception != (ExceptionInfo *) NULL);
00203   assert(exception->signature == MagickSignature);
00204   /*
00205     Open image file.
00206   */
00207   image=AllocateImage(image_info);
00208   status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
00209   if (status == MagickFalse)
00210     {
00211       image=DestroyImageList(image);
00212       return((Image *) NULL);
00213     }
00214   /*
00215     Set the page density.
00216   */
00217   dx_resolution=DefaultResolution;
00218   dy_resolution=DefaultResolution;
00219   if ((image->x_resolution == 0.0) || (image->y_resolution == 0.0))
00220     {
00221       GeometryInfo
00222         geometry_info;
00223 
00224       MagickStatusType
00225         flags;
00226 
00227       flags=ParseGeometry(PSDensityGeometry,&geometry_info);
00228       image->x_resolution=geometry_info.rho;
00229       image->y_resolution=geometry_info.sigma;
00230       if ((flags & SigmaValue) == 0)
00231         image->y_resolution=image->x_resolution;
00232     }
00233   (void) FormatMagickString(density,MaxTextExtent,"%gx%g",
00234     image->x_resolution,image->y_resolution);
00235   /*
00236     Determine page geometry from the PDF media box.
00237   */
00238   cmyk=MagickFalse;
00239   count=0;
00240   (void) ResetMagickMemory(&bounding_box,0,sizeof(bounding_box));
00241   (void) ResetMagickMemory(&bounds,0,sizeof(bounds));
00242   (void) ResetMagickMemory(&page,0,sizeof(page));
00243   for (p=command; (c=ReadBlobByte(image)) != EOF; )
00244   {
00245     if (image_info->page != (char *) NULL)
00246       continue;
00247     /*
00248       Note PDF elements.
00249     */
00250     *p++=(char) c;
00251     if ((c != (int) '/') && ((size_t) (p-command) < (MaxTextExtent-1)))
00252       continue;
00253     *p='\0';
00254     p=command;
00255     /*
00256       Is this a CMYK document?
00257     */
00258     if (LocaleNCompare(DeviceCMYK,command,strlen(DeviceCMYK)) == 0)
00259       cmyk=MagickTrue;
00260     if (LocaleNCompare(CropBox,command,strlen(CropBox)) == 0)
00261       {
00262         /*
00263           Note region defined by crop box.
00264         */
00265         count=(ssize_t) sscanf(command,"CropBox [%lf %lf %lf %lf",
00266           &bounds.x1,&bounds.y1,&bounds.x2,&bounds.y2);
00267         if (count != 4)
00268           count=(ssize_t) sscanf(command,"CropBox[%lf %lf %lf %lf",
00269             &bounds.x1,&bounds.y1,&bounds.x2,&bounds.y2);
00270       }
00271     if (LocaleNCompare(MediaBox,command,strlen(MediaBox)) == 0)
00272       {
00273         /*
00274           Note region defined by media box.
00275         */
00276         count=(ssize_t) sscanf(command,"MediaBox [%lf %lf %lf %lf",
00277           &bounds.x1,&bounds.y1,&bounds.x2,&bounds.y2);
00278         if (count != 4)
00279           count=(ssize_t) sscanf(command,"MediaBox[%lf %lf %lf %lf",
00280             &bounds.x1,&bounds.y1,&bounds.x2,&bounds.y2);
00281       }
00282     if (count != 4)
00283       continue;
00284     /*
00285       Set PDF render geometry.
00286     */
00287     width=(unsigned long) (bounds.x2-bounds.x1+0.5);
00288     height=(unsigned long) (bounds.y2-bounds.y1+0.5);
00289     if (width > page.width)
00290       page.width=width;
00291     if (height > page.height)
00292       page.height=height;
00293   }
00294   CloseBlob(image);
00295   /*
00296     Create Ghostscript control file.
00297   */
00298   file=AcquireUniqueFileResource(postscript_filename);
00299   if (file == -1)
00300     {
00301       ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
00302         image_info->filename);
00303       image=DestroyImage(image);
00304       return((Image *) NULL);
00305     }
00306   (void) write(file," ",1);
00307   file=close(file)-1;
00308   /*
00309     Render postscript with the Ghostscript delegate.
00310   */
00311   if ((page.width == 0) || (page.height == 0))
00312     (void) ParseAbsoluteGeometry(PSPageGeometry,&page);
00313   if (image_info->page != (char *) NULL)
00314     (void) ParseAbsoluteGeometry(image_info->page,&page);
00315   page.width=(unsigned long)
00316     (page.width*image->x_resolution/dx_resolution+0.5);
00317   page.height=(unsigned long)
00318     (page.height*image->y_resolution/dy_resolution+0.5);
00319   image=DestroyImage(image);
00320   (void) FormatMagickString(geometry,MaxTextExtent,"%lux%lu",
00321     page.width,page.height);
00322   if (image_info->monochrome != MagickFalse)
00323     delegate_info=GetDelegateInfo("gs-mono",(char *) NULL,exception);
00324   else
00325      if (cmyk != MagickFalse)
00326        delegate_info=GetDelegateInfo("gs-cmyk",(char *) NULL,exception);
00327      else
00328        delegate_info=GetDelegateInfo("gs-color",(char *) NULL,exception);
00329   if (delegate_info == (const DelegateInfo *) NULL)
00330     {
00331       (void) RelinquishUniqueFileResource(postscript_filename);
00332       return((Image *) NULL);
00333     }
00334   *options='\0';
00335   read_info=CloneImageInfo(image_info);
00336   *read_info->magick='\0';
00337   if (read_info->number_scenes != 0)
00338     {
00339       if (read_info->number_scenes != 1)
00340         (void) FormatMagickString(options,MaxTextExtent,"-dLastPage=%lu",
00341           read_info->scene+read_info->number_scenes);
00342       else
00343         (void) FormatMagickString(options,MaxTextExtent,
00344           "-dFirstPage=%lu -dLastPage=%lu",read_info->scene+1,read_info->scene+
00345           read_info->number_scenes);
00346       read_info->number_scenes=0;
00347       if (read_info->scenes != (char *) NULL)
00348         *read_info->scenes='\0';
00349     }
00350   if (read_info->authenticate != (char *) NULL)
00351     (void) FormatMagickString(options+strlen(options),MaxTextExtent,
00352       " -sPDFPassword=%s",read_info->authenticate);
00353   (void) CopyMagickString(filename,read_info->filename,MaxTextExtent);
00354   (void) AcquireUniqueFilename(read_info->filename);
00355   (void) FormatMagickString(command,MaxTextExtent,
00356     GetDelegateCommands(delegate_info),
00357     read_info->antialias != MagickFalse ? 4 : 1,
00358     read_info->antialias != MagickFalse ? 4 : 1,geometry,density,options,
00359     read_info->filename,postscript_filename,image_info->filename);
00360   status=InvokePostscriptDelegate(read_info->verbose,command);
00361   image=ReadImage(read_info,exception);
00362   (void) RelinquishUniqueFileResource(postscript_filename);
00363   (void) RelinquishUniqueFileResource(read_info->filename);
00364   read_info=DestroyImageInfo(read_info);
00365   if (image == (Image *) NULL)
00366     ThrowReaderException(DelegateError,"PostscriptDelegateFailed");
00367   if (LocaleCompare(image->magick,"BMP") == 0)
00368     {
00369       Image
00370         *cmyk_image;
00371 
00372       cmyk_image=ConsolidateCMYKImages(image,&image->exception);
00373       if (cmyk_image != (Image *) NULL)
00374         {
00375           image=DestroyImageList(image);
00376           image=cmyk_image;
00377         }
00378     }
00379   do
00380   {
00381     (void) CopyMagickString(image->filename,filename,MaxTextExtent);
00382     image->page=page;
00383     next_image=SyncNextImageInList(image);
00384     if (next_image != (Image *) NULL)
00385       image=next_image;
00386   } while (next_image != (Image *) NULL);
00387   return(GetFirstImageInList(image));
00388 }
00389 
00390 /*
00391 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00392 %                                                                             %
00393 %                                                                             %
00394 %                                                                             %
00395 %   R e g i s t e r P D F I m a g e                                           %
00396 %                                                                             %
00397 %                                                                             %
00398 %                                                                             %
00399 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00400 %
00401 %  RegisterPDFImage() adds attributes for the PDF image format to
00402 %  the list of supported formats.  The attributes include the image format
00403 %  tag, a method to read and/or write the format, whether the format
00404 %  supports the saving of more than one frame to the same file or blob,
00405 %  whether the format supports native in-memory I/O, and a brief
00406 %  description of the format.
00407 %
00408 %  The format of the RegisterPDFImage method is:
00409 %
00410 %      RegisterPDFImage(void)
00411 %
00412 */
00413 ModuleExport void RegisterPDFImage(void)
00414 {
00415   MagickInfo
00416     *entry;
00417 
00418   entry=SetMagickInfo("EPDF");
00419   entry->decoder=(DecoderHandler *) ReadPDFImage;
00420   entry->encoder=(EncoderHandler *) WritePDFImage;
00421   entry->adjoin=MagickFalse;
00422   entry->blob_support=MagickFalse;
00423   entry->seekable_stream=MagickTrue;
00424   entry->description=AcquireString("Encapsulated Portable Document Format");
00425   entry->module=AcquireString("PDF");
00426   (void) RegisterMagickInfo(entry);
00427   entry=SetMagickInfo("PDF");
00428   entry->decoder=(DecoderHandler *) ReadPDFImage;
00429   entry->encoder=(EncoderHandler *) WritePDFImage;
00430   entry->magick=(MagickHandler *) IsPDF;
00431   entry->blob_support=MagickFalse;
00432   entry->seekable_stream=MagickTrue;
00433   entry->description=AcquireString("Portable Document Format");
00434   entry->module=AcquireString("PDF");
00435   (void) RegisterMagickInfo(entry);
00436 }
00437 
00438 /*
00439 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00440 %                                                                             %
00441 %                                                                             %
00442 %                                                                             %
00443 %   U n r e g i s t e r P D F I m a g e                                       %
00444 %                                                                             %
00445 %                                                                             %
00446 %                                                                             %
00447 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00448 %
00449 %  UnregisterPDFImage() removes format registrations made by the
00450 %  PDF module from the list of supported formats.
00451 %
00452 %  The format of the UnregisterPDFImage method is:
00453 %
00454 %      UnregisterPDFImage(void)
00455 %
00456 */
00457 ModuleExport void UnregisterPDFImage(void)
00458 {
00459   (void) UnregisterMagickInfo("EPDF");
00460   (void) UnregisterMagickInfo("PDF");
00461 }
00462 
00463 /*
00464 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00465 %                                                                             %
00466 %                                                                             %
00467 %                                                                             %
00468 %   W r i t e P D F I m a g e                                                 %
00469 %                                                                             %
00470 %                                                                             %
00471 %                                                                             %
00472 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00473 %
00474 %  WritePDFImage() writes an image in the Portable Document image
00475 %  format.
00476 %
00477 %  The format of the WritePDFImage method is:
00478 %
00479 %      MagickBooleanType WritePDFImage(const ImageInfo *image_info,Image *image)
00480 %
00481 %  A description of each parameter follows.
00482 %
00483 %    o image_info: The image info.
00484 %
00485 %    o image:  The image.
00486 %
00487 %
00488 */
00489 
00490 static char *EscapeParenthesis(const char *text)
00491 {
00492   register char
00493     *p;
00494 
00495   register long
00496     i;
00497 
00498   static char
00499     buffer[MaxTextExtent];
00500 
00501   unsigned long
00502     escapes;
00503 
00504   escapes=0;
00505   p=buffer;
00506   for (i=0; i < Min((long) strlen(text),(long) (MaxTextExtent-escapes-1)); i++)
00507   {
00508     if ((text[i] == '(') || (text[i] == ')'))
00509       {
00510         *p++='\\';
00511         escapes++;
00512       }
00513     *p++=text[i];
00514   }
00515   *p='\0';
00516   return(buffer);
00517 }
00518 
00519 static MagickBooleanType WritePDFImage(const ImageInfo *image_info,Image *image)
00520 {
00521 #define CFormat  "/Filter [ /%s ]\n"
00522 #define ObjectsPerImage  12
00523 
00524   char
00525     buffer[MaxTextExtent],
00526     date[MaxTextExtent],
00527     **labels,
00528     page_geometry[MaxTextExtent];
00529 
00530   CompressionType
00531     compression;
00532 
00533   const ImageAttribute
00534     *attribute;
00535 
00536   double
00537     dx_resolution,
00538     dy_resolution,
00539     x_resolution,
00540     x_scale,
00541     y_resolution,
00542     y_scale;
00543 
00544   GeometryInfo
00545     geometry_info;
00546 
00547   long
00548     count,
00549     y;
00550 
00551   Image
00552     *tile_image;
00553 
00554   MagickBooleanType
00555     matte,
00556     status;
00557 
00558   MagickOffsetType
00559     offset,
00560     scene,
00561     *xref;
00562 
00563   MagickSizeType
00564     number_pixels;
00565 
00566   MagickStatusType
00567     flags;
00568 
00569   RectangleInfo
00570     geometry,
00571     media_info,
00572     page_info;
00573 
00574   register const PixelPacket
00575     *p;
00576 
00577   register IndexPacket
00578     *indexes;
00579 
00580   register unsigned char
00581     *q;
00582 
00583   register long
00584     i,
00585     x;
00586 
00587   size_t
00588     length;
00589 
00590   struct tm
00591     *time_meridian;
00592 
00593   time_t
00594     seconds;
00595 
00596   unsigned char
00597     *pixels;
00598 
00599   unsigned long
00600     info_id,
00601     object,
00602     pages_id,
00603     quality,
00604     root_id,
00605     text_size;
00606 
00607   /*
00608     Open output image file.
00609   */
00610   assert(image_info != (const ImageInfo *) NULL);
00611   assert(image_info->signature == MagickSignature);
00612   assert(image != (Image *) NULL);
00613   assert(image->signature == MagickSignature);
00614   if (image->debug != MagickFalse)
00615     (void) LogMagickEvent(TraceEvent,GetMagickModule(),image->filename);
00616   status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
00617   if (status == MagickFalse)
00618     return(status);
00619   compression=image->compression;
00620   quality=(unsigned long)
00621     (image->quality == UndefinedCompressionQuality ? 75 : image->quality);
00622   switch (compression)
00623   {
00624 #if !defined(HasJP2)
00625     case JP2Compression:
00626     {
00627       compression=RLECompression;
00628       (void) ThrowMagickException(&image->exception,GetMagickModule(),
00629         MissingDelegateError,"JP2LibraryIsNotAvailable","`%s'",image->filename);
00630       break;
00631     }
00632 #endif
00633 #if !defined(HasJPEG)
00634     case JPEGCompression:
00635     {
00636       compression=RLECompression;
00637       (void) ThrowMagickException(&image->exception,GetMagickModule(),
00638         MissingDelegateError,"JPEGLibraryIsNotAvailable","`%s'",
00639         image->filename);
00640       break;
00641     }
00642 #endif
00643 #if !defined(HasZLIB)
00644     case ZipCompression:
00645     {
00646       compression=RLECompression;
00647       (void) ThrowMagickException(&image->exception,GetMagickModule(),
00648         MissingDelegateError,"ZipLibraryIsNotAvailable","`%s'",image->filename);
00649       break;
00650     }
00651 #endif
00652     default:
00653       break;
00654   }
00655   /*
00656     Allocate X ref memory.
00657   */
00658   xref=(MagickOffsetType *) AcquireMagickMemory(2048*sizeof(*xref));
00659   if (xref == (MagickOffsetType *) NULL)
00660     ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
00661   (void) ResetMagickMemory(xref,0,2048*sizeof(*xref));
00662   /*
00663     Write Info object.
00664   */
00665   object=0;
00666   if (image->matte == MagickFalse)
00667     (void) WriteBlobString(image,"%PDF-1.3 \n");
00668   else
00669     (void) WriteBlobString(image,"%PDF-1.4 \n");
00670   xref[object++]=TellBlob(image);
00671   info_id=object;
00672   (void) FormatMagickString(buffer,MaxTextExtent,"%lu 0 obj\n",object);
00673   (void) WriteBlobString(image,buffer);
00674   (void) WriteBlobString(image,"<<\n");
00675   (void) FormatMagickString(buffer,MaxTextExtent,"/Title (%s)\n",
00676     EscapeParenthesis(image->filename));
00677   (void) WriteBlobString(image,buffer);
00678   seconds=time((time_t *) NULL);
00679   time_meridian=localtime(&seconds);
00680   (void) FormatMagickString(date,MaxTextExtent,"D:%04d%02d%02d%02d%02d%02d",
00681     time_meridian->tm_year+1900,time_meridian->tm_mon+1,time_meridian->tm_mday,
00682     time_meridian->tm_hour,time_meridian->tm_min,time_meridian->tm_sec);
00683   (void) FormatMagickString(buffer,MaxTextExtent,"/CreationDate (%s)\n",date);
00684   (void) WriteBlobString(image,buffer);
00685   (void) FormatMagickString(buffer,MaxTextExtent,"/ModDate (%s)\n",date);
00686   (void) WriteBlobString(image,buffer);
00687   (void) FormatMagickString(buffer,MaxTextExtent,"/Producer (%s)\n",
00688     EscapeParenthesis(GetMagickVersion((unsigned long *) NULL)));
00689   (void) WriteBlobString(image,buffer);
00690   (void) WriteBlobString(image,">>\n");
00691   (void) WriteBlobString(image,"endobj\n");
00692   /*
00693     Write Catalog object.
00694   */
00695   xref[object++]=TellBlob(image);
00696   root_id=object;
00697   (void) FormatMagickString(buffer,MaxTextExtent,"%lu 0 obj\n",object);
00698   (void) WriteBlobString(image,buffer);
00699   (void) WriteBlobString(image,"<<\n");
00700   (void) WriteBlobString(image,"/Type /Catalog\n");
00701   (void) FormatMagickString(buffer,MaxTextExtent,"/Pages %lu 0 R\n",object+1);
00702   (void) WriteBlobString(image,buffer);
00703   (void) WriteBlobString(image,">>\n");
00704   (void) WriteBlobString(image,"endobj\n");
00705   /*
00706     Write Pages object.
00707   */
00708   xref[object++]=TellBlob(image);
00709   pages_id=object;
00710   (void) FormatMagickString(buffer,MaxTextExtent,"%lu 0 obj\n",object);
00711   (void) WriteBlobString(image,buffer);
00712   (void) WriteBlobString(image,"<<\n");
00713   (void) WriteBlobString(image,"/Type /Pages\n");
00714   (void) FormatMagickString(buffer,MaxTextExtent,"/Kids [ %lu 0 R ",object+1);
00715   (void) WriteBlobString(image,buffer);
00716   count=(long) (pages_id+ObjectsPerImage+1);
00717   if (image_info->adjoin != MagickFalse)
00718     {
00719       Image
00720         *kid_image;
00721 
00722       /*
00723         Predict page object id's.
00724       */
00725       kid_image=image;
00726       for ( ; kid_image->next != (Image *) NULL; count+=ObjectsPerImage)
00727       {
00728         (void) FormatMagickString(buffer,MaxTextExtent,"%ld 0 R ",count);
00729         (void) WriteBlobString(image,buffer);
00730         kid_image=kid_image->next;
00731       }
00732       xref=(MagickOffsetType *)
00733         ResizeMagickMemory(xref,(size_t) (count+2048)*sizeof(*xref));
00734       if (xref == (MagickOffsetType *) NULL)
00735         ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
00736     }
00737   (void) WriteBlobString(image,"]\n");
00738   (void) FormatMagickString(buffer,MaxTextExtent,"/Count %lu\n",
00739     (count-pages_id)/ObjectsPerImage);
00740   (void) WriteBlobString(image,buffer);
00741   (void) WriteBlobString(image,">>\n");
00742   (void) WriteBlobString(image,"endobj\n");
00743   scene=0;
00744   do
00745   {
00746     /*
00747       Scale relative to dots-per-inch.
00748     */
00749     dx_resolution=DefaultResolution;
00750     dy_resolution=DefaultResolution;
00751     flags=ParseGeometry(PSDensityGeometry,&geometry_info);
00752     x_resolution=geometry_info.rho;
00753     y_resolution=geometry_info.sigma;
00754     if ((flags & SigmaValue) == 0)
00755       y_resolution=x_resolution;
00756     if (image->x_resolution != 0.0)
00757       x_resolution=image->x_resolution;
00758     if (image->y_resolution != 0.0)
00759       y_resolution=image->y_resolution;
00760     if (image_info->density != (char *) NULL)
00761       {
00762         flags=ParseGeometry(image_info->density,&geometry_info);
00763         x_resolution=geometry_info.rho;
00764         y_resolution=geometry_info.sigma;
00765         if ((flags & SigmaValue) == 0)
00766           y_resolution=x_resolution;
00767       }
00768     if (image->units == PixelsPerCentimeterResolution)
00769       {
00770         x_resolution*=2.54;
00771         y_resolution*=2.54;
00772       }
00773     SetGeometry(image,&geometry);
00774     (void) FormatMagickString(page_geometry,MaxTextExtent,"%lux%lu",
00775       image->columns,image->rows);
00776     if (image_info->page != (char *) NULL)
00777       (void) CopyMagickString(page_geometry,image_info->page,MaxTextExtent);
00778     else
00779       if ((image->page.width != 0) && (image->page.height != 0))
00780         (void) FormatMagickString(page_geometry,MaxTextExtent,"%lux%lu%+ld%+ld",
00781           image->page.width,image->page.height,image->page.x,image->page.y);
00782       else
00783         if ((image->gravity != UndefinedGravity) &&
00784             (LocaleCompare(image_info->magick,"PDF") == 0))
00785           (void) strcpy(page_geometry,PSPageGeometry);
00786     (void) ParseMetaGeometry(page_geometry,&geometry.x,&geometry.y,
00787       &geometry.width,&geometry.height);
00788     x_scale=(double) (geometry.width*dx_resolution)/x_resolution;
00789     geometry.width=(unsigned long) (x_scale+0.5);
00790     y_scale=(double) (geometry.height*dy_resolution)/y_resolution;
00791     geometry.height=(unsigned long) (y_scale+0.5);
00792     (void) ParseAbsoluteGeometry(page_geometry,&media_info);
00793     (void) ParseGravityGeometry(image,page_geometry,&page_info);
00794     if (image->gravity != UndefinedGravity)
00795       {
00796         geometry.x=(-page_info.x);
00797         geometry.y=(long) (media_info.height+page_info.y-image->rows);
00798       }
00799     text_size=0;
00800     attribute=GetImageAttribute(image,"Label");
00801     if (attribute != (const ImageAttribute *) NULL)
00802       text_size=(unsigned long)
00803         (MultilineCensus(attribute->value)*image_info->pointsize+12);
00804     /*
00805       Write Page object.
00806     */
00807     xref[object++]=TellBlob(image);
00808     (void) FormatMagickString(buffer,MaxTextExtent,"%lu 0 obj\n",object);
00809     (void) WriteBlobString(image,buffer);
00810     (void) WriteBlobString(image,"<<\n");
00811     (void) WriteBlobString(image,"/Type /Page\n");
00812     (void) FormatMagickString(buffer,MaxTextExtent,"/Parent %lu 0 R\n",
00813       pages_id);
00814     (void) WriteBlobString(image,buffer);
00815     (void) WriteBlobString(image,"/Resources <<\n");
00816     (void) FormatMagickString(buffer,MaxTextExtent,
00817       "/Font << /F%lu %lu 0 R >>\n",image->scene,object+4);
00818     (void) WriteBlobString(image,buffer);
00819     matte=image->matte;
00820     if (IsGrayImage(image,&image->exception) != MagickFalse)
00821       matte=MagickFalse;
00822     (void) FormatMagickString(buffer,MaxTextExtent,
00823       "/XObject << /Im%lu %lu 0 R >>\n",image->scene,object+
00824       (matte != MagickFalse ? 7 : 5));
00825     (void) WriteBlobString(image,buffer);
00826     (void) FormatMagickString(buffer,MaxTextExtent,"/ProcSet %lu 0 R >>\n",
00827       object+3);
00828     (void) WriteBlobString(image,buffer);
00829     (void) FormatMagickString(buffer,MaxTextExtent,"/MediaBox [0 0 %lu %lu]\n",
00830       media_info.width,media_info.height);
00831     (void) WriteBlobString(image,buffer);
00832     (void) FormatMagickString(buffer,MaxTextExtent,
00833       "/CropBox [%ld %ld %lu %lu]\n",geometry.x,geometry.y,geometry.x+
00834       geometry.width,geometry.y+geometry.height);
00835     (void) WriteBlobString(image,buffer);
00836     (void) FormatMagickString(buffer,MaxTextExtent,"/Contents %lu 0 R\n",
00837       object+1);
00838     (void) WriteBlobString(image,buffer);
00839     (void) FormatMagickString(buffer,MaxTextExtent,"/Thumb %lu 0 R\n",
00840       object+(matte != MagickFalse ? 10 : 8));
00841     (void) WriteBlobString(image,buffer);
00842     (void) WriteBlobString(image,">>\n");
00843     (void) WriteBlobString(image,"endobj\n");
00844     /*
00845       Write Contents object.
00846     */
00847     xref[object++]=TellBlob(image);
00848     (void) FormatMagickString(buffer,MaxTextExtent,"%lu 0 obj\n",object);
00849     (void) WriteBlobString(image,buffer);
00850     (void) WriteBlobString(image,"<<\n");
00851     (void) FormatMagickString(buffer,MaxTextExtent,"/Length %lu 0 R\n",
00852       object+1);
00853     (void) WriteBlobString(image,buffer);
00854     (void) WriteBlobString(image,">>\n");
00855     (void) WriteBlobString(image,"stream\n");
00856     offset=TellBlob(image);
00857     (void) WriteBlobString(image,"q\n");
00858     labels=(char **) NULL;
00859     attribute=GetImageAttribute(image,"Label");
00860     if (attribute != (const ImageAttribute *) NULL)
00861       labels=StringToList(attribute->value);
00862     if (labels != (char **) NULL)
00863       {
00864         for (i=0; labels[i] != (char *) NULL; i++)
00865         {
00866           (void) WriteBlobString(image,"BT\n");
00867           (void) FormatMagickString(buffer,MaxTextExtent,"/F%lu %g Tf\n",
00868             image->scene,image_info->pointsize);
00869           (void) WriteBlobString(image,buffer);
00870           (void) FormatMagickString(buffer,MaxTextExtent,"%ld %ld Td\n",
00871             geometry.x,(long) (geometry.y+geometry.height+i*
00872             image_info->pointsize+12));
00873           (void) WriteBlobString(image,buffer);
00874           (void) FormatMagickString(buffer,MaxTextExtent,"(%s) Tj\n",
00875             labels[i]);
00876           (void) WriteBlobString(image,buffer);
00877           (void) WriteBlobString(image,"ET\n");
00878           labels[i]=(char *) RelinquishMagickMemory(labels[i]);
00879         }
00880         labels=(char **) RelinquishMagickMemory(labels);
00881       }
00882     (void) FormatMagickString(buffer,MaxTextExtent,"%g 0 0 %g %ld %ld cm\n",
00883       x_scale,y_scale,geometry.x,geometry.y);
00884     (void) WriteBlobString(image,buffer);
00885     (void) FormatMagickString(buffer,MaxTextExtent,"/Im%lu Do\n",image->scene);
00886     (void) WriteBlobString(image,buffer);
00887     (void) WriteBlobString(image,"Q\n");
00888     offset=TellBlob(image)-offset;
00889     (void) WriteBlobString(image,"endstream\n");
00890     (void) WriteBlobString(image,"endobj\n");
00891     /*
00892       Write Length object.
00893     */
00894     xref[object++]=TellBlob(image);
00895     (void) FormatMagickString(buffer,MaxTextExtent,"%lu 0 obj\n",object);
00896     (void) WriteBlobString(image,buffer);
00897     (void) FormatMagickString(buffer,MaxTextExtent,"%lu\n",
00898       (unsigned long) offset);
00899     (void) WriteBlobString(image,buffer);
00900     (void) WriteBlobString(image,"endobj\n");
00901     /*
00902       Write Procset object.
00903     */
00904     xref[object++]=TellBlob(image);
00905     (void) FormatMagickString(buffer,MaxTextExtent,"%lu 0 obj\n",object);
00906     (void) WriteBlobString(image,buffer);
00907     if ((image->storage_class == DirectClass) || (image->colors > 256))
00908       (void) strcpy(buffer,"[ /PDF /Text /ImageC");
00909     else
00910       if (compression == FaxCompression)
00911         (void) strcpy(buffer,"[ /PDF /Text /ImageB");
00912       else
00913         (void) strcpy(buffer,"[ /PDF /Text /ImageI");
00914     (void) WriteBlobString(image,buffer);
00915     (void) WriteBlobString(image," ]\n");
00916     (void) WriteBlobString(image,"endobj\n");
00917     /*
00918       Write Font object.
00919     */
00920     xref[object++]=TellBlob(image);
00921     (void) FormatMagickString(buffer,MaxTextExtent,"%lu 0 obj\n",object);
00922     (void) WriteBlobString(image,buffer);
00923     (void) WriteBlobString(image,"<<\n");
00924     (void) WriteBlobString(image,"/Type /Font\n");
00925     (void) WriteBlobString(image,"/Subtype /Type1\n");
00926     (void) FormatMagickString(buffer,MaxTextExtent,"/Name /F%lu\n",
00927       image->scene);
00928     (void) WriteBlobString(image,buffer);
00929     (void) WriteBlobString(image,"/BaseFont /Helvetica\n");
00930     (void) WriteBlobString(image,"/Encoding /MacRomanEncoding\n");
00931     (void) WriteBlobString(image,">>\n");
00932     (void) WriteBlobString(image,"endobj\n");
00933     if (matte != MagickFalse)
00934       {
00935         /*
00936           Write softmask object.
00937         */
00938         xref[object++]=TellBlob(image);
00939         (void) FormatMagickString(buffer,MaxTextExtent,"%lu 0 obj\n",object);
00940         (void) WriteBlobString(image,buffer);
00941         (void) WriteBlobString(image,"<<\n");
00942         (void) WriteBlobString(image,"/Type /XObject\n");
00943         (void) WriteBlobString(image,"/Subtype /Image\n");
00944         (void) FormatMagickString(buffer,MaxTextExtent,"/Name /Ma%lu\n",
00945           image->scene);
00946         (void) WriteBlobString(image,buffer);
00947         switch (compression)
00948         {
00949           case NoCompression:
00950           {
00951             (void) FormatMagickString(buffer,MaxTextExtent,CFormat,
00952               "ASCII85Decode");
00953             break;
00954           }
00955           case LZWCompression:
00956           {
00957             (void) FormatMagickString(buffer,MaxTextExtent,CFormat,"LZWDecode");
00958             break;
00959           }
00960           case ZipCompression:
00961           {
00962             (void) FormatMagickString(buffer,MaxTextExtent,CFormat,
00963               "FlateDecode");
00964             break;
00965           }
00966           default:
00967           {
00968             (void) FormatMagickString(buffer,MaxTextExtent,CFormat,
00969               "RunLengthDecode");
00970             break;
00971           }
00972         }
00973         (void) WriteBlobString(image,buffer);
00974         (void) FormatMagickString(buffer,MaxTextExtent,"/Width %lu\n",
00975           image->columns);
00976         (void) WriteBlobString(image,buffer);
00977         (void) FormatMagickString(buffer,MaxTextExtent,"/Height %lu\n",
00978           image->rows);
00979         (void) WriteBlobString(image,buffer);
00980         (void) WriteBlobString(image,"/ColorSpace /DeviceGray\n");
00981         (void) FormatMagickString(buffer,MaxTextExtent,"/BitsPerComponent %d\n",
00982           compression == FaxCompression ? 1 : 8);
00983         (void) WriteBlobString(image,buffer);
00984         (void) FormatMagickString(buffer,MaxTextExtent,"/Length %lu 0 R\n",
00985           object+1);
00986         (void) WriteBlobString(image,buffer);
00987         (void) WriteBlobString(image,">>\n");
00988         (void) WriteBlobString(image,"stream\n");
00989         offset=TellBlob(image);
00990         number_pixels=(MagickSizeType) image->columns*image->rows;
00991         switch (compression)
00992         {
00993           case RLECompression:
00994           default:
00995           {
00996             /*
00997               Allocate pixel array.
00998             */
00999             length=(size_t) number_pixels;
01000             pixels=(unsigned char *) AcquireMagickMemory(length);
01001             if (pixels == (unsigned char *) NULL)
01002               {
01003                 image=DestroyImage(image);
01004                 ThrowWriterException(ResourceLimitError,
01005                   "MemoryAllocationFailed");
01006               }
01007             /*
01008               Dump Runlength encoded pixels.
01009             */
01010             q=pixels;
01011             for (y=0; y < (long) image->rows; y++)
01012             {
01013               p=AcquireImagePixels(image,0,y,image->columns,1,
01014                 &image->exception);
01015               if (p == (const PixelPacket *) NULL)
01016                 break;
01017               for (x=0; x < (long) image->columns; x++)
01018               {
01019                 *q++=ScaleQuantumToChar(MaxRGB-p->opacity);
01020                 p++;
01021               }
01022             }
01023 #if defined(HasZLIB)
01024             if (compression == ZipCompression)
01025               status=ZLIBEncodeImage(image,length,quality,pixels);
01026             else
01027 #endif
01028               if (compression == LZWCompression)
01029                 status=LZWEncodeImage(image,length,pixels);
01030               else
01031                 status=PackbitsEncodeImage(image,length,pixels);
01032             pixels=(unsigned char *) RelinquishMagickMemory(pixels);
01033             if (status == MagickFalse)
01034               {
01035                 CloseBlob(image);
01036                 return(MagickFalse);
01037               }
01038             break;
01039           }
01040           case NoCompression:
01041           {
01042             /*
01043               Dump uncompressed PseudoColor packets.
01044             */
01045             Ascii85Initialize(image);
01046             for (y=0; y < (long) image->rows; y++)
01047             {
01048               p=AcquireImagePixels(image,0,y,image->columns,1,
01049                 &image->exception);
01050               if (p == (const PixelPacket *) NULL)
01051                 break;
01052               for (x=0; x < (long) image->columns; x++)
01053               {
01054                 Ascii85Encode(image,ScaleQuantumToChar(MaxRGB-p->opacity));
01055                 p++;
01056               }
01057             }
01058             Ascii85Flush(image);
01059             break;
01060           }
01061         }
01062         offset=TellBlob(image)-offset;
01063         (void) WriteBlobString(image,"\nendstream\n");
01064         (void) WriteBlobString(image,"endobj\n");
01065         /*
01066           Write Length object.
01067         */
01068         xref[object++]=TellBlob(image);
01069         (void) FormatMagickString(buffer,MaxTextExtent,"%lu 0 obj\n",object);
01070         (void) WriteBlobString(image,buffer);
01071         (void) FormatMagickString(buffer,MaxTextExtent,"%lu\n",
01072           (unsigned long) offset);
01073         (void) WriteBlobString(image,buffer);
01074         (void) WriteBlobString(image,"endobj\n");
01075       }
01076     /*
01077       Write XObject object.
01078     */
01079     xref[object++]=TellBlob(image);
01080     (void) FormatMagickString(buffer,MaxTextExtent,"%lu 0 obj\n",object);
01081     (void) WriteBlobString(image,buffer);
01082     (void) WriteBlobString(image,"<<\n");
01083     (void) WriteBlobString(image,"/Type /XObject\n");
01084     (void) WriteBlobString(image,"/Subtype /Image\n");
01085     (void) FormatMagickString(buffer,MaxTextExtent,"/Name /Im%lu\n",
01086       image->scene);
01087     (void) WriteBlobString(image,buffer);
01088     switch (compression)
01089     {
01090       case NoCompression:
01091       {
01092         (void) FormatMagickString(buffer,MaxTextExtent,CFormat,"ASCII85Decode");
01093         break;
01094       }
01095       case JPEG2000Compression:
01096       {
01097         (void) FormatMagickString(buffer,MaxTextExtent,CFormat,"JPXDecode");
01098         if (image->colorspace != CMYKColorspace)
01099           break;
01100         (void) WriteBlobString(image,buffer);
01101         (void) strcpy(buffer,"/Decode [1 0 1 0 1 0 1 0]\n");
01102         break;
01103       }
01104       case JPEGCompression:
01105       {
01106         (void) FormatMagickString(buffer,MaxTextExtent,CFormat,"DCTDecode");
01107         if (image->colorspace != CMYKColorspace)
01108           break;
01109         (void) WriteBlobString(image,buffer);
01110         (void) strcpy(buffer,"/Decode [1 0 1 0 1 0 1 0]\n");
01111         break;
01112       }
01113       case LZWCompression:
01114       {
01115          (void) FormatMagickString(buffer,MaxTextExtent,CFormat,"LZWDecode");
01116          break;
01117       }
01118       case ZipCompression:
01119       {
01120          (void) FormatMagickString(buffer,MaxTextExtent,CFormat,"FlateDecode");
01121          break;
01122       }
01123       case FaxCompression:
01124       {
01125         (void) strcpy(buffer,"/Filter [ /CCITTFaxDecode ]\n");
01126         (void) WriteBlobString(image,buffer);
01127         (void) FormatMagickString(buffer,MaxTextExtent,
01128           "/DecodeParms [ << >> << /K %s /Columns %ld /Rows %ld >> ]\n",
01129           CCITTParam,image->columns,image->rows);
01130         break;
01131       }
01132       default:
01133       {
01134         (void) FormatMagickString(buffer,MaxTextExtent,CFormat,
01135           "RunLengthDecode");
01136         break;
01137       }
01138     }
01139     (void) WriteBlobString(image,buffer);
01140     (void) FormatMagickString(buffer,MaxTextExtent,"/Width %lu\n",
01141       image->columns);
01142     (void) WriteBlobString(image,buffer);
01143     (void) FormatMagickString(buffer,MaxTextExtent,"/Height %lu\n",image->rows);
01144     (void) WriteBlobString(image,buffer);
01145     (void) FormatMagickString(buffer,MaxTextExtent,"/ColorSpace %lu 0 R\n",
01146       object+2);
01147     (void) WriteBlobString(image,buffer);
01148     (void) FormatMagickString(buffer,MaxTextExtent,"/BitsPerComponent %d\n",
01149       compression == FaxCompression ? 1 : 8);
01150     (void) WriteBlobString(image,buffer);
01151     if (matte != MagickFalse)
01152       {
01153         (void) FormatMagickString(buffer,MaxTextExtent,"/SMask %lu 0 R\n",
01154           object-2);
01155         (void) WriteBlobString(image,buffer);
01156       }
01157     (void) FormatMagickString(buffer,MaxTextExtent,"/Length %lu 0 R\n",
01158       object+1);
01159     (void) WriteBlobString(image,buffer);
01160     (void) WriteBlobString(image,">>\n");
01161     (void) WriteBlobString(image,"stream\n");
01162     offset=TellBlob(image);
01163     number_pixels=(MagickSizeType) image->columns*image->rows;
01164     if (number_pixels != (MagickSizeType) ((size_t) number_pixels))
01165       ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
01166     if ((compression == FaxCompression) ||
01167         ((image_info->type != TrueColorType) &&
01168          (IsGrayImage(image,&image->exception) != MagickFalse)))
01169 
01170       {
01171         switch (compression)
01172         {
01173           case FaxCompression:
01174           {
01175             if (LocaleCompare(CCITTParam,"0") == 0)
01176               {
01177                 (void) HuffmanEncodeImage(image_info,image);
01178                 break;
01179               }
01180             (void) Huffman2DEncodeImage(image_info,image);
01181             break;
01182           }
01183           case JPEG2000Compression:
01184           {
01185             status=JP2EncodeImage(image_info,image);
01186             if (status == MagickFalse)
01187               ThrowWriterException(CoderError,image->exception.reason);
01188             break;
01189           }
01190           case JPEGCompression:
01191           {
01192             status=JPEGEncodeImage(image_info,image);
01193             if (status == MagickFalse)
01194               ThrowWriterException(CoderError,image->exception.reason);
01195             break;
01196           }
01197           case RLECompression:
01198           default:
01199           {
01200             /*
01201               Allocate pixel array.
01202             */
01203             length=(size_t) number_pixels;
01204             pixels=(unsigned char *) AcquireMagickMemory(length);
01205             if (pixels == (unsigned char *) NULL)
01206               ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
01207             /*
01208               Dump Runlength encoded pixels.
01209             */
01210             q=pixels;
01211             for (y=0; y < (long) image->rows; y++)
01212             {
01213               p=AcquireImagePixels(image,0,y,image->columns,1,
01214                 &image->exception);
01215               if (p == (const PixelPacket *) NULL)
01216                 break;
01217               for (x=0; x < (long) image->columns; x++)
01218               {
01219                 *q++=ScaleQuantumToChar(PixelIntensityToQuantum(p));
01220                 p++;
01221               }
01222               if (image->previous == (Image *) NULL)
01223                 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
01224                     (QuantumTick(y,image->rows) != MagickFalse))
01225                   {
01226                     status=image->progress_monitor(SaveImageTag,y,image->rows,
01227                       image->client_data);
01228                     if (status == MagickFalse)
01229                       break;
01230                   }
01231             }
01232 #if defined(HasZLIB)
01233             if (compression == ZipCompression)
01234               status=ZLIBEncodeImage(image,length,quality,pixels);
01235             else
01236 #endif
01237               if (compression == LZWCompression)
01238                 status=LZWEncodeImage(image,length,pixels);
01239               else
01240                 status=PackbitsEncodeImage(image,length,pixels);
01241             pixels=(unsigned char *) RelinquishMagickMemory(pixels);
01242             if (status == MagickFalse)
01243               {
01244                 CloseBlob(image);
01245                 return(MagickFalse);
01246               }
01247             break;
01248           }
01249           case NoCompression:
01250           {
01251             /*
01252               Dump uncompressed PseudoColor packets.
01253             */
01254             Ascii85Initialize(image);
01255             for (y=0; y < (long) image->rows; y++)
01256             {
01257               p=AcquireImagePixels(image,0,y,image->columns,1,
01258                 &image->exception);
01259               if (p == (const PixelPacket *) NULL)
01260                 break;
01261               for (x=0; x < (long) image->columns; x++)
01262               {
01263                 Ascii85Encode(image,
01264                   ScaleQuantumToChar(PixelIntensityToQuantum(p)));
01265                 p++;
01266               }
01267               if (image->previous == (Image *) NULL)
01268                 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
01269                     (QuantumTick(y,image->rows) != MagickFalse))
01270                   {
01271                     status=image->progress_monitor(SaveImageTag,y,image->rows,
01272                       image->client_data);
01273                     if (status == MagickFalse)
01274                       break;
01275                   }
01276             }
01277             Ascii85Flush(image);
01278             break;
01279           }
01280         }
01281       }
01282     else
01283       if ((image->storage_class == DirectClass) || (image->colors > 256) ||
01284           (compression == JPEG2000Compression) ||
01285           (compression == JPEGCompression))
01286         switch (compression)
01287         {
01288           case JPEG2000Compression:
01289           {
01290             status=JP2EncodeImage(image_info,image);
01291             if (status == MagickFalse)
01292               ThrowWriterException(CoderError,image->exception.reason);
01293             break;
01294           }
01295           case JPEGCompression:
01296           {
01297             status=JPEGEncodeImage(image_info,image);
01298             if (status == MagickFalse)
01299               ThrowWriterException(CoderError,image->exception.reason);
01300             break;
01301           }
01302           case RLECompression:
01303           default:
01304           {
01305             /*
01306               Allocate pixel array.
01307             */
01308             length=(size_t) ((image->colorspace == CMYKColorspace ? 4 : 3)*
01309               number_pixels);
01310             pixels=(unsigned char *) AcquireMagickMemory(length);
01311             if (pixels == (unsigned char *) NULL)
01312               ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
01313             /*
01314               Dump runoffset encoded pixels.
01315             */
01316             q=pixels;
01317             for (y=0; y < (long) image->rows; y++)
01318             {
01319               p=AcquireImagePixels(image,0,y,image->columns,1,
01320                 &image->exception);
01321               if (p == (const PixelPacket *) NULL)
01322                 break;
01323               indexes=GetIndexes(image);
01324               for (x=0; x < (long) image->columns; x++)
01325               {
01326                 *q++=ScaleQuantumToChar(p->red);
01327                 *q++=ScaleQuantumToChar(p->green);
01328                 *q++=ScaleQuantumToChar(p->blue);
01329                 if (image->colorspace == CMYKColorspace)
01330                   *q++=ScaleQuantumToChar(indexes[x]);
01331                 p++;
01332               }
01333               if (image->previous == (Image *) NULL)
01334                 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
01335                     (QuantumTick(y,image->rows) != MagickFalse))
01336                   {
01337                     status=image->progress_monitor(SaveImageTag,y,image->rows,
01338                       image->client_data);
01339                     if (status == MagickFalse)
01340                       break;
01341                   }
01342             }
01343 #if defined(HasZLIB)
01344             if (compression == ZipCompression)
01345               status=ZLIBEncodeImage(image,length,quality,pixels);
01346             else
01347 #endif
01348               if (compression == LZWCompression)
01349                 status=LZWEncodeImage(image,length,pixels);
01350               else
01351                 status=PackbitsEncodeImage(image,length,pixels);
01352             pixels=(unsigned char *) RelinquishMagickMemory(pixels);
01353             if (status == MagickFalse)
01354               {
01355                 CloseBlob(image);
01356                 return(MagickFalse);
01357               }
01358             break;
01359           }
01360           case NoCompression:
01361           {
01362             /*
01363               Dump uncompressed DirectColor packets.
01364             */
01365             Ascii85Initialize(image);
01366             for (y=0; y < (long) image->rows; y++)
01367             {
01368               p=AcquireImagePixels(image,0,y,image->columns,1,
01369                 &image->exception);
01370               if (p == (const PixelPacket *) NULL)
01371                 break;
01372               indexes=GetIndexes(image);
01373               for (x=0; x < (long) image->columns; x++)
01374               {
01375                 Ascii85Encode(image,ScaleQuantumToChar(p->red));
01376                 Ascii85Encode(image,ScaleQuantumToChar(p->green));
01377                 Ascii85Encode(image,ScaleQuantumToChar(p->blue));
01378                 if (image->colorspace == CMYKColorspace)
01379                   Ascii85Encode(image,ScaleQuantumToChar(indexes[x]));
01380                 p++;
01381               }
01382               if (image->previous == (Image *) NULL)
01383                 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
01384                     (QuantumTick(y,image->rows) != MagickFalse))
01385                   {
01386                     status=image->progress_monitor(SaveImageTag,y,image->rows,
01387                       image->client_data);
01388                     if (status == MagickFalse)
01389                       break;
01390                   }
01391             }
01392             Ascii85Flush(image);
01393             break;
01394           }
01395         }
01396       else
01397         {
01398           /*
01399             Dump number of colors and colormap.
01400           */
01401           switch (compression)
01402           {
01403             case RLECompression:
01404             default:
01405             {
01406               /*
01407                 Allocate pixel array.
01408               */
01409               length=(size_t) number_pixels;
01410               pixels=(unsigned char *) AcquireMagickMemory(length);
01411               if (pixels == (unsigned char *) NULL)
01412                 ThrowWriterException(ResourceLimitError,
01413                   "MemoryAllocationFailed");
01414               /*
01415                 Dump Runlength encoded pixels.
01416               */
01417               q=pixels;
01418               for (y=0; y < (long) image->rows; y++)
01419               {
01420                 p=AcquireImagePixels(image,0,y,image->columns,1,
01421                   &image->exception);
01422                 if (p == (const PixelPacket *) NULL)
01423                   break;
01424                 indexes=GetIndexes(image);
01425                 for (x=0; x < (long) image->columns; x++)
01426                   *q++=(unsigned char) indexes[x];
01427                 if (image->previous == (Image *) NULL)
01428                 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
01429                     (QuantumTick(y,image->rows) != MagickFalse))
01430                   {
01431                     status=image->progress_monitor(SaveImageTag,y,image->rows,
01432                       image->client_data);
01433                     if (status == MagickFalse)
01434                       break;
01435                   }
01436               }
01437 #if defined(HasZLIB)
01438               if (compression == ZipCompression)
01439                 status=ZLIBEncodeImage(image,length,quality,pixels);
01440               else
01441 #endif
01442                 if (compression == LZWCompression)
01443                   status=LZWEncodeImage(image,length,pixels);
01444                 else
01445                   status=PackbitsEncodeImage(image,length,pixels);
01446               pixels=(unsigned char *) RelinquishMagickMemory(pixels);
01447               if (status == MagickFalse)
01448                 {
01449                   CloseBlob(image);
01450                   return(MagickFalse);
01451                 }
01452               break;
01453             }
01454             case NoCompression:
01455             {
01456               /*
01457                 Dump uncompressed PseudoColor packets.
01458               */
01459               Ascii85Initialize(image);
01460               for (y=0; y < (long) image->rows; y++)
01461               {
01462                 p=AcquireImagePixels(image,0,y,image->columns,1,
01463                   &image->exception);
01464                 if (p == (const PixelPacket *) NULL)
01465                   break;
01466                 indexes=GetIndexes(image);
01467                 for (x=0; x < (long) image->columns; x++)
01468                   Ascii85Encode(image,(unsigned char) indexes[x]);
01469                 if (image->previous == (Image *) NULL)
01470                 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
01471                     (QuantumTick(y,image->rows) != MagickFalse))
01472                   {
01473                     status=image->progress_monitor(SaveImageTag,y,image->rows,
01474                       image->client_data);
01475                     if (status == MagickFalse)
01476                       break;
01477                   }
01478               }
01479               Ascii85Flush(image);
01480               break;
01481             }
01482           }
01483         }
01484     offset=TellBlob(image)-offset;
01485     (void) WriteBlobString(image,"\nendstream\n");
01486     (void) WriteBlobString(image,"endobj\n");
01487     /*
01488       Write Length object.
01489     */
01490     xref[object++]=TellBlob(image);
01491     (void) FormatMagickString(buffer,MaxTextExtent,"%lu 0 obj\n",object);
01492     (void) WriteBlobString(image,buffer);
01493     (void) FormatMagickString(buffer,MaxTextExtent,"%lu\n",
01494       (unsigned long) offset);
01495     (void) WriteBlobString(image,buffer);
01496     (void) WriteBlobString(image,"endobj\n");
01497     /*
01498       Write Colorspace object.
01499     */
01500     xref[object++]=TellBlob(image);
01501     (void) FormatMagickString(buffer,MaxTextExtent,"%lu 0 obj\n",object);
01502     (void) WriteBlobString(image,buffer);
01503     if (image->colorspace == CMYKColorspace)
01504       (void) strcpy(buffer,"/DeviceCMYK\n");
01505     else
01506       if ((compression == FaxCompression) ||
01507           ((image_info->type != TrueColorType) &&
01508            (IsGrayImage(image,&image->exception) != MagickFalse)))
01509           (void) strcpy(buffer,"/DeviceGray\n");
01510       else
01511         if ((image->storage_class == DirectClass) || (image->colors > 256) ||
01512             (compression == JPEG2000Compression) ||
01513             (compression == JPEGCompression))
01514           (void) strcpy(buffer,"/DeviceRGB\n");
01515         else
01516           (void) FormatMagickString(buffer,MaxTextExtent,
01517             "[ /Indexed /DeviceRGB %lu %lu 0 R ]\n",
01518             image->colors-1,object+3);
01519     (void) WriteBlobString(image,buffer);
01520     (void) WriteBlobString(image,"endobj\n");
01521     /*
01522       Write Thumb object.
01523     */
01524     SetGeometry(image,&geometry);
01525     (void) ParseMetaGeometry("106x106+0+0>",&geometry.x,&geometry.y,
01526       &geometry.width,&geometry.height);
01527     tile_image=ResizeImage(image,geometry.width,geometry.height,TriangleFilter,
01528       1.0,&image->exception);
01529     if (tile_image == (Image *) NULL)
01530       ThrowWriterException(ResourceLimitError,image->exception.reason);
01531     xref[object++]=TellBlob(image);
01532     (void) FormatMagickString(buffer,MaxTextExtent,"%lu 0 obj\n",object);
01533     (void) WriteBlobString(image,buffer);
01534     (void) WriteBlobString(image,"<<\n");
01535     switch (compression)
01536     {
01537       case NoCompression:
01538       {
01539         (void) FormatMagickString(buffer,MaxTextExtent,CFormat,"ASCII85Decode");
01540         break;
01541       }
01542       case JPEG2000Compression:
01543       {
01544         (void) FormatMagickString(buffer,MaxTextExtent,CFormat,"JPXDecode");
01545         if (image->colorspace != CMYKColorspace)
01546           break;
01547         (void) WriteBlobString(image,buffer);
01548         (void) strcpy(buffer,"/Decode [1 0 1 0 1 0 1 0]\n");
01549         break;
01550       }
01551       case JPEGCompression:
01552       {
01553         (void) FormatMagickString(buffer,MaxTextExtent,CFormat,"DCTDecode");
01554         if (image->colorspace != CMYKColorspace)
01555           break;
01556         (void) WriteBlobString(image,buffer);
01557         (void) strcpy(buffer,"/Decode [1 0 1 0 1 0 1 0]\n");
01558         break;
01559       }
01560       case LZWCompression:
01561       {
01562         (void) FormatMagickString(buffer,MaxTextExtent,CFormat,"LZWDecode");
01563         break;
01564       }
01565       case ZipCompression:
01566       {
01567         (void) FormatMagickString(buffer,MaxTextExtent,CFormat,"FlateDecode");
01568         break;
01569       }
01570       case FaxCompression:
01571       {
01572         (void) strcpy(buffer,"/Filter [ /CCITTFaxDecode ]\n");
01573         (void) WriteBlobString(image,buffer);
01574         (void) FormatMagickString(buffer,MaxTextExtent,
01575           "/DecodeParms [ << >> << /K %s /Columns %lu /Rows %lu >> ]\n",
01576           CCITTParam,image->columns,image->rows);
01577         break;
01578       }
01579       default:
01580       {
01581         (void) FormatMagickString(buffer,MaxTextExtent,CFormat,
01582           "RunLengthDecode");
01583         break;
01584       }
01585     }
01586     (void) WriteBlobString(image,buffer);
01587     (void) FormatMagickString(buffer,MaxTextExtent,"/Width %lu\n",
01588       tile_image->columns);
01589     (void) WriteBlobString(image,buffer);
01590     (void) FormatMagickString(buffer,MaxTextExtent,"/Height %lu\n",
01591       tile_image->rows);
01592     (void) WriteBlobString(image,buffer);
01593     (void) FormatMagickString(buffer,MaxTextExtent,"/ColorSpace %lu 0 R\n",
01594       object-1);
01595     (void) WriteBlobString(image,buffer);
01596     (void) FormatMagickString(buffer,MaxTextExtent,"/BitsPerComponent %d\n",
01597       compression == FaxCompression ? 1 : 8);
01598     (void) WriteBlobString(image,buffer);
01599     (void) FormatMagickString(buffer,MaxTextExtent,"/Length %lu 0 R\n",
01600       object+1);
01601     (void) WriteBlobString(image,buffer);
01602     (void) WriteBlobString(image,">>\n");
01603     (void) WriteBlobString(image,"stream\n");
01604     offset=TellBlob(image);
01605     number_pixels=(MagickSizeType) tile_image->columns*tile_image->rows;
01606     if ((compression == FaxCompression) ||
01607         ((image_info->type != TrueColorType) &&
01608          (IsGrayImage(tile_image,&image->exception) != MagickFalse)))
01609       {
01610         switch (compression)
01611         {
01612           case FaxCompression:
01613           {
01614             if (LocaleCompare(CCITTParam,"0") == 0)
01615               (void) HuffmanEncodeImage(image_info,tile_image);
01616             else
01617               (void) Huffman2DEncodeImage(image_info,tile_image);
01618             break;
01619           }
01620           case JPEG2000Compression:
01621           {
01622             status=JP2EncodeImage(image_info,tile_image);
01623             if (status == MagickFalse)
01624               ThrowWriterException(CoderError,tile_image->exception.reason);
01625             break;
01626           }
01627           case JPEGCompression:
01628           {
01629             status=JPEGEncodeImage(image_info,tile_image);
01630             if (status == MagickFalse)
01631               ThrowWriterException(CoderError,tile_image->exception.reason);
01632             break;
01633           }
01634           case RLECompression:
01635           default:
01636           {
01637             /*
01638               Allocate pixel array.
01639             */
01640             length=(size_t) number_pixels;
01641             pixels=(unsigned char *) AcquireMagickMemory(length);
01642             if (pixels == (unsigned char *) NULL)
01643               {
01644                 tile_image=DestroyImage(tile_image);
01645                 ThrowWriterException(ResourceLimitError,
01646                   "MemoryAllocationFailed");
01647               }
01648             /*
01649               Dump Runlength encoded pixels.
01650             */
01651             q=pixels;
01652             for (y=0; y < (long) tile_image->rows; y++)
01653             {
01654               p=AcquireImagePixels(tile_image,0,y,tile_image->columns,1,
01655                 &tile_image->exception);
01656               if (p == (const PixelPacket *) NULL)
01657                 break;
01658               for (x=0; x < (long) tile_image->columns; x++)
01659               {
01660                 *q++=ScaleQuantumToChar(PixelIntensityToQuantum(p));
01661                 p++;
01662               }
01663             }
01664 #if defined(HasZLIB)
01665             if (compression == ZipCompression)
01666               status=ZLIBEncodeImage(image,length,quality,pixels);
01667             else
01668 #endif
01669               if (compression == LZWCompression)
01670                 status=LZWEncodeImage(image,length,pixels);
01671               else
01672                 status=PackbitsEncodeImage(image,length,pixels);
01673             pixels=(unsigned char *) RelinquishMagickMemory(pixels);
01674             if (status == MagickFalse)
01675               {
01676                 CloseBlob(image);
01677                 return(MagickFalse);
01678               }
01679             break;
01680           }
01681           case NoCompression:
01682           {
01683             /*
01684               Dump uncompressed PseudoColor packets.
01685             */
01686             Ascii85Initialize(image);
01687             for (y=0; y < (long) tile_image->rows; y++)
01688             {
01689               p=AcquireImagePixels(tile_image,0,y,tile_image->columns,1,
01690                 &tile_image->exception);
01691               if (p == (const PixelPacket *) NULL)
01692                 break;
01693               for (x=0; x < (long) tile_image->columns; x++)
01694               {
01695                 Ascii85Encode(image,
01696                   ScaleQuantumToChar(PixelIntensityToQuantum(p)));
01697                 p++;
01698               }
01699             }
01700             Ascii85Flush(image);
01701             break;
01702           }
01703         }
01704       }
01705     else
01706       if ((tile_image->storage_class == DirectClass) ||
01707           (tile_image->colors > 256) || (compression == JPEG2000Compression) ||
01708           (compression == JPEGCompression))
01709         switch (compression)
01710         {
01711           case JPEG2000Compression:
01712           {
01713             status=JP2EncodeImage(image_info,tile_image);
01714             if (status == MagickFalse)
01715               ThrowWriterException(CoderError,tile_image->exception.reason);
01716             break;
01717           }
01718           case JPEGCompression:
01719           {
01720             status=JPEGEncodeImage(image_info,tile_image);
01721             if (status == MagickFalse)
01722               ThrowWriterException(CoderError,tile_image->exception.reason);
01723             break;
01724           }
01725           case RLECompression:
01726           default:
01727           {
01728             /*
01729               Allocate pixel array.
01730             */
01731             length=(size_t) ((tile_image->colorspace == CMYKColorspace ? 4 : 3)*
01732               number_pixels);
01733             pixels=(unsigned char *) AcquireMagickMemory(length);
01734             if (pixels == (unsigned char *) NULL)
01735               {
01736                 tile_image=DestroyImage(tile_image);
01737                 ThrowWriterException(ResourceLimitError,
01738                   "MemoryAllocationFailed");
01739               }
01740             /*
01741               Dump runoffset encoded pixels.
01742             */
01743             q=pixels;
01744             for (y=0; y < (long) tile_image->rows; y++)
01745             {
01746               p=AcquireImagePixels(tile_image,0,y,tile_image->columns,1,
01747                 &tile_image->exception);
01748               if (p == (const PixelPacket *) NULL)
01749                 break;
01750               indexes=GetIndexes(tile_image);
01751               for (x=0; x < (long) tile_image->columns; x++)
01752               {
01753                 *q++=ScaleQuantumToChar(p->red);
01754                 *q++=ScaleQuantumToChar(p->green);
01755                 *q++=ScaleQuantumToChar(p->blue);
01756                 if (image->colorspace == CMYKColorspace)
01757                   *q++=ScaleQuantumToChar(indexes[x]);
01758                 p++;
01759               }
01760             }
01761 #if defined(HasZLIB)
01762             if (compression == ZipCompression)
01763               status=ZLIBEncodeImage(image,length,quality,pixels);
01764             else
01765 #endif
01766               if (compression == LZWCompression)
01767                 status=LZWEncodeImage(image,length,pixels);
01768               else
01769                 status=PackbitsEncodeImage(image,length,pixels);
01770             pixels=(unsigned char *) RelinquishMagickMemory(pixels);
01771             if (status == MagickFalse)
01772               {
01773                 CloseBlob(image);
01774                 return(MagickFalse);
01775               }
01776             break;
01777           }
01778           case NoCompression:
01779           {
01780             /*
01781               Dump uncompressed DirectColor packets.
01782             */
01783             Ascii85Initialize(image);
01784             for (y=0; y < (long) tile_image->rows; y++)
01785             {
01786               p=AcquireImagePixels(tile_image,0,y,tile_image->columns,1,
01787                 &tile_image->exception);
01788               if (p == (const PixelPacket *) NULL)
01789                 break;
01790               indexes=GetIndexes(tile_image);
01791               for (x=0; x < (long) tile_image->columns; x++)
01792               {
01793                 Ascii85Encode(image,ScaleQuantumToChar(p->red));
01794                 Ascii85Encode(image,ScaleQuantumToChar(p->green));
01795                 Ascii85Encode(image,ScaleQuantumToChar(p->blue));
01796                 if (image->colorspace == CMYKColorspace)
01797                   Ascii85Encode(image,ScaleQuantumToChar(indexes[x]));
01798                 p++;
01799               }
01800             }
01801             Ascii85Flush(image);
01802             break;
01803           }
01804         }
01805       else
01806         {
01807           /*
01808             Dump number of colors and colormap.
01809           */
01810           switch (compression)
01811           {
01812             case RLECompression:
01813             default:
01814             {
01815               /*
01816                 Allocate pixel array.
01817               */
01818               length=(size_t) number_pixels;
01819               pixels=(unsigned char *) AcquireMagickMemory(length);
01820               if (pixels == (unsigned char *) NULL)
01821                 {
01822                   tile_image=DestroyImage(tile_image);
01823                   ThrowWriterException(ResourceLimitError,
01824                     "MemoryAllocationFailed");
01825                 }
01826               /*
01827                 Dump Runlength encoded pixels.
01828               */
01829               q=pixels;
01830               for (y=0; y < (long) tile_image->rows; y++)
01831               {
01832                 p=AcquireImagePixels(tile_image,0,y,tile_image->columns,1,
01833                   &tile_image->exception);
01834                 if (p == (const PixelPacket *) NULL)
01835                   break;
01836                 indexes=GetIndexes(tile_image);
01837                 for (x=0; x < (long) tile_image->columns; x++)
01838                   *q++=(unsigned char) indexes[x];
01839               }
01840 #if defined(HasZLIB)
01841               if (compression == ZipCompression)
01842                 status=ZLIBEncodeImage(image,length,quality,pixels);
01843               else
01844 #endif
01845                 if (compression == LZWCompression)
01846                   status=LZWEncodeImage(image,length,pixels);
01847                 else
01848                   status=PackbitsEncodeImage(image,length,pixels);
01849               pixels=(unsigned char *) RelinquishMagickMemory(pixels);
01850               if (status == MagickFalse)
01851                 {
01852                   CloseBlob(image);
01853                   return(MagickFalse);
01854                 }
01855               break;
01856             }
01857             case NoCompression:
01858             {
01859               /*
01860                 Dump uncompressed PseudoColor packets.
01861               */
01862               Ascii85Initialize(image);
01863               for (y=0; y < (long) tile_image->rows; y++)
01864               {
01865                 p=AcquireImagePixels(tile_image,0,y,tile_image->columns,1,
01866                   &tile_image->exception);
01867                 if (p == (const PixelPacket *) NULL)
01868                   break;
01869                 indexes=GetIndexes(tile_image);
01870                 for (x=0; x < (long) tile_image->columns; x++)
01871                   Ascii85Encode(image,(unsigned char) indexes[x]);
01872               }
01873               Ascii85Flush(image);
01874               break;
01875             }
01876           }
01877         }
01878     tile_image=DestroyImage(tile_image);
01879     offset=TellBlob(image)-offset;
01880     (void) WriteBlobString(image,"\nendstream\n");
01881     (void) WriteBlobString(image,"endobj\n");
01882     /*
01883       Write Length object.
01884     */
01885     xref[object++]=TellBlob(image);
01886     (void) FormatMagickString(buffer,MaxTextExtent,"%lu 0 obj\n",object);
01887     (void) WriteBlobString(image,buffer);
01888     (void) FormatMagickString(buffer,MaxTextExtent,"%lu\n",
01889       (unsigned long) offset);
01890     (void) WriteBlobString(image,buffer);
01891     (void) WriteBlobString(image,"endobj\n");
01892     /*
01893       Write Colormap object.
01894     */
01895     xref[object++]=TellBlob(image);
01896     (void) FormatMagickString(buffer,MaxTextExtent,"%lu 0 obj\n",object);
01897     (void) WriteBlobString(image,buffer);
01898     (void) WriteBlobString(image,"<<\n");
01899     if ((image->storage_class != DirectClass) && (image->colors <= 256) &&
01900         (compression != FaxCompression))
01901       {
01902         if (compression == NoCompression)
01903           (void) WriteBlobString(image,"/Filter [ /ASCII85Decode ]\n");
01904         (void) FormatMagickString(buffer,MaxTextExtent,"/Length %lu 0 R\n",
01905           object+1);
01906         (void) WriteBlobString(image,buffer);
01907         (void) WriteBlobString(image,">>\n");
01908         (void) WriteBlobString(image,"stream\n");
01909         offset=TellBlob(image);
01910         if (compression == NoCompression)
01911           Ascii85Initialize(image);
01912         for (i=0; i < (long) image->colors; i++)
01913         {
01914           if (compression == NoCompression)
01915             {
01916               Ascii85Encode(image,ScaleQuantumToChar(image->colormap[i].red));
01917               Ascii85Encode(image,ScaleQuantumToChar(image->colormap[i].green));
01918               Ascii85Encode(image,ScaleQuantumToChar(image->colormap[i].blue));
01919               continue;
01920             }
01921           (void) WriteBlobByte(image,
01922             ScaleQuantumToChar(image->colormap[i].red));
01923           (void) WriteBlobByte(image,
01924             ScaleQuantumToChar(image->colormap[i].green));
01925           (void) WriteBlobByte(image,
01926             ScaleQuantumToChar(image->colormap[i].blue));
01927         }
01928         if (compression == NoCompression)
01929           Ascii85Flush(image);
01930       }
01931     offset=TellBlob(image)-offset;
01932     (void) WriteBlobString(image,"\nendstream\n");
01933     (void) WriteBlobString(image,"endobj\n");
01934     /*
01935       Write Length object.
01936     */
01937     xref[object++]=TellBlob(image);
01938     (void) FormatMagickString(buffer,MaxTextExtent,"%lu 0 obj\n",object);
01939     (void) WriteBlobString(image,buffer);
01940     (void) FormatMagickString(buffer,MaxTextExtent,"%lu\n",
01941       (unsigned long) offset);
01942     (void) WriteBlobString(image,buffer);
01943     (void) WriteBlobString(image,"endobj\n");
01944     if (image->next == (Image *) NULL)
01945       break;
01946     image=SyncNextImageInList(image);
01947     if (image->progress_monitor != (MagickProgressMonitor) NULL)
01948       {
01949         status=image->progress_monitor(SaveImagesTag,scene,
01950           GetImageListLength(image),image->client_data);
01951         if (status == MagickFalse)
01952           break;
01953       }
01954     scene++;
01955   } while (image_info->adjoin != MagickFalse);
01956   /*
01957     Write Xref object.
01958   */
01959   offset=TellBlob(image)-xref[0]+10;
01960   (void) WriteBlobString(image,"xref\n");
01961   (void) FormatMagickString(buffer,MaxTextExtent,"0 %lu\n",object+1);
01962   (void) WriteBlobString(image,buffer);
01963   (void) WriteBlobString(image,"0000000000 65535 f \n");
01964   for (i=0; i < (long) object; i++)
01965   {
01966     (void) FormatMagickString(buffer,MaxTextExtent,"%010lu 00000 n \n",
01967       (unsigned long) xref[i]);
01968     (void) WriteBlobString(image,buffer);
01969   }
01970   (void) WriteBlobString(image,"trailer\n");
01971   (void) WriteBlobString(image,"<<\n");
01972   (void) FormatMagickString(buffer,MaxTextExtent,"/Size %lu\n",object+1);
01973   (void) WriteBlobString(image,buffer);
01974   (void) FormatMagickString(buffer,MaxTextExtent,"/Info %lu 0 R\n",info_id);
01975   (void) WriteBlobString(image,buffer);
01976   (void) FormatMagickString(buffer,MaxTextExtent,"/Root %lu 0 R\n",root_id);
01977   (void) WriteBlobString(image,buffer);
01978   (void) WriteBlobString(image,">>\n");
01979   (void) WriteBlobString(image,"startxref\n");
01980   (void) FormatMagickString(buffer,MaxTextExtent,"%lu\n",
01981     (unsigned long) offset);
01982   (void) WriteBlobString(image,buffer);
01983   (void) WriteBlobString(image,"%%EOF\n");
01984   xref=(MagickOffsetType *) RelinquishMagickMemory(xref);
01985   CloseBlob(image);
01986   return(MagickTrue);
01987 }

Generated on Fri Feb 29 11:55:58 2008 for ImageMagick by  doxygen 1.5.5