blob: 326367e46342f37e135b4e7c1c3cad4f1f6660e4 [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 */
cristy661b5ad2010-01-13 00:54:42 +00001727 q=pixels;
cristybb503372010-05-27 20:51:26 +00001728 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +00001729 {
cristy4c08aed2011-07-01 19:47:50 +00001730 register const Quantum
cristyc47d1f82009-11-26 01:44:43 +00001731 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +00001732
cristybb503372010-05-27 20:51:26 +00001733 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001734 x;
1735
cristy1e178e72011-08-28 19:44:34 +00001736 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
cristy4c08aed2011-07-01 19:47:50 +00001737 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001738 break;
cristybb503372010-05-27 20:51:26 +00001739 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00001740 {
cristyd0323222013-04-07 16:13:21 +00001741 pixel=ClampToQuantum(GetPixelLuma(image,p));
cristy661b5ad2010-01-13 00:54:42 +00001742 *q++=(unsigned char) (pixel >= (Quantum) (QuantumRange/2) ?
1743 '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 */
1912 image->depth=1;
1913 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
1914 if (quantum_info == (QuantumInfo *) NULL)
1915 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1916 quantum_info->min_is_white=MagickTrue;
1917 pixels=GetQuantumPixels(quantum_info);
cristybb503372010-05-27 20:51:26 +00001918 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +00001919 {
cristy4c08aed2011-07-01 19:47:50 +00001920 register const Quantum
cristyc47d1f82009-11-26 01:44:43 +00001921 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +00001922
cristy1e178e72011-08-28 19:44:34 +00001923 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
cristy4c08aed2011-07-01 19:47:50 +00001924 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001925 break;
cristy4c08aed2011-07-01 19:47:50 +00001926 extent=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
cristy1e178e72011-08-28 19:44:34 +00001927 GrayQuantum,pixels,exception);
cristy3ed852e2009-09-05 21:47:34 +00001928 count=WriteBlob(image,extent,pixels);
1929 if (count != (ssize_t) extent)
1930 break;
1931 if (image->previous == (Image *) NULL)
1932 {
cristycee97112010-05-28 00:44:52 +00001933 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1934 image->rows);
cristy3ed852e2009-09-05 21:47:34 +00001935 if (status == MagickFalse)
1936 break;
1937 }
1938 }
1939 quantum_info=DestroyQuantumInfo(quantum_info);
1940 break;
1941 }
1942 case '5':
1943 {
cristy3ed852e2009-09-05 21:47:34 +00001944 /*
1945 Convert image to a PGM image.
1946 */
cristy67d16d92013-09-29 18:31:17 +00001947 if (image->depth > 32)
cristyeff7fcc2013-09-30 10:27:08 +00001948 image->depth=32;
cristyb51dff52011-05-19 16:55:47 +00001949 (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g\n",(double)
cristy2b9582a2011-07-04 17:38:56 +00001950 ((MagickOffsetType) GetQuantumRange(image->depth)));
cristy3ed852e2009-09-05 21:47:34 +00001951 (void) WriteBlobString(image,buffer);
1952 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
1953 if (quantum_info == (QuantumInfo *) NULL)
1954 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1955 quantum_info->min_is_white=MagickTrue;
1956 pixels=GetQuantumPixels(quantum_info);
1957 extent=GetQuantumExtent(image,quantum_info,GrayQuantum);
cristybb503372010-05-27 20:51:26 +00001958 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +00001959 {
cristy4c08aed2011-07-01 19:47:50 +00001960 register const Quantum
cristyc47d1f82009-11-26 01:44:43 +00001961 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +00001962
cristybb503372010-05-27 20:51:26 +00001963 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001964 x;
1965
cristy1e178e72011-08-28 19:44:34 +00001966 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
cristy4c08aed2011-07-01 19:47:50 +00001967 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001968 break;
1969 q=pixels;
cristy67d16d92013-09-29 18:31:17 +00001970 switch (image->depth)
1971 {
1972 case 8:
1973 case 16:
1974 case 32:
1975 {
1976 extent=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1977 GrayQuantum,pixels,exception);
1978 break;
1979 }
1980 default:
cristy3ed852e2009-09-05 21:47:34 +00001981 {
1982 if (image->depth <= 8)
cristy3ed852e2009-09-05 21:47:34 +00001983 {
cristy67d16d92013-09-29 18:31:17 +00001984 for (x=0; x < (ssize_t) image->columns; x++)
1985 {
1986 if (IsPixelGray(image,p) == MagickFalse)
1987 pixel=ScaleQuantumToAny(ClampToQuantum(GetPixelLuma(
1988 image,p)),max_value);
1989 else
1990 {
1991 if (image->depth == 8)
1992 pixel=ScaleQuantumToChar(GetPixelRed(image,p));
1993 else
cristyeff7fcc2013-09-30 10:27:08 +00001994 pixel=ScaleQuantumToAny(GetPixelRed(image,p),
1995 max_value);
cristy67d16d92013-09-29 18:31:17 +00001996 }
1997 q=PopCharPixel((unsigned char) pixel,q);
1998 p+=GetPixelChannels(image);
1999 }
cristy66d892b2013-10-03 11:39:44 +00002000 extent=(size_t) (q-pixels);
cristy67d16d92013-09-29 18:31:17 +00002001 break;
cristy3ed852e2009-09-05 21:47:34 +00002002 }
cristy67d16d92013-09-29 18:31:17 +00002003 if (image->depth <= 16)
cristy3ed852e2009-09-05 21:47:34 +00002004 {
cristy67d16d92013-09-29 18:31:17 +00002005 for (x=0; x < (ssize_t) image->columns; x++)
2006 {
2007 if (IsPixelGray(image,p) == MagickFalse)
cristyeff7fcc2013-09-30 10:27:08 +00002008 pixel=ScaleQuantumToAny(ClampToQuantum(GetPixelLuma(image,
2009 p)),max_value);
cristy67d16d92013-09-29 18:31:17 +00002010 else
2011 {
2012 if (image->depth == 16)
2013 pixel=ScaleQuantumToShort(GetPixelRed(image,p));
2014 else
cristyeff7fcc2013-09-30 10:27:08 +00002015 pixel=ScaleQuantumToAny(GetPixelRed(image,p),
2016 max_value);
cristy67d16d92013-09-29 18:31:17 +00002017 }
2018 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2019 p+=GetPixelChannels(image);
2020 }
cristy66d892b2013-10-03 11:39:44 +00002021 extent=(size_t) (q-pixels);
cristy67d16d92013-09-29 18:31:17 +00002022 break;
cristy3ed852e2009-09-05 21:47:34 +00002023 }
cristy67d16d92013-09-29 18:31:17 +00002024 for (x=0; x < (ssize_t) image->columns; x++)
2025 {
2026 if (IsPixelGray(image,p) == MagickFalse)
cristyeff7fcc2013-09-30 10:27:08 +00002027 pixel=ScaleQuantumToAny(ClampToQuantum(GetPixelLuma(image,p)),
2028 max_value);
cristy67d16d92013-09-29 18:31:17 +00002029 else
2030 {
2031 if (image->depth == 16)
2032 pixel=ScaleQuantumToLong(GetPixelRed(image,p));
2033 else
2034 pixel=ScaleQuantumToAny(GetPixelRed(image,p),max_value);
2035 }
2036 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2037 p+=GetPixelChannels(image);
2038 }
cristy3ed852e2009-09-05 21:47:34 +00002039 extent=(size_t) (q-pixels);
cristy67d16d92013-09-29 18:31:17 +00002040 break;
cristy3ed852e2009-09-05 21:47:34 +00002041 }
cristy67d16d92013-09-29 18:31:17 +00002042 }
cristy3ed852e2009-09-05 21:47:34 +00002043 count=WriteBlob(image,extent,pixels);
2044 if (count != (ssize_t) extent)
2045 break;
2046 if (image->previous == (Image *) NULL)
2047 {
cristycee97112010-05-28 00:44:52 +00002048 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
2049 image->rows);
cristy3ed852e2009-09-05 21:47:34 +00002050 if (status == MagickFalse)
2051 break;
2052 }
2053 }
2054 quantum_info=DestroyQuantumInfo(quantum_info);
2055 break;
2056 }
2057 case '6':
2058 {
cristy3ed852e2009-09-05 21:47:34 +00002059 /*
2060 Convert image to a PNM image.
2061 */
cristy3d9f5ba2012-06-26 13:37:31 +00002062 if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
cristy8d218d72012-06-25 18:01:54 +00002063 (void) TransformImageColorspace(image,sRGBColorspace,exception);
cristy67d16d92013-09-29 18:31:17 +00002064 if (image->depth > 32)
2065 image->depth=32;
cristyb51dff52011-05-19 16:55:47 +00002066 (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g\n",(double)
cristy2b9582a2011-07-04 17:38:56 +00002067 ((MagickOffsetType) GetQuantumRange(image->depth)));
cristy3ed852e2009-09-05 21:47:34 +00002068 (void) WriteBlobString(image,buffer);
2069 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
2070 if (quantum_info == (QuantumInfo *) NULL)
2071 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
cristy70d7eae2012-11-17 19:40:21 +00002072 (void) SetQuantumEndian(image,quantum_info,MSBEndian);
cristy3ed852e2009-09-05 21:47:34 +00002073 pixels=GetQuantumPixels(quantum_info);
2074 extent=GetQuantumExtent(image,quantum_info,quantum_type);
cristybb503372010-05-27 20:51:26 +00002075 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +00002076 {
cristy4c08aed2011-07-01 19:47:50 +00002077 register const Quantum
cristyc47d1f82009-11-26 01:44:43 +00002078 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +00002079
cristybb503372010-05-27 20:51:26 +00002080 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002081 x;
2082
cristy1e178e72011-08-28 19:44:34 +00002083 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
cristy4c08aed2011-07-01 19:47:50 +00002084 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002085 break;
2086 q=pixels;
cristy67d16d92013-09-29 18:31:17 +00002087 switch (image->depth)
2088 {
2089 case 8:
2090 case 16:
2091 case 32:
2092 {
2093 extent=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2094 quantum_type,pixels,exception);
2095 break;
2096 }
2097 default:
cristy3ed852e2009-09-05 21:47:34 +00002098 {
2099 if (image->depth <= 8)
cristy3ed852e2009-09-05 21:47:34 +00002100 {
cristy67d16d92013-09-29 18:31:17 +00002101 for (x=0; x < (ssize_t) image->columns; x++)
2102 {
2103 pixel=ScaleQuantumToAny(GetPixelRed(image,p),max_value);
2104 q=PopCharPixel((unsigned char) pixel,q);
2105 pixel=ScaleQuantumToAny(GetPixelGreen(image,p),max_value);
2106 q=PopCharPixel((unsigned char) pixel,q);
2107 pixel=ScaleQuantumToAny(GetPixelBlue(image,p),max_value);
2108 q=PopCharPixel((unsigned char) pixel,q);
2109 p+=GetPixelChannels(image);
2110 }
cristy5838dba2013-10-03 11:42:05 +00002111 extent=(size_t) (q-pixels);
cristy67d16d92013-09-29 18:31:17 +00002112 break;
cristy3ed852e2009-09-05 21:47:34 +00002113 }
cristy67d16d92013-09-29 18:31:17 +00002114 if (image->depth <= 16)
cristy3ed852e2009-09-05 21:47:34 +00002115 {
cristy67d16d92013-09-29 18:31:17 +00002116 for (x=0; x < (ssize_t) image->columns; x++)
2117 {
2118 pixel=ScaleQuantumToAny(GetPixelRed(image,p),max_value);
2119 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2120 pixel=ScaleQuantumToAny(GetPixelGreen(image,p),max_value);
2121 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2122 pixel=ScaleQuantumToAny(GetPixelBlue(image,p),max_value);
2123 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2124 p+=GetPixelChannels(image);
2125 }
cristy5838dba2013-10-03 11:42:05 +00002126 extent=(size_t) (q-pixels);
cristy67d16d92013-09-29 18:31:17 +00002127 break;
cristy3ed852e2009-09-05 21:47:34 +00002128 }
cristy67d16d92013-09-29 18:31:17 +00002129 for (x=0; x < (ssize_t) image->columns; x++)
2130 {
2131 pixel=ScaleQuantumToAny(GetPixelRed(image,p),max_value);
2132 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2133 pixel=ScaleQuantumToAny(GetPixelGreen(image,p),max_value);
2134 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2135 pixel=ScaleQuantumToAny(GetPixelBlue(image,p),max_value);
2136 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2137 p+=GetPixelChannels(image);
2138 }
cristy3ed852e2009-09-05 21:47:34 +00002139 extent=(size_t) (q-pixels);
cristy67d16d92013-09-29 18:31:17 +00002140 break;
cristy3ed852e2009-09-05 21:47:34 +00002141 }
cristy67d16d92013-09-29 18:31:17 +00002142 }
cristy3ed852e2009-09-05 21:47:34 +00002143 count=WriteBlob(image,extent,pixels);
2144 if (count != (ssize_t) extent)
2145 break;
2146 if (image->previous == (Image *) NULL)
2147 {
cristycee97112010-05-28 00:44:52 +00002148 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
2149 image->rows);
cristy3ed852e2009-09-05 21:47:34 +00002150 if (status == MagickFalse)
2151 break;
2152 }
2153 }
2154 quantum_info=DestroyQuantumInfo(quantum_info);
2155 break;
2156 }
2157 case '7':
2158 {
cristy3ed852e2009-09-05 21:47:34 +00002159 /*
2160 Convert image to a PAM.
2161 */
cristy67d16d92013-09-29 18:31:17 +00002162 if (image->depth > 32)
2163 image->depth=32;
cristy3ed852e2009-09-05 21:47:34 +00002164 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
2165 pixels=GetQuantumPixels(quantum_info);
cristybb503372010-05-27 20:51:26 +00002166 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +00002167 {
cristy4c08aed2011-07-01 19:47:50 +00002168 register const Quantum
cristyc47d1f82009-11-26 01:44:43 +00002169 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +00002170
cristybb503372010-05-27 20:51:26 +00002171 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002172 x;
2173
cristy1e178e72011-08-28 19:44:34 +00002174 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
cristy4c08aed2011-07-01 19:47:50 +00002175 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002176 break;
cristy3ed852e2009-09-05 21:47:34 +00002177 q=pixels;
cristy67d16d92013-09-29 18:31:17 +00002178 switch (image->depth)
2179 {
2180 case 8:
2181 case 16:
2182 case 32:
2183 {
2184 extent=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2185 quantum_type,pixels,exception);
2186 break;
2187 }
2188 default:
cristy3ed852e2009-09-05 21:47:34 +00002189 {
2190 switch (quantum_type)
2191 {
2192 case GrayQuantum:
2193 case GrayAlphaQuantum:
2194 {
2195 if (image->depth <= 8)
cristy3ed852e2009-09-05 21:47:34 +00002196 {
cristy67d16d92013-09-29 18:31:17 +00002197 for (x=0; x < (ssize_t) image->columns; x++)
2198 {
2199 pixel=ScaleQuantumToAny(ClampToQuantum(GetPixelLuma(
2200 image,p)),max_value);
2201 q=PopCharPixel((unsigned char) pixel,q);
2202 if (image->alpha_trait == BlendPixelTrait)
2203 {
2204 pixel=(unsigned char) ScaleQuantumToAny(
2205 GetPixelAlpha(image,p),max_value);
2206 q=PopCharPixel((unsigned char) pixel,q);
2207 }
2208 p+=GetPixelChannels(image);
2209 }
2210 break;
cristy3ed852e2009-09-05 21:47:34 +00002211 }
cristy67d16d92013-09-29 18:31:17 +00002212 if (image->depth <= 16)
cristy3ed852e2009-09-05 21:47:34 +00002213 {
cristy67d16d92013-09-29 18:31:17 +00002214 for (x=0; x < (ssize_t) image->columns; x++)
2215 {
2216 pixel=ScaleQuantumToAny(ClampToQuantum(GetPixelLuma(
2217 image,p)),max_value);
2218 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2219 if (image->alpha_trait == BlendPixelTrait)
2220 {
2221 pixel=(unsigned char) ScaleQuantumToAny(
2222 GetPixelAlpha(image,p),max_value);
2223 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2224 }
2225 p+=GetPixelChannels(image);
2226 }
2227 break;
cristy3ed852e2009-09-05 21:47:34 +00002228 }
cristy67d16d92013-09-29 18:31:17 +00002229 for (x=0; x < (ssize_t) image->columns; x++)
2230 {
cristyeff7fcc2013-09-30 10:27:08 +00002231 pixel=ScaleQuantumToAny(ClampToQuantum(GetPixelLuma(image,
2232 p)),max_value);
cristy67d16d92013-09-29 18:31:17 +00002233 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2234 if (image->alpha_trait == BlendPixelTrait)
2235 {
2236 pixel=(unsigned char) ScaleQuantumToAny(
2237 GetPixelAlpha(image,p),max_value);
2238 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2239 }
2240 p+=GetPixelChannels(image);
2241 }
cristy3ed852e2009-09-05 21:47:34 +00002242 break;
2243 }
2244 case CMYKQuantum:
2245 case CMYKAQuantum:
2246 {
2247 if (image->depth <= 8)
cristy3ed852e2009-09-05 21:47:34 +00002248 {
cristy67d16d92013-09-29 18:31:17 +00002249 for (x=0; x < (ssize_t) image->columns; x++)
2250 {
2251 pixel=ScaleQuantumToAny(GetPixelRed(image,p),max_value);
2252 q=PopCharPixel((unsigned char) pixel,q);
cristyeff7fcc2013-09-30 10:27:08 +00002253 pixel=ScaleQuantumToAny(GetPixelGreen(image,p),
2254 max_value);
cristy67d16d92013-09-29 18:31:17 +00002255 q=PopCharPixel((unsigned char) pixel,q);
cristyeff7fcc2013-09-30 10:27:08 +00002256 pixel=ScaleQuantumToAny(GetPixelBlue(image,p),
2257 max_value);
cristy67d16d92013-09-29 18:31:17 +00002258 q=PopCharPixel((unsigned char) pixel,q);
cristyeff7fcc2013-09-30 10:27:08 +00002259 pixel=ScaleQuantumToAny(GetPixelBlack(image,p),
2260 max_value);
cristy67d16d92013-09-29 18:31:17 +00002261 q=PopCharPixel((unsigned char) pixel,q);
2262 if (image->alpha_trait == BlendPixelTrait)
2263 {
2264 pixel=ScaleQuantumToAny(GetPixelAlpha(image,p),
2265 max_value);
2266 q=PopCharPixel((unsigned char) pixel,q);
2267 }
2268 p+=GetPixelChannels(image);
2269 }
2270 break;
cristy3ed852e2009-09-05 21:47:34 +00002271 }
cristy67d16d92013-09-29 18:31:17 +00002272 if (image->depth <= 16)
cristy3ed852e2009-09-05 21:47:34 +00002273 {
cristy67d16d92013-09-29 18:31:17 +00002274 for (x=0; x < (ssize_t) image->columns; x++)
2275 {
2276 pixel=ScaleQuantumToAny(GetPixelRed(image,p),max_value);
2277 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
cristyeff7fcc2013-09-30 10:27:08 +00002278 pixel=ScaleQuantumToAny(GetPixelGreen(image,p),
2279 max_value);
cristy67d16d92013-09-29 18:31:17 +00002280 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
cristyeff7fcc2013-09-30 10:27:08 +00002281 pixel=ScaleQuantumToAny(GetPixelBlue(image,p),
2282 max_value);
cristy67d16d92013-09-29 18:31:17 +00002283 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
cristyeff7fcc2013-09-30 10:27:08 +00002284 pixel=ScaleQuantumToAny(GetPixelBlack(image,p),
2285 max_value);
cristy67d16d92013-09-29 18:31:17 +00002286 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2287 if (image->alpha_trait == BlendPixelTrait)
2288 {
2289 pixel=ScaleQuantumToAny(GetPixelAlpha(image,p),
2290 max_value);
2291 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2292 }
2293 p+=GetPixelChannels(image);
2294 }
2295 break;
cristy3ed852e2009-09-05 21:47:34 +00002296 }
cristy67d16d92013-09-29 18:31:17 +00002297 for (x=0; x < (ssize_t) image->columns; x++)
2298 {
2299 pixel=ScaleQuantumToAny(GetPixelRed(image,p),max_value);
2300 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2301 pixel=ScaleQuantumToAny(GetPixelGreen(image,p),max_value);
2302 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2303 pixel=ScaleQuantumToAny(GetPixelBlue(image,p),max_value);
2304 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2305 pixel=ScaleQuantumToAny(GetPixelBlack(image,p),max_value);
2306 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2307 if (image->alpha_trait == BlendPixelTrait)
2308 {
cristyeff7fcc2013-09-30 10:27:08 +00002309 pixel=ScaleQuantumToAny(GetPixelAlpha(image,p),
2310 max_value);
cristy67d16d92013-09-29 18:31:17 +00002311 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2312 }
2313 p+=GetPixelChannels(image);
2314 }
cristy3ed852e2009-09-05 21:47:34 +00002315 break;
2316 }
2317 default:
2318 {
2319 if (image->depth <= 8)
cristy3ed852e2009-09-05 21:47:34 +00002320 {
cristy67d16d92013-09-29 18:31:17 +00002321 for (x=0; x < (ssize_t) image->columns; x++)
2322 {
2323 pixel=ScaleQuantumToAny(GetPixelRed(image,p),max_value);
2324 q=PopCharPixel((unsigned char) pixel,q);
cristyeff7fcc2013-09-30 10:27:08 +00002325 pixel=ScaleQuantumToAny(GetPixelGreen(image,p),
2326 max_value);
cristy67d16d92013-09-29 18:31:17 +00002327 q=PopCharPixel((unsigned char) pixel,q);
cristyeff7fcc2013-09-30 10:27:08 +00002328 pixel=ScaleQuantumToAny(GetPixelBlue(image,p),
2329 max_value);
cristy67d16d92013-09-29 18:31:17 +00002330 q=PopCharPixel((unsigned char) pixel,q);
2331 if (image->alpha_trait == BlendPixelTrait)
2332 {
2333 pixel=ScaleQuantumToAny(GetPixelAlpha(image,p),
2334 max_value);
2335 q=PopCharPixel((unsigned char) pixel,q);
2336 }
2337 p+=GetPixelChannels(image);
2338 }
2339 break;
cristy3ed852e2009-09-05 21:47:34 +00002340 }
cristy67d16d92013-09-29 18:31:17 +00002341 if (image->depth <= 16)
cristy3ed852e2009-09-05 21:47:34 +00002342 {
cristy67d16d92013-09-29 18:31:17 +00002343 for (x=0; x < (ssize_t) image->columns; x++)
2344 {
2345 pixel=ScaleQuantumToAny(GetPixelRed(image,p),max_value);
2346 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
cristyeff7fcc2013-09-30 10:27:08 +00002347 pixel=ScaleQuantumToAny(GetPixelGreen(image,p),
2348 max_value);
cristy67d16d92013-09-29 18:31:17 +00002349 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
cristyeff7fcc2013-09-30 10:27:08 +00002350 pixel=ScaleQuantumToAny(GetPixelBlue(image,p),
2351 max_value);
cristy67d16d92013-09-29 18:31:17 +00002352 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2353 if (image->alpha_trait == BlendPixelTrait)
2354 {
2355 pixel=ScaleQuantumToAny(GetPixelAlpha(image,p),
2356 max_value);
2357 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2358 }
2359 p+=GetPixelChannels(image);
2360 }
2361 break;
cristy3ed852e2009-09-05 21:47:34 +00002362 }
cristy67d16d92013-09-29 18:31:17 +00002363 for (x=0; x < (ssize_t) image->columns; x++)
2364 {
2365 pixel=ScaleQuantumToAny(GetPixelRed(image,p),max_value);
2366 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2367 pixel=ScaleQuantumToAny(GetPixelGreen(image,p),max_value);
2368 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2369 pixel=ScaleQuantumToAny(GetPixelBlue(image,p),max_value);
2370 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2371 if (image->alpha_trait == BlendPixelTrait)
2372 {
cristyeff7fcc2013-09-30 10:27:08 +00002373 pixel=ScaleQuantumToAny(GetPixelAlpha(image,p),
2374 max_value);
cristy67d16d92013-09-29 18:31:17 +00002375 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2376 }
2377 p+=GetPixelChannels(image);
2378 }
cristy3ed852e2009-09-05 21:47:34 +00002379 break;
2380 }
2381 }
2382 extent=(size_t) (q-pixels);
cristy67d16d92013-09-29 18:31:17 +00002383 break;
cristy3ed852e2009-09-05 21:47:34 +00002384 }
cristy67d16d92013-09-29 18:31:17 +00002385 }
cristy3ed852e2009-09-05 21:47:34 +00002386 count=WriteBlob(image,extent,pixels);
2387 if (count != (ssize_t) extent)
2388 break;
2389 if (image->previous == (Image *) NULL)
2390 {
cristycee97112010-05-28 00:44:52 +00002391 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
2392 image->rows);
cristy3ed852e2009-09-05 21:47:34 +00002393 if (status == MagickFalse)
2394 break;
2395 }
2396 }
2397 quantum_info=DestroyQuantumInfo(quantum_info);
2398 break;
2399 }
2400 case 'F':
2401 case 'f':
2402 {
cristy1715f792012-11-22 16:56:12 +00002403 (void) WriteBlobString(image,image->endian == LSBEndian ? "-1.0\n" :
2404 "1.0\n");
cristy3ed852e2009-09-05 21:47:34 +00002405 image->depth=32;
2406 quantum_type=format == 'f' ? GrayQuantum : RGBQuantum;
2407 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
2408 if (quantum_info == (QuantumInfo *) NULL)
2409 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
2410 status=SetQuantumFormat(image,quantum_info,FloatingPointQuantumFormat);
2411 if (status == MagickFalse)
2412 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
2413 pixels=GetQuantumPixels(quantum_info);
cristybb503372010-05-27 20:51:26 +00002414 for (y=(ssize_t) image->rows-1; y >= 0; y--)
cristy3ed852e2009-09-05 21:47:34 +00002415 {
cristy4c08aed2011-07-01 19:47:50 +00002416 register const Quantum
cristyc47d1f82009-11-26 01:44:43 +00002417 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +00002418
cristy1e178e72011-08-28 19:44:34 +00002419 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
cristy4c08aed2011-07-01 19:47:50 +00002420 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002421 break;
cristy4c08aed2011-07-01 19:47:50 +00002422 extent=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
cristy1e178e72011-08-28 19:44:34 +00002423 quantum_type,pixels,exception);
cristy3ed852e2009-09-05 21:47:34 +00002424 (void) WriteBlob(image,extent,pixels);
2425 if (image->previous == (Image *) NULL)
2426 {
cristycee97112010-05-28 00:44:52 +00002427 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
2428 image->rows);
cristy3ed852e2009-09-05 21:47:34 +00002429 if (status == MagickFalse)
2430 break;
2431 }
2432 }
2433 quantum_info=DestroyQuantumInfo(quantum_info);
2434 break;
2435 }
2436 }
2437 if (GetNextImageInList(image) == (Image *) NULL)
2438 break;
2439 image=SyncNextImageInList(image);
2440 status=SetImageProgress(image,SaveImagesTag,scene++,
2441 GetImageListLength(image));
2442 if (status == MagickFalse)
2443 break;
2444 } while (image_info->adjoin != MagickFalse);
2445 (void) CloseBlob(image);
2446 return(MagickTrue);
2447}