blob: cf1f9113cbe84aff625d52cdcd08a3b4bbeb28bf [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% PPPP N N M M %
7% P P NN N MM MM %
8% PPPP N N N M M M %
9% P N NN M M %
10% P N N M M %
11% %
12% %
13% Read/Write PBMPlus Portable Anymap Image Format %
14% %
15% Software Design %
16% John Cristy %
17% July 1992 %
18% %
19% %
cristyfe676ee2013-11-18 13:03:38 +000020% Copyright 1999-2014 ImageMagick Studio LLC, a non-profit organization %
cristy3ed852e2009-09-05 21:47:34 +000021% dedicated to making software imaging solutions freely available. %
22% %
23% You may not use this file except in compliance with the License. You may %
24% obtain a copy of the License at %
25% %
26% http://www.imagemagick.org/script/license.php %
27% %
28% Unless required by applicable law or agreed to in writing, software %
29% distributed under the License is distributed on an "AS IS" BASIS, %
30% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31% See the License for the specific language governing permissions and %
32% limitations under the License. %
33% %
34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35%
36%
37*/
38
39/*
40 Include declarations.
41*/
cristy4c08aed2011-07-01 19:47:50 +000042#include "MagickCore/studio.h"
43#include "MagickCore/attribute.h"
44#include "MagickCore/blob.h"
45#include "MagickCore/blob-private.h"
46#include "MagickCore/cache.h"
47#include "MagickCore/color.h"
48#include "MagickCore/color-private.h"
49#include "MagickCore/colorspace.h"
cristy510d06a2011-07-06 23:43:54 +000050#include "MagickCore/colorspace-private.h"
cristy4c08aed2011-07-01 19:47:50 +000051#include "MagickCore/exception.h"
52#include "MagickCore/exception-private.h"
53#include "MagickCore/image.h"
54#include "MagickCore/image-private.h"
55#include "MagickCore/list.h"
56#include "MagickCore/magick.h"
57#include "MagickCore/memory_.h"
58#include "MagickCore/module.h"
59#include "MagickCore/monitor.h"
60#include "MagickCore/monitor-private.h"
61#include "MagickCore/pixel-accessor.h"
62#include "MagickCore/property.h"
63#include "MagickCore/quantum-private.h"
64#include "MagickCore/static.h"
65#include "MagickCore/statistic.h"
66#include "MagickCore/string_.h"
67#include "MagickCore/string-private.h"
cristy3ed852e2009-09-05 21:47:34 +000068
69/*
70 Forward declarations.
71*/
72static MagickBooleanType
cristy1e178e72011-08-28 19:44:34 +000073 WritePNMImage(const ImageInfo *,Image *,ExceptionInfo *);
cristy3ed852e2009-09-05 21:47:34 +000074
75/*
76%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
77% %
78% %
79% %
80% I s P N M %
81% %
82% %
83% %
84%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
85%
86% IsPNM() returns MagickTrue if the image format type, identified by the
87% magick string, is PNM.
88%
89% The format of the IsPNM method is:
90%
91% MagickBooleanType IsPNM(const unsigned char *magick,const size_t extent)
92%
93% A description of each parameter follows:
94%
95% o magick: compare image format pattern against these bytes.
96%
97% o extent: Specifies the extent of the magick string.
98%
99*/
100static MagickBooleanType IsPNM(const unsigned char *magick,const size_t extent)
101{
102 if (extent < 2)
103 return(MagickFalse);
104 if ((*magick == (unsigned char) 'P') &&
105 ((magick[1] == '1') || (magick[1] == '2') || (magick[1] == '3') ||
106 (magick[1] == '4') || (magick[1] == '5') || (magick[1] == '6') ||
107 (magick[1] == '7') || (magick[1] == 'F') || (magick[1] == 'f')))
108 return(MagickTrue);
109 return(MagickFalse);
110}
111
112/*
113%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
114% %
115% %
116% %
117% R e a d P N M I m a g e %
118% %
119% %
120% %
121%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
122%
123% ReadPNMImage() reads a Portable Anymap image file and returns it.
124% It allocates the memory necessary for the new Image structure and returns
125% a pointer to the new image.
126%
127% The format of the ReadPNMImage method is:
128%
129% Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception)
130%
131% A description of each parameter follows:
132%
133% o image_info: the image info.
134%
135% o exception: return any errors or warnings in this structure.
136%
137*/
138
cristybb503372010-05-27 20:51:26 +0000139static inline ssize_t ConstrainPixel(Image *image,const ssize_t offset,
cristyc82a27b2011-10-21 01:07:16 +0000140 const size_t extent,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000141{
cristybb503372010-05-27 20:51:26 +0000142 if ((offset < 0) || (offset > (ssize_t) extent))
cristy3ed852e2009-09-05 21:47:34 +0000143 {
cristyc82a27b2011-10-21 01:07:16 +0000144 (void) ThrowMagickException(exception,GetMagickModule(),CorruptImageError,
145 "InvalidPixel","`%s'",image->filename);
cristy3ed852e2009-09-05 21:47:34 +0000146 return(0);
147 }
148 return(offset);
149}
150
cristy542ea782013-05-24 15:53:01 +0000151static void PNMComment(Image *image,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000152{
cristy3ed852e2009-09-05 21:47:34 +0000153 int
154 c;
155
cristy542ea782013-05-24 15:53:01 +0000156 char
157 *comment;
158
cristy3ed852e2009-09-05 21:47:34 +0000159 register char
160 *p;
161
162 size_t
cristy542ea782013-05-24 15:53:01 +0000163 extent;
164
165 /*
166 Read comment.
167 */
168 comment=AcquireString(GetImageProperty(image,"comment",exception));
169 extent=strlen(comment);
170 p=comment+strlen(comment);
171 for (c='#'; (c != EOF) && (c != (int) '\n'); p++)
172 {
173 if ((size_t) (p-comment+1) >= extent)
174 {
175 extent<<=1;
176 comment=(char *) ResizeQuantumMemory(comment,extent+MaxTextExtent,
177 sizeof(*comment));
178 if (comment == (char *) NULL)
179 break;
180 p=comment+strlen(comment);
181 }
182 c=ReadBlobByte(image);
183 if (c != EOF)
184 {
185 *p=(char) c;
186 *(p+1)='\0';
187 }
188 }
189 if (comment == (char *) NULL)
190 return;
191 (void) SetImageProperty(image,"comment",comment,exception);
192 comment=DestroyString(comment);
193}
194
195static size_t PNMInteger(Image *image,const unsigned int base,
196 ExceptionInfo *exception)
197{
198 int
199 c;
200
201 size_t
cristy3ed852e2009-09-05 21:47:34 +0000202 value;
203
204 /*
205 Skip any leading whitespace.
206 */
cristy3ed852e2009-09-05 21:47:34 +0000207 do
208 {
209 c=ReadBlobByte(image);
210 if (c == EOF)
211 return(0);
212 if (c == (int) '#')
cristy542ea782013-05-24 15:53:01 +0000213 PNMComment(image,exception);
cristy3ed852e2009-09-05 21:47:34 +0000214 } while (isdigit(c) == MagickFalse);
cristy3ed852e2009-09-05 21:47:34 +0000215 if (base == 2)
cristybb503372010-05-27 20:51:26 +0000216 return((size_t) (c-(int) '0'));
cristy3ed852e2009-09-05 21:47:34 +0000217 /*
218 Evaluate number.
219 */
220 value=0;
221 do
222 {
223 value*=10;
224 value+=c-(int) '0';
225 c=ReadBlobByte(image);
226 if (c == EOF)
227 return(value);
228 } while (isdigit(c) != MagickFalse);
229 return(value);
230}
231
232static Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception)
233{
234 char
235 format;
236
237 double
238 quantum_scale;
239
240 Image
241 *image;
242
cristy3ed852e2009-09-05 21:47:34 +0000243 MagickBooleanType
244 status;
245
cristy92beec62013-08-26 12:23:46 +0000246 QuantumAny
247 max_value;
248
cristy3ed852e2009-09-05 21:47:34 +0000249 QuantumInfo
250 *quantum_info;
251
252 QuantumType
253 quantum_type;
254
cristy3ed852e2009-09-05 21:47:34 +0000255 size_t
cristyaff6d802011-04-26 01:46:31 +0000256 depth,
cristy3ed852e2009-09-05 21:47:34 +0000257 extent,
258 packet_size;
259
260 ssize_t
cristyaff6d802011-04-26 01:46:31 +0000261 count,
262 row,
263 y;
cristy3ed852e2009-09-05 21:47:34 +0000264
cristy3ed852e2009-09-05 21:47:34 +0000265 /*
266 Open image file.
267 */
268 assert(image_info != (const ImageInfo *) NULL);
269 assert(image_info->signature == MagickSignature);
270 if (image_info->debug != MagickFalse)
271 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
272 image_info->filename);
273 assert(exception != (ExceptionInfo *) NULL);
274 assert(exception->signature == MagickSignature);
cristy9950d572011-10-01 18:22:35 +0000275 image=AcquireImage(image_info,exception);
cristy3ed852e2009-09-05 21:47:34 +0000276 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
277 if (status == MagickFalse)
278 {
279 image=DestroyImageList(image);
280 return((Image *) NULL);
281 }
282 /*
283 Read PNM image.
284 */
285 count=ReadBlob(image,1,(unsigned char *) &format);
286 do
287 {
288 /*
289 Initialize image structure.
290 */
291 if ((count != 1) || (format != 'P'))
292 ThrowReaderException(CorruptImageError,"ImproperImageHeader");
293 max_value=1;
294 quantum_type=RGBQuantum;
295 quantum_scale=1.0;
296 format=(char) ReadBlobByte(image);
297 if (format != '7')
298 {
299 /*
300 PBM, PGM, PPM, and PNM.
301 */
cristyd15e6592011-10-15 00:13:06 +0000302 image->columns=PNMInteger(image,10,exception);
303 image->rows=PNMInteger(image,10,exception);
cristy3ed852e2009-09-05 21:47:34 +0000304 if ((format == 'f') || (format == 'F'))
305 {
306 char
307 scale[MaxTextExtent];
308
309 (void) ReadBlobString(image,scale);
cristydbdd0e32011-11-04 23:29:40 +0000310 quantum_scale=StringToDouble(scale,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000311 }
312 else
313 {
314 if ((format == '1') || (format == '4'))
315 max_value=1; /* bitmap */
316 else
cristyd15e6592011-10-15 00:13:06 +0000317 max_value=PNMInteger(image,10,exception);
cristy3ed852e2009-09-05 21:47:34 +0000318 }
319 }
320 else
321 {
322 char
323 keyword[MaxTextExtent],
324 value[MaxTextExtent];
325
326 int
327 c;
328
329 register char
330 *p;
331
332 /*
333 PAM.
334 */
335 for (c=ReadBlobByte(image); c != EOF; c=ReadBlobByte(image))
336 {
337 while (isspace((int) ((unsigned char) c)) != 0)
338 c=ReadBlobByte(image);
cristya4068ab2013-05-19 11:51:07 +0000339 if (c == '#')
340 {
341 /*
342 Comment.
343 */
cristy542ea782013-05-24 15:53:01 +0000344 PNMComment(image,exception);
345 c=ReadBlobByte(image);
cristya4068ab2013-05-19 11:51:07 +0000346 while (isspace((int) ((unsigned char) c)) != 0)
347 c=ReadBlobByte(image);
348 }
cristy3ed852e2009-09-05 21:47:34 +0000349 p=keyword;
350 do
351 {
352 if ((size_t) (p-keyword) < (MaxTextExtent-1))
353 *p++=c;
354 c=ReadBlobByte(image);
355 } while (isalnum(c));
356 *p='\0';
357 if (LocaleCompare(keyword,"endhdr") == 0)
358 break;
359 while (isspace((int) ((unsigned char) c)) != 0)
cristy4e285b92013-05-24 17:42:57 +0000360 c=ReadBlobByte(image);
cristy3ed852e2009-09-05 21:47:34 +0000361 p=value;
362 while (isalnum(c) || (c == '_'))
363 {
364 if ((size_t) (p-value) < (MaxTextExtent-1))
365 *p++=c;
366 c=ReadBlobByte(image);
367 }
368 *p='\0';
369 /*
370 Assign a value to the specified keyword.
371 */
372 if (LocaleCompare(keyword,"depth") == 0)
cristye27293e2009-12-18 02:53:20 +0000373 packet_size=StringToUnsignedLong(value);
cristyda16f162011-02-19 23:52:17 +0000374 (void) packet_size;
cristy3ed852e2009-09-05 21:47:34 +0000375 if (LocaleCompare(keyword,"height") == 0)
cristye27293e2009-12-18 02:53:20 +0000376 image->rows=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +0000377 if (LocaleCompare(keyword,"maxval") == 0)
cristye27293e2009-12-18 02:53:20 +0000378 max_value=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +0000379 if (LocaleCompare(keyword,"TUPLTYPE") == 0)
380 {
381 if (LocaleCompare(value,"BLACKANDWHITE") == 0)
cristyb3a73b52011-07-26 01:34:43 +0000382 {
cristy542ea782013-05-24 15:53:01 +0000383 (void) SetImageColorspace(image,GRAYColorspace,exception);
cristyb3a73b52011-07-26 01:34:43 +0000384 quantum_type=GrayQuantum;
385 }
cristy7a201992012-05-12 23:30:43 +0000386 if (LocaleCompare(value,"BLACKANDWHITE_ALPHA") == 0)
387 {
cristy542ea782013-05-24 15:53:01 +0000388 (void) SetImageColorspace(image,GRAYColorspace,exception);
cristy8a46d822012-08-28 23:32:39 +0000389 image->alpha_trait=BlendPixelTrait;
cristy7a201992012-05-12 23:30:43 +0000390 quantum_type=GrayAlphaQuantum;
391 }
392 if (LocaleCompare(value,"GRAYSCALE") == 0)
393 {
394 quantum_type=GrayQuantum;
cristy542ea782013-05-24 15:53:01 +0000395 (void) SetImageColorspace(image,GRAYColorspace,exception);
cristy7a201992012-05-12 23:30:43 +0000396 }
cristy3ed852e2009-09-05 21:47:34 +0000397 if (LocaleCompare(value,"GRAYSCALE_ALPHA") == 0)
398 {
cristy542ea782013-05-24 15:53:01 +0000399 (void) SetImageColorspace(image,GRAYColorspace,exception);
cristy8a46d822012-08-28 23:32:39 +0000400 image->alpha_trait=BlendPixelTrait;
cristyb3a73b52011-07-26 01:34:43 +0000401 quantum_type=GrayAlphaQuantum;
cristy3ed852e2009-09-05 21:47:34 +0000402 }
403 if (LocaleCompare(value,"RGB_ALPHA") == 0)
404 {
cristy8a46d822012-08-28 23:32:39 +0000405 image->alpha_trait=BlendPixelTrait;
cristy7a201992012-05-12 23:30:43 +0000406 quantum_type=RGBAQuantum;
cristy3ed852e2009-09-05 21:47:34 +0000407 }
408 if (LocaleCompare(value,"CMYK") == 0)
409 {
cristy542ea782013-05-24 15:53:01 +0000410 (void) SetImageColorspace(image,CMYKColorspace,exception);
cristy7a201992012-05-12 23:30:43 +0000411 quantum_type=CMYKQuantum;
cristy3ed852e2009-09-05 21:47:34 +0000412 }
413 if (LocaleCompare(value,"CMYK_ALPHA") == 0)
414 {
cristy542ea782013-05-24 15:53:01 +0000415 (void) SetImageColorspace(image,CMYKColorspace,exception);
cristy8a46d822012-08-28 23:32:39 +0000416 image->alpha_trait=BlendPixelTrait;
cristy7a201992012-05-12 23:30:43 +0000417 quantum_type=CMYKAQuantum;
cristy3ed852e2009-09-05 21:47:34 +0000418 }
419 }
420 if (LocaleCompare(keyword,"width") == 0)
cristye27293e2009-12-18 02:53:20 +0000421 image->columns=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +0000422 }
423 }
424 if ((image->columns == 0) || (image->rows == 0))
425 ThrowReaderException(CorruptImageError,"NegativeOrZeroImageSize");
cristyeff7fcc2013-09-30 10:27:08 +0000426 if (max_value > 4294967295)
cristy3ed852e2009-09-05 21:47:34 +0000427 ThrowReaderException(CorruptImageError,"ImproperImageHeader");
cristy3f1ee592011-06-15 23:03:58 +0000428 for (depth=1; GetQuantumRange(depth) < max_value; depth++) ;
cristy3ed852e2009-09-05 21:47:34 +0000429 image->depth=depth;
430 if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
431 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
432 break;
433 /*
434 Convert PNM pixels to runextent-encoded MIFF packets.
435 */
436 status=MagickTrue;
437 row=0;
438 switch (format)
439 {
440 case '1':
441 {
442 /*
443 Convert PBM image to pixel packets.
444 */
cristy4e285b92013-05-24 17:42:57 +0000445 (void) SetImageColorspace(image,GRAYColorspace,exception);
cristybb503372010-05-27 20:51:26 +0000446 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +0000447 {
cristybb503372010-05-27 20:51:26 +0000448 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000449 x;
450
cristy4c08aed2011-07-01 19:47:50 +0000451 register Quantum
cristyc47d1f82009-11-26 01:44:43 +0000452 *restrict q;
cristy3ed852e2009-09-05 21:47:34 +0000453
454 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
cristyacd2ed22011-08-30 01:44:23 +0000455 if (q == (Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000456 break;
cristybb503372010-05-27 20:51:26 +0000457 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +0000458 {
cristy08528502012-01-01 00:52:17 +0000459 SetPixelGray(image,PNMInteger(image,2,exception) == 0 ?
cristyd15e6592011-10-15 00:13:06 +0000460 QuantumRange : 0,q);
cristyed231572011-07-14 02:18:59 +0000461 q+=GetPixelChannels(image);
cristy3ed852e2009-09-05 21:47:34 +0000462 }
463 if (SyncAuthenticPixels(image,exception) == MagickFalse)
464 break;
465 if (image->previous == (Image *) NULL)
466 {
cristycee97112010-05-28 00:44:52 +0000467 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
468 image->rows);
cristy3ed852e2009-09-05 21:47:34 +0000469 if (status == MagickFalse)
470 break;
471 }
472 }
473 image->type=BilevelType;
474 break;
475 }
476 case '2':
477 {
cristybb503372010-05-27 20:51:26 +0000478 size_t
cristy3ed852e2009-09-05 21:47:34 +0000479 intensity;
480
481 /*
482 Convert PGM image to pixel packets.
483 */
cristy542ea782013-05-24 15:53:01 +0000484 (void) SetImageColorspace(image,GRAYColorspace,exception);
cristybb503372010-05-27 20:51:26 +0000485 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +0000486 {
cristybb503372010-05-27 20:51:26 +0000487 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000488 x;
489
cristy4c08aed2011-07-01 19:47:50 +0000490 register Quantum
cristyc47d1f82009-11-26 01:44:43 +0000491 *restrict q;
cristy3ed852e2009-09-05 21:47:34 +0000492
493 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
cristyb3a73b52011-07-26 01:34:43 +0000494 if (q == (Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000495 break;
cristybb503372010-05-27 20:51:26 +0000496 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +0000497 {
cristy67d16d92013-09-29 18:31:17 +0000498 intensity=ScaleAnyToQuantum(PNMInteger(image,10,exception),max_value);
499 SetPixelGray(image,intensity,q);
cristyed231572011-07-14 02:18:59 +0000500 q+=GetPixelChannels(image);
cristy3ed852e2009-09-05 21:47:34 +0000501 }
502 if (SyncAuthenticPixels(image,exception) == MagickFalse)
503 break;
504 if (image->previous == (Image *) NULL)
505 {
cristycee97112010-05-28 00:44:52 +0000506 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
507 image->rows);
cristy3ed852e2009-09-05 21:47:34 +0000508 if (status == MagickFalse)
509 break;
510 }
511 }
512 image->type=GrayscaleType;
cristy3ed852e2009-09-05 21:47:34 +0000513 break;
514 }
515 case '3':
516 {
cristy3ed852e2009-09-05 21:47:34 +0000517 /*
518 Convert PNM image to pixel packets.
519 */
cristybb503372010-05-27 20:51:26 +0000520 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +0000521 {
cristybb503372010-05-27 20:51:26 +0000522 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000523 x;
524
cristy4c08aed2011-07-01 19:47:50 +0000525 register Quantum
cristyc47d1f82009-11-26 01:44:43 +0000526 *restrict q;
cristy3ed852e2009-09-05 21:47:34 +0000527
528 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
cristyacd2ed22011-08-30 01:44:23 +0000529 if (q == (Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000530 break;
cristybb503372010-05-27 20:51:26 +0000531 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +0000532 {
cristy67d16d92013-09-29 18:31:17 +0000533 double
534 pixel;
535
536 pixel=ScaleAnyToQuantum(PNMInteger(image,10,exception),max_value);
537 SetPixelRed(image,pixel,q);
538 pixel=ScaleAnyToQuantum(PNMInteger(image,10,exception),max_value);
539 SetPixelGreen(image,pixel,q);
540 pixel=ScaleAnyToQuantum(PNMInteger(image,10,exception),max_value);
541 SetPixelBlue(image,pixel,q);
cristyed231572011-07-14 02:18:59 +0000542 q+=GetPixelChannels(image);
cristy3ed852e2009-09-05 21:47:34 +0000543 }
544 if (SyncAuthenticPixels(image,exception) == MagickFalse)
545 break;
546 if (image->previous == (Image *) NULL)
547 {
cristycee97112010-05-28 00:44:52 +0000548 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
549 image->rows);
cristy3ed852e2009-09-05 21:47:34 +0000550 if (status == MagickFalse)
551 break;
552 }
553 }
cristy3ed852e2009-09-05 21:47:34 +0000554 break;
555 }
556 case '4':
557 {
558 /*
559 Convert PBM raw image to pixel packets.
560 */
cristy542ea782013-05-24 15:53:01 +0000561 (void) SetImageColorspace(image,GRAYColorspace,exception);
cristy3ed852e2009-09-05 21:47:34 +0000562 quantum_type=GrayQuantum;
563 if (image->storage_class == PseudoClass)
564 quantum_type=IndexQuantum;
565 quantum_info=AcquireQuantumInfo(image_info,image);
566 if (quantum_info == (QuantumInfo *) NULL)
567 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
568 SetQuantumMinIsWhite(quantum_info,MagickTrue);
569 extent=GetQuantumExtent(image,quantum_info,quantum_type);
cristybb503372010-05-27 20:51:26 +0000570 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +0000571 {
cristy3ed852e2009-09-05 21:47:34 +0000572 MagickBooleanType
573 sync;
574
cristy4c08aed2011-07-01 19:47:50 +0000575 register Quantum
cristyc47d1f82009-11-26 01:44:43 +0000576 *restrict q;
cristy3ed852e2009-09-05 21:47:34 +0000577
578 ssize_t
cristyaff6d802011-04-26 01:46:31 +0000579 count,
580 offset;
cristy3ed852e2009-09-05 21:47:34 +0000581
582 size_t
583 length;
584
585 unsigned char
586 *pixels;
587
588 if (status == MagickFalse)
589 continue;
590 pixels=GetQuantumPixels(quantum_info);
cristy3ed852e2009-09-05 21:47:34 +0000591 {
592 count=ReadBlob(image,extent,pixels);
593 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
594 (image->previous == (Image *) NULL))
595 {
596 MagickBooleanType
597 proceed;
598
cristycee97112010-05-28 00:44:52 +0000599 proceed=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
600 row,image->rows);
cristy3ed852e2009-09-05 21:47:34 +0000601 if (proceed == MagickFalse)
602 status=MagickFalse;
603 }
604 offset=row++;
605 }
606 if (count != (ssize_t) extent)
607 status=MagickFalse;
cristyaa740112010-03-30 17:58:44 +0000608 q=QueueAuthenticPixels(image,0,offset,image->columns,1,exception);
cristyacd2ed22011-08-30 01:44:23 +0000609 if (q == (Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000610 {
611 status=MagickFalse;
612 continue;
613 }
cristyaa740112010-03-30 17:58:44 +0000614 length=ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
615 quantum_type,pixels,exception);
cristy3ed852e2009-09-05 21:47:34 +0000616 if (length != extent)
617 status=MagickFalse;
cristyaa740112010-03-30 17:58:44 +0000618 sync=SyncAuthenticPixels(image,exception);
cristy3ed852e2009-09-05 21:47:34 +0000619 if (sync == MagickFalse)
620 status=MagickFalse;
621 }
cristy3ed852e2009-09-05 21:47:34 +0000622 quantum_info=DestroyQuantumInfo(quantum_info);
623 if (status == MagickFalse)
624 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
625 SetQuantumImageType(image,quantum_type);
626 break;
627 }
628 case '5':
629 {
cristy3ed852e2009-09-05 21:47:34 +0000630 /*
631 Convert PGM raw image to pixel packets.
632 */
cristy542ea782013-05-24 15:53:01 +0000633 (void) SetImageColorspace(image,GRAYColorspace,exception);
cristy3ed852e2009-09-05 21:47:34 +0000634 quantum_type=GrayQuantum;
cristy67d16d92013-09-29 18:31:17 +0000635 if (image->depth <= 8)
636 extent=image->columns;
637 else
638 if (image->depth <= 16)
639 extent=2*image->columns;
640 else
641 extent=4*image->columns;
cristy3ed852e2009-09-05 21:47:34 +0000642 quantum_info=AcquireQuantumInfo(image_info,image);
643 if (quantum_info == (QuantumInfo *) NULL)
644 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
cristybb503372010-05-27 20:51:26 +0000645 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +0000646 {
cristy3ed852e2009-09-05 21:47:34 +0000647 MagickBooleanType
648 sync;
649
650 register const unsigned char
cristy3f2302b2010-03-11 03:16:37 +0000651 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +0000652
cristybb503372010-05-27 20:51:26 +0000653 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000654 x;
655
cristy4c08aed2011-07-01 19:47:50 +0000656 register Quantum
cristyc47d1f82009-11-26 01:44:43 +0000657 *restrict q;
cristy3ed852e2009-09-05 21:47:34 +0000658
659 ssize_t
cristyaff6d802011-04-26 01:46:31 +0000660 count,
661 offset;
cristy3ed852e2009-09-05 21:47:34 +0000662
663 unsigned char
664 *pixels;
665
666 if (status == MagickFalse)
667 continue;
668 pixels=GetQuantumPixels(quantum_info);
cristy3ed852e2009-09-05 21:47:34 +0000669 {
670 count=ReadBlob(image,extent,pixels);
671 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
672 (image->previous == (Image *) NULL))
673 {
674 MagickBooleanType
675 proceed;
676
cristy34575212010-11-06 12:39:23 +0000677 proceed=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
678 row,image->rows);
cristy3ed852e2009-09-05 21:47:34 +0000679 if (proceed == MagickFalse)
680 status=MagickFalse;
681 }
682 offset=row++;
683 }
684 if (count != (ssize_t) extent)
685 status=MagickFalse;
cristyaa740112010-03-30 17:58:44 +0000686 q=QueueAuthenticPixels(image,0,offset,image->columns,1,exception);
cristyacd2ed22011-08-30 01:44:23 +0000687 if (q == (Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000688 {
689 status=MagickFalse;
690 continue;
691 }
692 p=pixels;
cristy67d16d92013-09-29 18:31:17 +0000693 switch (image->depth)
694 {
695 case 8:
696 case 16:
697 case 32:
698 {
699 (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
700 quantum_type,pixels,exception);
701 break;
702 }
703 default:
704 {
705 unsigned int
706 pixel;
cristy3ed852e2009-09-05 21:47:34 +0000707
cristy67d16d92013-09-29 18:31:17 +0000708 if (image->depth <= 8)
cristy3ed852e2009-09-05 21:47:34 +0000709 {
cristy67d16d92013-09-29 18:31:17 +0000710 unsigned char
711 pixel;
cristy3ed852e2009-09-05 21:47:34 +0000712
cristy67d16d92013-09-29 18:31:17 +0000713 for (x=0; x < (ssize_t) image->columns; x++)
714 {
715 p=PushCharPixel(p,&pixel);
716 SetPixelGray(image,ScaleAnyToQuantum(pixel,max_value),q);
717 q+=GetPixelChannels(image);
718 }
719 break;
cristy3ed852e2009-09-05 21:47:34 +0000720 }
cristy67d16d92013-09-29 18:31:17 +0000721 if (image->depth <= 16)
722 {
723 unsigned short
724 pixel;
725
726 for (x=0; x < (ssize_t) image->columns; x++)
727 {
728 p=PushShortPixel(MSBEndian,p,&pixel);
729 SetPixelGray(image,ScaleAnyToQuantum(pixel,max_value),q);
730 q+=GetPixelChannels(image);
731 }
732 break;
733 }
734 for (x=0; x < (ssize_t) image->columns; x++)
735 {
736 p=PushLongPixel(MSBEndian,p,&pixel);
737 SetPixelGray(image,ScaleAnyToQuantum(pixel,max_value),q);
738 q+=GetPixelChannels(image);
cristy3ed852e2009-09-05 21:47:34 +0000739 }
cristy67d16d92013-09-29 18:31:17 +0000740 break;
741 }
742 }
cristyaa740112010-03-30 17:58:44 +0000743 sync=SyncAuthenticPixels(image,exception);
cristy3ed852e2009-09-05 21:47:34 +0000744 if (sync == MagickFalse)
745 status=MagickFalse;
746 }
cristy3ed852e2009-09-05 21:47:34 +0000747 quantum_info=DestroyQuantumInfo(quantum_info);
748 if (status == MagickFalse)
749 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
750 SetQuantumImageType(image,quantum_type);
751 break;
752 }
753 case '6':
754 {
cristy3ed852e2009-09-05 21:47:34 +0000755 /*
756 Convert PNM raster image to pixel packets.
757 */
cristy3ed852e2009-09-05 21:47:34 +0000758 quantum_type=RGBQuantum;
759 extent=3*(image->depth <= 8 ? 1 : 2)*image->columns;
cristy3ed852e2009-09-05 21:47:34 +0000760 quantum_info=AcquireQuantumInfo(image_info,image);
761 if (quantum_info == (QuantumInfo *) NULL)
762 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
cristy70d7eae2012-11-17 19:40:21 +0000763 (void) SetQuantumEndian(image,quantum_info,MSBEndian);
cristybb503372010-05-27 20:51:26 +0000764 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +0000765 {
cristy3ed852e2009-09-05 21:47:34 +0000766 MagickBooleanType
767 sync;
768
769 register const unsigned char
cristy3f2302b2010-03-11 03:16:37 +0000770 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +0000771
cristybb503372010-05-27 20:51:26 +0000772 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000773 x;
774
cristy4c08aed2011-07-01 19:47:50 +0000775 register Quantum
cristyc47d1f82009-11-26 01:44:43 +0000776 *restrict q;
cristy3ed852e2009-09-05 21:47:34 +0000777
778 ssize_t
cristyaff6d802011-04-26 01:46:31 +0000779 count,
780 offset;
cristy3ed852e2009-09-05 21:47:34 +0000781
cristy3ed852e2009-09-05 21:47:34 +0000782 unsigned char
783 *pixels;
784
785 if (status == MagickFalse)
786 continue;
787 pixels=GetQuantumPixels(quantum_info);
cristy3ed852e2009-09-05 21:47:34 +0000788 {
789 count=ReadBlob(image,extent,pixels);
790 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
791 (image->previous == (Image *) NULL))
792 {
793 MagickBooleanType
794 proceed;
795
cristy34575212010-11-06 12:39:23 +0000796 proceed=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
797 row,image->rows);
cristy3ed852e2009-09-05 21:47:34 +0000798 if (proceed == MagickFalse)
799 status=MagickFalse;
800 }
801 offset=row++;
802 }
803 if (count != (ssize_t) extent)
804 status=MagickFalse;
cristyaa740112010-03-30 17:58:44 +0000805 q=QueueAuthenticPixels(image,0,offset,image->columns,1,exception);
cristyacd2ed22011-08-30 01:44:23 +0000806 if (q == (Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000807 {
808 status=MagickFalse;
809 continue;
810 }
811 p=pixels;
cristy67d16d92013-09-29 18:31:17 +0000812 switch (image->depth)
813 {
814 case 8:
cristy3ed852e2009-09-05 21:47:34 +0000815 {
cristy67d16d92013-09-29 18:31:17 +0000816 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +0000817 {
cristy67d16d92013-09-29 18:31:17 +0000818 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
819 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
820 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
821 SetPixelAlpha(image,OpaqueAlpha,q);
822 q+=GetPixelChannels(image);
cristy3ed852e2009-09-05 21:47:34 +0000823 }
cristy67d16d92013-09-29 18:31:17 +0000824 break;
825 }
826 case 16:
827 {
828 unsigned short
829 pixel;
830
831 for (x=0; x < (ssize_t) image->columns; x++)
832 {
833 p=PushShortPixel(MSBEndian,p,&pixel);
834 SetPixelRed(image,ScaleShortToQuantum(pixel),q);
835 p=PushShortPixel(MSBEndian,p,&pixel);
836 SetPixelGreen(image,ScaleShortToQuantum(pixel),q);
837 p=PushShortPixel(MSBEndian,p,&pixel);
838 SetPixelBlue(image,ScaleShortToQuantum(pixel),q);
839 SetPixelAlpha(image,OpaqueAlpha,q);
840 q+=GetPixelChannels(image);
841 }
842 break;
843 }
844 case 32:
845 {
846 unsigned int
847 pixel;
848
849 for (x=0; x < (ssize_t) image->columns; x++)
850 {
851 p=PushLongPixel(MSBEndian,p,&pixel);
852 SetPixelRed(image,ScaleLongToQuantum(pixel),q);
853 p=PushLongPixel(MSBEndian,p,&pixel);
854 SetPixelGreen(image,ScaleLongToQuantum(pixel),q);
855 p=PushLongPixel(MSBEndian,p,&pixel);
856 SetPixelBlue(image,ScaleLongToQuantum(pixel),q);
857 SetPixelAlpha(image,OpaqueAlpha,q);
858 q+=GetPixelChannels(image);
859 }
860 break;
861 }
862 default:
863 {
864 unsigned int
865 pixel;
866
cristye90d7402010-03-14 18:21:29 +0000867 if (image->depth <= 8)
868 {
869 unsigned char
870 pixel;
871
cristybb503372010-05-27 20:51:26 +0000872 for (x=0; x < (ssize_t) image->columns; x++)
cristye90d7402010-03-14 18:21:29 +0000873 {
874 p=PushCharPixel(p,&pixel);
cristy92beec62013-08-26 12:23:46 +0000875 SetPixelRed(image,ScaleAnyToQuantum(pixel,max_value),q);
cristye90d7402010-03-14 18:21:29 +0000876 p=PushCharPixel(p,&pixel);
cristy92beec62013-08-26 12:23:46 +0000877 SetPixelGreen(image,ScaleAnyToQuantum(pixel,max_value),q);
cristye90d7402010-03-14 18:21:29 +0000878 p=PushCharPixel(p,&pixel);
cristy92beec62013-08-26 12:23:46 +0000879 SetPixelBlue(image,ScaleAnyToQuantum(pixel,max_value),q);
cristy4c08aed2011-07-01 19:47:50 +0000880 SetPixelAlpha(image,OpaqueAlpha,q);
cristyed231572011-07-14 02:18:59 +0000881 q+=GetPixelChannels(image);
cristye90d7402010-03-14 18:21:29 +0000882 }
cristy67d16d92013-09-29 18:31:17 +0000883 break;
cristye90d7402010-03-14 18:21:29 +0000884 }
cristy67d16d92013-09-29 18:31:17 +0000885 if (image->depth <= 16)
cristye90d7402010-03-14 18:21:29 +0000886 {
887 unsigned short
888 pixel;
889
cristybb503372010-05-27 20:51:26 +0000890 for (x=0; x < (ssize_t) image->columns; x++)
cristye90d7402010-03-14 18:21:29 +0000891 {
892 p=PushShortPixel(MSBEndian,p,&pixel);
cristy92beec62013-08-26 12:23:46 +0000893 SetPixelRed(image,ScaleAnyToQuantum(pixel,max_value),q);
cristye90d7402010-03-14 18:21:29 +0000894 p=PushShortPixel(MSBEndian,p,&pixel);
cristy92beec62013-08-26 12:23:46 +0000895 SetPixelGreen(image,ScaleAnyToQuantum(pixel,max_value),q);
cristye90d7402010-03-14 18:21:29 +0000896 p=PushShortPixel(MSBEndian,p,&pixel);
cristy92beec62013-08-26 12:23:46 +0000897 SetPixelBlue(image,ScaleAnyToQuantum(pixel,max_value),q);
cristy4c08aed2011-07-01 19:47:50 +0000898 SetPixelAlpha(image,OpaqueAlpha,q);
cristyed231572011-07-14 02:18:59 +0000899 q+=GetPixelChannels(image);
cristye90d7402010-03-14 18:21:29 +0000900 }
cristy67d16d92013-09-29 18:31:17 +0000901 break;
cristye90d7402010-03-14 18:21:29 +0000902 }
cristy67d16d92013-09-29 18:31:17 +0000903 for (x=0; x < (ssize_t) image->columns; x++)
904 {
905 p=PushLongPixel(MSBEndian,p,&pixel);
906 SetPixelRed(image,ScaleAnyToQuantum(pixel,max_value),q);
907 p=PushLongPixel(MSBEndian,p,&pixel);
908 SetPixelGreen(image,ScaleAnyToQuantum(pixel,max_value),q);
909 p=PushLongPixel(MSBEndian,p,&pixel);
910 SetPixelBlue(image,ScaleAnyToQuantum(pixel,max_value),q);
911 SetPixelAlpha(image,OpaqueAlpha,q);
912 q+=GetPixelChannels(image);
913 }
914 break;
915 }
916 }
cristyaa740112010-03-30 17:58:44 +0000917 sync=SyncAuthenticPixels(image,exception);
cristy3ed852e2009-09-05 21:47:34 +0000918 if (sync == MagickFalse)
919 status=MagickFalse;
920 }
cristy3ed852e2009-09-05 21:47:34 +0000921 quantum_info=DestroyQuantumInfo(quantum_info);
922 if (status == MagickFalse)
923 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
cristy3ed852e2009-09-05 21:47:34 +0000924 break;
925 }
926 case '7':
927 {
cristybb503372010-05-27 20:51:26 +0000928 size_t
cristy3ed852e2009-09-05 21:47:34 +0000929 channels;
930
931 /*
932 Convert PAM raster image to pixel packets.
933 */
cristy3ed852e2009-09-05 21:47:34 +0000934 switch (quantum_type)
935 {
936 case GrayQuantum:
937 case GrayAlphaQuantum:
938 {
939 channels=1;
940 break;
941 }
942 case CMYKQuantum:
943 case CMYKAQuantum:
944 {
945 channels=4;
946 break;
947 }
948 default:
949 {
950 channels=3;
951 break;
952 }
953 }
cristy8a46d822012-08-28 23:32:39 +0000954 if (image->alpha_trait == BlendPixelTrait)
cristy3ed852e2009-09-05 21:47:34 +0000955 channels++;
cristy67d16d92013-09-29 18:31:17 +0000956 if (image->depth <= 8)
957 extent=channels*image->columns;
958 else
959 if (image->depth <= 16)
960 extent=2*channels*image->columns;
961 else
962 extent=4*channels*image->columns;
cristy3ed852e2009-09-05 21:47:34 +0000963 quantum_info=AcquireQuantumInfo(image_info,image);
964 if (quantum_info == (QuantumInfo *) NULL)
965 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
cristybb503372010-05-27 20:51:26 +0000966 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +0000967 {
cristy3ed852e2009-09-05 21:47:34 +0000968 MagickBooleanType
969 sync;
970
971 register const unsigned char
cristy3f2302b2010-03-11 03:16:37 +0000972 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +0000973
cristybb503372010-05-27 20:51:26 +0000974 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000975 x;
976
cristy4c08aed2011-07-01 19:47:50 +0000977 register Quantum
cristyc47d1f82009-11-26 01:44:43 +0000978 *restrict q;
cristy3ed852e2009-09-05 21:47:34 +0000979
980 ssize_t
cristyaff6d802011-04-26 01:46:31 +0000981 count,
982 offset;
cristy3ed852e2009-09-05 21:47:34 +0000983
984 unsigned char
985 *pixels;
986
987 if (status == MagickFalse)
988 continue;
989 pixels=GetQuantumPixels(quantum_info);
cristy3ed852e2009-09-05 21:47:34 +0000990 {
991 count=ReadBlob(image,extent,pixels);
992 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
993 (image->previous == (Image *) NULL))
994 {
995 MagickBooleanType
996 proceed;
997
cristy34575212010-11-06 12:39:23 +0000998 proceed=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
999 row,image->rows);
cristy3ed852e2009-09-05 21:47:34 +00001000 if (proceed == MagickFalse)
1001 status=MagickFalse;
1002 }
1003 offset=row++;
1004 }
1005 if (count != (ssize_t) extent)
1006 status=MagickFalse;
cristyaa740112010-03-30 17:58:44 +00001007 q=QueueAuthenticPixels(image,0,offset,image->columns,1,exception);
cristyacd2ed22011-08-30 01:44:23 +00001008 if (q == (Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001009 {
1010 status=MagickFalse;
1011 continue;
1012 }
cristy3ed852e2009-09-05 21:47:34 +00001013 p=pixels;
cristy67d16d92013-09-29 18:31:17 +00001014 switch (image->depth)
1015 {
1016 case 8:
1017 case 16:
1018 case 32:
cristy3ed852e2009-09-05 21:47:34 +00001019 {
cristy67d16d92013-09-29 18:31:17 +00001020 (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1021 quantum_type,pixels,exception);
1022 break;
1023 }
1024 default:
1025 {
1026 switch (quantum_type)
cristy3ed852e2009-09-05 21:47:34 +00001027 {
cristy67d16d92013-09-29 18:31:17 +00001028 case GrayQuantum:
1029 case GrayAlphaQuantum:
1030 {
1031 unsigned int
1032 pixel;
cristy3ed852e2009-09-05 21:47:34 +00001033
cristy67d16d92013-09-29 18:31:17 +00001034 if (image->depth <= 8)
cristy3ed852e2009-09-05 21:47:34 +00001035 {
cristy67d16d92013-09-29 18:31:17 +00001036 unsigned char
1037 pixel;
cristy3ed852e2009-09-05 21:47:34 +00001038
cristy67d16d92013-09-29 18:31:17 +00001039 for (x=0; x < (ssize_t) image->columns; x++)
1040 {
1041 p=PushCharPixel(p,&pixel);
1042 SetPixelGray(image,ScaleAnyToQuantum(pixel,max_value),q);
1043 SetPixelAlpha(image,OpaqueAlpha,q);
1044 if (image->alpha_trait == BlendPixelTrait)
1045 {
1046 p=PushCharPixel(p,&pixel);
1047 SetPixelAlpha(image,ScaleAnyToQuantum(pixel,
1048 max_value),q);
1049 }
1050 q+=GetPixelChannels(image);
1051 }
1052 break;
cristy3ed852e2009-09-05 21:47:34 +00001053 }
cristy67d16d92013-09-29 18:31:17 +00001054 if (image->depth <= 16)
1055 {
1056 unsigned short
1057 pixel;
cristy3ed852e2009-09-05 21:47:34 +00001058
cristy67d16d92013-09-29 18:31:17 +00001059 for (x=0; x < (ssize_t) image->columns; x++)
1060 {
1061 p=PushShortPixel(MSBEndian,p,&pixel);
1062 SetPixelGray(image,ScaleAnyToQuantum(pixel,max_value),q);
1063 SetPixelAlpha(image,OpaqueAlpha,q);
1064 if (image->alpha_trait == BlendPixelTrait)
1065 {
1066 p=PushShortPixel(MSBEndian,p,&pixel);
1067 SetPixelAlpha(image,ScaleAnyToQuantum(pixel,
1068 max_value),q);
1069 }
1070 q+=GetPixelChannels(image);
1071 }
1072 break;
cristy3ed852e2009-09-05 21:47:34 +00001073 }
cristy67d16d92013-09-29 18:31:17 +00001074 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00001075 {
cristy67d16d92013-09-29 18:31:17 +00001076 p=PushLongPixel(MSBEndian,p,&pixel);
1077 SetPixelGray(image,ScaleAnyToQuantum(pixel,max_value),q);
1078 SetPixelAlpha(image,OpaqueAlpha,q);
1079 if (image->alpha_trait == BlendPixelTrait)
1080 {
1081 p=PushLongPixel(MSBEndian,p,&pixel);
1082 SetPixelAlpha(image,ScaleAnyToQuantum(pixel,max_value),q);
1083 }
1084 q+=GetPixelChannels(image);
cristy3ed852e2009-09-05 21:47:34 +00001085 }
cristy67d16d92013-09-29 18:31:17 +00001086 break;
1087 }
1088 case CMYKQuantum:
1089 case CMYKAQuantum:
1090 {
1091 unsigned int
1092 pixel;
1093
1094 if (image->depth <= 8)
1095 {
1096 unsigned char
1097 pixel;
1098
1099 for (x=0; x < (ssize_t) image->columns; x++)
1100 {
1101 p=PushCharPixel(p,&pixel);
1102 SetPixelRed(image,ScaleAnyToQuantum(pixel,max_value),q);
1103 p=PushCharPixel(p,&pixel);
1104 SetPixelGreen(image,ScaleAnyToQuantum(pixel,max_value),q);
1105 p=PushCharPixel(p,&pixel);
1106 SetPixelBlue(image,ScaleAnyToQuantum(pixel,max_value),q);
1107 p=PushCharPixel(p,&pixel);
1108 SetPixelBlack(image,ScaleAnyToQuantum(pixel,max_value),q);
1109 SetPixelAlpha(image,OpaqueAlpha,q);
1110 if (image->alpha_trait == BlendPixelTrait)
1111 {
1112 p=PushCharPixel(p,&pixel);
1113 SetPixelAlpha(image,ScaleAnyToQuantum(pixel,
1114 max_value),q);
1115 }
1116 q+=GetPixelChannels(image);
1117 }
1118 break;
1119 }
1120 if (image->depth <= 16)
1121 {
1122 unsigned short
1123 pixel;
1124
1125 for (x=0; x < (ssize_t) image->columns; x++)
1126 {
1127 p=PushShortPixel(MSBEndian,p,&pixel);
1128 SetPixelRed(image,ScaleAnyToQuantum(pixel,max_value),q);
1129 p=PushShortPixel(MSBEndian,p,&pixel);
1130 SetPixelGreen(image,ScaleAnyToQuantum(pixel,max_value),q);
1131 p=PushShortPixel(MSBEndian,p,&pixel);
1132 SetPixelBlue(image,ScaleAnyToQuantum(pixel,max_value),q);
1133 p=PushShortPixel(MSBEndian,p,&pixel);
1134 SetPixelBlack(image,ScaleAnyToQuantum(pixel,max_value),q);
1135 SetPixelAlpha(image,OpaqueAlpha,q);
1136 if (image->alpha_trait == BlendPixelTrait)
1137 {
1138 p=PushShortPixel(MSBEndian,p,&pixel);
1139 SetPixelAlpha(image,ScaleAnyToQuantum(pixel,
1140 max_value),q);
1141 }
1142 q+=GetPixelChannels(image);
1143 }
1144 }
1145 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00001146 {
cristy67d16d92013-09-29 18:31:17 +00001147 p=PushLongPixel(MSBEndian,p,&pixel);
1148 SetPixelRed(image,ScaleAnyToQuantum(pixel,max_value),q);
1149 p=PushLongPixel(MSBEndian,p,&pixel);
1150 SetPixelGreen(image,ScaleAnyToQuantum(pixel,max_value),q);
1151 p=PushLongPixel(MSBEndian,p,&pixel);
1152 SetPixelBlue(image,ScaleAnyToQuantum(pixel,max_value),q);
1153 p=PushLongPixel(MSBEndian,p,&pixel);
1154 SetPixelBlack(image,ScaleAnyToQuantum(pixel,max_value),q);
1155 SetPixelAlpha(image,OpaqueAlpha,q);
1156 if (image->alpha_trait == BlendPixelTrait)
1157 {
1158 p=PushLongPixel(MSBEndian,p,&pixel);
1159 SetPixelAlpha(image,ScaleAnyToQuantum(pixel,max_value),q);
1160 }
1161 q+=GetPixelChannels(image);
cristy3ed852e2009-09-05 21:47:34 +00001162 }
cristy67d16d92013-09-29 18:31:17 +00001163 break;
1164 }
1165 default:
1166 {
1167 unsigned int
1168 pixel;
1169
1170 if (image->depth <= 8)
1171 {
1172 unsigned char
1173 pixel;
1174
1175 for (x=0; x < (ssize_t) image->columns; x++)
1176 {
1177 p=PushCharPixel(p,&pixel);
1178 SetPixelRed(image,ScaleAnyToQuantum(pixel,max_value),q);
1179 p=PushCharPixel(p,&pixel);
1180 SetPixelGreen(image,ScaleAnyToQuantum(pixel,max_value),q);
1181 p=PushCharPixel(p,&pixel);
1182 SetPixelBlue(image,ScaleAnyToQuantum(pixel,max_value),q);
1183 SetPixelAlpha(image,OpaqueAlpha,q);
1184 if (image->alpha_trait == BlendPixelTrait)
1185 {
1186 p=PushCharPixel(p,&pixel);
1187 SetPixelAlpha(image,ScaleAnyToQuantum(pixel,max_value),q);
1188 }
1189 q+=GetPixelChannels(image);
1190 }
1191 break;
1192 }
1193 if (image->depth <= 16)
1194 {
1195 unsigned short
1196 pixel;
1197
1198 for (x=0; x < (ssize_t) image->columns; x++)
1199 {
1200 p=PushShortPixel(MSBEndian,p,&pixel);
1201 SetPixelRed(image,ScaleAnyToQuantum(pixel,max_value),q);
1202 p=PushShortPixel(MSBEndian,p,&pixel);
1203 SetPixelGreen(image,ScaleAnyToQuantum(pixel,max_value),q);
1204 p=PushShortPixel(MSBEndian,p,&pixel);
1205 SetPixelBlue(image,ScaleAnyToQuantum(pixel,max_value),q);
1206 SetPixelAlpha(image,OpaqueAlpha,q);
1207 if (image->alpha_trait == BlendPixelTrait)
1208 {
1209 p=PushShortPixel(MSBEndian,p,&pixel);
1210 SetPixelAlpha(image,ScaleAnyToQuantum(pixel,
1211 max_value),q);
1212 }
1213 q+=GetPixelChannels(image);
1214 }
1215 break;
1216 }
1217 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00001218 {
cristy67d16d92013-09-29 18:31:17 +00001219 p=PushLongPixel(MSBEndian,p,&pixel);
1220 SetPixelRed(image,ScaleAnyToQuantum(pixel,max_value),q);
1221 p=PushLongPixel(MSBEndian,p,&pixel);
1222 SetPixelGreen(image,ScaleAnyToQuantum(pixel,max_value),q);
1223 p=PushLongPixel(MSBEndian,p,&pixel);
1224 SetPixelBlue(image,ScaleAnyToQuantum(pixel,max_value),q);
1225 SetPixelAlpha(image,OpaqueAlpha,q);
1226 if (image->alpha_trait == BlendPixelTrait)
1227 {
1228 p=PushLongPixel(MSBEndian,p,&pixel);
1229 SetPixelAlpha(image,ScaleAnyToQuantum(pixel,max_value),q);
1230 }
1231 q+=GetPixelChannels(image);
cristy3ed852e2009-09-05 21:47:34 +00001232 }
cristy67d16d92013-09-29 18:31:17 +00001233 break;
1234 }
cristy3ed852e2009-09-05 21:47:34 +00001235 }
1236 }
cristy67d16d92013-09-29 18:31:17 +00001237 }
cristyaa740112010-03-30 17:58:44 +00001238 sync=SyncAuthenticPixels(image,exception);
cristy3ed852e2009-09-05 21:47:34 +00001239 if (sync == MagickFalse)
1240 status=MagickFalse;
1241 }
cristy3ed852e2009-09-05 21:47:34 +00001242 quantum_info=DestroyQuantumInfo(quantum_info);
1243 if (status == MagickFalse)
1244 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
1245 SetQuantumImageType(image,quantum_type);
1246 break;
1247 }
1248 case 'F':
1249 case 'f':
1250 {
1251 /*
1252 Convert PFM raster image to pixel packets.
1253 */
cristyaf6eb932012-01-01 01:22:59 +00001254 if (format == 'f')
cristy4e285b92013-05-24 17:42:57 +00001255 (void) SetImageColorspace(image,GRAYColorspace,exception);
cristy3ed852e2009-09-05 21:47:34 +00001256 quantum_type=format == 'f' ? GrayQuantum : RGBQuantum;
1257 image->endian=quantum_scale < 0.0 ? LSBEndian : MSBEndian;
1258 image->depth=32;
1259 quantum_info=AcquireQuantumInfo(image_info,image);
1260 if (quantum_info == (QuantumInfo *) NULL)
1261 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
1262 status=SetQuantumDepth(image,quantum_info,32);
1263 if (status == MagickFalse)
1264 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
1265 status=SetQuantumFormat(image,quantum_info,FloatingPointQuantumFormat);
1266 if (status == MagickFalse)
1267 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
cristy243166e2012-11-03 19:16:10 +00001268 SetQuantumScale(quantum_info,(double) QuantumRange*fabs(quantum_scale));
cristy3ed852e2009-09-05 21:47:34 +00001269 extent=GetQuantumExtent(image,quantum_info,quantum_type);
cristybb503372010-05-27 20:51:26 +00001270 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +00001271 {
cristy3ed852e2009-09-05 21:47:34 +00001272 MagickBooleanType
1273 sync;
1274
cristy4c08aed2011-07-01 19:47:50 +00001275 register Quantum
cristyc47d1f82009-11-26 01:44:43 +00001276 *restrict q;
cristy3ed852e2009-09-05 21:47:34 +00001277
1278 ssize_t
cristyaff6d802011-04-26 01:46:31 +00001279 count,
1280 offset;
cristy3ed852e2009-09-05 21:47:34 +00001281
1282 size_t
1283 length;
1284
1285 unsigned char
1286 *pixels;
1287
1288 if (status == MagickFalse)
1289 continue;
1290 pixels=GetQuantumPixels(quantum_info);
cristy3ed852e2009-09-05 21:47:34 +00001291 {
1292 count=ReadBlob(image,extent,pixels);
1293 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
1294 (image->previous == (Image *) NULL))
1295 {
1296 MagickBooleanType
1297 proceed;
1298
cristy34575212010-11-06 12:39:23 +00001299 proceed=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
1300 row,image->rows);
cristy3ed852e2009-09-05 21:47:34 +00001301 if (proceed == MagickFalse)
1302 status=MagickFalse;
1303 }
1304 offset=row++;
1305 }
1306 if ((size_t) count != extent)
1307 status=MagickFalse;
cristybb503372010-05-27 20:51:26 +00001308 q=QueueAuthenticPixels(image,0,(ssize_t) (image->rows-offset-1),
cristyaa740112010-03-30 17:58:44 +00001309 image->columns,1,exception);
cristyacd2ed22011-08-30 01:44:23 +00001310 if (q == (Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001311 {
1312 status=MagickFalse;
1313 continue;
1314 }
cristyaa740112010-03-30 17:58:44 +00001315 length=ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1316 quantum_type,pixels,exception);
cristy3ed852e2009-09-05 21:47:34 +00001317 if (length != extent)
1318 status=MagickFalse;
cristyaa740112010-03-30 17:58:44 +00001319 sync=SyncAuthenticPixels(image,exception);
cristy3ed852e2009-09-05 21:47:34 +00001320 if (sync == MagickFalse)
1321 status=MagickFalse;
1322 }
cristy3ed852e2009-09-05 21:47:34 +00001323 quantum_info=DestroyQuantumInfo(quantum_info);
1324 if (status == MagickFalse)
1325 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
1326 SetQuantumImageType(image,quantum_type);
1327 break;
1328 }
1329 default:
1330 ThrowReaderException(CorruptImageError,"ImproperImageHeader");
1331 }
1332 if (EOFBlob(image) != MagickFalse)
cristy5d792232012-01-31 17:02:45 +00001333 {
1334 (void) ThrowMagickException(exception,GetMagickModule(),
1335 CorruptImageError,"UnexpectedEndOfFile","`%s'",image->filename);
1336 break;
1337 }
cristy3ed852e2009-09-05 21:47:34 +00001338 /*
1339 Proceed to next image.
1340 */
1341 if (image_info->number_scenes != 0)
1342 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
1343 break;
1344 if ((format == '1') || (format == '2') || (format == '3'))
1345 do
1346 {
1347 /*
1348 Skip to end of line.
1349 */
1350 count=ReadBlob(image,1,(unsigned char *) &format);
1351 if (count == 0)
1352 break;
1353 if ((count != 0) && (format == 'P'))
1354 break;
1355 } while (format != '\n');
1356 count=ReadBlob(image,1,(unsigned char *) &format);
1357 if ((count == 1) && (format == 'P'))
1358 {
1359 /*
1360 Allocate next image structure.
1361 */
cristy9950d572011-10-01 18:22:35 +00001362 AcquireNextImage(image_info,image,exception);
cristy3ed852e2009-09-05 21:47:34 +00001363 if (GetNextImageInList(image) == (Image *) NULL)
1364 {
1365 image=DestroyImageList(image);
1366 return((Image *) NULL);
1367 }
1368 image=SyncNextImageInList(image);
1369 status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
1370 GetBlobSize(image));
1371 if (status == MagickFalse)
1372 break;
1373 }
1374 } while ((count == 1) && (format == 'P'));
1375 (void) CloseBlob(image);
1376 return(GetFirstImageInList(image));
1377}
1378
1379/*
1380%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1381% %
1382% %
1383% %
1384% R e g i s t e r P N M I m a g e %
1385% %
1386% %
1387% %
1388%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1389%
1390% RegisterPNMImage() adds properties for the PNM image format to
1391% the list of supported formats. The properties include the image format
1392% tag, a method to read and/or write the format, whether the format
1393% supports the saving of more than one frame to the same file or blob,
1394% whether the format supports native in-memory I/O, and a brief
1395% description of the format.
1396%
1397% The format of the RegisterPNMImage method is:
1398%
cristybb503372010-05-27 20:51:26 +00001399% size_t RegisterPNMImage(void)
cristy3ed852e2009-09-05 21:47:34 +00001400%
1401*/
cristybb503372010-05-27 20:51:26 +00001402ModuleExport size_t RegisterPNMImage(void)
cristy3ed852e2009-09-05 21:47:34 +00001403{
1404 MagickInfo
1405 *entry;
1406
1407 entry=SetMagickInfo("PAM");
1408 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1409 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1410 entry->description=ConstantString("Common 2-dimensional bitmap format");
cristyf0d061c2013-08-09 12:17:54 +00001411 entry->mime_type=ConstantString("image/x-portable-pixmap");
cristy3ed852e2009-09-05 21:47:34 +00001412 entry->module=ConstantString("PNM");
1413 (void) RegisterMagickInfo(entry);
1414 entry=SetMagickInfo("PBM");
1415 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1416 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1417 entry->description=ConstantString("Portable bitmap format (black and white)");
cristyf0d061c2013-08-09 12:17:54 +00001418 entry->mime_type=ConstantString("image/x-portable-bitmap");
cristy3ed852e2009-09-05 21:47:34 +00001419 entry->module=ConstantString("PNM");
1420 (void) RegisterMagickInfo(entry);
1421 entry=SetMagickInfo("PFM");
1422 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1423 entry->encoder=(EncodeImageHandler *) WritePNMImage;
cristye96405a2010-05-19 02:24:31 +00001424 entry->endian_support=MagickTrue;
cristy3ed852e2009-09-05 21:47:34 +00001425 entry->description=ConstantString("Portable float format");
1426 entry->module=ConstantString("PFM");
1427 (void) RegisterMagickInfo(entry);
1428 entry=SetMagickInfo("PGM");
1429 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1430 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1431 entry->description=ConstantString("Portable graymap format (gray scale)");
cristyf0d061c2013-08-09 12:17:54 +00001432 entry->mime_type=ConstantString("image/x-portable-greymap");
cristy3ed852e2009-09-05 21:47:34 +00001433 entry->module=ConstantString("PNM");
1434 (void) RegisterMagickInfo(entry);
1435 entry=SetMagickInfo("PNM");
1436 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1437 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1438 entry->magick=(IsImageFormatHandler *) IsPNM;
1439 entry->description=ConstantString("Portable anymap");
cristyf0d061c2013-08-09 12:17:54 +00001440 entry->mime_type=ConstantString("image/x-portable-pixmap");
cristy3ed852e2009-09-05 21:47:34 +00001441 entry->module=ConstantString("PNM");
1442 (void) RegisterMagickInfo(entry);
1443 entry=SetMagickInfo("PPM");
1444 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1445 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1446 entry->description=ConstantString("Portable pixmap format (color)");
cristyf0d061c2013-08-09 12:17:54 +00001447 entry->mime_type=ConstantString("image/x-portable-pixmap");
cristy3ed852e2009-09-05 21:47:34 +00001448 entry->module=ConstantString("PNM");
1449 (void) RegisterMagickInfo(entry);
1450 return(MagickImageCoderSignature);
1451}
1452
1453/*
1454%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1455% %
1456% %
1457% %
1458% U n r e g i s t e r P N M I m a g e %
1459% %
1460% %
1461% %
1462%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1463%
1464% UnregisterPNMImage() removes format registrations made by the
1465% PNM module from the list of supported formats.
1466%
1467% The format of the UnregisterPNMImage method is:
1468%
1469% UnregisterPNMImage(void)
1470%
1471*/
1472ModuleExport void UnregisterPNMImage(void)
1473{
1474 (void) UnregisterMagickInfo("PAM");
1475 (void) UnregisterMagickInfo("PBM");
1476 (void) UnregisterMagickInfo("PGM");
1477 (void) UnregisterMagickInfo("PNM");
1478 (void) UnregisterMagickInfo("PPM");
1479}
1480
1481/*
1482%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1483% %
1484% %
1485% %
1486% W r i t e P N M I m a g e %
1487% %
1488% %
1489% %
1490%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1491%
cristy661b5ad2010-01-13 00:54:42 +00001492% WritePNMImage() writes an image to a file in the PNM rasterfile format.
cristy3ed852e2009-09-05 21:47:34 +00001493%
1494% The format of the WritePNMImage method is:
1495%
cristy1e178e72011-08-28 19:44:34 +00001496% MagickBooleanType WritePNMImage(const ImageInfo *image_info,
1497% Image *image,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00001498%
1499% A description of each parameter follows.
1500%
1501% o image_info: the image info.
1502%
1503% o image: The image.
1504%
cristy1e178e72011-08-28 19:44:34 +00001505% o exception: return any errors or warnings in this structure.
1506%
cristy3ed852e2009-09-05 21:47:34 +00001507*/
cristy1e178e72011-08-28 19:44:34 +00001508static MagickBooleanType WritePNMImage(const ImageInfo *image_info,Image *image,
1509 ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00001510{
1511 char
1512 buffer[MaxTextExtent],
1513 format,
1514 magick[MaxTextExtent];
1515
1516 const char
1517 *value;
1518
cristy3ed852e2009-09-05 21:47:34 +00001519 MagickBooleanType
1520 status;
1521
1522 MagickOffsetType
1523 scene;
1524
cristy4c08aed2011-07-01 19:47:50 +00001525 Quantum
1526 index;
1527
cristy3ed852e2009-09-05 21:47:34 +00001528 QuantumAny
1529 pixel;
1530
1531 QuantumInfo
1532 *quantum_info;
1533
1534 QuantumType
1535 quantum_type;
1536
cristy3ed852e2009-09-05 21:47:34 +00001537 register unsigned char
1538 *pixels,
1539 *q;
1540
cristy3ed852e2009-09-05 21:47:34 +00001541 size_t
1542 extent,
1543 packet_size;
1544
cristy95802a72010-09-05 19:07:17 +00001545 ssize_t
cristyaff6d802011-04-26 01:46:31 +00001546 count,
1547 y;
cristy95802a72010-09-05 19:07:17 +00001548
cristy3ed852e2009-09-05 21:47:34 +00001549 /*
1550 Open output image file.
1551 */
1552 assert(image_info != (const ImageInfo *) NULL);
1553 assert(image_info->signature == MagickSignature);
1554 assert(image != (Image *) NULL);
1555 assert(image->signature == MagickSignature);
1556 if (image->debug != MagickFalse)
1557 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
cristy3a37efd2011-08-28 20:31:03 +00001558 assert(exception != (ExceptionInfo *) NULL);
1559 assert(exception->signature == MagickSignature);
cristy1e178e72011-08-28 19:44:34 +00001560 status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
cristy3ed852e2009-09-05 21:47:34 +00001561 if (status == MagickFalse)
1562 return(status);
1563 scene=0;
1564 do
1565 {
cristy92beec62013-08-26 12:23:46 +00001566 QuantumAny
1567 max_value;
1568
cristy3ed852e2009-09-05 21:47:34 +00001569 /*
1570 Write PNM file header.
1571 */
1572 packet_size=3;
1573 quantum_type=RGBQuantum;
1574 (void) CopyMagickString(magick,image_info->magick,MaxTextExtent);
cristy92beec62013-08-26 12:23:46 +00001575 max_value=GetQuantumRange(image->depth);
cristy3ed852e2009-09-05 21:47:34 +00001576 switch (magick[1])
1577 {
1578 case 'A':
1579 case 'a':
1580 {
1581 format='7';
1582 break;
1583 }
1584 case 'B':
1585 case 'b':
1586 {
1587 format='4';
1588 if (image_info->compression == NoCompression)
1589 format='1';
1590 break;
1591 }
1592 case 'F':
1593 case 'f':
1594 {
1595 format='F';
cristy1e178e72011-08-28 19:44:34 +00001596 if (IsImageGray(image,exception) != MagickFalse)
cristy3ed852e2009-09-05 21:47:34 +00001597 format='f';
1598 break;
1599 }
1600 case 'G':
1601 case 'g':
1602 {
1603 format='5';
1604 if (image_info->compression == NoCompression)
1605 format='2';
1606 break;
1607 }
1608 case 'N':
1609 case 'n':
1610 {
1611 if ((image_info->type != TrueColorType) &&
cristy1e178e72011-08-28 19:44:34 +00001612 (IsImageGray(image,exception) != MagickFalse))
cristy3ed852e2009-09-05 21:47:34 +00001613 {
1614 format='5';
1615 if (image_info->compression == NoCompression)
1616 format='2';
cristy1e178e72011-08-28 19:44:34 +00001617 if (IsImageMonochrome(image,exception) != MagickFalse)
cristy3ed852e2009-09-05 21:47:34 +00001618 {
1619 format='4';
1620 if (image_info->compression == NoCompression)
1621 format='1';
1622 }
1623 break;
1624 }
1625 }
1626 default:
1627 {
1628 format='6';
1629 if (image_info->compression == NoCompression)
1630 format='3';
1631 break;
1632 }
1633 }
cristyb51dff52011-05-19 16:55:47 +00001634 (void) FormatLocaleString(buffer,MaxTextExtent,"P%c\n",format);
cristy3ed852e2009-09-05 21:47:34 +00001635 (void) WriteBlobString(image,buffer);
cristyd15e6592011-10-15 00:13:06 +00001636 value=GetImageProperty(image,"comment",exception);
cristy3ed852e2009-09-05 21:47:34 +00001637 if (value != (const char *) NULL)
1638 {
1639 register const char
1640 *p;
1641
1642 /*
1643 Write comments to file.
1644 */
1645 (void) WriteBlobByte(image,'#');
1646 for (p=value; *p != '\0'; p++)
1647 {
1648 (void) WriteBlobByte(image,(unsigned char) *p);
cristy542ea782013-05-24 15:53:01 +00001649 if ((*p == '\n') || (*p == '\r'))
cristy3ed852e2009-09-05 21:47:34 +00001650 (void) WriteBlobByte(image,'#');
1651 }
1652 (void) WriteBlobByte(image,'\n');
1653 }
1654 if (format != '7')
1655 {
cristyb51dff52011-05-19 16:55:47 +00001656 (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g %.20g\n",
cristye8c25f92010-06-03 00:53:06 +00001657 (double) image->columns,(double) image->rows);
cristy3ed852e2009-09-05 21:47:34 +00001658 (void) WriteBlobString(image,buffer);
1659 }
1660 else
1661 {
1662 char
1663 type[MaxTextExtent];
1664
1665 /*
1666 PAM header.
1667 */
cristyb51dff52011-05-19 16:55:47 +00001668 (void) FormatLocaleString(buffer,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00001669 "WIDTH %.20g\nHEIGHT %.20g\n",(double) image->columns,(double)
1670 image->rows);
cristy3ed852e2009-09-05 21:47:34 +00001671 (void) WriteBlobString(image,buffer);
cristy1e178e72011-08-28 19:44:34 +00001672 quantum_type=GetQuantumType(image,exception);
cristy3ed852e2009-09-05 21:47:34 +00001673 switch (quantum_type)
1674 {
1675 case CMYKQuantum:
1676 case CMYKAQuantum:
1677 {
1678 packet_size=4;
1679 (void) CopyMagickString(type,"CMYK",MaxTextExtent);
1680 break;
1681 }
1682 case GrayQuantum:
1683 case GrayAlphaQuantum:
1684 {
1685 packet_size=1;
1686 (void) CopyMagickString(type,"GRAYSCALE",MaxTextExtent);
1687 break;
1688 }
1689 default:
1690 {
1691 quantum_type=RGBQuantum;
cristy8a46d822012-08-28 23:32:39 +00001692 if (image->alpha_trait == BlendPixelTrait)
cristy3ed852e2009-09-05 21:47:34 +00001693 quantum_type=RGBAQuantum;
1694 packet_size=3;
1695 (void) CopyMagickString(type,"RGB",MaxTextExtent);
1696 break;
1697 }
1698 }
cristy8a46d822012-08-28 23:32:39 +00001699 if (image->alpha_trait == BlendPixelTrait)
cristy3ed852e2009-09-05 21:47:34 +00001700 {
1701 packet_size++;
1702 (void) ConcatenateMagickString(type,"_ALPHA",MaxTextExtent);
1703 }
cristy67d16d92013-09-29 18:31:17 +00001704 if (image->depth > 32)
1705 image->depth=32;
cristyb51dff52011-05-19 16:55:47 +00001706 (void) FormatLocaleString(buffer,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00001707 "DEPTH %.20g\nMAXVAL %.20g\n",(double) packet_size,(double)
cristy2b9582a2011-07-04 17:38:56 +00001708 ((MagickOffsetType) GetQuantumRange(image->depth)));
cristy3ed852e2009-09-05 21:47:34 +00001709 (void) WriteBlobString(image,buffer);
cristyb51dff52011-05-19 16:55:47 +00001710 (void) FormatLocaleString(buffer,MaxTextExtent,"TUPLTYPE %s\nENDHDR\n",
cristy3ed852e2009-09-05 21:47:34 +00001711 type);
1712 (void) WriteBlobString(image,buffer);
1713 }
1714 /*
1715 Convert runextent encoded to PNM raster pixels.
1716 */
1717 switch (format)
1718 {
1719 case '1':
1720 {
cristy661b5ad2010-01-13 00:54:42 +00001721 unsigned char
1722 pixels[2048];
cristy3ed852e2009-09-05 21:47:34 +00001723
1724 /*
1725 Convert image to a PBM image.
1726 */
cristy7a4c0972013-11-22 17:48:43 +00001727 (void) SetImageType(image,BilevelType,exception);
cristy661b5ad2010-01-13 00:54:42 +00001728 q=pixels;
cristybb503372010-05-27 20:51:26 +00001729 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +00001730 {
cristy4c08aed2011-07-01 19:47:50 +00001731 register const Quantum
cristyc47d1f82009-11-26 01:44:43 +00001732 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +00001733
cristybb503372010-05-27 20:51:26 +00001734 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001735 x;
1736
cristy1e178e72011-08-28 19:44:34 +00001737 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
cristy4c08aed2011-07-01 19:47:50 +00001738 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001739 break;
cristybb503372010-05-27 20:51:26 +00001740 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00001741 {
cristy7a4c0972013-11-22 17:48:43 +00001742 *q++=(unsigned char) (GetPixelLuma(image,p) >= (QuantumRange/2.0) ?
cristy661b5ad2010-01-13 00:54:42 +00001743 '0' : '1');
1744 *q++=' ';
1745 if ((q-pixels+2) >= 80)
1746 {
1747 *q++='\n';
1748 (void) WriteBlob(image,q-pixels,pixels);
1749 q=pixels;
cristy661b5ad2010-01-13 00:54:42 +00001750 }
cristyed231572011-07-14 02:18:59 +00001751 p+=GetPixelChannels(image);
cristy3ed852e2009-09-05 21:47:34 +00001752 }
1753 if (image->previous == (Image *) NULL)
1754 {
cristycee97112010-05-28 00:44:52 +00001755 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1756 image->rows);
cristy3ed852e2009-09-05 21:47:34 +00001757 if (status == MagickFalse)
1758 break;
1759 }
1760 }
cristy661b5ad2010-01-13 00:54:42 +00001761 if (q != pixels)
1762 {
1763 *q++='\n';
1764 (void) WriteBlob(image,q-pixels,pixels);
1765 }
cristy3ed852e2009-09-05 21:47:34 +00001766 break;
1767 }
1768 case '2':
1769 {
cristy661b5ad2010-01-13 00:54:42 +00001770 unsigned char
1771 pixels[2048];
cristy3ed852e2009-09-05 21:47:34 +00001772
1773 /*
1774 Convert image to a PGM image.
1775 */
1776 if (image->depth <= 8)
1777 (void) WriteBlobString(image,"255\n");
1778 else
cristy67d16d92013-09-29 18:31:17 +00001779 if (image->depth <= 16)
1780 (void) WriteBlobString(image,"65535\n");
1781 else
1782 (void) WriteBlobString(image,"4294967295\n");
cristy661b5ad2010-01-13 00:54:42 +00001783 q=pixels;
cristybb503372010-05-27 20:51:26 +00001784 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +00001785 {
cristy4c08aed2011-07-01 19:47:50 +00001786 register const Quantum
cristyc47d1f82009-11-26 01:44:43 +00001787 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +00001788
cristybb503372010-05-27 20:51:26 +00001789 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001790 x;
1791
cristy1e178e72011-08-28 19:44:34 +00001792 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
cristy4c08aed2011-07-01 19:47:50 +00001793 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001794 break;
cristybb503372010-05-27 20:51:26 +00001795 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00001796 {
cristyd0323222013-04-07 16:13:21 +00001797 index=ClampToQuantum(GetPixelLuma(image,p));
cristy3ed852e2009-09-05 21:47:34 +00001798 if (image->depth <= 8)
cristyb51dff52011-05-19 16:55:47 +00001799 count=(ssize_t) FormatLocaleString(buffer,MaxTextExtent,"%u ",
cristy3ed852e2009-09-05 21:47:34 +00001800 ScaleQuantumToChar(index));
1801 else
cristy67d16d92013-09-29 18:31:17 +00001802 if (image->depth <= 16)
1803 count=(ssize_t) FormatLocaleString(buffer,MaxTextExtent,"%u ",
1804 ScaleQuantumToShort(index));
1805 else
1806 count=(ssize_t) FormatLocaleString(buffer,MaxTextExtent,"%u ",
1807 ScaleQuantumToLong(index));
cristy661b5ad2010-01-13 00:54:42 +00001808 extent=(size_t) count;
1809 (void) strncpy((char *) q,buffer,extent);
1810 q+=extent;
1811 if ((q-pixels+extent) >= 80)
1812 {
1813 *q++='\n';
1814 (void) WriteBlob(image,q-pixels,pixels);
1815 q=pixels;
1816 }
cristyed231572011-07-14 02:18:59 +00001817 p+=GetPixelChannels(image);
cristy3ed852e2009-09-05 21:47:34 +00001818 }
1819 if (image->previous == (Image *) NULL)
1820 {
cristycee97112010-05-28 00:44:52 +00001821 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1822 image->rows);
cristy3ed852e2009-09-05 21:47:34 +00001823 if (status == MagickFalse)
1824 break;
1825 }
1826 }
cristy661b5ad2010-01-13 00:54:42 +00001827 if (q != pixels)
1828 {
1829 *q++='\n';
1830 (void) WriteBlob(image,q-pixels,pixels);
1831 }
cristy3ed852e2009-09-05 21:47:34 +00001832 break;
1833 }
1834 case '3':
1835 {
cristy661b5ad2010-01-13 00:54:42 +00001836 unsigned char
1837 pixels[2048];
cristy3ed852e2009-09-05 21:47:34 +00001838
1839 /*
1840 Convert image to a PNM image.
1841 */
cristy3d9f5ba2012-06-26 13:37:31 +00001842 if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
cristy8d218d72012-06-25 18:01:54 +00001843 (void) TransformImageColorspace(image,sRGBColorspace,exception);
cristy3ed852e2009-09-05 21:47:34 +00001844 if (image->depth <= 8)
1845 (void) WriteBlobString(image,"255\n");
1846 else
cristy67d16d92013-09-29 18:31:17 +00001847 if (image->depth <= 16)
1848 (void) WriteBlobString(image,"65535\n");
1849 else
1850 (void) WriteBlobString(image,"4294967295\n");
cristy661b5ad2010-01-13 00:54:42 +00001851 q=pixels;
cristybb503372010-05-27 20:51:26 +00001852 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +00001853 {
cristy4c08aed2011-07-01 19:47:50 +00001854 register const Quantum
cristyc47d1f82009-11-26 01:44:43 +00001855 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +00001856
cristybb503372010-05-27 20:51:26 +00001857 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001858 x;
1859
cristy1e178e72011-08-28 19:44:34 +00001860 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
cristy4c08aed2011-07-01 19:47:50 +00001861 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001862 break;
cristybb503372010-05-27 20:51:26 +00001863 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00001864 {
1865 if (image->depth <= 8)
cristyb51dff52011-05-19 16:55:47 +00001866 count=(ssize_t) FormatLocaleString(buffer,MaxTextExtent,
cristy4c08aed2011-07-01 19:47:50 +00001867 "%u %u %u ",ScaleQuantumToChar(GetPixelRed(image,p)),
1868 ScaleQuantumToChar(GetPixelGreen(image,p)),
1869 ScaleQuantumToChar(GetPixelBlue(image,p)));
cristy3ed852e2009-09-05 21:47:34 +00001870 else
cristy67d16d92013-09-29 18:31:17 +00001871 if (image->depth <= 16)
1872 count=(ssize_t) FormatLocaleString(buffer,MaxTextExtent,
1873 "%u %u %u ",ScaleQuantumToShort(GetPixelRed(image,p)),
1874 ScaleQuantumToShort(GetPixelGreen(image,p)),
1875 ScaleQuantumToShort(GetPixelBlue(image,p)));
1876 else
1877 count=(ssize_t) FormatLocaleString(buffer,MaxTextExtent,
1878 "%u %u %u ",ScaleQuantumToLong(GetPixelRed(image,p)),
1879 ScaleQuantumToLong(GetPixelGreen(image,p)),
1880 ScaleQuantumToLong(GetPixelBlue(image,p)));
cristy661b5ad2010-01-13 00:54:42 +00001881 extent=(size_t) count;
1882 (void) strncpy((char *) q,buffer,extent);
1883 q+=extent;
1884 if ((q-pixels+extent) >= 80)
1885 {
1886 *q++='\n';
1887 (void) WriteBlob(image,q-pixels,pixels);
1888 q=pixels;
1889 }
cristyed231572011-07-14 02:18:59 +00001890 p+=GetPixelChannels(image);
cristy3ed852e2009-09-05 21:47:34 +00001891 }
1892 if (image->previous == (Image *) NULL)
1893 {
cristycee97112010-05-28 00:44:52 +00001894 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1895 image->rows);
cristy3ed852e2009-09-05 21:47:34 +00001896 if (status == MagickFalse)
1897 break;
1898 }
1899 }
cristy661b5ad2010-01-13 00:54:42 +00001900 if (q != pixels)
1901 {
1902 *q++='\n';
1903 (void) WriteBlob(image,q-pixels,pixels);
1904 }
cristy3ed852e2009-09-05 21:47:34 +00001905 break;
1906 }
1907 case '4':
1908 {
1909 /*
1910 Convert image to a PBM image.
1911 */
cristy7a4c0972013-11-22 17:48:43 +00001912 (void) SetImageType(image,BilevelType,exception);
cristy3ed852e2009-09-05 21:47:34 +00001913 image->depth=1;
1914 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
1915 if (quantum_info == (QuantumInfo *) NULL)
1916 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1917 quantum_info->min_is_white=MagickTrue;
1918 pixels=GetQuantumPixels(quantum_info);
cristybb503372010-05-27 20:51:26 +00001919 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +00001920 {
cristy4c08aed2011-07-01 19:47:50 +00001921 register const Quantum
cristyc47d1f82009-11-26 01:44:43 +00001922 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +00001923
cristy1e178e72011-08-28 19:44:34 +00001924 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
cristy4c08aed2011-07-01 19:47:50 +00001925 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001926 break;
cristy4c08aed2011-07-01 19:47:50 +00001927 extent=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
cristy1e178e72011-08-28 19:44:34 +00001928 GrayQuantum,pixels,exception);
cristy3ed852e2009-09-05 21:47:34 +00001929 count=WriteBlob(image,extent,pixels);
1930 if (count != (ssize_t) extent)
1931 break;
1932 if (image->previous == (Image *) NULL)
1933 {
cristycee97112010-05-28 00:44:52 +00001934 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1935 image->rows);
cristy3ed852e2009-09-05 21:47:34 +00001936 if (status == MagickFalse)
1937 break;
1938 }
1939 }
1940 quantum_info=DestroyQuantumInfo(quantum_info);
1941 break;
1942 }
1943 case '5':
1944 {
cristy3ed852e2009-09-05 21:47:34 +00001945 /*
1946 Convert image to a PGM image.
1947 */
cristy67d16d92013-09-29 18:31:17 +00001948 if (image->depth > 32)
cristyeff7fcc2013-09-30 10:27:08 +00001949 image->depth=32;
cristyb51dff52011-05-19 16:55:47 +00001950 (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g\n",(double)
cristy2b9582a2011-07-04 17:38:56 +00001951 ((MagickOffsetType) GetQuantumRange(image->depth)));
cristy3ed852e2009-09-05 21:47:34 +00001952 (void) WriteBlobString(image,buffer);
1953 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
1954 if (quantum_info == (QuantumInfo *) NULL)
1955 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1956 quantum_info->min_is_white=MagickTrue;
1957 pixels=GetQuantumPixels(quantum_info);
1958 extent=GetQuantumExtent(image,quantum_info,GrayQuantum);
cristybb503372010-05-27 20:51:26 +00001959 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +00001960 {
cristy4c08aed2011-07-01 19:47:50 +00001961 register const Quantum
cristyc47d1f82009-11-26 01:44:43 +00001962 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +00001963
cristybb503372010-05-27 20:51:26 +00001964 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001965 x;
1966
cristy1e178e72011-08-28 19:44:34 +00001967 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
cristy4c08aed2011-07-01 19:47:50 +00001968 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001969 break;
1970 q=pixels;
cristy67d16d92013-09-29 18:31:17 +00001971 switch (image->depth)
1972 {
1973 case 8:
1974 case 16:
1975 case 32:
1976 {
1977 extent=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1978 GrayQuantum,pixels,exception);
1979 break;
1980 }
1981 default:
cristy3ed852e2009-09-05 21:47:34 +00001982 {
1983 if (image->depth <= 8)
cristy3ed852e2009-09-05 21:47:34 +00001984 {
cristy67d16d92013-09-29 18:31:17 +00001985 for (x=0; x < (ssize_t) image->columns; x++)
1986 {
1987 if (IsPixelGray(image,p) == MagickFalse)
1988 pixel=ScaleQuantumToAny(ClampToQuantum(GetPixelLuma(
1989 image,p)),max_value);
1990 else
1991 {
1992 if (image->depth == 8)
1993 pixel=ScaleQuantumToChar(GetPixelRed(image,p));
1994 else
cristyeff7fcc2013-09-30 10:27:08 +00001995 pixel=ScaleQuantumToAny(GetPixelRed(image,p),
1996 max_value);
cristy67d16d92013-09-29 18:31:17 +00001997 }
1998 q=PopCharPixel((unsigned char) pixel,q);
1999 p+=GetPixelChannels(image);
2000 }
cristy66d892b2013-10-03 11:39:44 +00002001 extent=(size_t) (q-pixels);
cristy67d16d92013-09-29 18:31:17 +00002002 break;
cristy3ed852e2009-09-05 21:47:34 +00002003 }
cristy67d16d92013-09-29 18:31:17 +00002004 if (image->depth <= 16)
cristy3ed852e2009-09-05 21:47:34 +00002005 {
cristy67d16d92013-09-29 18:31:17 +00002006 for (x=0; x < (ssize_t) image->columns; x++)
2007 {
2008 if (IsPixelGray(image,p) == MagickFalse)
cristyeff7fcc2013-09-30 10:27:08 +00002009 pixel=ScaleQuantumToAny(ClampToQuantum(GetPixelLuma(image,
2010 p)),max_value);
cristy67d16d92013-09-29 18:31:17 +00002011 else
2012 {
2013 if (image->depth == 16)
2014 pixel=ScaleQuantumToShort(GetPixelRed(image,p));
2015 else
cristyeff7fcc2013-09-30 10:27:08 +00002016 pixel=ScaleQuantumToAny(GetPixelRed(image,p),
2017 max_value);
cristy67d16d92013-09-29 18:31:17 +00002018 }
2019 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2020 p+=GetPixelChannels(image);
2021 }
cristy66d892b2013-10-03 11:39:44 +00002022 extent=(size_t) (q-pixels);
cristy67d16d92013-09-29 18:31:17 +00002023 break;
cristy3ed852e2009-09-05 21:47:34 +00002024 }
cristy67d16d92013-09-29 18:31:17 +00002025 for (x=0; x < (ssize_t) image->columns; x++)
2026 {
2027 if (IsPixelGray(image,p) == MagickFalse)
cristyeff7fcc2013-09-30 10:27:08 +00002028 pixel=ScaleQuantumToAny(ClampToQuantum(GetPixelLuma(image,p)),
2029 max_value);
cristy67d16d92013-09-29 18:31:17 +00002030 else
2031 {
2032 if (image->depth == 16)
2033 pixel=ScaleQuantumToLong(GetPixelRed(image,p));
2034 else
2035 pixel=ScaleQuantumToAny(GetPixelRed(image,p),max_value);
2036 }
2037 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2038 p+=GetPixelChannels(image);
2039 }
cristy3ed852e2009-09-05 21:47:34 +00002040 extent=(size_t) (q-pixels);
cristy67d16d92013-09-29 18:31:17 +00002041 break;
cristy3ed852e2009-09-05 21:47:34 +00002042 }
cristy67d16d92013-09-29 18:31:17 +00002043 }
cristy3ed852e2009-09-05 21:47:34 +00002044 count=WriteBlob(image,extent,pixels);
2045 if (count != (ssize_t) extent)
2046 break;
2047 if (image->previous == (Image *) NULL)
2048 {
cristycee97112010-05-28 00:44:52 +00002049 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
2050 image->rows);
cristy3ed852e2009-09-05 21:47:34 +00002051 if (status == MagickFalse)
2052 break;
2053 }
2054 }
2055 quantum_info=DestroyQuantumInfo(quantum_info);
2056 break;
2057 }
2058 case '6':
2059 {
cristy3ed852e2009-09-05 21:47:34 +00002060 /*
2061 Convert image to a PNM image.
2062 */
cristy3d9f5ba2012-06-26 13:37:31 +00002063 if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
cristy8d218d72012-06-25 18:01:54 +00002064 (void) TransformImageColorspace(image,sRGBColorspace,exception);
cristy67d16d92013-09-29 18:31:17 +00002065 if (image->depth > 32)
2066 image->depth=32;
cristyb51dff52011-05-19 16:55:47 +00002067 (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g\n",(double)
cristy2b9582a2011-07-04 17:38:56 +00002068 ((MagickOffsetType) GetQuantumRange(image->depth)));
cristy3ed852e2009-09-05 21:47:34 +00002069 (void) WriteBlobString(image,buffer);
2070 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
2071 if (quantum_info == (QuantumInfo *) NULL)
2072 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
cristy70d7eae2012-11-17 19:40:21 +00002073 (void) SetQuantumEndian(image,quantum_info,MSBEndian);
cristy3ed852e2009-09-05 21:47:34 +00002074 pixels=GetQuantumPixels(quantum_info);
2075 extent=GetQuantumExtent(image,quantum_info,quantum_type);
cristybb503372010-05-27 20:51:26 +00002076 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +00002077 {
cristy4c08aed2011-07-01 19:47:50 +00002078 register const Quantum
cristyc47d1f82009-11-26 01:44:43 +00002079 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +00002080
cristybb503372010-05-27 20:51:26 +00002081 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002082 x;
2083
cristy1e178e72011-08-28 19:44:34 +00002084 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
cristy4c08aed2011-07-01 19:47:50 +00002085 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002086 break;
2087 q=pixels;
cristy67d16d92013-09-29 18:31:17 +00002088 switch (image->depth)
2089 {
2090 case 8:
2091 case 16:
2092 case 32:
2093 {
2094 extent=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2095 quantum_type,pixels,exception);
2096 break;
2097 }
2098 default:
cristy3ed852e2009-09-05 21:47:34 +00002099 {
2100 if (image->depth <= 8)
cristy3ed852e2009-09-05 21:47:34 +00002101 {
cristy67d16d92013-09-29 18:31:17 +00002102 for (x=0; x < (ssize_t) image->columns; x++)
2103 {
2104 pixel=ScaleQuantumToAny(GetPixelRed(image,p),max_value);
2105 q=PopCharPixel((unsigned char) pixel,q);
2106 pixel=ScaleQuantumToAny(GetPixelGreen(image,p),max_value);
2107 q=PopCharPixel((unsigned char) pixel,q);
2108 pixel=ScaleQuantumToAny(GetPixelBlue(image,p),max_value);
2109 q=PopCharPixel((unsigned char) pixel,q);
2110 p+=GetPixelChannels(image);
2111 }
cristy5838dba2013-10-03 11:42:05 +00002112 extent=(size_t) (q-pixels);
cristy67d16d92013-09-29 18:31:17 +00002113 break;
cristy3ed852e2009-09-05 21:47:34 +00002114 }
cristy67d16d92013-09-29 18:31:17 +00002115 if (image->depth <= 16)
cristy3ed852e2009-09-05 21:47:34 +00002116 {
cristy67d16d92013-09-29 18:31:17 +00002117 for (x=0; x < (ssize_t) image->columns; x++)
2118 {
2119 pixel=ScaleQuantumToAny(GetPixelRed(image,p),max_value);
2120 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2121 pixel=ScaleQuantumToAny(GetPixelGreen(image,p),max_value);
2122 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2123 pixel=ScaleQuantumToAny(GetPixelBlue(image,p),max_value);
2124 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2125 p+=GetPixelChannels(image);
2126 }
cristy5838dba2013-10-03 11:42:05 +00002127 extent=(size_t) (q-pixels);
cristy67d16d92013-09-29 18:31:17 +00002128 break;
cristy3ed852e2009-09-05 21:47:34 +00002129 }
cristy67d16d92013-09-29 18:31:17 +00002130 for (x=0; x < (ssize_t) image->columns; x++)
2131 {
2132 pixel=ScaleQuantumToAny(GetPixelRed(image,p),max_value);
2133 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2134 pixel=ScaleQuantumToAny(GetPixelGreen(image,p),max_value);
2135 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2136 pixel=ScaleQuantumToAny(GetPixelBlue(image,p),max_value);
2137 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2138 p+=GetPixelChannels(image);
2139 }
cristy3ed852e2009-09-05 21:47:34 +00002140 extent=(size_t) (q-pixels);
cristy67d16d92013-09-29 18:31:17 +00002141 break;
cristy3ed852e2009-09-05 21:47:34 +00002142 }
cristy67d16d92013-09-29 18:31:17 +00002143 }
cristy3ed852e2009-09-05 21:47:34 +00002144 count=WriteBlob(image,extent,pixels);
2145 if (count != (ssize_t) extent)
2146 break;
2147 if (image->previous == (Image *) NULL)
2148 {
cristycee97112010-05-28 00:44:52 +00002149 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
2150 image->rows);
cristy3ed852e2009-09-05 21:47:34 +00002151 if (status == MagickFalse)
2152 break;
2153 }
2154 }
2155 quantum_info=DestroyQuantumInfo(quantum_info);
2156 break;
2157 }
2158 case '7':
2159 {
cristy3ed852e2009-09-05 21:47:34 +00002160 /*
2161 Convert image to a PAM.
2162 */
cristy67d16d92013-09-29 18:31:17 +00002163 if (image->depth > 32)
2164 image->depth=32;
cristy3ed852e2009-09-05 21:47:34 +00002165 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
2166 pixels=GetQuantumPixels(quantum_info);
cristybb503372010-05-27 20:51:26 +00002167 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +00002168 {
cristy4c08aed2011-07-01 19:47:50 +00002169 register const Quantum
cristyc47d1f82009-11-26 01:44:43 +00002170 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +00002171
cristybb503372010-05-27 20:51:26 +00002172 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002173 x;
2174
cristy1e178e72011-08-28 19:44:34 +00002175 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
cristy4c08aed2011-07-01 19:47:50 +00002176 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002177 break;
cristy3ed852e2009-09-05 21:47:34 +00002178 q=pixels;
cristy67d16d92013-09-29 18:31:17 +00002179 switch (image->depth)
2180 {
2181 case 8:
2182 case 16:
2183 case 32:
2184 {
2185 extent=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2186 quantum_type,pixels,exception);
2187 break;
2188 }
2189 default:
cristy3ed852e2009-09-05 21:47:34 +00002190 {
2191 switch (quantum_type)
2192 {
2193 case GrayQuantum:
2194 case GrayAlphaQuantum:
2195 {
2196 if (image->depth <= 8)
cristy3ed852e2009-09-05 21:47:34 +00002197 {
cristy67d16d92013-09-29 18:31:17 +00002198 for (x=0; x < (ssize_t) image->columns; x++)
2199 {
2200 pixel=ScaleQuantumToAny(ClampToQuantum(GetPixelLuma(
2201 image,p)),max_value);
2202 q=PopCharPixel((unsigned char) pixel,q);
2203 if (image->alpha_trait == BlendPixelTrait)
2204 {
2205 pixel=(unsigned char) ScaleQuantumToAny(
2206 GetPixelAlpha(image,p),max_value);
2207 q=PopCharPixel((unsigned char) pixel,q);
2208 }
2209 p+=GetPixelChannels(image);
2210 }
2211 break;
cristy3ed852e2009-09-05 21:47:34 +00002212 }
cristy67d16d92013-09-29 18:31:17 +00002213 if (image->depth <= 16)
cristy3ed852e2009-09-05 21:47:34 +00002214 {
cristy67d16d92013-09-29 18:31:17 +00002215 for (x=0; x < (ssize_t) image->columns; x++)
2216 {
2217 pixel=ScaleQuantumToAny(ClampToQuantum(GetPixelLuma(
2218 image,p)),max_value);
2219 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2220 if (image->alpha_trait == BlendPixelTrait)
2221 {
2222 pixel=(unsigned char) ScaleQuantumToAny(
2223 GetPixelAlpha(image,p),max_value);
2224 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2225 }
2226 p+=GetPixelChannels(image);
2227 }
2228 break;
cristy3ed852e2009-09-05 21:47:34 +00002229 }
cristy67d16d92013-09-29 18:31:17 +00002230 for (x=0; x < (ssize_t) image->columns; x++)
2231 {
cristyeff7fcc2013-09-30 10:27:08 +00002232 pixel=ScaleQuantumToAny(ClampToQuantum(GetPixelLuma(image,
2233 p)),max_value);
cristy67d16d92013-09-29 18:31:17 +00002234 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2235 if (image->alpha_trait == BlendPixelTrait)
2236 {
2237 pixel=(unsigned char) ScaleQuantumToAny(
2238 GetPixelAlpha(image,p),max_value);
2239 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2240 }
2241 p+=GetPixelChannels(image);
2242 }
cristy3ed852e2009-09-05 21:47:34 +00002243 break;
2244 }
2245 case CMYKQuantum:
2246 case CMYKAQuantum:
2247 {
2248 if (image->depth <= 8)
cristy3ed852e2009-09-05 21:47:34 +00002249 {
cristy67d16d92013-09-29 18:31:17 +00002250 for (x=0; x < (ssize_t) image->columns; x++)
2251 {
2252 pixel=ScaleQuantumToAny(GetPixelRed(image,p),max_value);
2253 q=PopCharPixel((unsigned char) pixel,q);
cristyeff7fcc2013-09-30 10:27:08 +00002254 pixel=ScaleQuantumToAny(GetPixelGreen(image,p),
2255 max_value);
cristy67d16d92013-09-29 18:31:17 +00002256 q=PopCharPixel((unsigned char) pixel,q);
cristyeff7fcc2013-09-30 10:27:08 +00002257 pixel=ScaleQuantumToAny(GetPixelBlue(image,p),
2258 max_value);
cristy67d16d92013-09-29 18:31:17 +00002259 q=PopCharPixel((unsigned char) pixel,q);
cristyeff7fcc2013-09-30 10:27:08 +00002260 pixel=ScaleQuantumToAny(GetPixelBlack(image,p),
2261 max_value);
cristy67d16d92013-09-29 18:31:17 +00002262 q=PopCharPixel((unsigned char) pixel,q);
2263 if (image->alpha_trait == BlendPixelTrait)
2264 {
2265 pixel=ScaleQuantumToAny(GetPixelAlpha(image,p),
2266 max_value);
2267 q=PopCharPixel((unsigned char) pixel,q);
2268 }
2269 p+=GetPixelChannels(image);
2270 }
2271 break;
cristy3ed852e2009-09-05 21:47:34 +00002272 }
cristy67d16d92013-09-29 18:31:17 +00002273 if (image->depth <= 16)
cristy3ed852e2009-09-05 21:47:34 +00002274 {
cristy67d16d92013-09-29 18:31:17 +00002275 for (x=0; x < (ssize_t) image->columns; x++)
2276 {
2277 pixel=ScaleQuantumToAny(GetPixelRed(image,p),max_value);
2278 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
cristyeff7fcc2013-09-30 10:27:08 +00002279 pixel=ScaleQuantumToAny(GetPixelGreen(image,p),
2280 max_value);
cristy67d16d92013-09-29 18:31:17 +00002281 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
cristyeff7fcc2013-09-30 10:27:08 +00002282 pixel=ScaleQuantumToAny(GetPixelBlue(image,p),
2283 max_value);
cristy67d16d92013-09-29 18:31:17 +00002284 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
cristyeff7fcc2013-09-30 10:27:08 +00002285 pixel=ScaleQuantumToAny(GetPixelBlack(image,p),
2286 max_value);
cristy67d16d92013-09-29 18:31:17 +00002287 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2288 if (image->alpha_trait == BlendPixelTrait)
2289 {
2290 pixel=ScaleQuantumToAny(GetPixelAlpha(image,p),
2291 max_value);
2292 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2293 }
2294 p+=GetPixelChannels(image);
2295 }
2296 break;
cristy3ed852e2009-09-05 21:47:34 +00002297 }
cristy67d16d92013-09-29 18:31:17 +00002298 for (x=0; x < (ssize_t) image->columns; x++)
2299 {
2300 pixel=ScaleQuantumToAny(GetPixelRed(image,p),max_value);
2301 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2302 pixel=ScaleQuantumToAny(GetPixelGreen(image,p),max_value);
2303 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2304 pixel=ScaleQuantumToAny(GetPixelBlue(image,p),max_value);
2305 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2306 pixel=ScaleQuantumToAny(GetPixelBlack(image,p),max_value);
2307 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2308 if (image->alpha_trait == BlendPixelTrait)
2309 {
cristyeff7fcc2013-09-30 10:27:08 +00002310 pixel=ScaleQuantumToAny(GetPixelAlpha(image,p),
2311 max_value);
cristy67d16d92013-09-29 18:31:17 +00002312 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2313 }
2314 p+=GetPixelChannels(image);
2315 }
cristy3ed852e2009-09-05 21:47:34 +00002316 break;
2317 }
2318 default:
2319 {
2320 if (image->depth <= 8)
cristy3ed852e2009-09-05 21:47:34 +00002321 {
cristy67d16d92013-09-29 18:31:17 +00002322 for (x=0; x < (ssize_t) image->columns; x++)
2323 {
2324 pixel=ScaleQuantumToAny(GetPixelRed(image,p),max_value);
2325 q=PopCharPixel((unsigned char) pixel,q);
cristyeff7fcc2013-09-30 10:27:08 +00002326 pixel=ScaleQuantumToAny(GetPixelGreen(image,p),
2327 max_value);
cristy67d16d92013-09-29 18:31:17 +00002328 q=PopCharPixel((unsigned char) pixel,q);
cristyeff7fcc2013-09-30 10:27:08 +00002329 pixel=ScaleQuantumToAny(GetPixelBlue(image,p),
2330 max_value);
cristy67d16d92013-09-29 18:31:17 +00002331 q=PopCharPixel((unsigned char) pixel,q);
2332 if (image->alpha_trait == BlendPixelTrait)
2333 {
2334 pixel=ScaleQuantumToAny(GetPixelAlpha(image,p),
2335 max_value);
2336 q=PopCharPixel((unsigned char) pixel,q);
2337 }
2338 p+=GetPixelChannels(image);
2339 }
2340 break;
cristy3ed852e2009-09-05 21:47:34 +00002341 }
cristy67d16d92013-09-29 18:31:17 +00002342 if (image->depth <= 16)
cristy3ed852e2009-09-05 21:47:34 +00002343 {
cristy67d16d92013-09-29 18:31:17 +00002344 for (x=0; x < (ssize_t) image->columns; x++)
2345 {
2346 pixel=ScaleQuantumToAny(GetPixelRed(image,p),max_value);
2347 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
cristyeff7fcc2013-09-30 10:27:08 +00002348 pixel=ScaleQuantumToAny(GetPixelGreen(image,p),
2349 max_value);
cristy67d16d92013-09-29 18:31:17 +00002350 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
cristyeff7fcc2013-09-30 10:27:08 +00002351 pixel=ScaleQuantumToAny(GetPixelBlue(image,p),
2352 max_value);
cristy67d16d92013-09-29 18:31:17 +00002353 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2354 if (image->alpha_trait == BlendPixelTrait)
2355 {
2356 pixel=ScaleQuantumToAny(GetPixelAlpha(image,p),
2357 max_value);
2358 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2359 }
2360 p+=GetPixelChannels(image);
2361 }
2362 break;
cristy3ed852e2009-09-05 21:47:34 +00002363 }
cristy67d16d92013-09-29 18:31:17 +00002364 for (x=0; x < (ssize_t) image->columns; x++)
2365 {
2366 pixel=ScaleQuantumToAny(GetPixelRed(image,p),max_value);
2367 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2368 pixel=ScaleQuantumToAny(GetPixelGreen(image,p),max_value);
2369 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2370 pixel=ScaleQuantumToAny(GetPixelBlue(image,p),max_value);
2371 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2372 if (image->alpha_trait == BlendPixelTrait)
2373 {
cristyeff7fcc2013-09-30 10:27:08 +00002374 pixel=ScaleQuantumToAny(GetPixelAlpha(image,p),
2375 max_value);
cristy67d16d92013-09-29 18:31:17 +00002376 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2377 }
2378 p+=GetPixelChannels(image);
2379 }
cristy3ed852e2009-09-05 21:47:34 +00002380 break;
2381 }
2382 }
2383 extent=(size_t) (q-pixels);
cristy67d16d92013-09-29 18:31:17 +00002384 break;
cristy3ed852e2009-09-05 21:47:34 +00002385 }
cristy67d16d92013-09-29 18:31:17 +00002386 }
cristy3ed852e2009-09-05 21:47:34 +00002387 count=WriteBlob(image,extent,pixels);
2388 if (count != (ssize_t) extent)
2389 break;
2390 if (image->previous == (Image *) NULL)
2391 {
cristycee97112010-05-28 00:44:52 +00002392 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
2393 image->rows);
cristy3ed852e2009-09-05 21:47:34 +00002394 if (status == MagickFalse)
2395 break;
2396 }
2397 }
2398 quantum_info=DestroyQuantumInfo(quantum_info);
2399 break;
2400 }
2401 case 'F':
2402 case 'f':
2403 {
cristy1715f792012-11-22 16:56:12 +00002404 (void) WriteBlobString(image,image->endian == LSBEndian ? "-1.0\n" :
2405 "1.0\n");
cristy3ed852e2009-09-05 21:47:34 +00002406 image->depth=32;
2407 quantum_type=format == 'f' ? GrayQuantum : RGBQuantum;
2408 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
2409 if (quantum_info == (QuantumInfo *) NULL)
2410 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
2411 status=SetQuantumFormat(image,quantum_info,FloatingPointQuantumFormat);
2412 if (status == MagickFalse)
2413 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
2414 pixels=GetQuantumPixels(quantum_info);
cristybb503372010-05-27 20:51:26 +00002415 for (y=(ssize_t) image->rows-1; y >= 0; y--)
cristy3ed852e2009-09-05 21:47:34 +00002416 {
cristy4c08aed2011-07-01 19:47:50 +00002417 register const Quantum
cristyc47d1f82009-11-26 01:44:43 +00002418 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +00002419
cristy1e178e72011-08-28 19:44:34 +00002420 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
cristy4c08aed2011-07-01 19:47:50 +00002421 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002422 break;
cristy4c08aed2011-07-01 19:47:50 +00002423 extent=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
cristy1e178e72011-08-28 19:44:34 +00002424 quantum_type,pixels,exception);
cristy3ed852e2009-09-05 21:47:34 +00002425 (void) WriteBlob(image,extent,pixels);
2426 if (image->previous == (Image *) NULL)
2427 {
cristycee97112010-05-28 00:44:52 +00002428 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
2429 image->rows);
cristy3ed852e2009-09-05 21:47:34 +00002430 if (status == MagickFalse)
2431 break;
2432 }
2433 }
2434 quantum_info=DestroyQuantumInfo(quantum_info);
2435 break;
2436 }
2437 }
2438 if (GetNextImageInList(image) == (Image *) NULL)
2439 break;
2440 image=SyncNextImageInList(image);
2441 status=SetImageProgress(image,SaveImagesTag,scene++,
2442 GetImageListLength(image));
2443 if (status == MagickFalse)
2444 break;
2445 } while (image_info->adjoin != MagickFalse);
2446 (void) CloseBlob(image);
2447 return(MagickTrue);
2448}