00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
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
00075
00076 static MagickBooleanType
00077 WritePDFImage(const ImageInfo *,Image *);
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
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
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
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
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
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
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
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
00257
00258 if (LocaleNCompare(DeviceCMYK,command,strlen(DeviceCMYK)) == 0)
00259 cmyk=MagickTrue;
00260 if (LocaleNCompare(CropBox,command,strlen(CropBox)) == 0)
00261 {
00262
00263
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
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
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
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
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
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
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
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457 ModuleExport void UnregisterPDFImage(void)
00458 {
00459 (void) UnregisterMagickInfo("EPDF");
00460 (void) UnregisterMagickInfo("PDF");
00461 }
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
01400
01401 switch (compression)
01402 {
01403 case RLECompression:
01404 default:
01405 {
01406
01407
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
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
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
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
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
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
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
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
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
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
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
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
01809
01810 switch (compression)
01811 {
01812 case RLECompression:
01813 default:
01814 {
01815
01816
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
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
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
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
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
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
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 }