blob: 6a0290fe27ad07b0a3281782ebc42c0b90d16e2d [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% %
cristy7e41fe82010-12-04 23:12:08 +000020% Copyright 1999-2011 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*/
42#include "magick/studio.h"
43#include "magick/blob.h"
44#include "magick/blob-private.h"
45#include "magick/cache.h"
46#include "magick/color.h"
47#include "magick/color-private.h"
48#include "magick/colorspace.h"
49#include "magick/exception.h"
50#include "magick/exception-private.h"
51#include "magick/image.h"
52#include "magick/image-private.h"
53#include "magick/list.h"
54#include "magick/magick.h"
55#include "magick/memory_.h"
cristyf2f27272009-12-17 14:48:46 +000056#include "magick/module.h"
cristy3ed852e2009-09-05 21:47:34 +000057#include "magick/monitor.h"
58#include "magick/monitor-private.h"
59#include "magick/pixel-private.h"
60#include "magick/property.h"
61#include "magick/quantum-private.h"
62#include "magick/static.h"
63#include "magick/statistic.h"
64#include "magick/string_.h"
cristyf2f27272009-12-17 14:48:46 +000065#include "magick/string-private.h"
cristy3ed852e2009-09-05 21:47:34 +000066
67/*
68 Forward declarations.
69*/
70static MagickBooleanType
71 WritePNMImage(const ImageInfo *,Image *);
72
73/*
74%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
75% %
76% %
77% %
78% I s P N M %
79% %
80% %
81% %
82%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
83%
84% IsPNM() returns MagickTrue if the image format type, identified by the
85% magick string, is PNM.
86%
87% The format of the IsPNM method is:
88%
89% MagickBooleanType IsPNM(const unsigned char *magick,const size_t extent)
90%
91% A description of each parameter follows:
92%
93% o magick: compare image format pattern against these bytes.
94%
95% o extent: Specifies the extent of the magick string.
96%
97*/
98static MagickBooleanType IsPNM(const unsigned char *magick,const size_t extent)
99{
100 if (extent < 2)
101 return(MagickFalse);
102 if ((*magick == (unsigned char) 'P') &&
103 ((magick[1] == '1') || (magick[1] == '2') || (magick[1] == '3') ||
104 (magick[1] == '4') || (magick[1] == '5') || (magick[1] == '6') ||
105 (magick[1] == '7') || (magick[1] == 'F') || (magick[1] == 'f')))
106 return(MagickTrue);
107 return(MagickFalse);
108}
109
110/*
111%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
112% %
113% %
114% %
115% R e a d P N M I m a g e %
116% %
117% %
118% %
119%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
120%
121% ReadPNMImage() reads a Portable Anymap image file and returns it.
122% It allocates the memory necessary for the new Image structure and returns
123% a pointer to the new image.
124%
125% The format of the ReadPNMImage method is:
126%
127% Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception)
128%
129% A description of each parameter follows:
130%
131% o image_info: the image info.
132%
133% o exception: return any errors or warnings in this structure.
134%
135*/
136
cristybb503372010-05-27 20:51:26 +0000137static inline ssize_t ConstrainPixel(Image *image,const ssize_t offset,
138 const size_t extent)
cristy3ed852e2009-09-05 21:47:34 +0000139{
cristybb503372010-05-27 20:51:26 +0000140 if ((offset < 0) || (offset > (ssize_t) extent))
cristy3ed852e2009-09-05 21:47:34 +0000141 {
142 (void) ThrowMagickException(&image->exception,GetMagickModule(),
143 CorruptImageError,"InvalidPixel","`%s'",image->filename);
144 return(0);
145 }
146 return(offset);
147}
148
cristybb503372010-05-27 20:51:26 +0000149static size_t PNMInteger(Image *image,const unsigned int base)
cristy3ed852e2009-09-05 21:47:34 +0000150{
151 char
152 *comment;
153
154 int
155 c;
156
157 register char
158 *p;
159
160 size_t
161 extent;
162
cristybb503372010-05-27 20:51:26 +0000163 size_t
cristy3ed852e2009-09-05 21:47:34 +0000164 value;
165
166 /*
167 Skip any leading whitespace.
168 */
169 extent=MaxTextExtent;
170 comment=(char *) NULL;
171 p=comment;
172 do
173 {
174 c=ReadBlobByte(image);
175 if (c == EOF)
176 return(0);
177 if (c == (int) '#')
178 {
179 /*
180 Read comment.
181 */
182 if (comment == (char *) NULL)
183 comment=AcquireString((char *) NULL);
184 p=comment+strlen(comment);
185 for ( ; (c != EOF) && (c != (int) '\n'); p++)
186 {
187 if ((size_t) (p-comment+1) >= extent)
188 {
189 extent<<=1;
190 comment=(char *) ResizeQuantumMemory(comment,extent+MaxTextExtent,
191 sizeof(*comment));
192 if (comment == (char *) NULL)
193 break;
194 p=comment+strlen(comment);
195 }
196 c=ReadBlobByte(image);
197 *p=(char) c;
198 *(p+1)='\0';
199 }
200 if (comment == (char *) NULL)
201 return(0);
202 continue;
203 }
204 } while (isdigit(c) == MagickFalse);
205 if (comment != (char *) NULL)
206 {
207 (void) SetImageProperty(image,"comment",comment);
208 comment=DestroyString(comment);
209 }
210 if (base == 2)
cristybb503372010-05-27 20:51:26 +0000211 return((size_t) (c-(int) '0'));
cristy3ed852e2009-09-05 21:47:34 +0000212 /*
213 Evaluate number.
214 */
215 value=0;
216 do
217 {
218 value*=10;
219 value+=c-(int) '0';
220 c=ReadBlobByte(image);
221 if (c == EOF)
222 return(value);
223 } while (isdigit(c) != MagickFalse);
224 return(value);
225}
226
227static Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception)
228{
229 char
230 format;
231
232 double
233 quantum_scale;
234
235 Image
236 *image;
237
cristybb503372010-05-27 20:51:26 +0000238 ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000239 row,
240 y;
241
242 MagickBooleanType
243 status;
244
245 Quantum
246 *scale;
247
248 QuantumInfo
249 *quantum_info;
250
251 QuantumType
252 quantum_type;
253
cristybb503372010-05-27 20:51:26 +0000254 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000255 i;
256
257 size_t
258 extent,
259 packet_size;
260
261 ssize_t
262 count;
263
cristybb503372010-05-27 20:51:26 +0000264 size_t
cristy3ed852e2009-09-05 21:47:34 +0000265 depth,
266 max_value;
267
cristy3ed852e2009-09-05 21:47:34 +0000268 /*
269 Open image file.
270 */
271 assert(image_info != (const ImageInfo *) NULL);
272 assert(image_info->signature == MagickSignature);
273 if (image_info->debug != MagickFalse)
274 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
275 image_info->filename);
276 assert(exception != (ExceptionInfo *) NULL);
277 assert(exception->signature == MagickSignature);
278 image=AcquireImage(image_info);
279 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
280 if (status == MagickFalse)
281 {
282 image=DestroyImageList(image);
283 return((Image *) NULL);
284 }
285 /*
286 Read PNM image.
287 */
288 count=ReadBlob(image,1,(unsigned char *) &format);
289 do
290 {
291 /*
292 Initialize image structure.
293 */
294 if ((count != 1) || (format != 'P'))
295 ThrowReaderException(CorruptImageError,"ImproperImageHeader");
296 max_value=1;
297 quantum_type=RGBQuantum;
298 quantum_scale=1.0;
299 format=(char) ReadBlobByte(image);
300 if (format != '7')
301 {
302 /*
303 PBM, PGM, PPM, and PNM.
304 */
305 image->columns=PNMInteger(image,10);
306 image->rows=PNMInteger(image,10);
307 if ((format == 'f') || (format == 'F'))
308 {
309 char
310 scale[MaxTextExtent];
311
312 (void) ReadBlobString(image,scale);
cristyf2f27272009-12-17 14:48:46 +0000313 quantum_scale=StringToDouble(scale);
cristy3ed852e2009-09-05 21:47:34 +0000314 }
315 else
316 {
317 if ((format == '1') || (format == '4'))
318 max_value=1; /* bitmap */
319 else
320 max_value=PNMInteger(image,10);
321 }
322 }
323 else
324 {
325 char
326 keyword[MaxTextExtent],
327 value[MaxTextExtent];
328
329 int
330 c;
331
332 register char
333 *p;
334
335 /*
336 PAM.
337 */
338 for (c=ReadBlobByte(image); c != EOF; c=ReadBlobByte(image))
339 {
340 while (isspace((int) ((unsigned char) c)) != 0)
341 c=ReadBlobByte(image);
342 p=keyword;
343 do
344 {
345 if ((size_t) (p-keyword) < (MaxTextExtent-1))
346 *p++=c;
347 c=ReadBlobByte(image);
348 } while (isalnum(c));
349 *p='\0';
350 if (LocaleCompare(keyword,"endhdr") == 0)
351 break;
352 while (isspace((int) ((unsigned char) c)) != 0)
353 c=ReadBlobByte(image);
354 p=value;
355 while (isalnum(c) || (c == '_'))
356 {
357 if ((size_t) (p-value) < (MaxTextExtent-1))
358 *p++=c;
359 c=ReadBlobByte(image);
360 }
361 *p='\0';
362 /*
363 Assign a value to the specified keyword.
364 */
365 if (LocaleCompare(keyword,"depth") == 0)
cristye27293e2009-12-18 02:53:20 +0000366 packet_size=StringToUnsignedLong(value);
cristyda16f162011-02-19 23:52:17 +0000367 (void) packet_size;
cristy3ed852e2009-09-05 21:47:34 +0000368 if (LocaleCompare(keyword,"height") == 0)
cristye27293e2009-12-18 02:53:20 +0000369 image->rows=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +0000370 if (LocaleCompare(keyword,"maxval") == 0)
cristye27293e2009-12-18 02:53:20 +0000371 max_value=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +0000372 if (LocaleCompare(keyword,"TUPLTYPE") == 0)
373 {
374 if (LocaleCompare(value,"BLACKANDWHITE") == 0)
375 quantum_type=GrayQuantum;
376 if (LocaleCompare(value,"BLACKANDWHITE_ALPHA") == 0)
377 {
378 quantum_type=GrayAlphaQuantum;
379 image->matte=MagickTrue;
380 }
381 if (LocaleCompare(value,"GRAYSCALE") == 0)
382 quantum_type=GrayQuantum;
383 if (LocaleCompare(value,"GRAYSCALE_ALPHA") == 0)
384 {
385 quantum_type=GrayAlphaQuantum;
386 image->matte=MagickTrue;
387 }
388 if (LocaleCompare(value,"RGB_ALPHA") == 0)
389 {
390 quantum_type=RGBAQuantum;
391 image->matte=MagickTrue;
392 }
393 if (LocaleCompare(value,"CMYK") == 0)
394 {
395 quantum_type=CMYKQuantum;
396 image->colorspace=CMYKColorspace;
397 }
398 if (LocaleCompare(value,"CMYK_ALPHA") == 0)
399 {
400 quantum_type=CMYKAQuantum;
401 image->colorspace=CMYKColorspace;
402 image->matte=MagickTrue;
403 }
404 }
405 if (LocaleCompare(keyword,"width") == 0)
cristye27293e2009-12-18 02:53:20 +0000406 image->columns=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +0000407 }
408 }
409 if ((image->columns == 0) || (image->rows == 0))
410 ThrowReaderException(CorruptImageError,"NegativeOrZeroImageSize");
411 if (max_value >= 65536)
412 ThrowReaderException(CorruptImageError,"ImproperImageHeader");
413 for (depth=1; GetQuantumRange(depth) < max_value; depth++) ;
414 image->depth=depth;
415 if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
416 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
417 break;
418 /*
419 Convert PNM pixels to runextent-encoded MIFF packets.
420 */
421 status=MagickTrue;
422 row=0;
423 switch (format)
424 {
425 case '1':
426 {
427 /*
428 Convert PBM image to pixel packets.
429 */
cristybb503372010-05-27 20:51:26 +0000430 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +0000431 {
cristybb503372010-05-27 20:51:26 +0000432 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000433 x;
434
435 register PixelPacket
cristyc47d1f82009-11-26 01:44:43 +0000436 *restrict q;
cristy3ed852e2009-09-05 21:47:34 +0000437
438 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
439 if (q == (PixelPacket *) NULL)
440 break;
cristybb503372010-05-27 20:51:26 +0000441 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +0000442 {
443 q->red=(Quantum) (PNMInteger(image,2) == 0 ? QuantumRange : 0);
444 q->green=q->red;
445 q->blue=q->red;
446 q++;
447 }
448 if (SyncAuthenticPixels(image,exception) == MagickFalse)
449 break;
450 if (image->previous == (Image *) NULL)
451 {
cristycee97112010-05-28 00:44:52 +0000452 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
453 image->rows);
cristy3ed852e2009-09-05 21:47:34 +0000454 if (status == MagickFalse)
455 break;
456 }
457 }
458 image->type=BilevelType;
459 break;
460 }
461 case '2':
462 {
cristybb503372010-05-27 20:51:26 +0000463 size_t
cristy3ed852e2009-09-05 21:47:34 +0000464 intensity;
465
466 /*
467 Convert PGM image to pixel packets.
468 */
469 scale=(Quantum *) NULL;
470 if (max_value != (1U*QuantumRange))
471 {
472 /*
473 Compute pixel scaling table.
474 */
475 scale=(Quantum *) AcquireQuantumMemory((size_t) max_value+1UL,
476 sizeof(*scale));
477 if (scale == (Quantum *) NULL)
478 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
cristybb503372010-05-27 20:51:26 +0000479 for (i=0; i <= (ssize_t) max_value; i++)
cristy3ed852e2009-09-05 21:47:34 +0000480 scale[i]=(Quantum) (((double) QuantumRange*i)/max_value+0.5);
481 }
cristybb503372010-05-27 20:51:26 +0000482 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +0000483 {
cristybb503372010-05-27 20:51:26 +0000484 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000485 x;
486
487 register PixelPacket
cristyc47d1f82009-11-26 01:44:43 +0000488 *restrict q;
cristy3ed852e2009-09-05 21:47:34 +0000489
490 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
491 if (q == (PixelPacket *) NULL)
492 break;
cristybb503372010-05-27 20:51:26 +0000493 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +0000494 {
495 intensity=PNMInteger(image,10);
cristy3ed852e2009-09-05 21:47:34 +0000496 q->red=(Quantum) intensity;
cristyac23fd22010-05-11 14:48:58 +0000497 if (scale != (Quantum *) NULL)
cristybb503372010-05-27 20:51:26 +0000498 q->red=scale[ConstrainPixel(image,(ssize_t) intensity,max_value)];
cristy3ed852e2009-09-05 21:47:34 +0000499 q->green=q->red;
500 q->blue=q->red;
501 q++;
502 }
503 if (SyncAuthenticPixels(image,exception) == MagickFalse)
504 break;
505 if (image->previous == (Image *) NULL)
506 {
cristycee97112010-05-28 00:44:52 +0000507 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
508 image->rows);
cristy3ed852e2009-09-05 21:47:34 +0000509 if (status == MagickFalse)
510 break;
511 }
512 }
513 image->type=GrayscaleType;
514 if (scale != (Quantum *) NULL)
515 scale=(Quantum *) RelinquishMagickMemory(scale);
516 break;
517 }
518 case '3':
519 {
520 MagickPixelPacket
521 pixel;
522
523 /*
524 Convert PNM image to pixel packets.
525 */
526 scale=(Quantum *) NULL;
527 if (max_value != (1U*QuantumRange))
528 {
529 /*
530 Compute pixel scaling table.
531 */
532 scale=(Quantum *) AcquireQuantumMemory((size_t) max_value+1UL,
533 sizeof(*scale));
534 if (scale == (Quantum *) NULL)
535 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
cristybb503372010-05-27 20:51:26 +0000536 for (i=0; i <= (ssize_t) max_value; i++)
cristy3ed852e2009-09-05 21:47:34 +0000537 scale[i]=(Quantum) (((double) QuantumRange*i)/max_value+0.5);
538 }
cristybb503372010-05-27 20:51:26 +0000539 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +0000540 {
cristybb503372010-05-27 20:51:26 +0000541 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000542 x;
543
544 register PixelPacket
cristyc47d1f82009-11-26 01:44:43 +0000545 *restrict q;
cristy3ed852e2009-09-05 21:47:34 +0000546
547 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
548 if (q == (PixelPacket *) NULL)
549 break;
cristybb503372010-05-27 20:51:26 +0000550 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +0000551 {
552 pixel.red=(MagickRealType) PNMInteger(image,10);
553 pixel.green=(MagickRealType) PNMInteger(image,10);
554 pixel.blue=(MagickRealType) PNMInteger(image,10);
555 if (scale != (Quantum *) NULL)
556 {
cristybb503372010-05-27 20:51:26 +0000557 pixel.red=(MagickRealType) scale[ConstrainPixel(image,(ssize_t)
cristy3ed852e2009-09-05 21:47:34 +0000558 pixel.red,max_value)];
cristy34575212010-11-06 12:39:23 +0000559 pixel.green=(MagickRealType) scale[ConstrainPixel(image,
560 (ssize_t) pixel.green,max_value)];
cristybb503372010-05-27 20:51:26 +0000561 pixel.blue=(MagickRealType) scale[ConstrainPixel(image,(ssize_t)
cristy3ed852e2009-09-05 21:47:34 +0000562 pixel.blue,max_value)];
563 }
564 q->red=(Quantum) pixel.red;
565 q->green=(Quantum) pixel.green;
566 q->blue=(Quantum) pixel.blue;
567 q++;
568 }
569 if (SyncAuthenticPixels(image,exception) == MagickFalse)
570 break;
571 if (image->previous == (Image *) NULL)
572 {
cristycee97112010-05-28 00:44:52 +0000573 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
574 image->rows);
cristy3ed852e2009-09-05 21:47:34 +0000575 if (status == MagickFalse)
576 break;
577 }
578 }
579 if (scale != (Quantum *) NULL)
580 scale=(Quantum *) RelinquishMagickMemory(scale);
581 break;
582 }
583 case '4':
584 {
585 /*
586 Convert PBM raw image to pixel packets.
587 */
588 quantum_type=GrayQuantum;
589 if (image->storage_class == PseudoClass)
590 quantum_type=IndexQuantum;
591 quantum_info=AcquireQuantumInfo(image_info,image);
592 if (quantum_info == (QuantumInfo *) NULL)
593 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
594 SetQuantumMinIsWhite(quantum_info,MagickTrue);
595 extent=GetQuantumExtent(image,quantum_info,quantum_type);
cristybb503372010-05-27 20:51:26 +0000596 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +0000597 {
cristybb503372010-05-27 20:51:26 +0000598 ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000599 offset;
600
601 MagickBooleanType
602 sync;
603
604 register PixelPacket
cristyc47d1f82009-11-26 01:44:43 +0000605 *restrict q;
cristy3ed852e2009-09-05 21:47:34 +0000606
607 ssize_t
608 count;
609
610 size_t
611 length;
612
613 unsigned char
614 *pixels;
615
616 if (status == MagickFalse)
617 continue;
618 pixels=GetQuantumPixels(quantum_info);
cristy3ed852e2009-09-05 21:47:34 +0000619 {
620 count=ReadBlob(image,extent,pixels);
621 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
622 (image->previous == (Image *) NULL))
623 {
624 MagickBooleanType
625 proceed;
626
cristycee97112010-05-28 00:44:52 +0000627 proceed=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
628 row,image->rows);
cristy3ed852e2009-09-05 21:47:34 +0000629 if (proceed == MagickFalse)
630 status=MagickFalse;
631 }
632 offset=row++;
633 }
634 if (count != (ssize_t) extent)
635 status=MagickFalse;
cristyaa740112010-03-30 17:58:44 +0000636 q=QueueAuthenticPixels(image,0,offset,image->columns,1,exception);
cristy3ed852e2009-09-05 21:47:34 +0000637 if (q == (PixelPacket *) NULL)
638 {
639 status=MagickFalse;
640 continue;
641 }
cristyaa740112010-03-30 17:58:44 +0000642 length=ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
643 quantum_type,pixels,exception);
cristy3ed852e2009-09-05 21:47:34 +0000644 if (length != extent)
645 status=MagickFalse;
cristyaa740112010-03-30 17:58:44 +0000646 sync=SyncAuthenticPixels(image,exception);
cristy3ed852e2009-09-05 21:47:34 +0000647 if (sync == MagickFalse)
648 status=MagickFalse;
649 }
cristy3ed852e2009-09-05 21:47:34 +0000650 quantum_info=DestroyQuantumInfo(quantum_info);
651 if (status == MagickFalse)
652 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
653 SetQuantumImageType(image,quantum_type);
654 break;
655 }
656 case '5':
657 {
658 QuantumAny
659 range;
660
661 /*
662 Convert PGM raw image to pixel packets.
663 */
664 range=GetQuantumRange(image->depth);
665 quantum_type=GrayQuantum;
666 extent=(image->depth <= 8 ? 1 : 2)*image->columns;
667 quantum_info=AcquireQuantumInfo(image_info,image);
668 if (quantum_info == (QuantumInfo *) NULL)
669 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
cristybb503372010-05-27 20:51:26 +0000670 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +0000671 {
cristybb503372010-05-27 20:51:26 +0000672 ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000673 offset;
674
675 MagickBooleanType
676 sync;
677
678 register const unsigned char
cristy3f2302b2010-03-11 03:16:37 +0000679 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +0000680
cristybb503372010-05-27 20:51:26 +0000681 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000682 x;
683
684 register PixelPacket
cristyc47d1f82009-11-26 01:44:43 +0000685 *restrict q;
cristy3ed852e2009-09-05 21:47:34 +0000686
687 ssize_t
688 count;
689
690 unsigned char
691 *pixels;
692
693 if (status == MagickFalse)
694 continue;
695 pixels=GetQuantumPixels(quantum_info);
cristy3ed852e2009-09-05 21:47:34 +0000696 {
697 count=ReadBlob(image,extent,pixels);
698 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
699 (image->previous == (Image *) NULL))
700 {
701 MagickBooleanType
702 proceed;
703
cristy34575212010-11-06 12:39:23 +0000704 proceed=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
705 row,image->rows);
cristy3ed852e2009-09-05 21:47:34 +0000706 if (proceed == MagickFalse)
707 status=MagickFalse;
708 }
709 offset=row++;
710 }
711 if (count != (ssize_t) extent)
712 status=MagickFalse;
cristyaa740112010-03-30 17:58:44 +0000713 q=QueueAuthenticPixels(image,0,offset,image->columns,1,exception);
cristy3ed852e2009-09-05 21:47:34 +0000714 if (q == (PixelPacket *) NULL)
715 {
716 status=MagickFalse;
717 continue;
718 }
719 p=pixels;
720 if ((image->depth == 8) || (image->depth == 16))
cristyaa740112010-03-30 17:58:44 +0000721 (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
cristy3ed852e2009-09-05 21:47:34 +0000722 quantum_type,pixels,exception);
723 else
724 if (image->depth <= 8)
725 {
726 unsigned char
727 pixel;
728
cristybb503372010-05-27 20:51:26 +0000729 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +0000730 {
731 p=PushCharPixel(p,&pixel);
cristyce70c172010-01-07 17:15:30 +0000732 SetRedPixelComponent(q,ScaleAnyToQuantum(pixel,range));
cristy3ed852e2009-09-05 21:47:34 +0000733 q->green=q->red;
734 q->blue=q->red;
735 q++;
736 }
737 }
738 else
739 {
740 unsigned short
741 pixel;
742
cristybb503372010-05-27 20:51:26 +0000743 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +0000744 {
745 p=PushShortPixel(MSBEndian,p,&pixel);
cristyce70c172010-01-07 17:15:30 +0000746 SetRedPixelComponent(q,ScaleAnyToQuantum(pixel,range));
cristy3ed852e2009-09-05 21:47:34 +0000747 q->green=q->red;
748 q->blue=q->red;
749 q++;
750 }
751 }
cristyaa740112010-03-30 17:58:44 +0000752 sync=SyncAuthenticPixels(image,exception);
cristy3ed852e2009-09-05 21:47:34 +0000753 if (sync == MagickFalse)
754 status=MagickFalse;
755 }
cristy3ed852e2009-09-05 21:47:34 +0000756 quantum_info=DestroyQuantumInfo(quantum_info);
757 if (status == MagickFalse)
758 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
759 SetQuantumImageType(image,quantum_type);
760 break;
761 }
762 case '6':
763 {
764 ImageType
765 type;
766
767 QuantumAny
768 range;
769
770 /*
771 Convert PNM raster image to pixel packets.
772 */
773 type=BilevelType;
774 quantum_type=RGBQuantum;
775 extent=3*(image->depth <= 8 ? 1 : 2)*image->columns;
776 range=GetQuantumRange(image->depth);
777 quantum_info=AcquireQuantumInfo(image_info,image);
778 if (quantum_info == (QuantumInfo *) NULL)
779 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
cristybb503372010-05-27 20:51:26 +0000780 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +0000781 {
cristybb503372010-05-27 20:51:26 +0000782 ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000783 offset;
784
785 MagickBooleanType
786 sync;
787
788 register const unsigned char
cristy3f2302b2010-03-11 03:16:37 +0000789 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +0000790
cristybb503372010-05-27 20:51:26 +0000791 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000792 x;
793
794 register PixelPacket
cristyc47d1f82009-11-26 01:44:43 +0000795 *restrict q;
cristy3ed852e2009-09-05 21:47:34 +0000796
797 ssize_t
798 count;
799
cristy3ed852e2009-09-05 21:47:34 +0000800 unsigned char
801 *pixels;
802
803 if (status == MagickFalse)
804 continue;
805 pixels=GetQuantumPixels(quantum_info);
cristy3ed852e2009-09-05 21:47:34 +0000806 {
807 count=ReadBlob(image,extent,pixels);
808 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
809 (image->previous == (Image *) NULL))
810 {
811 MagickBooleanType
812 proceed;
813
cristy34575212010-11-06 12:39:23 +0000814 proceed=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
815 row,image->rows);
cristy3ed852e2009-09-05 21:47:34 +0000816 if (proceed == MagickFalse)
817 status=MagickFalse;
818 }
819 offset=row++;
820 }
821 if (count != (ssize_t) extent)
822 status=MagickFalse;
cristyaa740112010-03-30 17:58:44 +0000823 q=QueueAuthenticPixels(image,0,offset,image->columns,1,exception);
cristy3ed852e2009-09-05 21:47:34 +0000824 if (q == (PixelPacket *) NULL)
825 {
826 status=MagickFalse;
827 continue;
828 }
829 p=pixels;
cristye90d7402010-03-14 18:21:29 +0000830 if (image->depth == 8)
cristybb503372010-05-27 20:51:26 +0000831 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +0000832 {
cristye90d7402010-03-14 18:21:29 +0000833 q->red=ScaleCharToQuantum(*p++);
834 q->green=ScaleCharToQuantum(*p++);
835 q->blue=ScaleCharToQuantum(*p++);
836 q->opacity=OpaqueOpacity;
837 q++;
cristy3ed852e2009-09-05 21:47:34 +0000838 }
839 else
cristye90d7402010-03-14 18:21:29 +0000840 if (image->depth == 16)
cristy3ed852e2009-09-05 21:47:34 +0000841 {
842 unsigned short
843 pixel;
844
cristybb503372010-05-27 20:51:26 +0000845 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +0000846 {
847 p=PushShortPixel(MSBEndian,p,&pixel);
cristye90d7402010-03-14 18:21:29 +0000848 q->red=ScaleShortToQuantum(pixel);
cristy3ed852e2009-09-05 21:47:34 +0000849 p=PushShortPixel(MSBEndian,p,&pixel);
cristye90d7402010-03-14 18:21:29 +0000850 q->green=ScaleShortToQuantum(pixel);
cristy3ed852e2009-09-05 21:47:34 +0000851 p=PushShortPixel(MSBEndian,p,&pixel);
cristye90d7402010-03-14 18:21:29 +0000852 q->blue=ScaleShortToQuantum(pixel);
853 q->opacity=OpaqueOpacity;
854 q++;
cristy3ed852e2009-09-05 21:47:34 +0000855 }
856 }
cristye90d7402010-03-14 18:21:29 +0000857 else
858 if (image->depth <= 8)
859 {
860 unsigned char
861 pixel;
862
cristybb503372010-05-27 20:51:26 +0000863 for (x=0; x < (ssize_t) image->columns; x++)
cristye90d7402010-03-14 18:21:29 +0000864 {
865 p=PushCharPixel(p,&pixel);
866 q->red=ScaleAnyToQuantum(pixel,range);
867 p=PushCharPixel(p,&pixel);
868 q->green=ScaleAnyToQuantum(pixel,range);
869 p=PushCharPixel(p,&pixel);
870 q->blue=ScaleAnyToQuantum(pixel,range);
871 q->opacity=OpaqueOpacity;
872 q++;
873 }
874 }
875 else
876 {
877 unsigned short
878 pixel;
879
cristybb503372010-05-27 20:51:26 +0000880 for (x=0; x < (ssize_t) image->columns; x++)
cristye90d7402010-03-14 18:21:29 +0000881 {
882 p=PushShortPixel(MSBEndian,p,&pixel);
883 q->red=ScaleAnyToQuantum(pixel,range);
884 p=PushShortPixel(MSBEndian,p,&pixel);
885 q->green=ScaleAnyToQuantum(pixel,range);
886 p=PushShortPixel(MSBEndian,p,&pixel);
887 q->blue=ScaleAnyToQuantum(pixel,range);
888 q->opacity=OpaqueOpacity;
889 q++;
890 }
891 }
cristy3ed852e2009-09-05 21:47:34 +0000892 if ((type == BilevelType) || (type == GrayscaleType))
cristy3ed852e2009-09-05 21:47:34 +0000893 {
cristyaa740112010-03-30 17:58:44 +0000894 q=QueueAuthenticPixels(image,0,offset,image->columns,1,exception);
cristybb503372010-05-27 20:51:26 +0000895 for (x=0; x < (ssize_t) image->columns; x++)
cristye90d7402010-03-14 18:21:29 +0000896 {
897 if ((type == BilevelType) &&
898 (IsMonochromePixel(q) == MagickFalse))
cristy5f1c1ff2010-12-23 21:38:06 +0000899 type=IsGrayPixel(q) == MagickFalse ? UndefinedType :
cristye90d7402010-03-14 18:21:29 +0000900 GrayscaleType;
901 if ((type == GrayscaleType) && (IsGrayPixel(q) == MagickFalse))
cristy5f1c1ff2010-12-23 21:38:06 +0000902 type=UndefinedType;
cristye90d7402010-03-14 18:21:29 +0000903 if ((type != BilevelType) && (type != GrayscaleType))
904 break;
905 q++;
906 }
cristy3ed852e2009-09-05 21:47:34 +0000907 }
cristyaa740112010-03-30 17:58:44 +0000908 sync=SyncAuthenticPixels(image,exception);
cristy3ed852e2009-09-05 21:47:34 +0000909 if (sync == MagickFalse)
910 status=MagickFalse;
911 }
cristy3ed852e2009-09-05 21:47:34 +0000912 quantum_info=DestroyQuantumInfo(quantum_info);
913 if (status == MagickFalse)
914 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
cristy5f1c1ff2010-12-23 21:38:06 +0000915 if (type != UndefinedType)
cristy3ed852e2009-09-05 21:47:34 +0000916 image->type=type;
917 break;
918 }
919 case '7':
920 {
921 register IndexPacket
922 *indexes;
923
924 QuantumAny
925 range;
926
cristybb503372010-05-27 20:51:26 +0000927 size_t
cristy3ed852e2009-09-05 21:47:34 +0000928 channels;
929
930 /*
931 Convert PAM raster image to pixel packets.
932 */
933 range=GetQuantumRange(image->depth);
934 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 }
954 if (image->matte != MagickFalse)
955 channels++;
956 extent=channels*(image->depth <= 8 ? 1 : 2)*image->columns;
957 quantum_info=AcquireQuantumInfo(image_info,image);
958 if (quantum_info == (QuantumInfo *) NULL)
959 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
cristybb503372010-05-27 20:51:26 +0000960 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +0000961 {
cristybb503372010-05-27 20:51:26 +0000962 ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000963 offset;
964
965 MagickBooleanType
966 sync;
967
968 register const unsigned char
cristy3f2302b2010-03-11 03:16:37 +0000969 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +0000970
cristybb503372010-05-27 20:51:26 +0000971 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000972 x;
973
974 register PixelPacket
cristyc47d1f82009-11-26 01:44:43 +0000975 *restrict q;
cristy3ed852e2009-09-05 21:47:34 +0000976
977 ssize_t
978 count;
979
980 unsigned char
981 *pixels;
982
983 if (status == MagickFalse)
984 continue;
985 pixels=GetQuantumPixels(quantum_info);
cristy3ed852e2009-09-05 21:47:34 +0000986 {
987 count=ReadBlob(image,extent,pixels);
988 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
989 (image->previous == (Image *) NULL))
990 {
991 MagickBooleanType
992 proceed;
993
cristy34575212010-11-06 12:39:23 +0000994 proceed=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
995 row,image->rows);
cristy3ed852e2009-09-05 21:47:34 +0000996 if (proceed == MagickFalse)
997 status=MagickFalse;
998 }
999 offset=row++;
1000 }
1001 if (count != (ssize_t) extent)
1002 status=MagickFalse;
cristyaa740112010-03-30 17:58:44 +00001003 q=QueueAuthenticPixels(image,0,offset,image->columns,1,exception);
cristy3ed852e2009-09-05 21:47:34 +00001004 if (q == (PixelPacket *) NULL)
1005 {
1006 status=MagickFalse;
1007 continue;
1008 }
cristyaa740112010-03-30 17:58:44 +00001009 indexes=GetAuthenticIndexQueue(image);
cristy3ed852e2009-09-05 21:47:34 +00001010 p=pixels;
1011 if ((image->depth == 8) || (image->depth == 16))
cristyaa740112010-03-30 17:58:44 +00001012 (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
cristy3ed852e2009-09-05 21:47:34 +00001013 quantum_type,pixels,exception);
1014 else
1015 switch (quantum_type)
1016 {
1017 case GrayQuantum:
1018 case GrayAlphaQuantum:
1019 {
1020 if (image->depth <= 8)
1021 {
1022 unsigned char
1023 pixel;
1024
cristybb503372010-05-27 20:51:26 +00001025 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00001026 {
1027 p=PushCharPixel(p,&pixel);
cristyce70c172010-01-07 17:15:30 +00001028 SetRedPixelComponent(q,ScaleAnyToQuantum(pixel,range));
cristy3ed852e2009-09-05 21:47:34 +00001029 q->green=q->red;
1030 q->blue=q->red;
cristyce70c172010-01-07 17:15:30 +00001031 SetOpacityPixelComponent(q,OpaqueOpacity);
cristy3ed852e2009-09-05 21:47:34 +00001032 if (image->matte != MagickFalse)
1033 {
1034 p=PushCharPixel(p,&pixel);
cristy34575212010-11-06 12:39:23 +00001035 SetOpacityPixelComponent(q,ScaleAnyToQuantum(pixel,
1036 range));
cristy3ed852e2009-09-05 21:47:34 +00001037 }
1038 q++;
1039 }
1040 }
1041 else
1042 {
1043 unsigned short
1044 pixel;
1045
cristybb503372010-05-27 20:51:26 +00001046 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00001047 {
1048 p=PushShortPixel(MSBEndian,p,&pixel);
cristyce70c172010-01-07 17:15:30 +00001049 SetRedPixelComponent(q,ScaleAnyToQuantum(pixel,range));
cristy3ed852e2009-09-05 21:47:34 +00001050 q->green=q->red;
1051 q->blue=q->red;
cristyce70c172010-01-07 17:15:30 +00001052 SetOpacityPixelComponent(q,OpaqueOpacity);
cristy3ed852e2009-09-05 21:47:34 +00001053 if (image->matte != MagickFalse)
1054 {
1055 p=PushShortPixel(MSBEndian,p,&pixel);
cristy34575212010-11-06 12:39:23 +00001056 SetOpacityPixelComponent(q,ScaleAnyToQuantum(pixel,
1057 range));
cristy3ed852e2009-09-05 21:47:34 +00001058 }
1059 q++;
1060 }
1061 }
1062 break;
1063 }
1064 case CMYKQuantum:
1065 case CMYKAQuantum:
1066 {
1067 if (image->depth <= 8)
1068 {
1069 unsigned char
1070 pixel;
1071
cristybb503372010-05-27 20:51:26 +00001072 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00001073 {
1074 p=PushCharPixel(p,&pixel);
cristyce70c172010-01-07 17:15:30 +00001075 SetRedPixelComponent(q,ScaleAnyToQuantum(pixel,range));
cristy3ed852e2009-09-05 21:47:34 +00001076 p=PushCharPixel(p,&pixel);
cristyce70c172010-01-07 17:15:30 +00001077 SetGreenPixelComponent(q,ScaleAnyToQuantum(pixel,range));
cristy3ed852e2009-09-05 21:47:34 +00001078 p=PushCharPixel(p,&pixel);
cristyce70c172010-01-07 17:15:30 +00001079 SetBluePixelComponent(q,ScaleAnyToQuantum(pixel,range));
cristy3ed852e2009-09-05 21:47:34 +00001080 p=PushCharPixel(p,&pixel);
1081 indexes[x]=ScaleAnyToQuantum(pixel,range);
cristyce70c172010-01-07 17:15:30 +00001082 SetOpacityPixelComponent(q,OpaqueOpacity);
cristy3ed852e2009-09-05 21:47:34 +00001083 if (image->matte != MagickFalse)
1084 {
1085 p=PushCharPixel(p,&pixel);
cristy34575212010-11-06 12:39:23 +00001086 SetOpacityPixelComponent(q,ScaleAnyToQuantum(pixel,
1087 range));
cristy3ed852e2009-09-05 21:47:34 +00001088 }
1089 q++;
1090 }
1091 }
1092 else
1093 {
1094 unsigned short
1095 pixel;
1096
cristybb503372010-05-27 20:51:26 +00001097 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00001098 {
1099 p=PushShortPixel(MSBEndian,p,&pixel);
cristyce70c172010-01-07 17:15:30 +00001100 SetRedPixelComponent(q,ScaleAnyToQuantum(pixel,range));
cristy3ed852e2009-09-05 21:47:34 +00001101 p=PushShortPixel(MSBEndian,p,&pixel);
cristyce70c172010-01-07 17:15:30 +00001102 SetGreenPixelComponent(q,ScaleAnyToQuantum(pixel,range));
cristy3ed852e2009-09-05 21:47:34 +00001103 p=PushShortPixel(MSBEndian,p,&pixel);
cristyce70c172010-01-07 17:15:30 +00001104 SetBluePixelComponent(q,ScaleAnyToQuantum(pixel,range));
cristy3ed852e2009-09-05 21:47:34 +00001105 p=PushShortPixel(MSBEndian,p,&pixel);
1106 indexes[x]=ScaleAnyToQuantum(pixel,range);
cristyce70c172010-01-07 17:15:30 +00001107 SetOpacityPixelComponent(q,OpaqueOpacity);
cristy3ed852e2009-09-05 21:47:34 +00001108 if (image->matte != MagickFalse)
1109 {
1110 p=PushShortPixel(MSBEndian,p,&pixel);
cristy34575212010-11-06 12:39:23 +00001111 SetOpacityPixelComponent(q,ScaleAnyToQuantum(pixel,
1112 range));
cristy3ed852e2009-09-05 21:47:34 +00001113 }
1114 q++;
1115 }
1116 }
1117 break;
1118 }
1119 default:
1120 {
1121 if (image->depth <= 8)
1122 {
1123 unsigned char
1124 pixel;
1125
cristybb503372010-05-27 20:51:26 +00001126 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00001127 {
1128 p=PushCharPixel(p,&pixel);
cristyce70c172010-01-07 17:15:30 +00001129 SetRedPixelComponent(q,ScaleAnyToQuantum(pixel,range));
cristy3ed852e2009-09-05 21:47:34 +00001130 p=PushCharPixel(p,&pixel);
cristyce70c172010-01-07 17:15:30 +00001131 SetGreenPixelComponent(q,ScaleAnyToQuantum(pixel,range));
cristy3ed852e2009-09-05 21:47:34 +00001132 p=PushCharPixel(p,&pixel);
cristyce70c172010-01-07 17:15:30 +00001133 SetBluePixelComponent(q,ScaleAnyToQuantum(pixel,range));
1134 SetOpacityPixelComponent(q,OpaqueOpacity);
cristy3ed852e2009-09-05 21:47:34 +00001135 if (image->matte != MagickFalse)
1136 {
1137 p=PushCharPixel(p,&pixel);
cristy34575212010-11-06 12:39:23 +00001138 SetOpacityPixelComponent(q,ScaleAnyToQuantum(pixel,
1139 range));
cristy3ed852e2009-09-05 21:47:34 +00001140 }
1141 q++;
1142 }
1143 }
1144 else
1145 {
1146 unsigned short
1147 pixel;
1148
cristybb503372010-05-27 20:51:26 +00001149 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00001150 {
1151 p=PushShortPixel(MSBEndian,p,&pixel);
cristyce70c172010-01-07 17:15:30 +00001152 SetRedPixelComponent(q,ScaleAnyToQuantum(pixel,range));
cristy3ed852e2009-09-05 21:47:34 +00001153 p=PushShortPixel(MSBEndian,p,&pixel);
cristyce70c172010-01-07 17:15:30 +00001154 SetGreenPixelComponent(q,ScaleAnyToQuantum(pixel,range));
cristy3ed852e2009-09-05 21:47:34 +00001155 p=PushShortPixel(MSBEndian,p,&pixel);
cristyce70c172010-01-07 17:15:30 +00001156 SetBluePixelComponent(q,ScaleAnyToQuantum(pixel,range));
1157 SetOpacityPixelComponent(q,OpaqueOpacity);
cristy3ed852e2009-09-05 21:47:34 +00001158 if (image->matte != MagickFalse)
1159 {
1160 p=PushShortPixel(MSBEndian,p,&pixel);
cristy34575212010-11-06 12:39:23 +00001161 SetOpacityPixelComponent(q,ScaleAnyToQuantum(pixel,
1162 range));
cristy3ed852e2009-09-05 21:47:34 +00001163 }
1164 q++;
1165 }
1166 }
1167 break;
1168 }
1169 }
cristyaa740112010-03-30 17:58:44 +00001170 sync=SyncAuthenticPixels(image,exception);
cristy3ed852e2009-09-05 21:47:34 +00001171 if (sync == MagickFalse)
1172 status=MagickFalse;
1173 }
cristy3ed852e2009-09-05 21:47:34 +00001174 quantum_info=DestroyQuantumInfo(quantum_info);
1175 if (status == MagickFalse)
1176 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
1177 SetQuantumImageType(image,quantum_type);
1178 break;
1179 }
1180 case 'F':
1181 case 'f':
1182 {
1183 /*
1184 Convert PFM raster image to pixel packets.
1185 */
1186 quantum_type=format == 'f' ? GrayQuantum : RGBQuantum;
1187 image->endian=quantum_scale < 0.0 ? LSBEndian : MSBEndian;
1188 image->depth=32;
1189 quantum_info=AcquireQuantumInfo(image_info,image);
1190 if (quantum_info == (QuantumInfo *) NULL)
1191 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
1192 status=SetQuantumDepth(image,quantum_info,32);
1193 if (status == MagickFalse)
1194 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
1195 status=SetQuantumFormat(image,quantum_info,FloatingPointQuantumFormat);
1196 if (status == MagickFalse)
1197 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
1198 SetQuantumScale(quantum_info,(MagickRealType) QuantumRange*
1199 fabs(quantum_scale));
1200 extent=GetQuantumExtent(image,quantum_info,quantum_type);
cristybb503372010-05-27 20:51:26 +00001201 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +00001202 {
cristybb503372010-05-27 20:51:26 +00001203 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001204 offset;
1205
1206 MagickBooleanType
1207 sync;
1208
1209 register PixelPacket
cristyc47d1f82009-11-26 01:44:43 +00001210 *restrict q;
cristy3ed852e2009-09-05 21:47:34 +00001211
1212 ssize_t
1213 count;
1214
1215 size_t
1216 length;
1217
1218 unsigned char
1219 *pixels;
1220
1221 if (status == MagickFalse)
1222 continue;
1223 pixels=GetQuantumPixels(quantum_info);
cristy3ed852e2009-09-05 21:47:34 +00001224 {
1225 count=ReadBlob(image,extent,pixels);
1226 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
1227 (image->previous == (Image *) NULL))
1228 {
1229 MagickBooleanType
1230 proceed;
1231
cristy34575212010-11-06 12:39:23 +00001232 proceed=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
1233 row,image->rows);
cristy3ed852e2009-09-05 21:47:34 +00001234 if (proceed == MagickFalse)
1235 status=MagickFalse;
1236 }
1237 offset=row++;
1238 }
1239 if ((size_t) count != extent)
1240 status=MagickFalse;
cristybb503372010-05-27 20:51:26 +00001241 q=QueueAuthenticPixels(image,0,(ssize_t) (image->rows-offset-1),
cristyaa740112010-03-30 17:58:44 +00001242 image->columns,1,exception);
cristy3ed852e2009-09-05 21:47:34 +00001243 if (q == (PixelPacket *) NULL)
1244 {
1245 status=MagickFalse;
1246 continue;
1247 }
cristyaa740112010-03-30 17:58:44 +00001248 length=ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1249 quantum_type,pixels,exception);
cristy3ed852e2009-09-05 21:47:34 +00001250 if (length != extent)
1251 status=MagickFalse;
cristyaa740112010-03-30 17:58:44 +00001252 sync=SyncAuthenticPixels(image,exception);
cristy3ed852e2009-09-05 21:47:34 +00001253 if (sync == MagickFalse)
1254 status=MagickFalse;
1255 }
cristy3ed852e2009-09-05 21:47:34 +00001256 quantum_info=DestroyQuantumInfo(quantum_info);
1257 if (status == MagickFalse)
1258 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
1259 SetQuantumImageType(image,quantum_type);
1260 break;
1261 }
1262 default:
1263 ThrowReaderException(CorruptImageError,"ImproperImageHeader");
1264 }
1265 if (EOFBlob(image) != MagickFalse)
1266 (void) ThrowMagickException(exception,GetMagickModule(),CorruptImageError,
1267 "UnexpectedEndOfFile","`%s'",image->filename);
1268 /*
1269 Proceed to next image.
1270 */
1271 if (image_info->number_scenes != 0)
1272 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
1273 break;
1274 if ((format == '1') || (format == '2') || (format == '3'))
1275 do
1276 {
1277 /*
1278 Skip to end of line.
1279 */
1280 count=ReadBlob(image,1,(unsigned char *) &format);
1281 if (count == 0)
1282 break;
1283 if ((count != 0) && (format == 'P'))
1284 break;
1285 } while (format != '\n');
1286 count=ReadBlob(image,1,(unsigned char *) &format);
1287 if ((count == 1) && (format == 'P'))
1288 {
1289 /*
1290 Allocate next image structure.
1291 */
1292 AcquireNextImage(image_info,image);
1293 if (GetNextImageInList(image) == (Image *) NULL)
1294 {
1295 image=DestroyImageList(image);
1296 return((Image *) NULL);
1297 }
1298 image=SyncNextImageInList(image);
1299 status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
1300 GetBlobSize(image));
1301 if (status == MagickFalse)
1302 break;
1303 }
1304 } while ((count == 1) && (format == 'P'));
1305 (void) CloseBlob(image);
1306 return(GetFirstImageInList(image));
1307}
1308
1309/*
1310%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1311% %
1312% %
1313% %
1314% R e g i s t e r P N M I m a g e %
1315% %
1316% %
1317% %
1318%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1319%
1320% RegisterPNMImage() adds properties for the PNM image format to
1321% the list of supported formats. The properties include the image format
1322% tag, a method to read and/or write the format, whether the format
1323% supports the saving of more than one frame to the same file or blob,
1324% whether the format supports native in-memory I/O, and a brief
1325% description of the format.
1326%
1327% The format of the RegisterPNMImage method is:
1328%
cristybb503372010-05-27 20:51:26 +00001329% size_t RegisterPNMImage(void)
cristy3ed852e2009-09-05 21:47:34 +00001330%
1331*/
cristybb503372010-05-27 20:51:26 +00001332ModuleExport size_t RegisterPNMImage(void)
cristy3ed852e2009-09-05 21:47:34 +00001333{
1334 MagickInfo
1335 *entry;
1336
1337 entry=SetMagickInfo("PAM");
1338 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1339 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1340 entry->description=ConstantString("Common 2-dimensional bitmap format");
1341 entry->module=ConstantString("PNM");
1342 (void) RegisterMagickInfo(entry);
1343 entry=SetMagickInfo("PBM");
1344 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1345 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1346 entry->description=ConstantString("Portable bitmap format (black and white)");
1347 entry->module=ConstantString("PNM");
1348 (void) RegisterMagickInfo(entry);
1349 entry=SetMagickInfo("PFM");
1350 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1351 entry->encoder=(EncodeImageHandler *) WritePNMImage;
cristye96405a2010-05-19 02:24:31 +00001352 entry->endian_support=MagickTrue;
cristy3ed852e2009-09-05 21:47:34 +00001353 entry->description=ConstantString("Portable float format");
1354 entry->module=ConstantString("PFM");
1355 (void) RegisterMagickInfo(entry);
1356 entry=SetMagickInfo("PGM");
1357 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1358 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1359 entry->description=ConstantString("Portable graymap format (gray scale)");
1360 entry->module=ConstantString("PNM");
1361 (void) RegisterMagickInfo(entry);
1362 entry=SetMagickInfo("PNM");
1363 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1364 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1365 entry->magick=(IsImageFormatHandler *) IsPNM;
1366 entry->description=ConstantString("Portable anymap");
1367 entry->module=ConstantString("PNM");
1368 (void) RegisterMagickInfo(entry);
1369 entry=SetMagickInfo("PPM");
1370 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1371 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1372 entry->description=ConstantString("Portable pixmap format (color)");
1373 entry->module=ConstantString("PNM");
1374 (void) RegisterMagickInfo(entry);
1375 return(MagickImageCoderSignature);
1376}
1377
1378/*
1379%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1380% %
1381% %
1382% %
1383% U n r e g i s t e r P N M I m a g e %
1384% %
1385% %
1386% %
1387%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1388%
1389% UnregisterPNMImage() removes format registrations made by the
1390% PNM module from the list of supported formats.
1391%
1392% The format of the UnregisterPNMImage method is:
1393%
1394% UnregisterPNMImage(void)
1395%
1396*/
1397ModuleExport void UnregisterPNMImage(void)
1398{
1399 (void) UnregisterMagickInfo("PAM");
1400 (void) UnregisterMagickInfo("PBM");
1401 (void) UnregisterMagickInfo("PGM");
1402 (void) UnregisterMagickInfo("PNM");
1403 (void) UnregisterMagickInfo("PPM");
1404}
1405
1406/*
1407%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1408% %
1409% %
1410% %
1411% W r i t e P N M I m a g e %
1412% %
1413% %
1414% %
1415%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1416%
cristy661b5ad2010-01-13 00:54:42 +00001417% WritePNMImage() writes an image to a file in the PNM rasterfile format.
cristy3ed852e2009-09-05 21:47:34 +00001418%
1419% The format of the WritePNMImage method is:
1420%
1421% MagickBooleanType WritePNMImage(const ImageInfo *image_info,Image *image)
1422%
1423% A description of each parameter follows.
1424%
1425% o image_info: the image info.
1426%
1427% o image: The image.
1428%
1429*/
1430static MagickBooleanType WritePNMImage(const ImageInfo *image_info,Image *image)
1431{
1432 char
1433 buffer[MaxTextExtent],
1434 format,
1435 magick[MaxTextExtent];
1436
1437 const char
1438 *value;
1439
1440 IndexPacket
1441 index;
1442
cristybb503372010-05-27 20:51:26 +00001443 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001444 y;
1445
1446 MagickBooleanType
1447 status;
1448
1449 MagickOffsetType
1450 scene;
1451
1452 QuantumAny
1453 pixel;
1454
1455 QuantumInfo
1456 *quantum_info;
1457
1458 QuantumType
1459 quantum_type;
1460
cristy3ed852e2009-09-05 21:47:34 +00001461 register unsigned char
1462 *pixels,
1463 *q;
1464
cristy3ed852e2009-09-05 21:47:34 +00001465 size_t
1466 extent,
1467 packet_size;
1468
cristy95802a72010-09-05 19:07:17 +00001469 ssize_t
1470 count;
1471
cristy3ed852e2009-09-05 21:47:34 +00001472 /*
1473 Open output image file.
1474 */
1475 assert(image_info != (const ImageInfo *) NULL);
1476 assert(image_info->signature == MagickSignature);
1477 assert(image != (Image *) NULL);
1478 assert(image->signature == MagickSignature);
1479 if (image->debug != MagickFalse)
1480 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1481 status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
1482 if (status == MagickFalse)
1483 return(status);
1484 scene=0;
1485 do
1486 {
1487 /*
1488 Write PNM file header.
1489 */
1490 packet_size=3;
1491 quantum_type=RGBQuantum;
1492 (void) CopyMagickString(magick,image_info->magick,MaxTextExtent);
1493 switch (magick[1])
1494 {
1495 case 'A':
1496 case 'a':
1497 {
1498 format='7';
1499 break;
1500 }
1501 case 'B':
1502 case 'b':
1503 {
1504 format='4';
1505 if (image_info->compression == NoCompression)
1506 format='1';
1507 break;
1508 }
1509 case 'F':
1510 case 'f':
1511 {
1512 format='F';
1513 if (IsGrayImage(image,&image->exception) != MagickFalse)
1514 format='f';
1515 break;
1516 }
1517 case 'G':
1518 case 'g':
1519 {
1520 format='5';
1521 if (image_info->compression == NoCompression)
1522 format='2';
1523 break;
1524 }
1525 case 'N':
1526 case 'n':
1527 {
1528 if ((image_info->type != TrueColorType) &&
1529 (IsGrayImage(image,&image->exception) != MagickFalse))
1530 {
1531 format='5';
1532 if (image_info->compression == NoCompression)
1533 format='2';
1534 if (IsMonochromeImage(image,&image->exception) != MagickFalse)
1535 {
1536 format='4';
1537 if (image_info->compression == NoCompression)
1538 format='1';
1539 }
1540 break;
1541 }
1542 }
1543 default:
1544 {
1545 format='6';
1546 if (image_info->compression == NoCompression)
1547 format='3';
1548 break;
1549 }
1550 }
1551 (void) FormatMagickString(buffer,MaxTextExtent,"P%c\n",format);
1552 (void) WriteBlobString(image,buffer);
1553 value=GetImageProperty(image,"comment");
1554 if (value != (const char *) NULL)
1555 {
1556 register const char
1557 *p;
1558
1559 /*
1560 Write comments to file.
1561 */
1562 (void) WriteBlobByte(image,'#');
1563 for (p=value; *p != '\0'; p++)
1564 {
1565 (void) WriteBlobByte(image,(unsigned char) *p);
1566 if ((*p == '\r') && (*(p+1) != '\0'))
1567 (void) WriteBlobByte(image,'#');
1568 if ((*p == '\n') && (*(p+1) != '\0'))
1569 (void) WriteBlobByte(image,'#');
1570 }
1571 (void) WriteBlobByte(image,'\n');
1572 }
1573 if (format != '7')
1574 {
1575 if (image->colorspace != RGBColorspace)
1576 (void) TransformImageColorspace(image,RGBColorspace);
cristye8c25f92010-06-03 00:53:06 +00001577 (void) FormatMagickString(buffer,MaxTextExtent,"%.20g %.20g\n",
1578 (double) image->columns,(double) image->rows);
cristy3ed852e2009-09-05 21:47:34 +00001579 (void) WriteBlobString(image,buffer);
1580 }
1581 else
1582 {
1583 char
1584 type[MaxTextExtent];
1585
1586 /*
1587 PAM header.
1588 */
1589 (void) FormatMagickString(buffer,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00001590 "WIDTH %.20g\nHEIGHT %.20g\n",(double) image->columns,(double)
1591 image->rows);
cristy3ed852e2009-09-05 21:47:34 +00001592 (void) WriteBlobString(image,buffer);
1593 quantum_type=GetQuantumType(image,&image->exception);
1594 switch (quantum_type)
1595 {
1596 case CMYKQuantum:
1597 case CMYKAQuantum:
1598 {
1599 packet_size=4;
1600 (void) CopyMagickString(type,"CMYK",MaxTextExtent);
1601 break;
1602 }
1603 case GrayQuantum:
1604 case GrayAlphaQuantum:
1605 {
1606 packet_size=1;
1607 (void) CopyMagickString(type,"GRAYSCALE",MaxTextExtent);
1608 break;
1609 }
1610 default:
1611 {
1612 quantum_type=RGBQuantum;
1613 if (image->matte != MagickFalse)
1614 quantum_type=RGBAQuantum;
1615 packet_size=3;
1616 (void) CopyMagickString(type,"RGB",MaxTextExtent);
1617 break;
1618 }
1619 }
1620 if (image->matte != MagickFalse)
1621 {
1622 packet_size++;
1623 (void) ConcatenateMagickString(type,"_ALPHA",MaxTextExtent);
1624 }
1625 if (image->depth > 16)
1626 image->depth=16;
1627 (void) FormatMagickString(buffer,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00001628 "DEPTH %.20g\nMAXVAL %.20g\n",(double) packet_size,(double)
cristy3ed852e2009-09-05 21:47:34 +00001629 GetQuantumRange(image->depth));
1630 (void) WriteBlobString(image,buffer);
1631 (void) FormatMagickString(buffer,MaxTextExtent,"TUPLTYPE %s\nENDHDR\n",
1632 type);
1633 (void) WriteBlobString(image,buffer);
1634 }
1635 /*
1636 Convert runextent encoded to PNM raster pixels.
1637 */
1638 switch (format)
1639 {
1640 case '1':
1641 {
cristy661b5ad2010-01-13 00:54:42 +00001642 unsigned char
1643 pixels[2048];
cristy3ed852e2009-09-05 21:47:34 +00001644
1645 /*
1646 Convert image to a PBM image.
1647 */
cristy661b5ad2010-01-13 00:54:42 +00001648 q=pixels;
cristybb503372010-05-27 20:51:26 +00001649 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +00001650 {
cristy3ed852e2009-09-05 21:47:34 +00001651 register const PixelPacket
cristyc47d1f82009-11-26 01:44:43 +00001652 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +00001653
cristybb503372010-05-27 20:51:26 +00001654 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001655 x;
1656
1657 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1658 if (p == (const PixelPacket *) NULL)
1659 break;
cristybb503372010-05-27 20:51:26 +00001660 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00001661 {
1662 pixel=PixelIntensityToQuantum(p);
cristy661b5ad2010-01-13 00:54:42 +00001663 *q++=(unsigned char) (pixel >= (Quantum) (QuantumRange/2) ?
1664 '0' : '1');
1665 *q++=' ';
1666 if ((q-pixels+2) >= 80)
1667 {
1668 *q++='\n';
1669 (void) WriteBlob(image,q-pixels,pixels);
1670 q=pixels;
cristy661b5ad2010-01-13 00:54:42 +00001671 }
cristy3ed852e2009-09-05 21:47:34 +00001672 p++;
1673 }
1674 if (image->previous == (Image *) NULL)
1675 {
cristycee97112010-05-28 00:44:52 +00001676 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1677 image->rows);
cristy3ed852e2009-09-05 21:47:34 +00001678 if (status == MagickFalse)
1679 break;
1680 }
1681 }
cristy661b5ad2010-01-13 00:54:42 +00001682 if (q != pixels)
1683 {
1684 *q++='\n';
1685 (void) WriteBlob(image,q-pixels,pixels);
1686 }
cristy3ed852e2009-09-05 21:47:34 +00001687 break;
1688 }
1689 case '2':
1690 {
cristy661b5ad2010-01-13 00:54:42 +00001691 unsigned char
1692 pixels[2048];
cristy3ed852e2009-09-05 21:47:34 +00001693
1694 /*
1695 Convert image to a PGM image.
1696 */
1697 if (image->depth <= 8)
1698 (void) WriteBlobString(image,"255\n");
1699 else
1700 (void) WriteBlobString(image,"65535\n");
cristy661b5ad2010-01-13 00:54:42 +00001701 q=pixels;
cristybb503372010-05-27 20:51:26 +00001702 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +00001703 {
1704 register const PixelPacket
cristyc47d1f82009-11-26 01:44:43 +00001705 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +00001706
cristybb503372010-05-27 20:51:26 +00001707 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001708 x;
1709
1710 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1711 if (p == (const PixelPacket *) NULL)
1712 break;
cristybb503372010-05-27 20:51:26 +00001713 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00001714 {
1715 index=PixelIntensityToQuantum(p);
1716 if (image->depth <= 8)
1717 count=(ssize_t) FormatMagickString(buffer,MaxTextExtent,"%u ",
1718 ScaleQuantumToChar(index));
1719 else
1720 count=(ssize_t) FormatMagickString(buffer,MaxTextExtent,"%u ",
1721 ScaleQuantumToShort(index));
cristy661b5ad2010-01-13 00:54:42 +00001722 extent=(size_t) count;
1723 (void) strncpy((char *) q,buffer,extent);
1724 q+=extent;
1725 if ((q-pixels+extent) >= 80)
1726 {
1727 *q++='\n';
1728 (void) WriteBlob(image,q-pixels,pixels);
1729 q=pixels;
1730 }
cristy3ed852e2009-09-05 21:47:34 +00001731 p++;
1732 }
1733 if (image->previous == (Image *) NULL)
1734 {
cristycee97112010-05-28 00:44:52 +00001735 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1736 image->rows);
cristy3ed852e2009-09-05 21:47:34 +00001737 if (status == MagickFalse)
1738 break;
1739 }
1740 }
cristy661b5ad2010-01-13 00:54:42 +00001741 if (q != pixels)
1742 {
1743 *q++='\n';
1744 (void) WriteBlob(image,q-pixels,pixels);
1745 }
cristy3ed852e2009-09-05 21:47:34 +00001746 break;
1747 }
1748 case '3':
1749 {
cristy661b5ad2010-01-13 00:54:42 +00001750 unsigned char
1751 pixels[2048];
cristy3ed852e2009-09-05 21:47:34 +00001752
1753 /*
1754 Convert image to a PNM image.
1755 */
1756 if (image->depth <= 8)
1757 (void) WriteBlobString(image,"255\n");
1758 else
1759 (void) WriteBlobString(image,"65535\n");
cristy661b5ad2010-01-13 00:54:42 +00001760 q=pixels;
cristybb503372010-05-27 20:51:26 +00001761 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +00001762 {
1763 register const PixelPacket
cristyc47d1f82009-11-26 01:44:43 +00001764 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +00001765
cristybb503372010-05-27 20:51:26 +00001766 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001767 x;
1768
1769 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1770 if (p == (const PixelPacket *) NULL)
1771 break;
cristybb503372010-05-27 20:51:26 +00001772 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00001773 {
1774 if (image->depth <= 8)
1775 count=(ssize_t) FormatMagickString(buffer,MaxTextExtent,
cristyce70c172010-01-07 17:15:30 +00001776 "%u %u %u ",ScaleQuantumToChar(GetRedPixelComponent(p)),
cristy375dc4b2010-01-12 20:24:58 +00001777 ScaleQuantumToChar(GetGreenPixelComponent(p)),
1778 ScaleQuantumToChar(GetBluePixelComponent(p)));
cristy3ed852e2009-09-05 21:47:34 +00001779 else
1780 count=(ssize_t) FormatMagickString(buffer,MaxTextExtent,
cristyce70c172010-01-07 17:15:30 +00001781 "%u %u %u ",ScaleQuantumToShort(GetRedPixelComponent(p)),
cristy375dc4b2010-01-12 20:24:58 +00001782 ScaleQuantumToShort(GetGreenPixelComponent(p)),
1783 ScaleQuantumToShort(GetBluePixelComponent(p)));
cristy661b5ad2010-01-13 00:54:42 +00001784 extent=(size_t) count;
1785 (void) strncpy((char *) q,buffer,extent);
1786 q+=extent;
1787 if ((q-pixels+extent) >= 80)
1788 {
1789 *q++='\n';
1790 (void) WriteBlob(image,q-pixels,pixels);
1791 q=pixels;
1792 }
cristy3ed852e2009-09-05 21:47:34 +00001793 p++;
1794 }
1795 if (image->previous == (Image *) NULL)
1796 {
cristycee97112010-05-28 00:44:52 +00001797 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1798 image->rows);
cristy3ed852e2009-09-05 21:47:34 +00001799 if (status == MagickFalse)
1800 break;
1801 }
1802 }
cristy661b5ad2010-01-13 00:54:42 +00001803 if (q != pixels)
1804 {
1805 *q++='\n';
1806 (void) WriteBlob(image,q-pixels,pixels);
1807 }
cristy3ed852e2009-09-05 21:47:34 +00001808 break;
1809 }
1810 case '4':
1811 {
1812 /*
1813 Convert image to a PBM image.
1814 */
1815 image->depth=1;
1816 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
1817 if (quantum_info == (QuantumInfo *) NULL)
1818 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1819 quantum_info->min_is_white=MagickTrue;
1820 pixels=GetQuantumPixels(quantum_info);
cristybb503372010-05-27 20:51:26 +00001821 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +00001822 {
1823 register const PixelPacket
cristyc47d1f82009-11-26 01:44:43 +00001824 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +00001825
1826 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1827 if (p == (const PixelPacket *) NULL)
1828 break;
1829 extent=ExportQuantumPixels(image,(const CacheView *) NULL,
1830 quantum_info,GrayQuantum,pixels,&image->exception);
1831 count=WriteBlob(image,extent,pixels);
1832 if (count != (ssize_t) extent)
1833 break;
1834 if (image->previous == (Image *) NULL)
1835 {
cristycee97112010-05-28 00:44:52 +00001836 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1837 image->rows);
cristy3ed852e2009-09-05 21:47:34 +00001838 if (status == MagickFalse)
1839 break;
1840 }
1841 }
1842 quantum_info=DestroyQuantumInfo(quantum_info);
1843 break;
1844 }
1845 case '5':
1846 {
1847 QuantumAny
1848 range;
1849
1850 /*
1851 Convert image to a PGM image.
1852 */
1853 if (image->depth > 8)
1854 image->depth=16;
cristye8c25f92010-06-03 00:53:06 +00001855 (void) FormatMagickString(buffer,MaxTextExtent,"%.20g\n",(double)
cristy3ed852e2009-09-05 21:47:34 +00001856 GetQuantumRange(image->depth));
1857 (void) WriteBlobString(image,buffer);
1858 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
1859 if (quantum_info == (QuantumInfo *) NULL)
1860 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1861 quantum_info->min_is_white=MagickTrue;
1862 pixels=GetQuantumPixels(quantum_info);
1863 extent=GetQuantumExtent(image,quantum_info,GrayQuantum);
1864 range=GetQuantumRange(image->depth);
cristybb503372010-05-27 20:51:26 +00001865 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +00001866 {
1867 register const PixelPacket
cristyc47d1f82009-11-26 01:44:43 +00001868 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +00001869
cristybb503372010-05-27 20:51:26 +00001870 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001871 x;
1872
1873 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1874 if (p == (const PixelPacket *) NULL)
1875 break;
1876 q=pixels;
1877 if ((image->depth == 8) || (image->depth == 16))
1878 extent=ExportQuantumPixels(image,(const CacheView *) NULL,
1879 quantum_info,GrayQuantum,pixels,&image->exception);
1880 else
1881 {
1882 if (image->depth <= 8)
cristybb503372010-05-27 20:51:26 +00001883 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00001884 {
1885 if (IsGrayPixel(p) == MagickFalse)
1886 pixel=ScaleQuantumToAny(PixelIntensityToQuantum(p),range);
1887 else
1888 {
1889 if (image->depth == 8)
cristyce70c172010-01-07 17:15:30 +00001890 pixel=ScaleQuantumToChar(GetRedPixelComponent(p));
cristy3ed852e2009-09-05 21:47:34 +00001891 else
cristy89bbeaf2011-04-22 20:25:27 +00001892 pixel=ScaleQuantumToAny(GetRedPixelComponent(p),range);
cristy3ed852e2009-09-05 21:47:34 +00001893 }
1894 q=PopCharPixel((unsigned char) pixel,q);
1895 p++;
1896 }
1897 else
cristybb503372010-05-27 20:51:26 +00001898 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00001899 {
1900 if (IsGrayPixel(p) == MagickFalse)
1901 pixel=ScaleQuantumToAny(PixelIntensityToQuantum(p),range);
1902 else
1903 {
1904 if (image->depth == 16)
cristyce70c172010-01-07 17:15:30 +00001905 pixel=ScaleQuantumToShort(GetRedPixelComponent(p));
cristy3ed852e2009-09-05 21:47:34 +00001906 else
cristy89bbeaf2011-04-22 20:25:27 +00001907 pixel=ScaleQuantumToAny(GetRedPixelComponent(p),range);
cristy3ed852e2009-09-05 21:47:34 +00001908 }
1909 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
1910 p++;
1911 }
1912 extent=(size_t) (q-pixels);
1913 }
1914 count=WriteBlob(image,extent,pixels);
1915 if (count != (ssize_t) extent)
1916 break;
1917 if (image->previous == (Image *) NULL)
1918 {
cristycee97112010-05-28 00:44:52 +00001919 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1920 image->rows);
cristy3ed852e2009-09-05 21:47:34 +00001921 if (status == MagickFalse)
1922 break;
1923 }
1924 }
1925 quantum_info=DestroyQuantumInfo(quantum_info);
1926 break;
1927 }
1928 case '6':
1929 {
1930 QuantumAny
1931 range;
1932
1933 /*
1934 Convert image to a PNM image.
1935 */
1936 if (image->depth > 8)
1937 image->depth=16;
cristye8c25f92010-06-03 00:53:06 +00001938 (void) FormatMagickString(buffer,MaxTextExtent,"%.20g\n",(double)
cristy3ed852e2009-09-05 21:47:34 +00001939 GetQuantumRange(image->depth));
1940 (void) WriteBlobString(image,buffer);
1941 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
1942 if (quantum_info == (QuantumInfo *) NULL)
1943 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1944 pixels=GetQuantumPixels(quantum_info);
1945 extent=GetQuantumExtent(image,quantum_info,quantum_type);
1946 range=GetQuantumRange(image->depth);
cristybb503372010-05-27 20:51:26 +00001947 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +00001948 {
1949 register const PixelPacket
cristyc47d1f82009-11-26 01:44:43 +00001950 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +00001951
cristybb503372010-05-27 20:51:26 +00001952 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001953 x;
1954
1955 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1956 if (p == (const PixelPacket *) NULL)
1957 break;
1958 q=pixels;
1959 if ((image->depth == 8) || (image->depth == 16))
1960 extent=ExportQuantumPixels(image,(const CacheView *) NULL,
1961 quantum_info,quantum_type,pixels,&image->exception);
1962 else
1963 {
1964 if (image->depth <= 8)
cristybb503372010-05-27 20:51:26 +00001965 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00001966 {
cristy89bbeaf2011-04-22 20:25:27 +00001967 pixel=ScaleQuantumToAny(GetRedPixelComponent(p),range);
cristy3ed852e2009-09-05 21:47:34 +00001968 q=PopCharPixel((unsigned char) pixel,q);
cristy89bbeaf2011-04-22 20:25:27 +00001969 pixel=ScaleQuantumToAny(GetGreenPixelComponent(p),range);
cristy3ed852e2009-09-05 21:47:34 +00001970 q=PopCharPixel((unsigned char) pixel,q);
cristy89bbeaf2011-04-22 20:25:27 +00001971 pixel=ScaleQuantumToAny(GetBluePixelComponent(p),range);
cristy3ed852e2009-09-05 21:47:34 +00001972 q=PopCharPixel((unsigned char) pixel,q);
cristy3ed852e2009-09-05 21:47:34 +00001973 p++;
1974 }
1975 else
cristybb503372010-05-27 20:51:26 +00001976 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00001977 {
cristy89bbeaf2011-04-22 20:25:27 +00001978 pixel=ScaleQuantumToAny(GetRedPixelComponent(p),range);
cristy3ed852e2009-09-05 21:47:34 +00001979 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
cristy89bbeaf2011-04-22 20:25:27 +00001980 pixel=ScaleQuantumToAny(GetGreenPixelComponent(p),range);
cristy3ed852e2009-09-05 21:47:34 +00001981 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
cristy89bbeaf2011-04-22 20:25:27 +00001982 pixel=ScaleQuantumToAny(GetBluePixelComponent(p),range);
cristy3ed852e2009-09-05 21:47:34 +00001983 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
cristy3ed852e2009-09-05 21:47:34 +00001984 p++;
1985 }
1986 extent=(size_t) (q-pixels);
1987 }
1988 count=WriteBlob(image,extent,pixels);
1989 if (count != (ssize_t) extent)
1990 break;
1991 if (image->previous == (Image *) NULL)
1992 {
cristycee97112010-05-28 00:44:52 +00001993 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1994 image->rows);
cristy3ed852e2009-09-05 21:47:34 +00001995 if (status == MagickFalse)
1996 break;
1997 }
1998 }
1999 quantum_info=DestroyQuantumInfo(quantum_info);
2000 break;
2001 }
2002 case '7':
2003 {
2004 QuantumAny
2005 range;
2006
2007 /*
2008 Convert image to a PAM.
2009 */
2010 if (image->depth > 16)
2011 image->depth=16;
2012 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
2013 pixels=GetQuantumPixels(quantum_info);
2014 range=GetQuantumRange(image->depth);
cristybb503372010-05-27 20:51:26 +00002015 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +00002016 {
2017 register const IndexPacket
cristyc47d1f82009-11-26 01:44:43 +00002018 *restrict indexes;
cristy3ed852e2009-09-05 21:47:34 +00002019
2020 register const PixelPacket
cristyc47d1f82009-11-26 01:44:43 +00002021 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +00002022
cristybb503372010-05-27 20:51:26 +00002023 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002024 x;
2025
2026 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
2027 if (p == (const PixelPacket *) NULL)
2028 break;
2029 indexes=GetVirtualIndexQueue(image);
2030 q=pixels;
2031 if ((image->depth == 8) || (image->depth == 16))
2032 extent=ExportQuantumPixels(image,(const CacheView *) NULL,
2033 quantum_info,quantum_type,pixels,&image->exception);
2034 else
2035 {
2036 switch (quantum_type)
2037 {
2038 case GrayQuantum:
2039 case GrayAlphaQuantum:
2040 {
2041 if (image->depth <= 8)
cristybb503372010-05-27 20:51:26 +00002042 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00002043 {
2044 pixel=ScaleQuantumToAny(PixelIntensityToQuantum(p),range);
2045 q=PopCharPixel((unsigned char) pixel,q);
2046 if (image->matte != MagickFalse)
2047 {
cristy89bbeaf2011-04-22 20:25:27 +00002048 pixel=(unsigned char) ScaleQuantumToAny(GetOpacityPixelComponent(p),
cristy3ed852e2009-09-05 21:47:34 +00002049 range);
2050 q=PopCharPixel((unsigned char) pixel,q);
2051 }
2052 p++;
2053 }
2054 else
cristybb503372010-05-27 20:51:26 +00002055 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00002056 {
2057 pixel=ScaleQuantumToAny(PixelIntensityToQuantum(p),range);
2058 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2059 if (image->matte != MagickFalse)
2060 {
cristy89bbeaf2011-04-22 20:25:27 +00002061 pixel=(unsigned char) ScaleQuantumToAny(GetOpacityPixelComponent(p),
cristy3ed852e2009-09-05 21:47:34 +00002062 range);
2063 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2064 }
2065 p++;
2066 }
2067 break;
2068 }
2069 case CMYKQuantum:
2070 case CMYKAQuantum:
2071 {
2072 if (image->depth <= 8)
cristybb503372010-05-27 20:51:26 +00002073 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00002074 {
cristy89bbeaf2011-04-22 20:25:27 +00002075 pixel=ScaleQuantumToAny(GetRedPixelComponent(p),range);
cristy3ed852e2009-09-05 21:47:34 +00002076 q=PopCharPixel((unsigned char) pixel,q);
cristy89bbeaf2011-04-22 20:25:27 +00002077 pixel=ScaleQuantumToAny(GetGreenPixelComponent(p),range);
cristy3ed852e2009-09-05 21:47:34 +00002078 q=PopCharPixel((unsigned char) pixel,q);
cristy89bbeaf2011-04-22 20:25:27 +00002079 pixel=ScaleQuantumToAny(GetBluePixelComponent(p),range);
cristy3ed852e2009-09-05 21:47:34 +00002080 q=PopCharPixel((unsigned char) pixel,q);
cristy89bbeaf2011-04-22 20:25:27 +00002081 pixel=ScaleQuantumToAny(GetIndexPixelComponent(indexes+x),range);
cristy3ed852e2009-09-05 21:47:34 +00002082 q=PopCharPixel((unsigned char) pixel,q);
2083 if (image->matte != MagickFalse)
2084 {
2085 pixel=ScaleQuantumToAny((Quantum) (QuantumRange-
cristyce70c172010-01-07 17:15:30 +00002086 GetOpacityPixelComponent(p)),range);
cristy3ed852e2009-09-05 21:47:34 +00002087 q=PopCharPixel((unsigned char) pixel,q);
2088 }
2089 p++;
2090 }
2091 else
cristybb503372010-05-27 20:51:26 +00002092 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00002093 {
cristy89bbeaf2011-04-22 20:25:27 +00002094 pixel=ScaleQuantumToAny(GetRedPixelComponent(p),range);
cristy3ed852e2009-09-05 21:47:34 +00002095 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
cristy89bbeaf2011-04-22 20:25:27 +00002096 pixel=ScaleQuantumToAny(GetGreenPixelComponent(p),range);
cristy3ed852e2009-09-05 21:47:34 +00002097 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
cristy89bbeaf2011-04-22 20:25:27 +00002098 pixel=ScaleQuantumToAny(GetBluePixelComponent(p),range);
cristy3ed852e2009-09-05 21:47:34 +00002099 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
cristy89bbeaf2011-04-22 20:25:27 +00002100 pixel=ScaleQuantumToAny(GetIndexPixelComponent(indexes+x),range);
cristy3ed852e2009-09-05 21:47:34 +00002101 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2102 if (image->matte != MagickFalse)
2103 {
2104 pixel=ScaleQuantumToAny((Quantum) (QuantumRange-
cristyce70c172010-01-07 17:15:30 +00002105 GetOpacityPixelComponent(p)),range);
cristy3ed852e2009-09-05 21:47:34 +00002106 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2107 }
2108 p++;
2109 }
2110 break;
2111 }
2112 default:
2113 {
2114 if (image->depth <= 8)
cristybb503372010-05-27 20:51:26 +00002115 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00002116 {
cristy89bbeaf2011-04-22 20:25:27 +00002117 pixel=ScaleQuantumToAny(GetRedPixelComponent(p),range);
cristy3ed852e2009-09-05 21:47:34 +00002118 q=PopCharPixel((unsigned char) pixel,q);
cristy89bbeaf2011-04-22 20:25:27 +00002119 pixel=ScaleQuantumToAny(GetGreenPixelComponent(p),range);
cristy3ed852e2009-09-05 21:47:34 +00002120 q=PopCharPixel((unsigned char) pixel,q);
cristy89bbeaf2011-04-22 20:25:27 +00002121 pixel=ScaleQuantumToAny(GetBluePixelComponent(p),range);
cristy3ed852e2009-09-05 21:47:34 +00002122 q=PopCharPixel((unsigned char) pixel,q);
2123 if (image->matte != MagickFalse)
2124 {
2125 pixel=ScaleQuantumToAny((Quantum) (QuantumRange-
cristyce70c172010-01-07 17:15:30 +00002126 GetOpacityPixelComponent(p)),range);
cristy3ed852e2009-09-05 21:47:34 +00002127 q=PopCharPixel((unsigned char) pixel,q);
2128 }
2129 p++;
2130 }
2131 else
cristybb503372010-05-27 20:51:26 +00002132 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00002133 {
cristy89bbeaf2011-04-22 20:25:27 +00002134 pixel=ScaleQuantumToAny(GetRedPixelComponent(p),range);
cristy3ed852e2009-09-05 21:47:34 +00002135 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
cristy89bbeaf2011-04-22 20:25:27 +00002136 pixel=ScaleQuantumToAny(GetGreenPixelComponent(p),range);
cristy3ed852e2009-09-05 21:47:34 +00002137 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
cristy89bbeaf2011-04-22 20:25:27 +00002138 pixel=ScaleQuantumToAny(GetBluePixelComponent(p),range);
cristy3ed852e2009-09-05 21:47:34 +00002139 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2140 if (image->matte != MagickFalse)
2141 {
2142 pixel=ScaleQuantumToAny((Quantum) (QuantumRange-
cristyce70c172010-01-07 17:15:30 +00002143 GetOpacityPixelComponent(p)),range);
cristy3ed852e2009-09-05 21:47:34 +00002144 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2145 }
2146 p++;
2147 }
2148 break;
2149 }
2150 }
2151 extent=(size_t) (q-pixels);
2152 }
2153 count=WriteBlob(image,extent,pixels);
2154 if (count != (ssize_t) extent)
2155 break;
2156 if (image->previous == (Image *) NULL)
2157 {
cristycee97112010-05-28 00:44:52 +00002158 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
2159 image->rows);
cristy3ed852e2009-09-05 21:47:34 +00002160 if (status == MagickFalse)
2161 break;
2162 }
2163 }
2164 quantum_info=DestroyQuantumInfo(quantum_info);
2165 break;
2166 }
2167 case 'F':
2168 case 'f':
2169 {
2170 (void) WriteBlobString(image,image->endian != LSBEndian ? "1.0\n" :
2171 "-1.0\n");
2172 image->depth=32;
2173 quantum_type=format == 'f' ? GrayQuantum : RGBQuantum;
2174 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
2175 if (quantum_info == (QuantumInfo *) NULL)
2176 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
2177 status=SetQuantumFormat(image,quantum_info,FloatingPointQuantumFormat);
2178 if (status == MagickFalse)
2179 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
2180 pixels=GetQuantumPixels(quantum_info);
cristybb503372010-05-27 20:51:26 +00002181 for (y=(ssize_t) image->rows-1; y >= 0; y--)
cristy3ed852e2009-09-05 21:47:34 +00002182 {
2183 register const PixelPacket
cristyc47d1f82009-11-26 01:44:43 +00002184 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +00002185
2186 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
2187 if (p == (const PixelPacket *) NULL)
2188 break;
2189 extent=ExportQuantumPixels(image,(const CacheView *) NULL,
2190 quantum_info,quantum_type,pixels,&image->exception);
2191 (void) WriteBlob(image,extent,pixels);
2192 if (image->previous == (Image *) NULL)
2193 {
cristycee97112010-05-28 00:44:52 +00002194 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
2195 image->rows);
cristy3ed852e2009-09-05 21:47:34 +00002196 if (status == MagickFalse)
2197 break;
2198 }
2199 }
2200 quantum_info=DestroyQuantumInfo(quantum_info);
2201 break;
2202 }
2203 }
2204 if (GetNextImageInList(image) == (Image *) NULL)
2205 break;
2206 image=SyncNextImageInList(image);
2207 status=SetImageProgress(image,SaveImagesTag,scene++,
2208 GetImageListLength(image));
2209 if (status == MagickFalse)
2210 break;
2211 } while (image_info->adjoin != MagickFalse);
2212 (void) CloseBlob(image);
2213 return(MagickTrue);
2214}