Coverage Report

Created: 2025-07-23 08:18

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