Coverage Report

Created: 2026-01-20 07:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/graphicsmagick/coders/ps2.c
Line
Count
Source
1
/*
2
% Copyright (C) 2003-2025 GraphicsMagick Group
3
% Copyright (C) 2002 ImageMagick Studio
4
% Copyright 1991-1999 E. I. du Pont de Nemours and Company
5
%
6
% This program is covered by multiple licenses, which are described in
7
% Copyright.txt. You should have received a copy of Copyright.txt with this
8
% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
9
%
10
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11
%                                                                             %
12
%                                                                             %
13
%                                                                             %
14
%                            PPPP   SSSSS  22222                              %
15
%                            P   P  SS        22                              %
16
%                            PPPP    SSS    222                               %
17
%                            P         SS  22                                 %
18
%                            P      SSSSS  22222                              %
19
%                                                                             %
20
%                                                                             %
21
%                     Write Postscript Level II Format.                       %
22
%                                                                             %
23
%                                                                             %
24
%                              Software Design                                %
25
%                                John Cristy                                  %
26
%                                 July 1992                                   %
27
%                                                                             %
28
%                                                                             %
29
%                                                                             %
30
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
31
%
32
%
33
*/
34

35
/*
36
  Include declarations.
37
*/
38
#include "magick/studio.h"
39
#include "magick/analyze.h"
40
#include "magick/attribute.h"
41
#include "magick/blob.h"
42
#include "magick/pixel_cache.h"
43
#include "magick/color.h"
44
#include "magick/constitute.h"
45
#include "magick/compress.h"
46
#include "magick/enum_strings.h"
47
#include "magick/magick.h"
48
#include "magick/monitor.h"
49
#include "magick/tempfile.h"
50
#include "magick/utility.h"
51
#include "magick/static.h"
52
#if defined(HasTIFF)
53
0
#define CCITTParam  "-1"
54
#else
55
#define CCITTParam  "0"
56
#endif
57

58
/*
59
  Forward declarations.
60
*/
61
static unsigned int
62
  WritePS2Image(const ImageInfo *,Image *);
63

64
#if defined(HasTIFF)
65
#if defined(HAVE_TIFFCONF_H)
66
#  include "tiffconf.h"
67
#endif
68
#include "tiffio.h"
69
70
#if (TIFFLIB_VERSION >= 20201219)
71
#  undef uint16
72
0
#  define uint16 uint16_t
73
#  undef uint32
74
#  define uint32 uint32_t
75
#endif /* TIFFLIB_VERSION */
76
77
/*
78
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
79
%                                                                             %
80
%                                                                             %
81
%                                                                             %
82
%   H u f f m a n 2 D E n c o d e I m a g e                                   %
83
%                                                                             %
84
%                                                                             %
85
%                                                                             %
86
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
87
%
88
%  Method Huffman2DEncodeImage compresses an image via two-dimensional
89
%  Huffman-coding.
90
%
91
%  The format of the Huffman2DEncodeImage method is:
92
%
93
%      unsigned int Huffman2DEncodeImage(const ImageInfo *image_info,
94
%        Image *image)
95
%
96
%  A description of each parameter follows:
97
%
98
%    o status:  Method Huffman2DEncodeImage returns True if all the pixels are
99
%      compressed without error, otherwise False.
100
%
101
%    o image_info: The image info..
102
%
103
%    o image: The image.
104
%
105
*/
106
static unsigned int Huffman2DEncodeImage(const ImageInfo *image_info,
107
  Image *image)
108
0
{
109
0
  char
110
0
    filename[MaxTextExtent];
111
112
0
  Image
113
0
    *huffman_image;
114
115
0
  ImageInfo
116
0
    *clone_info;
117
118
0
  long
119
0
    count,
120
0
    j;
121
122
0
  register long
123
0
    i;
124
125
0
  TIFF
126
0
    *tiff;
127
128
0
  uint16
129
0
    fillorder;
130
131
0
  unsigned char
132
0
    *buffer;
133
134
0
  unsigned int
135
0
    status;
136
137
0
  unsigned long
138
0
    *byte_count,
139
0
    strip_size;
140
141
  /*
142
    Write image as CCITTFax4 TIFF image to a temporary file.
143
  */
144
0
  assert(image_info != (ImageInfo *) NULL);
145
0
  assert(image_info->signature == MagickSignature);
146
0
  assert(image != (Image *) NULL);
147
0
  assert(image->signature == MagickSignature);
148
0
  huffman_image=CloneImage(image,0,0,True,&image->exception);
149
0
  if (huffman_image == (Image *) NULL)
150
0
    return(False);
151
0
  (void) SetImageType(huffman_image,BilevelType);
152
0
  if(!AcquireTemporaryFileName(filename))
153
0
    {
154
0
      DestroyImage(huffman_image);
155
0
      ThrowBinaryException(FileOpenError,UnableToCreateTemporaryFile,
156
0
        filename);
157
0
    }
158
0
  FormatString(huffman_image->filename,"tiff:%s",filename);
159
0
  clone_info=CloneImageInfo(image_info);
160
0
  clone_info->compression=Group4Compression;
161
0
  clone_info->type=BilevelType;
162
0
  (void) AddDefinitions(clone_info,"tiff:fill-order=msb2lsb",
163
0
                        &image->exception);
164
0
  status=WriteImage(clone_info,huffman_image);
165
0
  DestroyImageInfo(clone_info);
166
0
  DestroyImage(huffman_image);
167
0
  if (status == False)
168
0
    return(False);
169
0
  tiff=TIFFOpen(filename,"rb");
170
0
  if (tiff == (TIFF *) NULL)
171
0
    {
172
0
      (void) LiberateTemporaryFile(filename);
173
0
      ThrowBinaryException(FileOpenError,UnableToOpenFile,
174
0
        image_info->filename)
175
0
    }
176
  /*
177
    Allocate raw strip buffer.
178
  */
179
0
  (void) TIFFGetField(tiff,TIFFTAG_STRIPBYTECOUNTS,&byte_count);
180
0
  strip_size=byte_count[0];
181
0
  for (i=1; i < (long) TIFFNumberOfStrips(tiff); i++)
182
0
    if (byte_count[i] > strip_size)
183
0
      strip_size=byte_count[i];
184
0
  buffer=MagickAllocateResourceLimitedMemory(unsigned char *,strip_size);
185
0
  if (buffer == (unsigned char *) NULL)
186
0
    {
187
0
      TIFFClose(tiff);
188
0
      (void) LiberateTemporaryFile(filename);
189
0
      ThrowBinaryException(ResourceLimitError,MemoryAllocationFailed,
190
0
        (char *) NULL)
191
0
    }
192
  /*
193
    Compress runlength encoded to 2D Huffman pixels.
194
  */
195
0
  (void) TIFFGetFieldDefaulted(tiff,TIFFTAG_FILLORDER,&fillorder);
196
0
  for (i=0; i < (long) TIFFNumberOfStrips(tiff); i++)
197
0
  {
198
0
    Ascii85Initialize(image);
199
0
    count=TIFFReadRawStrip(tiff,(uint32) i,buffer,(long) byte_count[i]);
200
0
    if (fillorder == FILLORDER_LSB2MSB)
201
0
      TIFFReverseBits(buffer,count);
202
0
    for (j=0; j < count; j++)
203
0
      Ascii85Encode(image,(unsigned long) buffer[j]);
204
0
    Ascii85Flush(image);
205
0
  }
206
0
  MagickFreeResourceLimitedMemory(unsigned char *,buffer);
207
0
  TIFFClose(tiff);
208
0
  (void) LiberateTemporaryFile(filename);
209
0
  return(True);
210
0
}
211
#else
212
static unsigned int Huffman2DEncodeImage(const ImageInfo *image_info,
213
  Image *image)
214
{
215
  ARG_NOT_USED(image_info);
216
  assert(image != (Image *) NULL);
217
  assert(image->signature == MagickSignature);
218
  ThrowBinaryException(MissingDelegateError,TIFFLibraryIsNotAvailable,image->filename);
219
}
220
#endif
221

222
/*
223
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
224
%                                                                             %
225
%                                                                             %
226
%                                                                             %
227
%   R e g i s t e r P S 2 I m a g e                                           %
228
%                                                                             %
229
%                                                                             %
230
%                                                                             %
231
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
232
%
233
%  Method RegisterPS2Image adds attributes for the PS2 image format to
234
%  the list of supported formats.  The attributes include the image format
235
%  tag, a method to read and/or write the format, whether the format
236
%  supports the saving of more than one frame to the same file or blob,
237
%  whether the format supports native in-memory I/O, and a brief
238
%  description of the format.
239
%
240
%  The format of the RegisterPS2Image method is:
241
%
242
%      RegisterPS2Image(void)
243
%
244
*/
245
ModuleExport void RegisterPS2Image(void)
246
0
{
247
0
  MagickInfo
248
0
    *entry;
249
250
0
  entry=SetMagickInfo("EPS2");
251
0
  entry->encoder=(EncoderHandler) WritePS2Image;
252
0
  entry->adjoin=False;
253
0
  entry->seekable_stream=True;
254
0
  entry->description="Adobe Level II Encapsulated PostScript";
255
0
  entry->module="PS2";
256
0
  entry->coder_class=PrimaryCoderClass;
257
0
  (void) RegisterMagickInfo(entry);
258
259
0
  entry=SetMagickInfo("PS2");
260
0
  entry->encoder=(EncoderHandler) WritePS2Image;
261
0
  entry->seekable_stream=True;
262
0
  entry->description="Adobe Level II PostScript";
263
0
  entry->module="PS2";
264
0
  entry->coder_class=PrimaryCoderClass;
265
0
  (void) RegisterMagickInfo(entry);
266
0
}
267

268
/*
269
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
270
%                                                                             %
271
%                                                                             %
272
%                                                                             %
273
%   U n r e g i s t e r P S 2 I m a g e                                       %
274
%                                                                             %
275
%                                                                             %
276
%                                                                             %
277
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
278
%
279
%  Method UnregisterPS2Image removes format registrations made by the
280
%  PS2 module from the list of supported formats.
281
%
282
%  The format of the UnregisterPS2Image method is:
283
%
284
%      UnregisterPS2Image(void)
285
%
286
*/
287
ModuleExport void UnregisterPS2Image(void)
288
0
{
289
0
  (void) UnregisterMagickInfo("EPS2");
290
0
  (void) UnregisterMagickInfo("PS2");
291
0
}
292

293
/*
294
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
295
%                                                                             %
296
%                                                                             %
297
%                                                                             %
298
%   W r i t e P S 2 I m a g e                                                 %
299
%                                                                             %
300
%                                                                             %
301
%                                                                             %
302
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
303
%
304
%  Method WritePS2Image translates an image to encapsulated Postscript
305
%  Level II for printing.  If the supplied geometry is null, the image is
306
%  centered on the Postscript page.  Otherwise, the image is positioned as
307
%  specified by the geometry.
308
%
309
%  The format of the WritePS2Image method is:
310
%
311
%      unsigned int WritePS2Image(const ImageInfo *image_info,Image *image)
312
%
313
%  A description of each parameter follows:
314
%
315
%    o status: Method WritePS2Image return True if the image is printed.
316
%      False is returned if the image file cannot be opened for printing.
317
%
318
%    o image_info: Specifies a pointer to a ImageInfo structure.
319
%
320
%    o image: The address of a structure of type Image;  returned from
321
%      ReadImage.
322
%
323
%
324
*/
325
static unsigned int WritePS2Image(const ImageInfo *image_info,Image *image)
326
0
{
327
0
  char
328
0
    buffer[MaxTextExtent],
329
0
    date[MaxTextExtent],
330
0
    density[MaxTextExtent],
331
0
    page_geometry[MaxTextExtent],
332
0
    **labels;
333
334
0
  CompressionType
335
0
    compression;
336
337
0
  const ImageAttribute
338
0
    *attribute;
339
340
0
  double
341
0
    dx_resolution,
342
0
    dy_resolution,
343
0
    x_resolution,
344
0
    x_scale,
345
0
    y_resolution,
346
0
    y_scale;
347
348
0
  magick_off_t
349
0
    current,
350
0
    start,
351
0
    stop;
352
353
0
  int
354
0
    count,
355
0
    status;
356
357
0
  long
358
0
    j,
359
0
    y;
360
361
0
  RectangleInfo
362
0
    geometry;
363
364
0
  register const PixelPacket
365
0
    *p;
366
367
0
  register const IndexPacket
368
0
    *indexes;
369
370
0
  register long
371
0
    x;
372
373
0
  register long
374
0
    i;
375
376
0
  SegmentInfo
377
0
    bounds={0.0,0.0,0.0,0.0};
378
379
0
  size_t
380
0
    length;
381
382
0
  time_t
383
0
    timer;
384
385
0
  unsigned char
386
0
    *pixels;
387
388
0
  unsigned long
389
0
    number_pixels,
390
0
    page,
391
0
    scene,
392
0
    text_size;
393
394
0
  void
395
0
    *blob;
396
397
0
  size_t
398
0
    image_list_length;
399
400
  /*
401
    Open output image file.
402
  */
403
0
  assert(image_info != (const ImageInfo *) NULL);
404
0
  assert(image_info->signature == MagickSignature);
405
0
  assert(image != (Image *) NULL);
406
0
  assert(image->signature == MagickSignature);
407
0
  image_list_length=GetImageListLength(image);
408
0
  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
409
0
  if (status == False)
410
0
    ThrowWriterException(FileOpenError,UnableToOpenFile,image);
411
0
  compression=image->compression;
412
0
  if (image_info->compression != UndefinedCompression)
413
0
    compression=image_info->compression;
414
0
  switch (compression)
415
0
  {
416
#if !defined(HasJPEG)
417
    case JPEGCompression:
418
    {
419
      compression=RLECompression;
420
      ThrowException(&image->exception,MissingDelegateError,JPEGLibraryIsNotAvailable,image->filename);
421
      break;
422
    }
423
#endif
424
#if !defined(HasZLIB)
425
    case ZipCompression:
426
    {
427
      compression=RLECompression;
428
      ThrowException(&image->exception,MissingDelegateError,ZipLibraryIsNotAvailable,image->filename);
429
      break;
430
    }
431
#endif
432
0
    default:
433
0
      break;
434
0
  }
435
0
  page=1;
436
0
  scene=0;
437
0
  do
438
0
  {
439
0
    ImageCharacteristics
440
0
      characteristics;
441
442
    /*
443
      Scale image to size of Postscript page.
444
    */
445
0
    text_size=0;
446
0
    attribute=GetImageAttribute(image,"label");
447
0
    if (attribute != (const ImageAttribute *) NULL)
448
0
      text_size=(unsigned int)
449
0
        (MultilineCensus(attribute->value)*image_info->pointsize+12);
450
0
    SetGeometry(image,&geometry);
451
0
    geometry.y=(long) text_size;
452
0
    FormatString(page_geometry,"%lux%lu",image->columns,image->rows);
453
0
    if (image_info->page != (char *) NULL)
454
0
      (void) strlcpy(page_geometry,image_info->page,MaxTextExtent);
455
0
    else
456
0
      if ((image->page.width != 0) && (image->page.height != 0))
457
0
        (void) FormatString(page_geometry,"%lux%lu%+ld%+ld",image->page.width,
458
0
          image->page.height,image->page.x,image->page.y);
459
0
      else
460
0
        if (LocaleCompare(image_info->magick,"PS2") == 0)
461
0
          (void) strlcpy(page_geometry,PSPageGeometry,sizeof(page_geometry));
462
0
    (void) GetMagickGeometry(page_geometry,&geometry.x,&geometry.y,
463
0
       &geometry.width,&geometry.height);
464
0
    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
465
0
                          "Image Resolution: %gx%g %s",
466
0
                          image->x_resolution,
467
0
                          image->y_resolution,
468
0
                          ResolutionTypeToString(image->units));
469
    /*
470
      Scale relative to dots-per-inch.
471
    */
472
0
    dx_resolution=72.0;
473
0
    dy_resolution=72.0;
474
0
    x_resolution=72.0;
475
0
    (void) strlcpy(density,PSDensityGeometry,sizeof(density));
476
0
    count=GetMagickDimension(density,&x_resolution,&y_resolution,NULL,NULL);
477
0
    if (count != 2)
478
0
      y_resolution=x_resolution;
479
    /*
480
      Use override resolution information if it appears to be valid.
481
    */
482
0
    if ((image_info->density != (char *) NULL) &&
483
0
        ((image_info->units == PixelsPerInchResolution) ||
484
0
         (image_info->units == PixelsPerCentimeterResolution)))
485
0
      {
486
0
        count=GetMagickDimension(image_info->density,&x_resolution,
487
0
          &y_resolution,NULL,NULL);
488
0
        if (count != 2)
489
0
          y_resolution=x_resolution;
490
0
        if (image_info->units == PixelsPerCentimeterResolution)
491
0
          {
492
0
            x_resolution *= 2.54;
493
0
            y_resolution *= 2.54;
494
0
          }
495
0
      }
496
    /*
497
      Use image resolution information if it appears to be valid.
498
    */
499
0
    else if ((image->x_resolution > 0.0) && (image->y_resolution > 0.0) &&
500
0
             ((image->units == PixelsPerInchResolution) ||
501
0
              (image->units == PixelsPerCentimeterResolution)))
502
0
      {
503
0
        x_resolution = image->x_resolution;
504
0
        y_resolution = image->y_resolution;
505
0
        if (image->units == PixelsPerCentimeterResolution)
506
0
          {
507
0
            x_resolution *= 2.54;
508
0
            y_resolution *= 2.54;
509
0
          }
510
0
      }
511
0
    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
512
0
                          "Postscript Resolution: %gx%g DPI",
513
0
                          x_resolution,y_resolution);
514
0
    x_scale=(geometry.width*dx_resolution)/x_resolution;
515
0
    geometry.width=(unsigned long) (x_scale+0.5);
516
0
    y_scale=(geometry.height*dy_resolution)/y_resolution;
517
0
    geometry.height=(unsigned long) (y_scale+0.5);
518
0
    if (page == 1)
519
0
      {
520
        /*
521
          Output Postscript header.
522
        */
523
0
 #if defined(HAVE_CTIME_R)
524
0
        char time_buf[26];
525
0
#endif /* defined(HAVE_CTIME_R) */
526
0
       if (LocaleCompare(image_info->magick,"PS2") == 0)
527
0
         (void) strlcpy(buffer,"%!PS-Adobe-3.0\n",sizeof(buffer));
528
0
        else
529
0
          (void) strlcpy(buffer,"%!PS-Adobe-3.0 EPSF-3.0\n",sizeof(buffer));
530
0
        (void) WriteBlobString(image,buffer);
531
0
        (void) WriteBlobString(image,"%%Creator: (GraphicsMagick)\n");
532
0
        FormatString(buffer,"%%%%Title: (%.1024s)\n",image->filename);
533
0
        (void) WriteBlobString(image,buffer);
534
0
        timer=time((time_t *) NULL);
535
0
#if defined(HAVE_CTIME_R)
536
0
        (void) strlcpy(date,ctime_r(&timer,time_buf),MaxTextExtent);
537
#else
538
        (void) strlcpy(date,ctime(&timer),MaxTextExtent); /* Thread-unsafe version */
539
#endif /* defined(HAVE_CTIME_R) */
540
0
        date[strlen(date)-1]='\0';
541
0
        FormatString(buffer,"%%%%CreationDate: (%.1024s)\n",date);
542
0
        (void) WriteBlobString(image,buffer);
543
0
        bounds.x1=geometry.x;
544
0
        bounds.y1=geometry.y;
545
0
        bounds.x2=geometry.x+(size_t) geometry.width;
546
0
        bounds.y2=geometry.y+(size_t) geometry.height+text_size;
547
0
        if (image_info->adjoin && (image->next != (Image *) NULL))
548
0
          (void) strlcpy(buffer,"%%BoundingBox: (atend)\n",sizeof(buffer));
549
0
        else
550
0
          FormatString(buffer,"%%%%BoundingBox: %g %g %g %g\n",
551
0
            floor(bounds.x1+0.5),floor(bounds.y1+0.5),ceil(bounds.x2-0.5),
552
0
            ceil(bounds.y2-0.5));
553
0
        (void) WriteBlobString(image,buffer);
554
0
        attribute=GetImageAttribute(image,"label");
555
0
        if (attribute != (const ImageAttribute *) NULL)
556
0
          (void) WriteBlobString(image,
557
0
            "%%DocumentNeededResources: font Helvetica\n");
558
0
        (void) WriteBlobString(image,"%%LanguageLevel: 2\n");
559
0
        if (LocaleCompare(image_info->magick,"PS2") != 0)
560
0
          (void) WriteBlobString(image,"%%Pages: 1\n");
561
0
        else
562
0
          {
563
0
            (void) WriteBlobString(image,"%%Orientation: Portrait\n");
564
0
            (void) WriteBlobString(image,"%%PageOrder: Ascend\n");
565
0
            if (!image_info->adjoin)
566
0
              (void) strlcpy(buffer,"%%Pages: 1\n",sizeof(buffer));
567
0
            else
568
0
              FormatString(buffer,"%%%%Pages: %lu\n",(unsigned long)
569
0
                image_list_length);
570
0
            (void) WriteBlobString(image,buffer);
571
0
          }
572
0
        (void) WriteBlobString(image,"%%EndComments\n");
573
0
        (void) WriteBlobString(image,"\n%%BeginDefaults\n");
574
0
        (void) WriteBlobString(image,"%%EndDefaults\n\n");
575
        /*
576
          Output Postscript commands.
577
        */
578
0
        {
579
0
          const char * ps_compress;
580
581
0
          switch (compression)
582
0
          {
583
0
          case NoCompression: ps_compress="ASCII85Decode"; break;
584
0
            case JPEGCompression: ps_compress="DCTDecode"; break;
585
0
            case LZWCompression: ps_compress="LZWDecode"; break;
586
0
            case FaxCompression: ps_compress="ASCII85Decode"; break;
587
0
            default: ps_compress="RunLengthDecode"; break;
588
0
          }
589
0
          (void) WriteBlobString(image,
590
0
                       "%%BeginProlog\n"
591
0
                       "%\n"
592
0
                       "% Display a color image.  The image is displayed in color on\n"
593
0
                       "% Postscript viewers or printers that support color, otherwise\n"
594
0
                       "% it is displayed as grayscale.\n"
595
0
                       "%\n"
596
0
                       "/DirectClassImage\n");
597
0
          FormatString(buffer,
598
0
                       "{\n"
599
0
                       "  %%\n"
600
0
                       "  %% Display a DirectClass image.\n"
601
0
                       "  %%\n"
602
0
                       "  colorspace 0 eq\n"
603
0
                       "  {\n"
604
0
                       "    /DeviceRGB setcolorspace\n"
605
0
                       "    <<\n"
606
0
                       "      /ImageType 1\n"
607
0
                       "      /Width columns\n"
608
0
                       "      /Height rows\n"
609
0
                       "      /BitsPerComponent 8\n"
610
0
                       "      /Decode [0 1 0 1 0 1]\n"
611
0
                       "      /ImageMatrix [columns 0 0 rows neg 0 rows]\n"
612
0
                       "      compression 0 gt\n"
613
0
                       "      { /DataSource pixel_stream /%.1024s filter }\n"
614
0
                       "      { /DataSource pixel_stream /%.1024s filter } ifelse\n"
615
0
                       "    >> image\n"
616
0
                       "  }\n",
617
0
                       ps_compress, ps_compress);
618
0
          (void) WriteBlobString(image,buffer);
619
0
          FormatString(buffer,
620
0
                       "  {\n"
621
0
                       "    /DeviceCMYK setcolorspace\n"
622
0
                       "    <<\n"
623
0
                       "      /ImageType 1\n"
624
0
                       "      /Width columns\n"
625
0
                       "      /Height rows\n"
626
0
                       "      /BitsPerComponent 8\n"
627
0
                       "      /Decode [1 0 1 0 1 0 1 0]\n"
628
0
                       "      /ImageMatrix [columns 0 0 rows neg 0 rows]\n"
629
0
                       "      compression 0 gt\n"
630
0
                       "      { /DataSource pixel_stream /%.1024s filter }\n"
631
0
                       "      { /DataSource pixel_stream /%.1024s filter } ifelse\n"
632
0
                       "    >> image\n"
633
0
                       "  } ifelse\n"
634
0
                       "} bind def\n"
635
0
                       "\n",
636
0
                       ps_compress, ps_compress);
637
0
          (void) WriteBlobString(image,buffer);
638
0
          FormatString(buffer,
639
0
                       "/PseudoClassImage\n"
640
0
                       "{\n"
641
0
                       "  %%\n"
642
0
                       "  %% Display a PseudoClass image.\n"
643
0
                       "  %%\n"
644
0
                       "  %% Parameters:\n"
645
0
                       "  %%   colors: number of colors in the colormap.\n"
646
0
                       "  %%\n"
647
0
                       "  currentfile buffer readline pop\n"
648
0
                       "  token pop /colors exch def pop\n"
649
0
                       "  colors 0 eq\n"
650
0
                       "  {\n"
651
0
                       "    %%\n"
652
0
                       "    %% Image is grayscale.\n"
653
0
                       "    %%\n"
654
0
                       "    currentfile buffer readline pop\n"
655
0
                       "    token pop /bits exch def pop\n"
656
0
                       "    /DeviceGray setcolorspace\n"
657
0
                       "    <<\n"
658
0
                       "      /ImageType 1\n"
659
0
                       "      /Width columns\n"
660
0
                       "      /Height rows\n"
661
0
                       "      /BitsPerComponent bits\n"
662
0
                       "      /Decode [0 1]\n"
663
0
                       "      /ImageMatrix [columns 0 0 rows neg 0 rows]\n"
664
0
                       "      compression 0 gt\n"
665
0
                       "      { /DataSource pixel_stream /%.1024s filter }\n"
666
0
                       "      {\n"
667
0
                       "        /DataSource pixel_stream /%.1024s filter\n"
668
0
                       "        <<\n"
669
0
                       "           /K " CCITTParam "\n"
670
0
                       "           /Columns columns\n"
671
0
                       "           /Rows rows\n"
672
0
                       "        >> /CCITTFaxDecode filter\n"
673
0
                       "      } ifelse\n"
674
0
                       "    >> image\n"
675
0
                       "  }\n",
676
0
                       ps_compress, ps_compress);
677
0
          (void) WriteBlobString(image,buffer);
678
0
          FormatString(buffer,
679
0
                       "  {\n"
680
0
                       "    %%\n"
681
0
                       "    %% Parameters:\n"
682
0
                       "    %%   colormap: red, green, blue color packets.\n"
683
0
                       "    %%\n"
684
0
                       "    /colormap colors 3 mul string def\n"
685
0
                       "    currentfile colormap readhexstring pop pop\n"
686
0
                       "    currentfile buffer readline pop\n"
687
0
                       "    [ /Indexed /DeviceRGB colors 1 sub colormap ] setcolorspace\n"
688
0
                       "    <<\n"
689
0
                       "      /ImageType 1\n"
690
0
                       "      /Width columns\n"
691
0
                       "      /Height rows\n"
692
0
                       "      /BitsPerComponent 8\n"
693
0
                       "      /Decode [0 255]\n"
694
0
                       "      /ImageMatrix [columns 0 0 rows neg 0 rows]\n"
695
0
                       "      compression 0 gt\n"
696
0
                       "      { /DataSource pixel_stream /%.1024s filter }\n"
697
0
                       "      { /DataSource pixel_stream /%.1024s filter } ifelse\n"
698
0
                       "    >> image\n"
699
0
                       "  } ifelse\n"
700
0
                       "} bind def\n"
701
0
                       "\n",
702
0
                       ps_compress, ps_compress);
703
0
          (void) WriteBlobString(image,buffer);
704
0
          (void) WriteBlobString(image,
705
0
                       "/DisplayImage\n"
706
0
                       "{\n"
707
0
                       "  %\n"
708
0
                       "  % Display a DirectClass or PseudoClass image.\n"
709
0
                       "  %\n"
710
0
                       "  % Parameters:\n"
711
0
                       "  %   x & y translation.\n"
712
0
                       "  %   x & y scale.\n"
713
0
                       "  %   label pointsize.\n"
714
0
                       "  %   image label.\n"
715
0
                       "  %   image columns & rows.\n"
716
0
                       "  %   class: 0-DirectClass or 1-PseudoClass.\n"
717
0
                       "  %   colorspace: 0-RGB or 1-CMYK.\n"
718
0
                       "  %   compression: 0-RLECompression or 1-NoCompression.\n"
719
0
                       "  %   hex color packets.\n"
720
0
                       "  %\n"
721
0
                       "  gsave\n"
722
0
                       "  /buffer 512 string def\n"
723
0
                       "  /pixel_stream currentfile def\n"
724
0
                       "\n"
725
0
                       "  currentfile buffer readline pop\n"
726
0
                       "  token pop /x exch def\n"
727
0
                       "  token pop /y exch def pop\n"
728
0
                       "  x y translate\n"
729
0
                       "  currentfile buffer readline pop\n"
730
0
                       "  token pop /x exch def\n"
731
0
                       "  token pop /y exch def pop\n"
732
0
                       "  currentfile buffer readline pop\n"
733
0
                       "  token pop /pointsize exch def pop\n"
734
0
                       "  /Helvetica findfont pointsize scalefont setfont\n"
735
0
               );
736
0
        }
737
0
        attribute=GetImageAttribute(image,"label");
738
0
        if (attribute != (const ImageAttribute *) NULL)
739
0
          for (j=(long) MultilineCensus(attribute->value)-1; j >= 0; j--)
740
0
          {
741
0
            (void) WriteBlobString(image,"  /label 512 string def\n");
742
0
            (void) WriteBlobString(image,"  currentfile label readline pop\n");
743
0
            FormatString(buffer,"  0 y %g add moveto label show pop\n",
744
0
              j*image_info->pointsize+12);
745
0
            (void) WriteBlobString(image,buffer);
746
0
          }
747
0
            (void) WriteBlobString(image,
748
0
                                   "  x y scale\n"
749
0
                                   "  currentfile buffer readline pop\n"
750
0
                                   "  token pop /columns exch def\n"
751
0
                                   "  token pop /rows exch def pop\n"
752
0
                                   "  currentfile buffer readline pop\n"
753
0
                                   "  token pop /class exch def pop\n"
754
0
                                   "  currentfile buffer readline pop\n"
755
0
                                   "  token pop /colorspace exch def pop\n"
756
0
                                   "  currentfile buffer readline pop\n"
757
0
                                   "  token pop /compression exch def pop\n"
758
0
                                   "  class 0 gt { PseudoClassImage } { DirectClassImage } ifelse\n"
759
0
                                   "  grestore\n");
760
0
        if (LocaleCompare(image_info->magick,"PS2") == 0)
761
0
          (void) WriteBlobString(image,"  showpage\n");
762
0
        (void) WriteBlobString(image,"} bind def\n");
763
0
        (void) WriteBlobString(image,"%%EndProlog\n");
764
0
      }
765
0
    FormatString(buffer,"%%%%Page:  1 %lu\n",page++);
766
0
    (void) WriteBlobString(image,buffer);
767
0
    FormatString(buffer,"%%%%PageBoundingBox: %ld %ld %ld %ld\n",geometry.x,
768
0
      geometry.y,geometry.x+(long) geometry.width,geometry.y+(long)
769
0
      (geometry.height+text_size));
770
0
    (void) WriteBlobString(image,buffer);
771
0
    if (geometry.x < bounds.x1)
772
0
      bounds.x1=geometry.x;
773
0
    if (geometry.y < bounds.y1)
774
0
      bounds.y1=geometry.y;
775
0
    if ((geometry.x+(size_t) geometry.width-1) > bounds.x2)
776
0
      bounds.x2=geometry.x+(size_t) geometry.width-1;
777
0
    if ((geometry.y+((size_t) geometry.height+text_size)-1) > bounds.y2)
778
0
      bounds.y2=geometry.y+((size_t) geometry.height+text_size)-1;
779
0
    attribute=GetImageAttribute(image,"label");
780
0
    if (attribute != (const ImageAttribute *) NULL)
781
0
      (void) WriteBlobString(image,"%%PageResources: font Times-Roman\n");
782
0
    if (LocaleCompare(image_info->magick,"PS2") != 0)
783
0
      (void) WriteBlobString(image,"userdict begin\n");
784
0
    start=TellBlob(image);
785
0
    if (start < 0)
786
0
      ThrowWriterException(BlobError,UnableToObtainOffset,image);
787
0
    FormatString(buffer,"%%%%BeginData:%13ld %s Bytes\n",0L,
788
0
      compression == NoCompression ? "ASCII" : "Binary");
789
0
    (void) WriteBlobString(image,buffer);
790
0
    stop=TellBlob(image);
791
0
    if (stop < 0)
792
0
      ThrowWriterException(BlobError,UnableToObtainOffset,image);
793
0
    (void) WriteBlobString(image,"DisplayImage\n");
794
    /*
795
      Output image data.
796
    */
797
0
    FormatString(buffer,"%ld %ld\n%g %g\n%f\n",geometry.x,geometry.y,
798
0
      x_scale,y_scale,image_info->pointsize);
799
0
    (void) WriteBlobString(image,buffer);
800
0
    labels=(char **) NULL;
801
0
    attribute=GetImageAttribute(image,"label");
802
0
    if (attribute != (const ImageAttribute *) NULL)
803
0
      labels=StringToList(attribute->value);
804
0
    if (labels != (char **) NULL)
805
0
      {
806
0
        for (i=0; labels[i] != (char *) NULL; i++)
807
0
        {
808
0
          FormatString(buffer,"%.1024s \n",labels[i]);
809
0
          (void) WriteBlobString(image,buffer);
810
0
          MagickFreeMemory(labels[i]);
811
0
        }
812
0
        MagickFreeMemory(labels);
813
0
      }
814
0
    number_pixels=image->columns*image->rows;
815
816
    /*
817
      Analyze image to be written.
818
    */
819
0
    (void) GetImageCharacteristics(image,&characteristics,
820
0
                                   (OptimizeType == image_info->type),
821
0
                                   &image->exception);
822
0
    if ((compression == FaxCompression) ||
823
0
        ((image_info->type != TrueColorType) &&
824
0
         (characteristics.grayscale)))
825
0
      {
826
0
        FormatString(buffer,"%lu %lu\n1\n%d\n",image->columns,image->rows,
827
0
          (int) (image->colorspace == CMYKColorspace));
828
0
        (void) WriteBlobString(image,buffer);
829
0
        FormatString(buffer,"%d\n",(int) (compression != FaxCompression));
830
0
        (void) WriteBlobString(image,buffer);
831
0
        (void) WriteBlobString(image,"0\n");
832
0
        FormatString(buffer,"%d\n",compression == FaxCompression ? 1 : 8);
833
0
        (void) WriteBlobString(image,buffer);
834
0
        switch (compression)
835
0
        {
836
0
          case FaxCompression:
837
0
          {
838
0
            if (LocaleCompare(CCITTParam,"0") == 0)
839
0
              {
840
0
                (void) HuffmanEncodeImage(image_info,image);
841
0
                break;
842
0
              }
843
0
            (void) Huffman2DEncodeImage(image_info,image);
844
0
            break;
845
0
          }
846
0
          case JPEGCompression:
847
0
          {
848
            /*
849
              Write image in JPEG format.
850
            */
851
0
            blob=ImageToJPEGBlob(image,image_info,&length,&image->exception);
852
0
            if (blob == (char *) NULL)
853
0
              ThrowWriterException2(CoderError,image->exception.reason,image);
854
0
            (void) WriteBlob(image,length,blob);
855
0
            MagickFreeMemory(blob);
856
0
            break;
857
0
          }
858
0
          case RLECompression:
859
0
          default:
860
0
          {
861
0
            register unsigned char
862
0
              *q;
863
864
            /*
865
              Allocate pixel array.
866
            */
867
0
            length=number_pixels;
868
0
            pixels=MagickAllocateResourceLimitedMemory(unsigned char *,length);
869
0
            if (pixels == (unsigned char *) NULL)
870
0
              ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,
871
0
                image);
872
            /*
873
              Dump Runlength encoded pixels.
874
            */
875
0
            q=pixels;
876
0
            for (y=0; y < (long) image->rows; y++)
877
0
            {
878
0
              p=AcquireImagePixels(image,0,y,image->columns,1,
879
0
                &image->exception);
880
0
              if (p == (const PixelPacket *) NULL)
881
0
                break;
882
0
              for (x=0; x < (long) image->columns; x++)
883
0
              {
884
0
                *q++=ScaleQuantumToChar(PixelIntensityToQuantum(p));
885
0
                p++;
886
0
              }
887
0
              if (image->previous == (Image *) NULL)
888
0
                if (QuantumTick(y,image->rows))
889
0
                  {
890
0
                    status=MagickMonitorFormatted(y,image->rows,
891
0
                                                  &image->exception,
892
0
                                                  SaveImageText,
893
0
                                                  image->filename,
894
0
                                                  image->columns,image->rows);
895
0
                    if (status == False)
896
0
                      break;
897
0
                  }
898
0
            }
899
0
            if (compression == LZWCompression)
900
0
              status=LZWEncodeImage(image,length,pixels);
901
0
            else
902
0
              status=PackbitsEncodeImage(image,length,pixels);
903
0
            MagickFreeResourceLimitedMemory(unsigned char *,pixels);
904
0
            if (!status)
905
0
              {
906
0
                CloseBlob(image);
907
0
                return(False);
908
0
              }
909
0
            break;
910
0
          }
911
0
          case NoCompression:
912
0
          {
913
            /*
914
              Dump uncompressed PseudoColor packets.
915
            */
916
0
            Ascii85Initialize(image);
917
0
            for (y=0; y < (long) image->rows; y++)
918
0
            {
919
0
              p=AcquireImagePixels(image,0,y,image->columns,1,
920
0
                &image->exception);
921
0
              if (p == (const PixelPacket *) NULL)
922
0
                break;
923
0
              for (x=0; x < (long) image->columns; x++)
924
0
              {
925
0
                Ascii85Encode(image,
926
0
                  ScaleQuantumToChar(PixelIntensityToQuantum(p)));
927
0
                p++;
928
0
              }
929
0
              if (image->previous == (Image *) NULL)
930
0
                if (QuantumTick(y,image->rows))
931
0
                  {
932
0
                    status=MagickMonitorFormatted(y,image->rows,
933
0
                                                  &image->exception,
934
0
                                                  SaveImageText,
935
0
                                                  image->filename,
936
0
                                                  image->columns,image->rows);
937
0
                    if (status == False)
938
0
                      break;
939
0
                  }
940
0
            }
941
0
            Ascii85Flush(image);
942
0
            break;
943
0
          }
944
0
        }
945
0
      }
946
0
    else
947
0
      if ((image->storage_class == DirectClass) || (image->colors > 256) ||
948
0
          (compression == JPEGCompression))
949
0
        {
950
0
          FormatString(buffer,"%lu %lu\n0\n%d\n",image->columns,image->rows,
951
0
            (int) (image->colorspace == CMYKColorspace));
952
0
          (void) WriteBlobString(image,buffer);
953
0
          FormatString(buffer,"%d\n",(int) (compression == NoCompression));
954
0
          (void) WriteBlobString(image,buffer);
955
0
          switch (compression)
956
0
          {
957
0
            case JPEGCompression:
958
0
            {
959
              /*
960
                Write image in JPEG format.
961
              */
962
0
              blob=ImageToJPEGBlob(image,image_info,&length,&image->exception);
963
0
              if (blob == (char *) NULL)
964
0
                ThrowWriterException2(CoderError,image->exception.reason,image);
965
0
              (void) WriteBlob(image,length,blob);
966
0
              MagickFreeMemory(blob);
967
0
              break;
968
0
            }
969
0
            case RLECompression:
970
0
            default:
971
0
            {
972
0
              register unsigned char
973
0
                *q;
974
975
              /*
976
                Allocate pixel array.
977
              */
978
0
              length=MagickArraySize(image->colorspace == CMYKColorspace ? 4 : 3,
979
0
                number_pixels);
980
0
              pixels=MagickAllocateResourceLimitedMemory(unsigned char *,length);
981
0
              if (pixels == (unsigned char *) NULL)
982
0
                ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
983
              /*
984
                Dump Packbit encoded pixels.
985
              */
986
0
              q=pixels;
987
0
              for (y=0; y < (long) image->rows; y++)
988
0
              {
989
0
                p=AcquireImagePixels(image,0,y,image->columns,1,
990
0
                  &image->exception);
991
0
                if (p == (const PixelPacket *) NULL)
992
0
                  break;
993
0
                for (x=0; x < (long) image->columns; x++)
994
0
                {
995
0
                  if (image->matte && (p->opacity == TransparentOpacity))
996
0
                    {
997
0
                      *q++=ScaleQuantumToChar(MaxRGB);
998
0
                      *q++=ScaleQuantumToChar(MaxRGB);
999
0
                      *q++=ScaleQuantumToChar(MaxRGB);
1000
0
                    }
1001
0
                  else
1002
0
                    if (image->colorspace != CMYKColorspace)
1003
0
                      {
1004
0
                        *q++=ScaleQuantumToChar(p->red);
1005
0
                        *q++=ScaleQuantumToChar(p->green);
1006
0
                        *q++=ScaleQuantumToChar(p->blue);
1007
0
                      }
1008
0
                    else
1009
0
                      {
1010
0
                        *q++=ScaleQuantumToChar(p->red);
1011
0
                        *q++=ScaleQuantumToChar(p->green);
1012
0
                        *q++=ScaleQuantumToChar(p->blue);
1013
0
                        *q++=ScaleQuantumToChar(p->opacity);
1014
0
                      }
1015
0
                  p++;
1016
0
                }
1017
0
                if (image->previous == (Image *) NULL)
1018
0
                  if (QuantumTick(y,image->rows))
1019
0
                    {
1020
0
                      status=MagickMonitorFormatted(y,image->rows,
1021
0
                                                    &image->exception,
1022
0
                                                    SaveImageText,
1023
0
                                                    image->filename,
1024
0
                                                    image->columns,image->rows);
1025
0
                      if (status == False)
1026
0
                        break;
1027
0
                    }
1028
0
              }
1029
0
              if (compression == LZWCompression)
1030
0
                status=LZWEncodeImage(image,length,pixels);
1031
0
              else
1032
0
                status=PackbitsEncodeImage(image,length,pixels);
1033
0
              if (!status)
1034
0
                {
1035
0
                  CloseBlob(image);
1036
0
                  return(False);
1037
0
                }
1038
0
              MagickFreeResourceLimitedMemory(unsigned char *,pixels);
1039
0
              break;
1040
0
            }
1041
0
            case NoCompression:
1042
0
            {
1043
              /*
1044
                Dump uncompressed DirectColor packets.
1045
              */
1046
0
              Ascii85Initialize(image);
1047
0
              for (y=0; y < (long) image->rows; y++)
1048
0
              {
1049
0
                p=AcquireImagePixels(image,0,y,image->columns,1,
1050
0
                  &image->exception);
1051
0
                if (p == (const PixelPacket *) NULL)
1052
0
                  break;
1053
0
                for (x=0; x < (long) image->columns; x++)
1054
0
                {
1055
0
                  if (image->matte && (p->opacity == TransparentOpacity))
1056
0
                    {
1057
0
                      Ascii85Encode(image,ScaleQuantumToChar(MaxRGB));
1058
0
                      Ascii85Encode(image,ScaleQuantumToChar(MaxRGB));
1059
0
                      Ascii85Encode(image,ScaleQuantumToChar(MaxRGB));
1060
0
                    }
1061
0
                  else
1062
0
                    if (image->colorspace != CMYKColorspace)
1063
0
                      {
1064
0
                        Ascii85Encode(image,ScaleQuantumToChar(p->red));
1065
0
                        Ascii85Encode(image,ScaleQuantumToChar(p->green));
1066
0
                        Ascii85Encode(image,ScaleQuantumToChar(p->blue));
1067
0
                      }
1068
0
                    else
1069
0
                      {
1070
0
                        Ascii85Encode(image,ScaleQuantumToChar(p->red));
1071
0
                        Ascii85Encode(image,ScaleQuantumToChar(p->green));
1072
0
                        Ascii85Encode(image,ScaleQuantumToChar(p->blue));
1073
0
                        Ascii85Encode(image,ScaleQuantumToChar(p->opacity));
1074
0
                      }
1075
0
                  p++;
1076
0
                }
1077
0
                if (image->previous == (Image *) NULL)
1078
0
                  if (QuantumTick(y,image->rows))
1079
0
                    {
1080
0
                      status=MagickMonitorFormatted(y,image->rows,
1081
0
                                                    &image->exception,
1082
0
                                                    SaveImageText,
1083
0
                                                    image->filename,
1084
0
                                                    image->columns,image->rows);
1085
0
                      if (status == False)
1086
0
                        break;
1087
0
                    }
1088
0
              }
1089
0
              Ascii85Flush(image);
1090
0
              break;
1091
0
            }
1092
0
          }
1093
0
        }
1094
0
      else
1095
0
        {
1096
          /*
1097
            Dump number of colors and colormap.
1098
          */
1099
0
          FormatString(buffer,"%lu %lu\n1\n%d\n",image->columns,image->rows,
1100
0
            (int) (image->colorspace == CMYKColorspace));
1101
0
          (void) WriteBlobString(image,buffer);
1102
0
          FormatString(buffer,"%d\n",(int) (compression == NoCompression));
1103
0
          (void) WriteBlobString(image,buffer);
1104
0
          FormatString(buffer,"%u\n",image->colors);
1105
0
          (void) WriteBlobString(image,buffer);
1106
0
          for (i=0; i < (long) image->colors; i++)
1107
0
          {
1108
0
            FormatString(buffer,"%02X%02X%02X\n",
1109
0
              ScaleQuantumToChar(image->colormap[i].red),
1110
0
              ScaleQuantumToChar(image->colormap[i].green),
1111
0
              ScaleQuantumToChar(image->colormap[i].blue));
1112
0
            (void) WriteBlobString(image,buffer);
1113
0
          }
1114
0
          switch (compression)
1115
0
          {
1116
0
            case RLECompression:
1117
0
            default:
1118
0
            {
1119
0
              register unsigned char
1120
0
                *q;
1121
1122
              /*
1123
                Allocate pixel array.
1124
              */
1125
0
              length=number_pixels;
1126
0
              pixels=MagickAllocateResourceLimitedMemory(unsigned char *,length);
1127
0
              if (pixels == (unsigned char *) NULL)
1128
0
                ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
1129
              /*
1130
                Dump Runlength encoded pixels.
1131
              */
1132
0
              q=pixels;
1133
0
              for (y=0; y < (long) image->rows; y++)
1134
0
              {
1135
0
                p=AcquireImagePixels(image,0,y,image->columns,1,
1136
0
                  &image->exception);
1137
0
                if (p == (const PixelPacket *) NULL)
1138
0
                  break;
1139
0
                indexes=AccessImmutableIndexes(image);
1140
0
                for (x=0; x < (long) image->columns; x++)
1141
0
                  *q++=indexes[x];
1142
0
                if (image->previous == (Image *) NULL)
1143
0
                  if (QuantumTick(y,image->rows))
1144
0
                    {
1145
0
                      status=MagickMonitorFormatted(y,image->rows,
1146
0
                                                    &image->exception,
1147
0
                                                    SaveImageText,
1148
0
                                                    image->filename,
1149
0
                                                    image->columns,image->rows);
1150
0
                      if (status == False)
1151
0
                        break;
1152
0
                    }
1153
0
              }
1154
0
              if (compression == LZWCompression)
1155
0
                status=LZWEncodeImage(image,length,pixels);
1156
0
              else
1157
0
                status=PackbitsEncodeImage(image,length,pixels);
1158
0
              MagickFreeResourceLimitedMemory(unsigned char *,pixels);
1159
0
              if (!status)
1160
0
                {
1161
0
                  CloseBlob(image);
1162
0
                  return(False);
1163
0
                }
1164
0
              break;
1165
0
            }
1166
0
            case NoCompression:
1167
0
            {
1168
              /*
1169
                Dump uncompressed PseudoColor packets.
1170
              */
1171
0
              Ascii85Initialize(image);
1172
0
              for (y=0; y < (long) image->rows; y++)
1173
0
              {
1174
0
                p=AcquireImagePixels(image,0,y,image->columns,1,
1175
0
                  &image->exception);
1176
0
                if (p == (const PixelPacket *) NULL)
1177
0
                  break;
1178
0
                indexes=AccessImmutableIndexes(image);
1179
0
                for (x=0; x < (long) image->columns; x++)
1180
0
                  Ascii85Encode(image,indexes[x]);
1181
0
                if (image->previous == (Image *) NULL)
1182
0
                  if (QuantumTick(y,image->rows))
1183
0
                    {
1184
0
                      status=MagickMonitorFormatted(y,image->rows,
1185
0
                                                    &image->exception,
1186
0
                                                    SaveImageText,
1187
0
                                                    image->filename,
1188
0
                                                    image->columns,image->rows);
1189
0
                      if (status == False)
1190
0
                        break;
1191
0
                    }
1192
0
              }
1193
0
              Ascii85Flush(image);
1194
0
              break;
1195
0
            }
1196
0
          }
1197
0
        }
1198
0
    (void) WriteBlobByte(image,'\n');
1199
0
    current=TellBlob(image);
1200
0
    if (current < 0)
1201
0
      ThrowWriterException(BlobError,UnableToObtainOffset,image);
1202
0
    length=current-stop;
1203
0
    stop=TellBlob(image);
1204
0
    if (stop < 0)
1205
0
      ThrowWriterException(BlobError,UnableToObtainOffset,image);
1206
0
    if (SeekBlob(image,start,SEEK_SET) != start)
1207
0
      ThrowWriterException(BlobError,UnableToSeekToOffset,image);
1208
0
    FormatString(buffer,"%%%%BeginData:%13ld %s Bytes\n",(long) length,
1209
0
      compression == NoCompression ? "ASCII" : "Binary");
1210
0
    (void) WriteBlobString(image,buffer);
1211
0
    if (SeekBlob(image,stop,SEEK_SET) != stop)
1212
0
      ThrowWriterException(BlobError,UnableToSeekToOffset,image);
1213
0
    (void) WriteBlobString(image,"%%EndData\n");
1214
0
    if (LocaleCompare(image_info->magick,"PS2") != 0)
1215
0
      (void) WriteBlobString(image,"end\n");
1216
0
    (void) WriteBlobString(image,"%%PageTrailer\n");
1217
0
    if (image->next == (Image *) NULL)
1218
0
      break;
1219
0
    image=SyncNextImageInList(image);
1220
0
    status=MagickMonitorFormatted(scene++,image_list_length,
1221
0
                                  &image->exception,SaveImagesText,
1222
0
                                  image->filename);
1223
0
    if (status == False)
1224
0
      break;
1225
0
  } while (image_info->adjoin);
1226
0
  if (image_info->adjoin)
1227
0
    while (image->previous != (Image *) NULL)
1228
0
      image=image->previous;
1229
0
  (void) WriteBlobString(image,"%%Trailer\n");
1230
0
  if (page > 1)
1231
0
    {
1232
0
      FormatString(buffer,"%%%%BoundingBox: %g %g %g %g\n",floor(bounds.x1+0.5),
1233
0
        floor(bounds.y1+0.5),ceil(bounds.x2-0.5),ceil(bounds.y2-0.5));
1234
0
      (void) WriteBlobString(image,buffer);
1235
0
    }
1236
0
  (void) WriteBlobString(image,"%%EOF\n");
1237
0
  status &= CloseBlob(image);
1238
0
  return(status);
1239
0
}