blob: 3182e56ddbae0079399ce4c46043a9712149aa30 [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
cristyaff6d802011-04-26 01:46:31 +0000161 extent,
cristy3ed852e2009-09-05 21:47:34 +0000162 value;
163
164 /*
165 Skip any leading whitespace.
166 */
167 extent=MaxTextExtent;
168 comment=(char *) NULL;
169 p=comment;
170 do
171 {
172 c=ReadBlobByte(image);
173 if (c == EOF)
174 return(0);
175 if (c == (int) '#')
176 {
177 /*
178 Read comment.
179 */
180 if (comment == (char *) NULL)
181 comment=AcquireString((char *) NULL);
182 p=comment+strlen(comment);
183 for ( ; (c != EOF) && (c != (int) '\n'); p++)
184 {
185 if ((size_t) (p-comment+1) >= extent)
186 {
187 extent<<=1;
188 comment=(char *) ResizeQuantumMemory(comment,extent+MaxTextExtent,
189 sizeof(*comment));
190 if (comment == (char *) NULL)
191 break;
192 p=comment+strlen(comment);
193 }
194 c=ReadBlobByte(image);
195 *p=(char) c;
196 *(p+1)='\0';
197 }
198 if (comment == (char *) NULL)
199 return(0);
200 continue;
201 }
202 } while (isdigit(c) == MagickFalse);
203 if (comment != (char *) NULL)
204 {
205 (void) SetImageProperty(image,"comment",comment);
206 comment=DestroyString(comment);
207 }
208 if (base == 2)
cristybb503372010-05-27 20:51:26 +0000209 return((size_t) (c-(int) '0'));
cristy3ed852e2009-09-05 21:47:34 +0000210 /*
211 Evaluate number.
212 */
213 value=0;
214 do
215 {
216 value*=10;
217 value+=c-(int) '0';
218 c=ReadBlobByte(image);
219 if (c == EOF)
220 return(value);
221 } while (isdigit(c) != MagickFalse);
222 return(value);
223}
224
225static Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception)
226{
227 char
228 format;
229
230 double
231 quantum_scale;
232
233 Image
234 *image;
235
cristy3ed852e2009-09-05 21:47:34 +0000236 MagickBooleanType
237 status;
238
239 Quantum
240 *scale;
241
242 QuantumInfo
243 *quantum_info;
244
245 QuantumType
246 quantum_type;
247
cristybb503372010-05-27 20:51:26 +0000248 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000249 i;
250
251 size_t
cristyaff6d802011-04-26 01:46:31 +0000252 depth,
cristy3ed852e2009-09-05 21:47:34 +0000253 extent,
cristyaff6d802011-04-26 01:46:31 +0000254 max_value,
cristy3ed852e2009-09-05 21:47:34 +0000255 packet_size;
256
257 ssize_t
cristyaff6d802011-04-26 01:46:31 +0000258 count,
259 row,
260 y;
cristy3ed852e2009-09-05 21:47:34 +0000261
cristy3ed852e2009-09-05 21:47:34 +0000262 /*
263 Open image file.
264 */
265 assert(image_info != (const ImageInfo *) NULL);
266 assert(image_info->signature == MagickSignature);
267 if (image_info->debug != MagickFalse)
268 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
269 image_info->filename);
270 assert(exception != (ExceptionInfo *) NULL);
271 assert(exception->signature == MagickSignature);
272 image=AcquireImage(image_info);
273 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
274 if (status == MagickFalse)
275 {
276 image=DestroyImageList(image);
277 return((Image *) NULL);
278 }
279 /*
280 Read PNM image.
281 */
282 count=ReadBlob(image,1,(unsigned char *) &format);
283 do
284 {
285 /*
286 Initialize image structure.
287 */
288 if ((count != 1) || (format != 'P'))
289 ThrowReaderException(CorruptImageError,"ImproperImageHeader");
290 max_value=1;
291 quantum_type=RGBQuantum;
292 quantum_scale=1.0;
293 format=(char) ReadBlobByte(image);
294 if (format != '7')
295 {
296 /*
297 PBM, PGM, PPM, and PNM.
298 */
299 image->columns=PNMInteger(image,10);
300 image->rows=PNMInteger(image,10);
301 if ((format == 'f') || (format == 'F'))
302 {
303 char
304 scale[MaxTextExtent];
305
306 (void) ReadBlobString(image,scale);
cristyc1acd842011-05-19 23:05:47 +0000307 quantum_scale=InterpretLocaleValue(scale,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000308 }
309 else
310 {
311 if ((format == '1') || (format == '4'))
312 max_value=1; /* bitmap */
313 else
314 max_value=PNMInteger(image,10);
315 }
316 }
317 else
318 {
319 char
320 keyword[MaxTextExtent],
321 value[MaxTextExtent];
322
323 int
324 c;
325
326 register char
327 *p;
328
329 /*
330 PAM.
331 */
332 for (c=ReadBlobByte(image); c != EOF; c=ReadBlobByte(image))
333 {
334 while (isspace((int) ((unsigned char) c)) != 0)
335 c=ReadBlobByte(image);
336 p=keyword;
337 do
338 {
339 if ((size_t) (p-keyword) < (MaxTextExtent-1))
340 *p++=c;
341 c=ReadBlobByte(image);
342 } while (isalnum(c));
343 *p='\0';
344 if (LocaleCompare(keyword,"endhdr") == 0)
345 break;
346 while (isspace((int) ((unsigned char) c)) != 0)
347 c=ReadBlobByte(image);
348 p=value;
349 while (isalnum(c) || (c == '_'))
350 {
351 if ((size_t) (p-value) < (MaxTextExtent-1))
352 *p++=c;
353 c=ReadBlobByte(image);
354 }
355 *p='\0';
356 /*
357 Assign a value to the specified keyword.
358 */
359 if (LocaleCompare(keyword,"depth") == 0)
cristye27293e2009-12-18 02:53:20 +0000360 packet_size=StringToUnsignedLong(value);
cristyda16f162011-02-19 23:52:17 +0000361 (void) packet_size;
cristy3ed852e2009-09-05 21:47:34 +0000362 if (LocaleCompare(keyword,"height") == 0)
cristye27293e2009-12-18 02:53:20 +0000363 image->rows=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +0000364 if (LocaleCompare(keyword,"maxval") == 0)
cristye27293e2009-12-18 02:53:20 +0000365 max_value=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +0000366 if (LocaleCompare(keyword,"TUPLTYPE") == 0)
367 {
368 if (LocaleCompare(value,"BLACKANDWHITE") == 0)
369 quantum_type=GrayQuantum;
370 if (LocaleCompare(value,"BLACKANDWHITE_ALPHA") == 0)
371 {
372 quantum_type=GrayAlphaQuantum;
373 image->matte=MagickTrue;
374 }
375 if (LocaleCompare(value,"GRAYSCALE") == 0)
376 quantum_type=GrayQuantum;
377 if (LocaleCompare(value,"GRAYSCALE_ALPHA") == 0)
378 {
379 quantum_type=GrayAlphaQuantum;
380 image->matte=MagickTrue;
381 }
382 if (LocaleCompare(value,"RGB_ALPHA") == 0)
383 {
384 quantum_type=RGBAQuantum;
385 image->matte=MagickTrue;
386 }
387 if (LocaleCompare(value,"CMYK") == 0)
388 {
389 quantum_type=CMYKQuantum;
390 image->colorspace=CMYKColorspace;
391 }
392 if (LocaleCompare(value,"CMYK_ALPHA") == 0)
393 {
394 quantum_type=CMYKAQuantum;
395 image->colorspace=CMYKColorspace;
396 image->matte=MagickTrue;
397 }
398 }
399 if (LocaleCompare(keyword,"width") == 0)
cristye27293e2009-12-18 02:53:20 +0000400 image->columns=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +0000401 }
402 }
403 if ((image->columns == 0) || (image->rows == 0))
404 ThrowReaderException(CorruptImageError,"NegativeOrZeroImageSize");
405 if (max_value >= 65536)
406 ThrowReaderException(CorruptImageError,"ImproperImageHeader");
407 for (depth=1; GetQuantumRange(depth) < max_value; depth++) ;
408 image->depth=depth;
409 if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
410 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
411 break;
412 /*
413 Convert PNM pixels to runextent-encoded MIFF packets.
414 */
415 status=MagickTrue;
416 row=0;
417 switch (format)
418 {
419 case '1':
420 {
421 /*
422 Convert PBM image to pixel packets.
423 */
cristybb503372010-05-27 20:51:26 +0000424 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +0000425 {
cristybb503372010-05-27 20:51:26 +0000426 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000427 x;
428
429 register PixelPacket
cristyc47d1f82009-11-26 01:44:43 +0000430 *restrict q;
cristy3ed852e2009-09-05 21:47:34 +0000431
432 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
433 if (q == (PixelPacket *) NULL)
434 break;
cristybb503372010-05-27 20:51:26 +0000435 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +0000436 {
cristyaff6d802011-04-26 01:46:31 +0000437 SetRedPixelComponent(q,PNMInteger(image,2) == 0 ? QuantumRange : 0);
cristy5fde9aa2011-04-23 01:31:53 +0000438 SetGreenPixelComponent(q,GetRedPixelComponent(q));
439 SetBluePixelComponent(q,GetRedPixelComponent(q));
cristy3ed852e2009-09-05 21:47:34 +0000440 q++;
441 }
442 if (SyncAuthenticPixels(image,exception) == MagickFalse)
443 break;
444 if (image->previous == (Image *) NULL)
445 {
cristycee97112010-05-28 00:44:52 +0000446 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
447 image->rows);
cristy3ed852e2009-09-05 21:47:34 +0000448 if (status == MagickFalse)
449 break;
450 }
451 }
452 image->type=BilevelType;
453 break;
454 }
455 case '2':
456 {
cristybb503372010-05-27 20:51:26 +0000457 size_t
cristy3ed852e2009-09-05 21:47:34 +0000458 intensity;
459
460 /*
461 Convert PGM image to pixel packets.
462 */
463 scale=(Quantum *) NULL;
464 if (max_value != (1U*QuantumRange))
465 {
466 /*
467 Compute pixel scaling table.
468 */
469 scale=(Quantum *) AcquireQuantumMemory((size_t) max_value+1UL,
470 sizeof(*scale));
471 if (scale == (Quantum *) NULL)
472 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
cristybb503372010-05-27 20:51:26 +0000473 for (i=0; i <= (ssize_t) max_value; i++)
cristy3ed852e2009-09-05 21:47:34 +0000474 scale[i]=(Quantum) (((double) QuantumRange*i)/max_value+0.5);
475 }
cristybb503372010-05-27 20:51:26 +0000476 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +0000477 {
cristybb503372010-05-27 20:51:26 +0000478 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000479 x;
480
481 register PixelPacket
cristyc47d1f82009-11-26 01:44:43 +0000482 *restrict q;
cristy3ed852e2009-09-05 21:47:34 +0000483
484 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
485 if (q == (PixelPacket *) NULL)
486 break;
cristybb503372010-05-27 20:51:26 +0000487 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +0000488 {
489 intensity=PNMInteger(image,10);
cristyaff6d802011-04-26 01:46:31 +0000490 SetRedPixelComponent(q,intensity);
cristyac23fd22010-05-11 14:48:58 +0000491 if (scale != (Quantum *) NULL)
cristyaff6d802011-04-26 01:46:31 +0000492 SetRedPixelComponent(q,scale[ConstrainPixel(image,(ssize_t)
493 intensity,max_value)]);
cristy5fde9aa2011-04-23 01:31:53 +0000494 SetGreenPixelComponent(q,GetRedPixelComponent(q));
495 SetBluePixelComponent(q,GetRedPixelComponent(q));
cristy3ed852e2009-09-05 21:47:34 +0000496 q++;
497 }
498 if (SyncAuthenticPixels(image,exception) == MagickFalse)
499 break;
500 if (image->previous == (Image *) NULL)
501 {
cristycee97112010-05-28 00:44:52 +0000502 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
503 image->rows);
cristy3ed852e2009-09-05 21:47:34 +0000504 if (status == MagickFalse)
505 break;
506 }
507 }
508 image->type=GrayscaleType;
509 if (scale != (Quantum *) NULL)
510 scale=(Quantum *) RelinquishMagickMemory(scale);
511 break;
512 }
513 case '3':
514 {
515 MagickPixelPacket
516 pixel;
517
518 /*
519 Convert PNM image to pixel packets.
520 */
521 scale=(Quantum *) NULL;
522 if (max_value != (1U*QuantumRange))
523 {
524 /*
525 Compute pixel scaling table.
526 */
527 scale=(Quantum *) AcquireQuantumMemory((size_t) max_value+1UL,
528 sizeof(*scale));
529 if (scale == (Quantum *) NULL)
530 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
cristybb503372010-05-27 20:51:26 +0000531 for (i=0; i <= (ssize_t) max_value; i++)
cristy3ed852e2009-09-05 21:47:34 +0000532 scale[i]=(Quantum) (((double) QuantumRange*i)/max_value+0.5);
533 }
cristybb503372010-05-27 20:51:26 +0000534 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +0000535 {
cristybb503372010-05-27 20:51:26 +0000536 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000537 x;
538
539 register PixelPacket
cristyc47d1f82009-11-26 01:44:43 +0000540 *restrict q;
cristy3ed852e2009-09-05 21:47:34 +0000541
542 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
543 if (q == (PixelPacket *) NULL)
544 break;
cristybb503372010-05-27 20:51:26 +0000545 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +0000546 {
547 pixel.red=(MagickRealType) PNMInteger(image,10);
548 pixel.green=(MagickRealType) PNMInteger(image,10);
549 pixel.blue=(MagickRealType) PNMInteger(image,10);
550 if (scale != (Quantum *) NULL)
551 {
cristybb503372010-05-27 20:51:26 +0000552 pixel.red=(MagickRealType) scale[ConstrainPixel(image,(ssize_t)
cristy3ed852e2009-09-05 21:47:34 +0000553 pixel.red,max_value)];
cristy34575212010-11-06 12:39:23 +0000554 pixel.green=(MagickRealType) scale[ConstrainPixel(image,
555 (ssize_t) pixel.green,max_value)];
cristybb503372010-05-27 20:51:26 +0000556 pixel.blue=(MagickRealType) scale[ConstrainPixel(image,(ssize_t)
cristy3ed852e2009-09-05 21:47:34 +0000557 pixel.blue,max_value)];
558 }
cristyaff6d802011-04-26 01:46:31 +0000559 SetRedPixelComponent(q,pixel.red);
560 SetGreenPixelComponent(q,pixel.green);
561 SetBluePixelComponent(q,pixel.blue);
cristy3ed852e2009-09-05 21:47:34 +0000562 q++;
563 }
564 if (SyncAuthenticPixels(image,exception) == MagickFalse)
565 break;
566 if (image->previous == (Image *) NULL)
567 {
cristycee97112010-05-28 00:44:52 +0000568 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
569 image->rows);
cristy3ed852e2009-09-05 21:47:34 +0000570 if (status == MagickFalse)
571 break;
572 }
573 }
574 if (scale != (Quantum *) NULL)
575 scale=(Quantum *) RelinquishMagickMemory(scale);
576 break;
577 }
578 case '4':
579 {
580 /*
581 Convert PBM raw image to pixel packets.
582 */
583 quantum_type=GrayQuantum;
584 if (image->storage_class == PseudoClass)
585 quantum_type=IndexQuantum;
586 quantum_info=AcquireQuantumInfo(image_info,image);
587 if (quantum_info == (QuantumInfo *) NULL)
588 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
589 SetQuantumMinIsWhite(quantum_info,MagickTrue);
590 extent=GetQuantumExtent(image,quantum_info,quantum_type);
cristybb503372010-05-27 20:51:26 +0000591 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +0000592 {
cristy3ed852e2009-09-05 21:47:34 +0000593 MagickBooleanType
594 sync;
595
596 register PixelPacket
cristyc47d1f82009-11-26 01:44:43 +0000597 *restrict q;
cristy3ed852e2009-09-05 21:47:34 +0000598
599 ssize_t
cristyaff6d802011-04-26 01:46:31 +0000600 count,
601 offset;
cristy3ed852e2009-09-05 21:47:34 +0000602
603 size_t
604 length;
605
606 unsigned char
607 *pixels;
608
609 if (status == MagickFalse)
610 continue;
611 pixels=GetQuantumPixels(quantum_info);
cristy3ed852e2009-09-05 21:47:34 +0000612 {
613 count=ReadBlob(image,extent,pixels);
614 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
615 (image->previous == (Image *) NULL))
616 {
617 MagickBooleanType
618 proceed;
619
cristycee97112010-05-28 00:44:52 +0000620 proceed=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
621 row,image->rows);
cristy3ed852e2009-09-05 21:47:34 +0000622 if (proceed == MagickFalse)
623 status=MagickFalse;
624 }
625 offset=row++;
626 }
627 if (count != (ssize_t) extent)
628 status=MagickFalse;
cristyaa740112010-03-30 17:58:44 +0000629 q=QueueAuthenticPixels(image,0,offset,image->columns,1,exception);
cristy3ed852e2009-09-05 21:47:34 +0000630 if (q == (PixelPacket *) NULL)
631 {
632 status=MagickFalse;
633 continue;
634 }
cristyaa740112010-03-30 17:58:44 +0000635 length=ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
636 quantum_type,pixels,exception);
cristy3ed852e2009-09-05 21:47:34 +0000637 if (length != extent)
638 status=MagickFalse;
cristyaa740112010-03-30 17:58:44 +0000639 sync=SyncAuthenticPixels(image,exception);
cristy3ed852e2009-09-05 21:47:34 +0000640 if (sync == MagickFalse)
641 status=MagickFalse;
642 }
cristy3ed852e2009-09-05 21:47:34 +0000643 quantum_info=DestroyQuantumInfo(quantum_info);
644 if (status == MagickFalse)
645 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
646 SetQuantumImageType(image,quantum_type);
647 break;
648 }
649 case '5':
650 {
651 QuantumAny
652 range;
653
654 /*
655 Convert PGM raw image to pixel packets.
656 */
657 range=GetQuantumRange(image->depth);
658 quantum_type=GrayQuantum;
659 extent=(image->depth <= 8 ? 1 : 2)*image->columns;
660 quantum_info=AcquireQuantumInfo(image_info,image);
661 if (quantum_info == (QuantumInfo *) NULL)
662 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
cristybb503372010-05-27 20:51:26 +0000663 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +0000664 {
cristy3ed852e2009-09-05 21:47:34 +0000665 MagickBooleanType
666 sync;
667
668 register const unsigned char
cristy3f2302b2010-03-11 03:16:37 +0000669 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +0000670
cristybb503372010-05-27 20:51:26 +0000671 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000672 x;
673
674 register PixelPacket
cristyc47d1f82009-11-26 01:44:43 +0000675 *restrict q;
cristy3ed852e2009-09-05 21:47:34 +0000676
677 ssize_t
cristyaff6d802011-04-26 01:46:31 +0000678 count,
679 offset;
cristy3ed852e2009-09-05 21:47:34 +0000680
681 unsigned char
682 *pixels;
683
684 if (status == MagickFalse)
685 continue;
686 pixels=GetQuantumPixels(quantum_info);
cristy3ed852e2009-09-05 21:47:34 +0000687 {
688 count=ReadBlob(image,extent,pixels);
689 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
690 (image->previous == (Image *) NULL))
691 {
692 MagickBooleanType
693 proceed;
694
cristy34575212010-11-06 12:39:23 +0000695 proceed=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
696 row,image->rows);
cristy3ed852e2009-09-05 21:47:34 +0000697 if (proceed == MagickFalse)
698 status=MagickFalse;
699 }
700 offset=row++;
701 }
702 if (count != (ssize_t) extent)
703 status=MagickFalse;
cristyaa740112010-03-30 17:58:44 +0000704 q=QueueAuthenticPixels(image,0,offset,image->columns,1,exception);
cristy3ed852e2009-09-05 21:47:34 +0000705 if (q == (PixelPacket *) NULL)
706 {
707 status=MagickFalse;
708 continue;
709 }
710 p=pixels;
711 if ((image->depth == 8) || (image->depth == 16))
cristyaa740112010-03-30 17:58:44 +0000712 (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
cristy3ed852e2009-09-05 21:47:34 +0000713 quantum_type,pixels,exception);
714 else
715 if (image->depth <= 8)
716 {
717 unsigned char
718 pixel;
719
cristybb503372010-05-27 20:51:26 +0000720 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +0000721 {
722 p=PushCharPixel(p,&pixel);
cristyce70c172010-01-07 17:15:30 +0000723 SetRedPixelComponent(q,ScaleAnyToQuantum(pixel,range));
cristy5fde9aa2011-04-23 01:31:53 +0000724 SetGreenPixelComponent(q,GetRedPixelComponent(q));
725 SetBluePixelComponent(q,GetRedPixelComponent(q));
cristy3ed852e2009-09-05 21:47:34 +0000726 q++;
727 }
728 }
729 else
730 {
731 unsigned short
732 pixel;
733
cristybb503372010-05-27 20:51:26 +0000734 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +0000735 {
736 p=PushShortPixel(MSBEndian,p,&pixel);
cristyce70c172010-01-07 17:15:30 +0000737 SetRedPixelComponent(q,ScaleAnyToQuantum(pixel,range));
cristy5fde9aa2011-04-23 01:31:53 +0000738 SetGreenPixelComponent(q,GetRedPixelComponent(q));
739 SetBluePixelComponent(q,GetRedPixelComponent(q));
cristy3ed852e2009-09-05 21:47:34 +0000740 q++;
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 {
755 ImageType
756 type;
757
758 QuantumAny
759 range;
760
761 /*
762 Convert PNM raster image to pixel packets.
763 */
764 type=BilevelType;
765 quantum_type=RGBQuantum;
766 extent=3*(image->depth <= 8 ? 1 : 2)*image->columns;
767 range=GetQuantumRange(image->depth);
768 quantum_info=AcquireQuantumInfo(image_info,image);
769 if (quantum_info == (QuantumInfo *) NULL)
770 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
cristybb503372010-05-27 20:51:26 +0000771 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +0000772 {
cristy3ed852e2009-09-05 21:47:34 +0000773 MagickBooleanType
774 sync;
775
776 register const unsigned char
cristy3f2302b2010-03-11 03:16:37 +0000777 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +0000778
cristybb503372010-05-27 20:51:26 +0000779 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000780 x;
781
782 register PixelPacket
cristyc47d1f82009-11-26 01:44:43 +0000783 *restrict q;
cristy3ed852e2009-09-05 21:47:34 +0000784
785 ssize_t
cristyaff6d802011-04-26 01:46:31 +0000786 count,
787 offset;
cristy3ed852e2009-09-05 21:47:34 +0000788
cristy3ed852e2009-09-05 21:47:34 +0000789 unsigned char
790 *pixels;
791
792 if (status == MagickFalse)
793 continue;
794 pixels=GetQuantumPixels(quantum_info);
cristy3ed852e2009-09-05 21:47:34 +0000795 {
796 count=ReadBlob(image,extent,pixels);
797 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
798 (image->previous == (Image *) NULL))
799 {
800 MagickBooleanType
801 proceed;
802
cristy34575212010-11-06 12:39:23 +0000803 proceed=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
804 row,image->rows);
cristy3ed852e2009-09-05 21:47:34 +0000805 if (proceed == MagickFalse)
806 status=MagickFalse;
807 }
808 offset=row++;
809 }
810 if (count != (ssize_t) extent)
811 status=MagickFalse;
cristyaa740112010-03-30 17:58:44 +0000812 q=QueueAuthenticPixels(image,0,offset,image->columns,1,exception);
cristy3ed852e2009-09-05 21:47:34 +0000813 if (q == (PixelPacket *) NULL)
814 {
815 status=MagickFalse;
816 continue;
817 }
818 p=pixels;
cristye90d7402010-03-14 18:21:29 +0000819 if (image->depth == 8)
cristybb503372010-05-27 20:51:26 +0000820 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +0000821 {
cristy5fde9aa2011-04-23 01:31:53 +0000822 SetRedPixelComponent(q,ScaleCharToQuantum(*p++));
823 SetGreenPixelComponent(q,ScaleCharToQuantum(*p++));
824 SetBluePixelComponent(q,ScaleCharToQuantum(*p++));
cristye90d7402010-03-14 18:21:29 +0000825 q->opacity=OpaqueOpacity;
826 q++;
cristy3ed852e2009-09-05 21:47:34 +0000827 }
828 else
cristye90d7402010-03-14 18:21:29 +0000829 if (image->depth == 16)
cristy3ed852e2009-09-05 21:47:34 +0000830 {
831 unsigned short
832 pixel;
833
cristybb503372010-05-27 20:51:26 +0000834 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +0000835 {
836 p=PushShortPixel(MSBEndian,p,&pixel);
cristyaff6d802011-04-26 01:46:31 +0000837 SetRedPixelComponent(q,ScaleShortToQuantum(pixel));
cristy3ed852e2009-09-05 21:47:34 +0000838 p=PushShortPixel(MSBEndian,p,&pixel);
cristyaff6d802011-04-26 01:46:31 +0000839 SetGreenPixelComponent(q,ScaleShortToQuantum(pixel));
cristy3ed852e2009-09-05 21:47:34 +0000840 p=PushShortPixel(MSBEndian,p,&pixel);
cristyaff6d802011-04-26 01:46:31 +0000841 SetBluePixelComponent(q,ScaleShortToQuantum(pixel));
842 SetOpacityPixelComponent(q,OpaqueOpacity);
cristye90d7402010-03-14 18:21:29 +0000843 q++;
cristy3ed852e2009-09-05 21:47:34 +0000844 }
845 }
cristye90d7402010-03-14 18:21:29 +0000846 else
847 if (image->depth <= 8)
848 {
849 unsigned char
850 pixel;
851
cristybb503372010-05-27 20:51:26 +0000852 for (x=0; x < (ssize_t) image->columns; x++)
cristye90d7402010-03-14 18:21:29 +0000853 {
854 p=PushCharPixel(p,&pixel);
cristyaff6d802011-04-26 01:46:31 +0000855 SetRedPixelComponent(q,ScaleAnyToQuantum(pixel,range));
cristye90d7402010-03-14 18:21:29 +0000856 p=PushCharPixel(p,&pixel);
cristyaff6d802011-04-26 01:46:31 +0000857 SetGreenPixelComponent(q,ScaleAnyToQuantum(pixel,range));
cristye90d7402010-03-14 18:21:29 +0000858 p=PushCharPixel(p,&pixel);
cristyaff6d802011-04-26 01:46:31 +0000859 SetBluePixelComponent(q,ScaleAnyToQuantum(pixel,range));
860 SetOpacityPixelComponent(q,OpaqueOpacity);
cristye90d7402010-03-14 18:21:29 +0000861 q++;
862 }
863 }
864 else
865 {
866 unsigned short
867 pixel;
868
cristybb503372010-05-27 20:51:26 +0000869 for (x=0; x < (ssize_t) image->columns; x++)
cristye90d7402010-03-14 18:21:29 +0000870 {
871 p=PushShortPixel(MSBEndian,p,&pixel);
cristyaff6d802011-04-26 01:46:31 +0000872 SetRedPixelComponent(q,ScaleAnyToQuantum(pixel,range));
cristye90d7402010-03-14 18:21:29 +0000873 p=PushShortPixel(MSBEndian,p,&pixel);
cristyaff6d802011-04-26 01:46:31 +0000874 SetGreenPixelComponent(q,ScaleAnyToQuantum(pixel,range));
cristye90d7402010-03-14 18:21:29 +0000875 p=PushShortPixel(MSBEndian,p,&pixel);
cristyaff6d802011-04-26 01:46:31 +0000876 SetBluePixelComponent(q,ScaleAnyToQuantum(pixel,range));
877 SetOpacityPixelComponent(q,OpaqueOpacity);
cristye90d7402010-03-14 18:21:29 +0000878 q++;
879 }
880 }
cristy3ed852e2009-09-05 21:47:34 +0000881 if ((type == BilevelType) || (type == GrayscaleType))
cristy3ed852e2009-09-05 21:47:34 +0000882 {
cristyaa740112010-03-30 17:58:44 +0000883 q=QueueAuthenticPixels(image,0,offset,image->columns,1,exception);
cristybb503372010-05-27 20:51:26 +0000884 for (x=0; x < (ssize_t) image->columns; x++)
cristye90d7402010-03-14 18:21:29 +0000885 {
886 if ((type == BilevelType) &&
887 (IsMonochromePixel(q) == MagickFalse))
cristy5f1c1ff2010-12-23 21:38:06 +0000888 type=IsGrayPixel(q) == MagickFalse ? UndefinedType :
cristye90d7402010-03-14 18:21:29 +0000889 GrayscaleType;
890 if ((type == GrayscaleType) && (IsGrayPixel(q) == MagickFalse))
cristy5f1c1ff2010-12-23 21:38:06 +0000891 type=UndefinedType;
cristye90d7402010-03-14 18:21:29 +0000892 if ((type != BilevelType) && (type != GrayscaleType))
893 break;
894 q++;
895 }
cristy3ed852e2009-09-05 21:47:34 +0000896 }
cristyaa740112010-03-30 17:58:44 +0000897 sync=SyncAuthenticPixels(image,exception);
cristy3ed852e2009-09-05 21:47:34 +0000898 if (sync == MagickFalse)
899 status=MagickFalse;
900 }
cristy3ed852e2009-09-05 21:47:34 +0000901 quantum_info=DestroyQuantumInfo(quantum_info);
902 if (status == MagickFalse)
903 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
cristy5f1c1ff2010-12-23 21:38:06 +0000904 if (type != UndefinedType)
cristy3ed852e2009-09-05 21:47:34 +0000905 image->type=type;
906 break;
907 }
908 case '7':
909 {
910 register IndexPacket
911 *indexes;
912
913 QuantumAny
914 range;
915
cristybb503372010-05-27 20:51:26 +0000916 size_t
cristy3ed852e2009-09-05 21:47:34 +0000917 channels;
918
919 /*
920 Convert PAM raster image to pixel packets.
921 */
922 range=GetQuantumRange(image->depth);
923 switch (quantum_type)
924 {
925 case GrayQuantum:
926 case GrayAlphaQuantum:
927 {
928 channels=1;
929 break;
930 }
931 case CMYKQuantum:
932 case CMYKAQuantum:
933 {
934 channels=4;
935 break;
936 }
937 default:
938 {
939 channels=3;
940 break;
941 }
942 }
943 if (image->matte != MagickFalse)
944 channels++;
945 extent=channels*(image->depth <= 8 ? 1 : 2)*image->columns;
946 quantum_info=AcquireQuantumInfo(image_info,image);
947 if (quantum_info == (QuantumInfo *) NULL)
948 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
cristybb503372010-05-27 20:51:26 +0000949 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +0000950 {
cristy3ed852e2009-09-05 21:47:34 +0000951 MagickBooleanType
952 sync;
953
954 register const unsigned char
cristy3f2302b2010-03-11 03:16:37 +0000955 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +0000956
cristybb503372010-05-27 20:51:26 +0000957 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000958 x;
959
960 register PixelPacket
cristyc47d1f82009-11-26 01:44:43 +0000961 *restrict q;
cristy3ed852e2009-09-05 21:47:34 +0000962
963 ssize_t
cristyaff6d802011-04-26 01:46:31 +0000964 count,
965 offset;
cristy3ed852e2009-09-05 21:47:34 +0000966
967 unsigned char
968 *pixels;
969
970 if (status == MagickFalse)
971 continue;
972 pixels=GetQuantumPixels(quantum_info);
cristy3ed852e2009-09-05 21:47:34 +0000973 {
974 count=ReadBlob(image,extent,pixels);
975 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
976 (image->previous == (Image *) NULL))
977 {
978 MagickBooleanType
979 proceed;
980
cristy34575212010-11-06 12:39:23 +0000981 proceed=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
982 row,image->rows);
cristy3ed852e2009-09-05 21:47:34 +0000983 if (proceed == MagickFalse)
984 status=MagickFalse;
985 }
986 offset=row++;
987 }
988 if (count != (ssize_t) extent)
989 status=MagickFalse;
cristyaa740112010-03-30 17:58:44 +0000990 q=QueueAuthenticPixels(image,0,offset,image->columns,1,exception);
cristy3ed852e2009-09-05 21:47:34 +0000991 if (q == (PixelPacket *) NULL)
992 {
993 status=MagickFalse;
994 continue;
995 }
cristyaa740112010-03-30 17:58:44 +0000996 indexes=GetAuthenticIndexQueue(image);
cristy3ed852e2009-09-05 21:47:34 +0000997 p=pixels;
998 if ((image->depth == 8) || (image->depth == 16))
cristyaa740112010-03-30 17:58:44 +0000999 (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
cristy3ed852e2009-09-05 21:47:34 +00001000 quantum_type,pixels,exception);
1001 else
1002 switch (quantum_type)
1003 {
1004 case GrayQuantum:
1005 case GrayAlphaQuantum:
1006 {
1007 if (image->depth <= 8)
1008 {
1009 unsigned char
1010 pixel;
1011
cristybb503372010-05-27 20:51:26 +00001012 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00001013 {
1014 p=PushCharPixel(p,&pixel);
cristyce70c172010-01-07 17:15:30 +00001015 SetRedPixelComponent(q,ScaleAnyToQuantum(pixel,range));
cristy5fde9aa2011-04-23 01:31:53 +00001016 SetGreenPixelComponent(q,GetRedPixelComponent(q));
1017 SetBluePixelComponent(q,GetRedPixelComponent(q));
cristyce70c172010-01-07 17:15:30 +00001018 SetOpacityPixelComponent(q,OpaqueOpacity);
cristy3ed852e2009-09-05 21:47:34 +00001019 if (image->matte != MagickFalse)
1020 {
1021 p=PushCharPixel(p,&pixel);
cristy34575212010-11-06 12:39:23 +00001022 SetOpacityPixelComponent(q,ScaleAnyToQuantum(pixel,
1023 range));
cristy3ed852e2009-09-05 21:47:34 +00001024 }
1025 q++;
1026 }
1027 }
1028 else
1029 {
1030 unsigned short
1031 pixel;
1032
cristybb503372010-05-27 20:51:26 +00001033 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00001034 {
1035 p=PushShortPixel(MSBEndian,p,&pixel);
cristyce70c172010-01-07 17:15:30 +00001036 SetRedPixelComponent(q,ScaleAnyToQuantum(pixel,range));
cristy5fde9aa2011-04-23 01:31:53 +00001037 SetGreenPixelComponent(q,GetRedPixelComponent(q));
1038 SetBluePixelComponent(q,GetRedPixelComponent(q));
cristyce70c172010-01-07 17:15:30 +00001039 SetOpacityPixelComponent(q,OpaqueOpacity);
cristy3ed852e2009-09-05 21:47:34 +00001040 if (image->matte != MagickFalse)
1041 {
1042 p=PushShortPixel(MSBEndian,p,&pixel);
cristy34575212010-11-06 12:39:23 +00001043 SetOpacityPixelComponent(q,ScaleAnyToQuantum(pixel,
1044 range));
cristy3ed852e2009-09-05 21:47:34 +00001045 }
1046 q++;
1047 }
1048 }
1049 break;
1050 }
1051 case CMYKQuantum:
1052 case CMYKAQuantum:
1053 {
1054 if (image->depth <= 8)
1055 {
1056 unsigned char
1057 pixel;
1058
cristybb503372010-05-27 20:51:26 +00001059 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00001060 {
1061 p=PushCharPixel(p,&pixel);
cristyce70c172010-01-07 17:15:30 +00001062 SetRedPixelComponent(q,ScaleAnyToQuantum(pixel,range));
cristy3ed852e2009-09-05 21:47:34 +00001063 p=PushCharPixel(p,&pixel);
cristyce70c172010-01-07 17:15:30 +00001064 SetGreenPixelComponent(q,ScaleAnyToQuantum(pixel,range));
cristy3ed852e2009-09-05 21:47:34 +00001065 p=PushCharPixel(p,&pixel);
cristyce70c172010-01-07 17:15:30 +00001066 SetBluePixelComponent(q,ScaleAnyToQuantum(pixel,range));
cristy3ed852e2009-09-05 21:47:34 +00001067 p=PushCharPixel(p,&pixel);
cristyaff6d802011-04-26 01:46:31 +00001068 SetIndexPixelComponent(indexes+x,ScaleAnyToQuantum(pixel,
1069 range));
cristyce70c172010-01-07 17:15:30 +00001070 SetOpacityPixelComponent(q,OpaqueOpacity);
cristy3ed852e2009-09-05 21:47:34 +00001071 if (image->matte != MagickFalse)
1072 {
1073 p=PushCharPixel(p,&pixel);
cristy34575212010-11-06 12:39:23 +00001074 SetOpacityPixelComponent(q,ScaleAnyToQuantum(pixel,
1075 range));
cristy3ed852e2009-09-05 21:47:34 +00001076 }
1077 q++;
1078 }
1079 }
1080 else
1081 {
1082 unsigned short
1083 pixel;
1084
cristybb503372010-05-27 20:51:26 +00001085 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00001086 {
1087 p=PushShortPixel(MSBEndian,p,&pixel);
cristyce70c172010-01-07 17:15:30 +00001088 SetRedPixelComponent(q,ScaleAnyToQuantum(pixel,range));
cristy3ed852e2009-09-05 21:47:34 +00001089 p=PushShortPixel(MSBEndian,p,&pixel);
cristyce70c172010-01-07 17:15:30 +00001090 SetGreenPixelComponent(q,ScaleAnyToQuantum(pixel,range));
cristy3ed852e2009-09-05 21:47:34 +00001091 p=PushShortPixel(MSBEndian,p,&pixel);
cristyce70c172010-01-07 17:15:30 +00001092 SetBluePixelComponent(q,ScaleAnyToQuantum(pixel,range));
cristy3ed852e2009-09-05 21:47:34 +00001093 p=PushShortPixel(MSBEndian,p,&pixel);
cristyaff6d802011-04-26 01:46:31 +00001094 SetIndexPixelComponent(indexes+x,ScaleAnyToQuantum(pixel,
1095 range));
cristyce70c172010-01-07 17:15:30 +00001096 SetOpacityPixelComponent(q,OpaqueOpacity);
cristy3ed852e2009-09-05 21:47:34 +00001097 if (image->matte != MagickFalse)
1098 {
1099 p=PushShortPixel(MSBEndian,p,&pixel);
cristy34575212010-11-06 12:39:23 +00001100 SetOpacityPixelComponent(q,ScaleAnyToQuantum(pixel,
1101 range));
cristy3ed852e2009-09-05 21:47:34 +00001102 }
1103 q++;
1104 }
1105 }
1106 break;
1107 }
1108 default:
1109 {
1110 if (image->depth <= 8)
1111 {
1112 unsigned char
1113 pixel;
1114
cristybb503372010-05-27 20:51:26 +00001115 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00001116 {
1117 p=PushCharPixel(p,&pixel);
cristyce70c172010-01-07 17:15:30 +00001118 SetRedPixelComponent(q,ScaleAnyToQuantum(pixel,range));
cristy3ed852e2009-09-05 21:47:34 +00001119 p=PushCharPixel(p,&pixel);
cristyce70c172010-01-07 17:15:30 +00001120 SetGreenPixelComponent(q,ScaleAnyToQuantum(pixel,range));
cristy3ed852e2009-09-05 21:47:34 +00001121 p=PushCharPixel(p,&pixel);
cristyce70c172010-01-07 17:15:30 +00001122 SetBluePixelComponent(q,ScaleAnyToQuantum(pixel,range));
1123 SetOpacityPixelComponent(q,OpaqueOpacity);
cristy3ed852e2009-09-05 21:47:34 +00001124 if (image->matte != MagickFalse)
1125 {
1126 p=PushCharPixel(p,&pixel);
cristy34575212010-11-06 12:39:23 +00001127 SetOpacityPixelComponent(q,ScaleAnyToQuantum(pixel,
1128 range));
cristy3ed852e2009-09-05 21:47:34 +00001129 }
1130 q++;
1131 }
1132 }
1133 else
1134 {
1135 unsigned short
1136 pixel;
1137
cristybb503372010-05-27 20:51:26 +00001138 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00001139 {
1140 p=PushShortPixel(MSBEndian,p,&pixel);
cristyce70c172010-01-07 17:15:30 +00001141 SetRedPixelComponent(q,ScaleAnyToQuantum(pixel,range));
cristy3ed852e2009-09-05 21:47:34 +00001142 p=PushShortPixel(MSBEndian,p,&pixel);
cristyce70c172010-01-07 17:15:30 +00001143 SetGreenPixelComponent(q,ScaleAnyToQuantum(pixel,range));
cristy3ed852e2009-09-05 21:47:34 +00001144 p=PushShortPixel(MSBEndian,p,&pixel);
cristyce70c172010-01-07 17:15:30 +00001145 SetBluePixelComponent(q,ScaleAnyToQuantum(pixel,range));
1146 SetOpacityPixelComponent(q,OpaqueOpacity);
cristy3ed852e2009-09-05 21:47:34 +00001147 if (image->matte != MagickFalse)
1148 {
1149 p=PushShortPixel(MSBEndian,p,&pixel);
cristy34575212010-11-06 12:39:23 +00001150 SetOpacityPixelComponent(q,ScaleAnyToQuantum(pixel,
1151 range));
cristy3ed852e2009-09-05 21:47:34 +00001152 }
1153 q++;
1154 }
1155 }
1156 break;
1157 }
1158 }
cristyaa740112010-03-30 17:58:44 +00001159 sync=SyncAuthenticPixels(image,exception);
cristy3ed852e2009-09-05 21:47:34 +00001160 if (sync == MagickFalse)
1161 status=MagickFalse;
1162 }
cristy3ed852e2009-09-05 21:47:34 +00001163 quantum_info=DestroyQuantumInfo(quantum_info);
1164 if (status == MagickFalse)
1165 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
1166 SetQuantumImageType(image,quantum_type);
1167 break;
1168 }
1169 case 'F':
1170 case 'f':
1171 {
1172 /*
1173 Convert PFM raster image to pixel packets.
1174 */
1175 quantum_type=format == 'f' ? GrayQuantum : RGBQuantum;
1176 image->endian=quantum_scale < 0.0 ? LSBEndian : MSBEndian;
1177 image->depth=32;
1178 quantum_info=AcquireQuantumInfo(image_info,image);
1179 if (quantum_info == (QuantumInfo *) NULL)
1180 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
1181 status=SetQuantumDepth(image,quantum_info,32);
1182 if (status == MagickFalse)
1183 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
1184 status=SetQuantumFormat(image,quantum_info,FloatingPointQuantumFormat);
1185 if (status == MagickFalse)
1186 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
1187 SetQuantumScale(quantum_info,(MagickRealType) QuantumRange*
1188 fabs(quantum_scale));
1189 extent=GetQuantumExtent(image,quantum_info,quantum_type);
cristybb503372010-05-27 20:51:26 +00001190 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +00001191 {
cristy3ed852e2009-09-05 21:47:34 +00001192 MagickBooleanType
1193 sync;
1194
1195 register PixelPacket
cristyc47d1f82009-11-26 01:44:43 +00001196 *restrict q;
cristy3ed852e2009-09-05 21:47:34 +00001197
1198 ssize_t
cristyaff6d802011-04-26 01:46:31 +00001199 count,
1200 offset;
cristy3ed852e2009-09-05 21:47:34 +00001201
1202 size_t
1203 length;
1204
1205 unsigned char
1206 *pixels;
1207
1208 if (status == MagickFalse)
1209 continue;
1210 pixels=GetQuantumPixels(quantum_info);
cristy3ed852e2009-09-05 21:47:34 +00001211 {
1212 count=ReadBlob(image,extent,pixels);
1213 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
1214 (image->previous == (Image *) NULL))
1215 {
1216 MagickBooleanType
1217 proceed;
1218
cristy34575212010-11-06 12:39:23 +00001219 proceed=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
1220 row,image->rows);
cristy3ed852e2009-09-05 21:47:34 +00001221 if (proceed == MagickFalse)
1222 status=MagickFalse;
1223 }
1224 offset=row++;
1225 }
1226 if ((size_t) count != extent)
1227 status=MagickFalse;
cristybb503372010-05-27 20:51:26 +00001228 q=QueueAuthenticPixels(image,0,(ssize_t) (image->rows-offset-1),
cristyaa740112010-03-30 17:58:44 +00001229 image->columns,1,exception);
cristy3ed852e2009-09-05 21:47:34 +00001230 if (q == (PixelPacket *) NULL)
1231 {
1232 status=MagickFalse;
1233 continue;
1234 }
cristyaa740112010-03-30 17:58:44 +00001235 length=ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1236 quantum_type,pixels,exception);
cristy3ed852e2009-09-05 21:47:34 +00001237 if (length != extent)
1238 status=MagickFalse;
cristyaa740112010-03-30 17:58:44 +00001239 sync=SyncAuthenticPixels(image,exception);
cristy3ed852e2009-09-05 21:47:34 +00001240 if (sync == MagickFalse)
1241 status=MagickFalse;
1242 }
cristy3ed852e2009-09-05 21:47:34 +00001243 quantum_info=DestroyQuantumInfo(quantum_info);
1244 if (status == MagickFalse)
1245 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
1246 SetQuantumImageType(image,quantum_type);
1247 break;
1248 }
1249 default:
1250 ThrowReaderException(CorruptImageError,"ImproperImageHeader");
1251 }
1252 if (EOFBlob(image) != MagickFalse)
1253 (void) ThrowMagickException(exception,GetMagickModule(),CorruptImageError,
1254 "UnexpectedEndOfFile","`%s'",image->filename);
1255 /*
1256 Proceed to next image.
1257 */
1258 if (image_info->number_scenes != 0)
1259 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
1260 break;
1261 if ((format == '1') || (format == '2') || (format == '3'))
1262 do
1263 {
1264 /*
1265 Skip to end of line.
1266 */
1267 count=ReadBlob(image,1,(unsigned char *) &format);
1268 if (count == 0)
1269 break;
1270 if ((count != 0) && (format == 'P'))
1271 break;
1272 } while (format != '\n');
1273 count=ReadBlob(image,1,(unsigned char *) &format);
1274 if ((count == 1) && (format == 'P'))
1275 {
1276 /*
1277 Allocate next image structure.
1278 */
1279 AcquireNextImage(image_info,image);
1280 if (GetNextImageInList(image) == (Image *) NULL)
1281 {
1282 image=DestroyImageList(image);
1283 return((Image *) NULL);
1284 }
1285 image=SyncNextImageInList(image);
1286 status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
1287 GetBlobSize(image));
1288 if (status == MagickFalse)
1289 break;
1290 }
1291 } while ((count == 1) && (format == 'P'));
1292 (void) CloseBlob(image);
1293 return(GetFirstImageInList(image));
1294}
1295
1296/*
1297%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1298% %
1299% %
1300% %
1301% R e g i s t e r P N M I m a g e %
1302% %
1303% %
1304% %
1305%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1306%
1307% RegisterPNMImage() adds properties for the PNM image format to
1308% the list of supported formats. The properties include the image format
1309% tag, a method to read and/or write the format, whether the format
1310% supports the saving of more than one frame to the same file or blob,
1311% whether the format supports native in-memory I/O, and a brief
1312% description of the format.
1313%
1314% The format of the RegisterPNMImage method is:
1315%
cristybb503372010-05-27 20:51:26 +00001316% size_t RegisterPNMImage(void)
cristy3ed852e2009-09-05 21:47:34 +00001317%
1318*/
cristybb503372010-05-27 20:51:26 +00001319ModuleExport size_t RegisterPNMImage(void)
cristy3ed852e2009-09-05 21:47:34 +00001320{
1321 MagickInfo
1322 *entry;
1323
1324 entry=SetMagickInfo("PAM");
1325 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1326 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1327 entry->description=ConstantString("Common 2-dimensional bitmap format");
1328 entry->module=ConstantString("PNM");
1329 (void) RegisterMagickInfo(entry);
1330 entry=SetMagickInfo("PBM");
1331 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1332 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1333 entry->description=ConstantString("Portable bitmap format (black and white)");
1334 entry->module=ConstantString("PNM");
1335 (void) RegisterMagickInfo(entry);
1336 entry=SetMagickInfo("PFM");
1337 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1338 entry->encoder=(EncodeImageHandler *) WritePNMImage;
cristye96405a2010-05-19 02:24:31 +00001339 entry->endian_support=MagickTrue;
cristy3ed852e2009-09-05 21:47:34 +00001340 entry->description=ConstantString("Portable float format");
1341 entry->module=ConstantString("PFM");
1342 (void) RegisterMagickInfo(entry);
1343 entry=SetMagickInfo("PGM");
1344 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1345 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1346 entry->description=ConstantString("Portable graymap format (gray scale)");
1347 entry->module=ConstantString("PNM");
1348 (void) RegisterMagickInfo(entry);
1349 entry=SetMagickInfo("PNM");
1350 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1351 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1352 entry->magick=(IsImageFormatHandler *) IsPNM;
1353 entry->description=ConstantString("Portable anymap");
1354 entry->module=ConstantString("PNM");
1355 (void) RegisterMagickInfo(entry);
1356 entry=SetMagickInfo("PPM");
1357 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1358 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1359 entry->description=ConstantString("Portable pixmap format (color)");
1360 entry->module=ConstantString("PNM");
1361 (void) RegisterMagickInfo(entry);
1362 return(MagickImageCoderSignature);
1363}
1364
1365/*
1366%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1367% %
1368% %
1369% %
1370% U n r e g i s t e r P N M I m a g e %
1371% %
1372% %
1373% %
1374%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1375%
1376% UnregisterPNMImage() removes format registrations made by the
1377% PNM module from the list of supported formats.
1378%
1379% The format of the UnregisterPNMImage method is:
1380%
1381% UnregisterPNMImage(void)
1382%
1383*/
1384ModuleExport void UnregisterPNMImage(void)
1385{
1386 (void) UnregisterMagickInfo("PAM");
1387 (void) UnregisterMagickInfo("PBM");
1388 (void) UnregisterMagickInfo("PGM");
1389 (void) UnregisterMagickInfo("PNM");
1390 (void) UnregisterMagickInfo("PPM");
1391}
1392
1393/*
1394%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1395% %
1396% %
1397% %
1398% W r i t e P N M I m a g e %
1399% %
1400% %
1401% %
1402%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1403%
cristy661b5ad2010-01-13 00:54:42 +00001404% WritePNMImage() writes an image to a file in the PNM rasterfile format.
cristy3ed852e2009-09-05 21:47:34 +00001405%
1406% The format of the WritePNMImage method is:
1407%
1408% MagickBooleanType WritePNMImage(const ImageInfo *image_info,Image *image)
1409%
1410% A description of each parameter follows.
1411%
1412% o image_info: the image info.
1413%
1414% o image: The image.
1415%
1416*/
1417static MagickBooleanType WritePNMImage(const ImageInfo *image_info,Image *image)
1418{
1419 char
1420 buffer[MaxTextExtent],
1421 format,
1422 magick[MaxTextExtent];
1423
1424 const char
1425 *value;
1426
1427 IndexPacket
1428 index;
1429
cristy3ed852e2009-09-05 21:47:34 +00001430 MagickBooleanType
1431 status;
1432
1433 MagickOffsetType
1434 scene;
1435
1436 QuantumAny
1437 pixel;
1438
1439 QuantumInfo
1440 *quantum_info;
1441
1442 QuantumType
1443 quantum_type;
1444
cristy3ed852e2009-09-05 21:47:34 +00001445 register unsigned char
1446 *pixels,
1447 *q;
1448
cristy3ed852e2009-09-05 21:47:34 +00001449 size_t
1450 extent,
1451 packet_size;
1452
cristy95802a72010-09-05 19:07:17 +00001453 ssize_t
cristyaff6d802011-04-26 01:46:31 +00001454 count,
1455 y;
cristy95802a72010-09-05 19:07:17 +00001456
cristy3ed852e2009-09-05 21:47:34 +00001457 /*
1458 Open output image file.
1459 */
1460 assert(image_info != (const ImageInfo *) NULL);
1461 assert(image_info->signature == MagickSignature);
1462 assert(image != (Image *) NULL);
1463 assert(image->signature == MagickSignature);
1464 if (image->debug != MagickFalse)
1465 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1466 status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
1467 if (status == MagickFalse)
1468 return(status);
1469 scene=0;
1470 do
1471 {
1472 /*
1473 Write PNM file header.
1474 */
1475 packet_size=3;
1476 quantum_type=RGBQuantum;
1477 (void) CopyMagickString(magick,image_info->magick,MaxTextExtent);
1478 switch (magick[1])
1479 {
1480 case 'A':
1481 case 'a':
1482 {
1483 format='7';
1484 break;
1485 }
1486 case 'B':
1487 case 'b':
1488 {
1489 format='4';
1490 if (image_info->compression == NoCompression)
1491 format='1';
1492 break;
1493 }
1494 case 'F':
1495 case 'f':
1496 {
1497 format='F';
1498 if (IsGrayImage(image,&image->exception) != MagickFalse)
1499 format='f';
1500 break;
1501 }
1502 case 'G':
1503 case 'g':
1504 {
1505 format='5';
1506 if (image_info->compression == NoCompression)
1507 format='2';
1508 break;
1509 }
1510 case 'N':
1511 case 'n':
1512 {
1513 if ((image_info->type != TrueColorType) &&
1514 (IsGrayImage(image,&image->exception) != MagickFalse))
1515 {
1516 format='5';
1517 if (image_info->compression == NoCompression)
1518 format='2';
1519 if (IsMonochromeImage(image,&image->exception) != MagickFalse)
1520 {
1521 format='4';
1522 if (image_info->compression == NoCompression)
1523 format='1';
1524 }
1525 break;
1526 }
1527 }
1528 default:
1529 {
1530 format='6';
1531 if (image_info->compression == NoCompression)
1532 format='3';
1533 break;
1534 }
1535 }
cristyb51dff52011-05-19 16:55:47 +00001536 (void) FormatLocaleString(buffer,MaxTextExtent,"P%c\n",format);
cristy3ed852e2009-09-05 21:47:34 +00001537 (void) WriteBlobString(image,buffer);
1538 value=GetImageProperty(image,"comment");
1539 if (value != (const char *) NULL)
1540 {
1541 register const char
1542 *p;
1543
1544 /*
1545 Write comments to file.
1546 */
1547 (void) WriteBlobByte(image,'#');
1548 for (p=value; *p != '\0'; p++)
1549 {
1550 (void) WriteBlobByte(image,(unsigned char) *p);
1551 if ((*p == '\r') && (*(p+1) != '\0'))
1552 (void) WriteBlobByte(image,'#');
1553 if ((*p == '\n') && (*(p+1) != '\0'))
1554 (void) WriteBlobByte(image,'#');
1555 }
1556 (void) WriteBlobByte(image,'\n');
1557 }
1558 if (format != '7')
1559 {
1560 if (image->colorspace != RGBColorspace)
1561 (void) TransformImageColorspace(image,RGBColorspace);
cristyb51dff52011-05-19 16:55:47 +00001562 (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g %.20g\n",
cristye8c25f92010-06-03 00:53:06 +00001563 (double) image->columns,(double) image->rows);
cristy3ed852e2009-09-05 21:47:34 +00001564 (void) WriteBlobString(image,buffer);
1565 }
1566 else
1567 {
1568 char
1569 type[MaxTextExtent];
1570
1571 /*
1572 PAM header.
1573 */
cristyb51dff52011-05-19 16:55:47 +00001574 (void) FormatLocaleString(buffer,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00001575 "WIDTH %.20g\nHEIGHT %.20g\n",(double) image->columns,(double)
1576 image->rows);
cristy3ed852e2009-09-05 21:47:34 +00001577 (void) WriteBlobString(image,buffer);
1578 quantum_type=GetQuantumType(image,&image->exception);
1579 switch (quantum_type)
1580 {
1581 case CMYKQuantum:
1582 case CMYKAQuantum:
1583 {
1584 packet_size=4;
1585 (void) CopyMagickString(type,"CMYK",MaxTextExtent);
1586 break;
1587 }
1588 case GrayQuantum:
1589 case GrayAlphaQuantum:
1590 {
1591 packet_size=1;
1592 (void) CopyMagickString(type,"GRAYSCALE",MaxTextExtent);
1593 break;
1594 }
1595 default:
1596 {
1597 quantum_type=RGBQuantum;
1598 if (image->matte != MagickFalse)
1599 quantum_type=RGBAQuantum;
1600 packet_size=3;
1601 (void) CopyMagickString(type,"RGB",MaxTextExtent);
1602 break;
1603 }
1604 }
1605 if (image->matte != MagickFalse)
1606 {
1607 packet_size++;
1608 (void) ConcatenateMagickString(type,"_ALPHA",MaxTextExtent);
1609 }
1610 if (image->depth > 16)
1611 image->depth=16;
cristyb51dff52011-05-19 16:55:47 +00001612 (void) FormatLocaleString(buffer,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00001613 "DEPTH %.20g\nMAXVAL %.20g\n",(double) packet_size,(double)
cristy3ed852e2009-09-05 21:47:34 +00001614 GetQuantumRange(image->depth));
1615 (void) WriteBlobString(image,buffer);
cristyb51dff52011-05-19 16:55:47 +00001616 (void) FormatLocaleString(buffer,MaxTextExtent,"TUPLTYPE %s\nENDHDR\n",
cristy3ed852e2009-09-05 21:47:34 +00001617 type);
1618 (void) WriteBlobString(image,buffer);
1619 }
1620 /*
1621 Convert runextent encoded to PNM raster pixels.
1622 */
1623 switch (format)
1624 {
1625 case '1':
1626 {
cristy661b5ad2010-01-13 00:54:42 +00001627 unsigned char
1628 pixels[2048];
cristy3ed852e2009-09-05 21:47:34 +00001629
1630 /*
1631 Convert image to a PBM image.
1632 */
cristy661b5ad2010-01-13 00:54:42 +00001633 q=pixels;
cristybb503372010-05-27 20:51:26 +00001634 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +00001635 {
cristy3ed852e2009-09-05 21:47:34 +00001636 register const PixelPacket
cristyc47d1f82009-11-26 01:44:43 +00001637 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +00001638
cristybb503372010-05-27 20:51:26 +00001639 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001640 x;
1641
1642 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1643 if (p == (const PixelPacket *) NULL)
1644 break;
cristybb503372010-05-27 20:51:26 +00001645 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00001646 {
1647 pixel=PixelIntensityToQuantum(p);
cristy661b5ad2010-01-13 00:54:42 +00001648 *q++=(unsigned char) (pixel >= (Quantum) (QuantumRange/2) ?
1649 '0' : '1');
1650 *q++=' ';
1651 if ((q-pixels+2) >= 80)
1652 {
1653 *q++='\n';
1654 (void) WriteBlob(image,q-pixels,pixels);
1655 q=pixels;
cristy661b5ad2010-01-13 00:54:42 +00001656 }
cristy3ed852e2009-09-05 21:47:34 +00001657 p++;
1658 }
1659 if (image->previous == (Image *) NULL)
1660 {
cristycee97112010-05-28 00:44:52 +00001661 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1662 image->rows);
cristy3ed852e2009-09-05 21:47:34 +00001663 if (status == MagickFalse)
1664 break;
1665 }
1666 }
cristy661b5ad2010-01-13 00:54:42 +00001667 if (q != pixels)
1668 {
1669 *q++='\n';
1670 (void) WriteBlob(image,q-pixels,pixels);
1671 }
cristy3ed852e2009-09-05 21:47:34 +00001672 break;
1673 }
1674 case '2':
1675 {
cristy661b5ad2010-01-13 00:54:42 +00001676 unsigned char
1677 pixels[2048];
cristy3ed852e2009-09-05 21:47:34 +00001678
1679 /*
1680 Convert image to a PGM image.
1681 */
1682 if (image->depth <= 8)
1683 (void) WriteBlobString(image,"255\n");
1684 else
1685 (void) WriteBlobString(image,"65535\n");
cristy661b5ad2010-01-13 00:54:42 +00001686 q=pixels;
cristybb503372010-05-27 20:51:26 +00001687 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +00001688 {
1689 register const PixelPacket
cristyc47d1f82009-11-26 01:44:43 +00001690 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +00001691
cristybb503372010-05-27 20:51:26 +00001692 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001693 x;
1694
1695 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1696 if (p == (const PixelPacket *) NULL)
1697 break;
cristybb503372010-05-27 20:51:26 +00001698 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00001699 {
1700 index=PixelIntensityToQuantum(p);
1701 if (image->depth <= 8)
cristyb51dff52011-05-19 16:55:47 +00001702 count=(ssize_t) FormatLocaleString(buffer,MaxTextExtent,"%u ",
cristy3ed852e2009-09-05 21:47:34 +00001703 ScaleQuantumToChar(index));
1704 else
cristyb51dff52011-05-19 16:55:47 +00001705 count=(ssize_t) FormatLocaleString(buffer,MaxTextExtent,"%u ",
cristy3ed852e2009-09-05 21:47:34 +00001706 ScaleQuantumToShort(index));
cristy661b5ad2010-01-13 00:54:42 +00001707 extent=(size_t) count;
1708 (void) strncpy((char *) q,buffer,extent);
1709 q+=extent;
1710 if ((q-pixels+extent) >= 80)
1711 {
1712 *q++='\n';
1713 (void) WriteBlob(image,q-pixels,pixels);
1714 q=pixels;
1715 }
cristy3ed852e2009-09-05 21:47:34 +00001716 p++;
1717 }
1718 if (image->previous == (Image *) NULL)
1719 {
cristycee97112010-05-28 00:44:52 +00001720 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1721 image->rows);
cristy3ed852e2009-09-05 21:47:34 +00001722 if (status == MagickFalse)
1723 break;
1724 }
1725 }
cristy661b5ad2010-01-13 00:54:42 +00001726 if (q != pixels)
1727 {
1728 *q++='\n';
1729 (void) WriteBlob(image,q-pixels,pixels);
1730 }
cristy3ed852e2009-09-05 21:47:34 +00001731 break;
1732 }
1733 case '3':
1734 {
cristy661b5ad2010-01-13 00:54:42 +00001735 unsigned char
1736 pixels[2048];
cristy3ed852e2009-09-05 21:47:34 +00001737
1738 /*
1739 Convert image to a PNM image.
1740 */
1741 if (image->depth <= 8)
1742 (void) WriteBlobString(image,"255\n");
1743 else
1744 (void) WriteBlobString(image,"65535\n");
cristy661b5ad2010-01-13 00:54:42 +00001745 q=pixels;
cristybb503372010-05-27 20:51:26 +00001746 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +00001747 {
1748 register const PixelPacket
cristyc47d1f82009-11-26 01:44:43 +00001749 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +00001750
cristybb503372010-05-27 20:51:26 +00001751 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001752 x;
1753
1754 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1755 if (p == (const PixelPacket *) NULL)
1756 break;
cristybb503372010-05-27 20:51:26 +00001757 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00001758 {
1759 if (image->depth <= 8)
cristyb51dff52011-05-19 16:55:47 +00001760 count=(ssize_t) FormatLocaleString(buffer,MaxTextExtent,
cristyce70c172010-01-07 17:15:30 +00001761 "%u %u %u ",ScaleQuantumToChar(GetRedPixelComponent(p)),
cristy375dc4b2010-01-12 20:24:58 +00001762 ScaleQuantumToChar(GetGreenPixelComponent(p)),
1763 ScaleQuantumToChar(GetBluePixelComponent(p)));
cristy3ed852e2009-09-05 21:47:34 +00001764 else
cristyb51dff52011-05-19 16:55:47 +00001765 count=(ssize_t) FormatLocaleString(buffer,MaxTextExtent,
cristyce70c172010-01-07 17:15:30 +00001766 "%u %u %u ",ScaleQuantumToShort(GetRedPixelComponent(p)),
cristy375dc4b2010-01-12 20:24:58 +00001767 ScaleQuantumToShort(GetGreenPixelComponent(p)),
1768 ScaleQuantumToShort(GetBluePixelComponent(p)));
cristy661b5ad2010-01-13 00:54:42 +00001769 extent=(size_t) count;
1770 (void) strncpy((char *) q,buffer,extent);
1771 q+=extent;
1772 if ((q-pixels+extent) >= 80)
1773 {
1774 *q++='\n';
1775 (void) WriteBlob(image,q-pixels,pixels);
1776 q=pixels;
1777 }
cristy3ed852e2009-09-05 21:47:34 +00001778 p++;
1779 }
1780 if (image->previous == (Image *) NULL)
1781 {
cristycee97112010-05-28 00:44:52 +00001782 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1783 image->rows);
cristy3ed852e2009-09-05 21:47:34 +00001784 if (status == MagickFalse)
1785 break;
1786 }
1787 }
cristy661b5ad2010-01-13 00:54:42 +00001788 if (q != pixels)
1789 {
1790 *q++='\n';
1791 (void) WriteBlob(image,q-pixels,pixels);
1792 }
cristy3ed852e2009-09-05 21:47:34 +00001793 break;
1794 }
1795 case '4':
1796 {
1797 /*
1798 Convert image to a PBM image.
1799 */
1800 image->depth=1;
1801 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
1802 if (quantum_info == (QuantumInfo *) NULL)
1803 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1804 quantum_info->min_is_white=MagickTrue;
1805 pixels=GetQuantumPixels(quantum_info);
cristybb503372010-05-27 20:51:26 +00001806 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +00001807 {
1808 register const PixelPacket
cristyc47d1f82009-11-26 01:44:43 +00001809 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +00001810
1811 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1812 if (p == (const PixelPacket *) NULL)
1813 break;
1814 extent=ExportQuantumPixels(image,(const CacheView *) NULL,
1815 quantum_info,GrayQuantum,pixels,&image->exception);
1816 count=WriteBlob(image,extent,pixels);
1817 if (count != (ssize_t) extent)
1818 break;
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 }
1827 quantum_info=DestroyQuantumInfo(quantum_info);
1828 break;
1829 }
1830 case '5':
1831 {
1832 QuantumAny
1833 range;
1834
1835 /*
1836 Convert image to a PGM image.
1837 */
1838 if (image->depth > 8)
1839 image->depth=16;
cristyb51dff52011-05-19 16:55:47 +00001840 (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g\n",(double)
cristy3ed852e2009-09-05 21:47:34 +00001841 GetQuantumRange(image->depth));
1842 (void) WriteBlobString(image,buffer);
1843 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
1844 if (quantum_info == (QuantumInfo *) NULL)
1845 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1846 quantum_info->min_is_white=MagickTrue;
1847 pixels=GetQuantumPixels(quantum_info);
1848 extent=GetQuantumExtent(image,quantum_info,GrayQuantum);
1849 range=GetQuantumRange(image->depth);
cristybb503372010-05-27 20:51:26 +00001850 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +00001851 {
1852 register const PixelPacket
cristyc47d1f82009-11-26 01:44:43 +00001853 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +00001854
cristybb503372010-05-27 20:51:26 +00001855 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001856 x;
1857
1858 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1859 if (p == (const PixelPacket *) NULL)
1860 break;
1861 q=pixels;
1862 if ((image->depth == 8) || (image->depth == 16))
1863 extent=ExportQuantumPixels(image,(const CacheView *) NULL,
1864 quantum_info,GrayQuantum,pixels,&image->exception);
1865 else
1866 {
1867 if (image->depth <= 8)
cristybb503372010-05-27 20:51:26 +00001868 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00001869 {
1870 if (IsGrayPixel(p) == MagickFalse)
1871 pixel=ScaleQuantumToAny(PixelIntensityToQuantum(p),range);
1872 else
1873 {
1874 if (image->depth == 8)
cristyce70c172010-01-07 17:15:30 +00001875 pixel=ScaleQuantumToChar(GetRedPixelComponent(p));
cristy3ed852e2009-09-05 21:47:34 +00001876 else
cristy89bbeaf2011-04-22 20:25:27 +00001877 pixel=ScaleQuantumToAny(GetRedPixelComponent(p),range);
cristy3ed852e2009-09-05 21:47:34 +00001878 }
1879 q=PopCharPixel((unsigned char) pixel,q);
1880 p++;
1881 }
1882 else
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 == 16)
cristyce70c172010-01-07 17:15:30 +00001890 pixel=ScaleQuantumToShort(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=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
1895 p++;
1896 }
1897 extent=(size_t) (q-pixels);
1898 }
1899 count=WriteBlob(image,extent,pixels);
1900 if (count != (ssize_t) extent)
1901 break;
1902 if (image->previous == (Image *) NULL)
1903 {
cristycee97112010-05-28 00:44:52 +00001904 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1905 image->rows);
cristy3ed852e2009-09-05 21:47:34 +00001906 if (status == MagickFalse)
1907 break;
1908 }
1909 }
1910 quantum_info=DestroyQuantumInfo(quantum_info);
1911 break;
1912 }
1913 case '6':
1914 {
1915 QuantumAny
1916 range;
1917
1918 /*
1919 Convert image to a PNM image.
1920 */
1921 if (image->depth > 8)
1922 image->depth=16;
cristyb51dff52011-05-19 16:55:47 +00001923 (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g\n",(double)
cristy3ed852e2009-09-05 21:47:34 +00001924 GetQuantumRange(image->depth));
1925 (void) WriteBlobString(image,buffer);
1926 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
1927 if (quantum_info == (QuantumInfo *) NULL)
1928 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1929 pixels=GetQuantumPixels(quantum_info);
1930 extent=GetQuantumExtent(image,quantum_info,quantum_type);
1931 range=GetQuantumRange(image->depth);
cristybb503372010-05-27 20:51:26 +00001932 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +00001933 {
1934 register const PixelPacket
cristyc47d1f82009-11-26 01:44:43 +00001935 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +00001936
cristybb503372010-05-27 20:51:26 +00001937 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001938 x;
1939
1940 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1941 if (p == (const PixelPacket *) NULL)
1942 break;
1943 q=pixels;
1944 if ((image->depth == 8) || (image->depth == 16))
1945 extent=ExportQuantumPixels(image,(const CacheView *) NULL,
1946 quantum_info,quantum_type,pixels,&image->exception);
1947 else
1948 {
1949 if (image->depth <= 8)
cristybb503372010-05-27 20:51:26 +00001950 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00001951 {
cristy89bbeaf2011-04-22 20:25:27 +00001952 pixel=ScaleQuantumToAny(GetRedPixelComponent(p),range);
cristy3ed852e2009-09-05 21:47:34 +00001953 q=PopCharPixel((unsigned char) pixel,q);
cristy89bbeaf2011-04-22 20:25:27 +00001954 pixel=ScaleQuantumToAny(GetGreenPixelComponent(p),range);
cristy3ed852e2009-09-05 21:47:34 +00001955 q=PopCharPixel((unsigned char) pixel,q);
cristy89bbeaf2011-04-22 20:25:27 +00001956 pixel=ScaleQuantumToAny(GetBluePixelComponent(p),range);
cristy3ed852e2009-09-05 21:47:34 +00001957 q=PopCharPixel((unsigned char) pixel,q);
cristy3ed852e2009-09-05 21:47:34 +00001958 p++;
1959 }
1960 else
cristybb503372010-05-27 20:51:26 +00001961 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00001962 {
cristy89bbeaf2011-04-22 20:25:27 +00001963 pixel=ScaleQuantumToAny(GetRedPixelComponent(p),range);
cristy3ed852e2009-09-05 21:47:34 +00001964 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
cristy89bbeaf2011-04-22 20:25:27 +00001965 pixel=ScaleQuantumToAny(GetGreenPixelComponent(p),range);
cristy3ed852e2009-09-05 21:47:34 +00001966 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
cristy89bbeaf2011-04-22 20:25:27 +00001967 pixel=ScaleQuantumToAny(GetBluePixelComponent(p),range);
cristy3ed852e2009-09-05 21:47:34 +00001968 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
cristy3ed852e2009-09-05 21:47:34 +00001969 p++;
1970 }
1971 extent=(size_t) (q-pixels);
1972 }
1973 count=WriteBlob(image,extent,pixels);
1974 if (count != (ssize_t) extent)
1975 break;
1976 if (image->previous == (Image *) NULL)
1977 {
cristycee97112010-05-28 00:44:52 +00001978 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1979 image->rows);
cristy3ed852e2009-09-05 21:47:34 +00001980 if (status == MagickFalse)
1981 break;
1982 }
1983 }
1984 quantum_info=DestroyQuantumInfo(quantum_info);
1985 break;
1986 }
1987 case '7':
1988 {
1989 QuantumAny
1990 range;
1991
1992 /*
1993 Convert image to a PAM.
1994 */
1995 if (image->depth > 16)
1996 image->depth=16;
1997 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
1998 pixels=GetQuantumPixels(quantum_info);
1999 range=GetQuantumRange(image->depth);
cristybb503372010-05-27 20:51:26 +00002000 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +00002001 {
2002 register const IndexPacket
cristyc47d1f82009-11-26 01:44:43 +00002003 *restrict indexes;
cristy3ed852e2009-09-05 21:47:34 +00002004
2005 register const PixelPacket
cristyc47d1f82009-11-26 01:44:43 +00002006 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +00002007
cristybb503372010-05-27 20:51:26 +00002008 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002009 x;
2010
2011 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
2012 if (p == (const PixelPacket *) NULL)
2013 break;
2014 indexes=GetVirtualIndexQueue(image);
2015 q=pixels;
2016 if ((image->depth == 8) || (image->depth == 16))
2017 extent=ExportQuantumPixels(image,(const CacheView *) NULL,
2018 quantum_info,quantum_type,pixels,&image->exception);
2019 else
2020 {
2021 switch (quantum_type)
2022 {
2023 case GrayQuantum:
2024 case GrayAlphaQuantum:
2025 {
2026 if (image->depth <= 8)
cristybb503372010-05-27 20:51:26 +00002027 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00002028 {
2029 pixel=ScaleQuantumToAny(PixelIntensityToQuantum(p),range);
2030 q=PopCharPixel((unsigned char) pixel,q);
2031 if (image->matte != MagickFalse)
2032 {
cristyaff6d802011-04-26 01:46:31 +00002033 pixel=(unsigned char) ScaleQuantumToAny(
2034 GetOpacityPixelComponent(p),range);
cristy3ed852e2009-09-05 21:47:34 +00002035 q=PopCharPixel((unsigned char) pixel,q);
2036 }
2037 p++;
2038 }
2039 else
cristybb503372010-05-27 20:51:26 +00002040 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00002041 {
2042 pixel=ScaleQuantumToAny(PixelIntensityToQuantum(p),range);
2043 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2044 if (image->matte != MagickFalse)
2045 {
cristyaff6d802011-04-26 01:46:31 +00002046 pixel=(unsigned char) ScaleQuantumToAny(
2047 GetOpacityPixelComponent(p),range);
cristy3ed852e2009-09-05 21:47:34 +00002048 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2049 }
2050 p++;
2051 }
2052 break;
2053 }
2054 case CMYKQuantum:
2055 case CMYKAQuantum:
2056 {
2057 if (image->depth <= 8)
cristybb503372010-05-27 20:51:26 +00002058 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00002059 {
cristy89bbeaf2011-04-22 20:25:27 +00002060 pixel=ScaleQuantumToAny(GetRedPixelComponent(p),range);
cristy3ed852e2009-09-05 21:47:34 +00002061 q=PopCharPixel((unsigned char) pixel,q);
cristy89bbeaf2011-04-22 20:25:27 +00002062 pixel=ScaleQuantumToAny(GetGreenPixelComponent(p),range);
cristy3ed852e2009-09-05 21:47:34 +00002063 q=PopCharPixel((unsigned char) pixel,q);
cristy89bbeaf2011-04-22 20:25:27 +00002064 pixel=ScaleQuantumToAny(GetBluePixelComponent(p),range);
cristy3ed852e2009-09-05 21:47:34 +00002065 q=PopCharPixel((unsigned char) pixel,q);
cristyaff6d802011-04-26 01:46:31 +00002066 pixel=ScaleQuantumToAny(
2067 GetIndexPixelComponent(indexes+x),range);
cristy3ed852e2009-09-05 21:47:34 +00002068 q=PopCharPixel((unsigned char) pixel,q);
2069 if (image->matte != MagickFalse)
2070 {
2071 pixel=ScaleQuantumToAny((Quantum) (QuantumRange-
cristyce70c172010-01-07 17:15:30 +00002072 GetOpacityPixelComponent(p)),range);
cristy3ed852e2009-09-05 21:47:34 +00002073 q=PopCharPixel((unsigned char) pixel,q);
2074 }
2075 p++;
2076 }
2077 else
cristybb503372010-05-27 20:51:26 +00002078 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00002079 {
cristy89bbeaf2011-04-22 20:25:27 +00002080 pixel=ScaleQuantumToAny(GetRedPixelComponent(p),range);
cristy3ed852e2009-09-05 21:47:34 +00002081 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
cristy89bbeaf2011-04-22 20:25:27 +00002082 pixel=ScaleQuantumToAny(GetGreenPixelComponent(p),range);
cristy3ed852e2009-09-05 21:47:34 +00002083 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
cristy89bbeaf2011-04-22 20:25:27 +00002084 pixel=ScaleQuantumToAny(GetBluePixelComponent(p),range);
cristy3ed852e2009-09-05 21:47:34 +00002085 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
cristyaff6d802011-04-26 01:46:31 +00002086 pixel=ScaleQuantumToAny(
2087 GetIndexPixelComponent(indexes+x),range);
cristy3ed852e2009-09-05 21:47:34 +00002088 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2089 if (image->matte != MagickFalse)
2090 {
2091 pixel=ScaleQuantumToAny((Quantum) (QuantumRange-
cristyce70c172010-01-07 17:15:30 +00002092 GetOpacityPixelComponent(p)),range);
cristy3ed852e2009-09-05 21:47:34 +00002093 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2094 }
2095 p++;
2096 }
2097 break;
2098 }
2099 default:
2100 {
2101 if (image->depth <= 8)
cristybb503372010-05-27 20:51:26 +00002102 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00002103 {
cristy89bbeaf2011-04-22 20:25:27 +00002104 pixel=ScaleQuantumToAny(GetRedPixelComponent(p),range);
cristy3ed852e2009-09-05 21:47:34 +00002105 q=PopCharPixel((unsigned char) pixel,q);
cristy89bbeaf2011-04-22 20:25:27 +00002106 pixel=ScaleQuantumToAny(GetGreenPixelComponent(p),range);
cristy3ed852e2009-09-05 21:47:34 +00002107 q=PopCharPixel((unsigned char) pixel,q);
cristy89bbeaf2011-04-22 20:25:27 +00002108 pixel=ScaleQuantumToAny(GetBluePixelComponent(p),range);
cristy3ed852e2009-09-05 21:47:34 +00002109 q=PopCharPixel((unsigned char) pixel,q);
2110 if (image->matte != MagickFalse)
2111 {
2112 pixel=ScaleQuantumToAny((Quantum) (QuantumRange-
cristyce70c172010-01-07 17:15:30 +00002113 GetOpacityPixelComponent(p)),range);
cristy3ed852e2009-09-05 21:47:34 +00002114 q=PopCharPixel((unsigned char) pixel,q);
2115 }
2116 p++;
2117 }
2118 else
cristybb503372010-05-27 20:51:26 +00002119 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +00002120 {
cristy89bbeaf2011-04-22 20:25:27 +00002121 pixel=ScaleQuantumToAny(GetRedPixelComponent(p),range);
cristy3ed852e2009-09-05 21:47:34 +00002122 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
cristy89bbeaf2011-04-22 20:25:27 +00002123 pixel=ScaleQuantumToAny(GetGreenPixelComponent(p),range);
cristy3ed852e2009-09-05 21:47:34 +00002124 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
cristy89bbeaf2011-04-22 20:25:27 +00002125 pixel=ScaleQuantumToAny(GetBluePixelComponent(p),range);
cristy3ed852e2009-09-05 21:47:34 +00002126 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2127 if (image->matte != MagickFalse)
2128 {
2129 pixel=ScaleQuantumToAny((Quantum) (QuantumRange-
cristyce70c172010-01-07 17:15:30 +00002130 GetOpacityPixelComponent(p)),range);
cristy3ed852e2009-09-05 21:47:34 +00002131 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2132 }
2133 p++;
2134 }
2135 break;
2136 }
2137 }
2138 extent=(size_t) (q-pixels);
2139 }
2140 count=WriteBlob(image,extent,pixels);
2141 if (count != (ssize_t) extent)
2142 break;
2143 if (image->previous == (Image *) NULL)
2144 {
cristycee97112010-05-28 00:44:52 +00002145 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
2146 image->rows);
cristy3ed852e2009-09-05 21:47:34 +00002147 if (status == MagickFalse)
2148 break;
2149 }
2150 }
2151 quantum_info=DestroyQuantumInfo(quantum_info);
2152 break;
2153 }
2154 case 'F':
2155 case 'f':
2156 {
2157 (void) WriteBlobString(image,image->endian != LSBEndian ? "1.0\n" :
2158 "-1.0\n");
2159 image->depth=32;
2160 quantum_type=format == 'f' ? GrayQuantum : RGBQuantum;
2161 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
2162 if (quantum_info == (QuantumInfo *) NULL)
2163 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
2164 status=SetQuantumFormat(image,quantum_info,FloatingPointQuantumFormat);
2165 if (status == MagickFalse)
2166 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
2167 pixels=GetQuantumPixels(quantum_info);
cristybb503372010-05-27 20:51:26 +00002168 for (y=(ssize_t) image->rows-1; y >= 0; y--)
cristy3ed852e2009-09-05 21:47:34 +00002169 {
2170 register const PixelPacket
cristyc47d1f82009-11-26 01:44:43 +00002171 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +00002172
2173 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
2174 if (p == (const PixelPacket *) NULL)
2175 break;
2176 extent=ExportQuantumPixels(image,(const CacheView *) NULL,
2177 quantum_info,quantum_type,pixels,&image->exception);
2178 (void) WriteBlob(image,extent,pixels);
2179 if (image->previous == (Image *) NULL)
2180 {
cristycee97112010-05-28 00:44:52 +00002181 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
2182 image->rows);
cristy3ed852e2009-09-05 21:47:34 +00002183 if (status == MagickFalse)
2184 break;
2185 }
2186 }
2187 quantum_info=DestroyQuantumInfo(quantum_info);
2188 break;
2189 }
2190 }
2191 if (GetNextImageInList(image) == (Image *) NULL)
2192 break;
2193 image=SyncNextImageInList(image);
2194 status=SetImageProgress(image,SaveImagesTag,scene++,
2195 GetImageListLength(image));
2196 if (status == MagickFalse)
2197 break;
2198 } while (image_info->adjoin != MagickFalse);
2199 (void) CloseBlob(image);
2200 return(MagickTrue);
2201}