2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13 % Read/Write PBMPlus Portable Anymap Image Format %
20 % Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
26 % http://www.imagemagick.org/script/license.php %
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. %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
42 #include "MagickCore/studio.h"
43 #include "MagickCore/attribute.h"
44 #include "MagickCore/blob.h"
45 #include "MagickCore/blob-private.h"
46 #include "MagickCore/cache.h"
47 #include "MagickCore/color.h"
48 #include "MagickCore/color-private.h"
49 #include "MagickCore/colorspace.h"
50 #include "MagickCore/colorspace-private.h"
51 #include "MagickCore/exception.h"
52 #include "MagickCore/exception-private.h"
53 #include "MagickCore/image.h"
54 #include "MagickCore/image-private.h"
55 #include "MagickCore/list.h"
56 #include "MagickCore/magick.h"
57 #include "MagickCore/memory_.h"
58 #include "MagickCore/module.h"
59 #include "MagickCore/monitor.h"
60 #include "MagickCore/monitor-private.h"
61 #include "MagickCore/pixel-accessor.h"
62 #include "MagickCore/property.h"
63 #include "MagickCore/quantum-private.h"
64 #include "MagickCore/static.h"
65 #include "MagickCore/statistic.h"
66 #include "MagickCore/string_.h"
67 #include "MagickCore/string-private.h"
72 static MagickBooleanType
73 WritePNMImage(const ImageInfo *,Image *,ExceptionInfo *);
76 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
84 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
86 % IsPNM() returns MagickTrue if the image format type, identified by the
87 % magick string, is PNM.
89 % The format of the IsPNM method is:
91 % MagickBooleanType IsPNM(const unsigned char *magick,const size_t extent)
93 % A description of each parameter follows:
95 % o magick: compare image format pattern against these bytes.
97 % o extent: Specifies the extent of the magick string.
100 static MagickBooleanType IsPNM(const unsigned char *magick,const size_t extent)
104 if ((*magick == (unsigned char) 'P') &&
105 ((magick[1] == '1') || (magick[1] == '2') || (magick[1] == '3') ||
106 (magick[1] == '4') || (magick[1] == '5') || (magick[1] == '6') ||
107 (magick[1] == '7') || (magick[1] == 'F') || (magick[1] == 'f')))
113 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
117 % R e a d P N M I m a g e %
121 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
123 % ReadPNMImage() reads a Portable Anymap image file and returns it.
124 % It allocates the memory necessary for the new Image structure and returns
125 % a pointer to the new image.
127 % The format of the ReadPNMImage method is:
129 % Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception)
131 % A description of each parameter follows:
133 % o image_info: the image info.
135 % o exception: return any errors or warnings in this structure.
139 static inline ssize_t ConstrainPixel(Image *image,const ssize_t offset,
140 const size_t extent,ExceptionInfo *exception)
142 if ((offset < 0) || (offset > (ssize_t) extent))
144 (void) ThrowMagickException(exception,GetMagickModule(),CorruptImageError,
145 "InvalidPixel","`%s'",image->filename);
151 static size_t PNMInteger(Image *image,const unsigned int base,
152 ExceptionInfo *exception)
168 Skip any leading whitespace.
170 extent=MaxTextExtent;
171 comment=(char *) NULL;
175 c=ReadBlobByte(image);
183 if (comment == (char *) NULL)
184 comment=AcquireString((char *) NULL);
185 p=comment+strlen(comment);
186 for ( ; (c != EOF) && (c != (int) '\n'); p++)
188 if ((size_t) (p-comment+1) >= extent)
191 comment=(char *) ResizeQuantumMemory(comment,extent+MaxTextExtent,
193 if (comment == (char *) NULL)
195 p=comment+strlen(comment);
197 c=ReadBlobByte(image);
201 if (comment == (char *) NULL)
205 } while (isdigit(c) == MagickFalse);
206 if (comment != (char *) NULL)
208 (void) SetImageProperty(image,"comment",comment,exception);
209 comment=DestroyString(comment);
212 return((size_t) (c-(int) '0'));
221 c=ReadBlobByte(image);
224 } while (isdigit(c) != MagickFalse);
228 static Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception)
268 assert(image_info != (const ImageInfo *) NULL);
269 assert(image_info->signature == MagickSignature);
270 if (image_info->debug != MagickFalse)
271 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
272 image_info->filename);
273 assert(exception != (ExceptionInfo *) NULL);
274 assert(exception->signature == MagickSignature);
275 image=AcquireImage(image_info,exception);
276 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
277 if (status == MagickFalse)
279 image=DestroyImageList(image);
280 return((Image *) NULL);
285 count=ReadBlob(image,1,(unsigned char *) &format);
289 Initialize image structure.
291 if ((count != 1) || (format != 'P'))
292 ThrowReaderException(CorruptImageError,"ImproperImageHeader");
294 quantum_type=RGBQuantum;
296 format=(char) ReadBlobByte(image);
300 PBM, PGM, PPM, and PNM.
302 image->columns=PNMInteger(image,10,exception);
303 image->rows=PNMInteger(image,10,exception);
304 if ((format == 'f') || (format == 'F'))
307 scale[MaxTextExtent];
309 (void) ReadBlobString(image,scale);
310 quantum_scale=StringToDouble(scale,(char **) NULL);
314 if ((format == '1') || (format == '4'))
315 max_value=1; /* bitmap */
317 max_value=PNMInteger(image,10,exception);
323 keyword[MaxTextExtent],
324 value[MaxTextExtent];
335 for (c=ReadBlobByte(image); c != EOF; c=ReadBlobByte(image))
337 while (isspace((int) ((unsigned char) c)) != 0)
338 c=ReadBlobByte(image);
342 if ((size_t) (p-keyword) < (MaxTextExtent-1))
344 c=ReadBlobByte(image);
345 } while (isalnum(c));
347 if (LocaleCompare(keyword,"endhdr") == 0)
349 while (isspace((int) ((unsigned char) c)) != 0)
350 c=ReadBlobByte(image);
352 while (isalnum(c) || (c == '_'))
354 if ((size_t) (p-value) < (MaxTextExtent-1))
356 c=ReadBlobByte(image);
360 Assign a value to the specified keyword.
362 if (LocaleCompare(keyword,"depth") == 0)
363 packet_size=StringToUnsignedLong(value);
365 if (LocaleCompare(keyword,"height") == 0)
366 image->rows=StringToUnsignedLong(value);
367 if (LocaleCompare(keyword,"maxval") == 0)
368 max_value=StringToUnsignedLong(value);
369 if (LocaleCompare(keyword,"TUPLTYPE") == 0)
371 if (LocaleCompare(value,"BLACKANDWHITE") == 0)
372 quantum_type=GrayQuantum;
373 if (LocaleCompare(value,"BLACKANDWHITE_ALPHA") == 0)
375 quantum_type=GrayAlphaQuantum;
376 image->matte=MagickTrue;
378 if (LocaleCompare(value,"GRAYSCALE") == 0)
380 image->colorspace=GRAYColorspace;
381 quantum_type=GrayQuantum;
383 if (LocaleCompare(value,"GRAYSCALE_ALPHA") == 0)
385 image->colorspace=GRAYColorspace;
386 image->matte=MagickTrue;
387 quantum_type=GrayAlphaQuantum;
389 if (LocaleCompare(value,"RGB_ALPHA") == 0)
391 quantum_type=RGBAQuantum;
392 image->matte=MagickTrue;
394 if (LocaleCompare(value,"CMYK") == 0)
396 quantum_type=CMYKQuantum;
397 image->colorspace=CMYKColorspace;
399 if (LocaleCompare(value,"CMYK_ALPHA") == 0)
401 quantum_type=CMYKAQuantum;
402 image->colorspace=CMYKColorspace;
403 image->matte=MagickTrue;
406 if (LocaleCompare(keyword,"width") == 0)
407 image->columns=StringToUnsignedLong(value);
410 if ((image->columns == 0) || (image->rows == 0))
411 ThrowReaderException(CorruptImageError,"NegativeOrZeroImageSize");
412 if (max_value >= 65536)
413 ThrowReaderException(CorruptImageError,"ImproperImageHeader");
414 for (depth=1; GetQuantumRange(depth) < max_value; depth++) ;
416 if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
417 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
420 Convert PNM pixels to runextent-encoded MIFF packets.
429 Convert PBM image to pixel packets.
431 image->colorspace=GRAYColorspace;
432 for (y=0; y < (ssize_t) image->rows; y++)
440 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
441 if (q == (Quantum *) NULL)
443 for (x=0; x < (ssize_t) image->columns; x++)
445 SetPixelRed(image,PNMInteger(image,2,exception) == 0 ?
447 SetPixelGreen(image,GetPixelRed(image,q),q);
448 SetPixelBlue(image,GetPixelRed(image,q),q);
449 q+=GetPixelChannels(image);
451 if (SyncAuthenticPixels(image,exception) == MagickFalse)
453 if (image->previous == (Image *) NULL)
455 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
457 if (status == MagickFalse)
461 image->type=BilevelType;
470 Convert PGM image to pixel packets.
472 image->colorspace=GRAYColorspace;
473 scale=(Quantum *) NULL;
474 if (max_value != (1U*QuantumRange))
477 Compute pixel scaling table.
479 scale=(Quantum *) AcquireQuantumMemory((size_t) max_value+1UL,
481 if (scale == (Quantum *) NULL)
482 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
483 for (i=0; i <= (ssize_t) max_value; i++)
484 scale[i]=(Quantum) (((double) QuantumRange*i)/max_value+0.5);
486 for (y=0; y < (ssize_t) image->rows; y++)
494 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
495 if (q == (Quantum *) NULL)
497 for (x=0; x < (ssize_t) image->columns; x++)
499 intensity=PNMInteger(image,10,exception);
500 SetPixelRed(image,intensity,q);
501 if (scale != (Quantum *) NULL)
502 SetPixelRed(image,scale[ConstrainPixel(image,(ssize_t) intensity,
503 max_value,exception)],q);
504 SetPixelGreen(image,GetPixelRed(image,q),q);
505 SetPixelBlue(image,GetPixelRed(image,q),q);
506 q+=GetPixelChannels(image);
508 if (SyncAuthenticPixels(image,exception) == MagickFalse)
510 if (image->previous == (Image *) NULL)
512 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
514 if (status == MagickFalse)
518 image->type=GrayscaleType;
519 if (scale != (Quantum *) NULL)
520 scale=(Quantum *) RelinquishMagickMemory(scale);
529 Convert PNM image to pixel packets.
531 scale=(Quantum *) NULL;
532 if (max_value != (1U*QuantumRange))
535 Compute pixel scaling table.
537 scale=(Quantum *) AcquireQuantumMemory((size_t) max_value+1UL,
539 if (scale == (Quantum *) NULL)
540 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
541 for (i=0; i <= (ssize_t) max_value; i++)
542 scale[i]=(Quantum) (((double) QuantumRange*i)/max_value+0.5);
544 for (y=0; y < (ssize_t) image->rows; y++)
552 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
553 if (q == (Quantum *) NULL)
555 for (x=0; x < (ssize_t) image->columns; x++)
557 pixel.red=(MagickRealType) PNMInteger(image,10,exception);
558 pixel.green=(MagickRealType) PNMInteger(image,10,exception);
559 pixel.blue=(MagickRealType) PNMInteger(image,10,exception);
560 if (scale != (Quantum *) NULL)
562 pixel.red=(MagickRealType) scale[ConstrainPixel(image,(ssize_t)
563 pixel.red,max_value,exception)];
564 pixel.green=(MagickRealType) scale[ConstrainPixel(image,
565 (ssize_t) pixel.green,max_value,exception)];
566 pixel.blue=(MagickRealType) scale[ConstrainPixel(image,(ssize_t)
567 pixel.blue,max_value,exception)];
569 SetPixelRed(image,ClampToQuantum(pixel.red),q);
570 SetPixelGreen(image,ClampToQuantum(pixel.green),q);
571 SetPixelBlue(image,ClampToQuantum(pixel.blue),q);
572 q+=GetPixelChannels(image);
574 if (SyncAuthenticPixels(image,exception) == MagickFalse)
576 if (image->previous == (Image *) NULL)
578 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
580 if (status == MagickFalse)
584 if (scale != (Quantum *) NULL)
585 scale=(Quantum *) RelinquishMagickMemory(scale);
591 Convert PBM raw image to pixel packets.
593 image->colorspace=GRAYColorspace;
594 quantum_type=GrayQuantum;
595 if (image->storage_class == PseudoClass)
596 quantum_type=IndexQuantum;
597 quantum_info=AcquireQuantumInfo(image_info,image);
598 if (quantum_info == (QuantumInfo *) NULL)
599 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
600 SetQuantumMinIsWhite(quantum_info,MagickTrue);
601 extent=GetQuantumExtent(image,quantum_info,quantum_type);
602 for (y=0; y < (ssize_t) image->rows; y++)
620 if (status == MagickFalse)
622 pixels=GetQuantumPixels(quantum_info);
624 count=ReadBlob(image,extent,pixels);
625 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
626 (image->previous == (Image *) NULL))
631 proceed=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
633 if (proceed == MagickFalse)
638 if (count != (ssize_t) extent)
640 q=QueueAuthenticPixels(image,0,offset,image->columns,1,exception);
641 if (q == (Quantum *) NULL)
646 length=ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
647 quantum_type,pixels,exception);
648 if (length != extent)
650 sync=SyncAuthenticPixels(image,exception);
651 if (sync == MagickFalse)
654 quantum_info=DestroyQuantumInfo(quantum_info);
655 if (status == MagickFalse)
656 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
657 SetQuantumImageType(image,quantum_type);
666 Convert PGM raw image to pixel packets.
668 image->colorspace=GRAYColorspace;
669 range=GetQuantumRange(image->depth);
670 quantum_type=GrayQuantum;
671 extent=(image->depth <= 8 ? 1 : 2)*image->columns;
672 quantum_info=AcquireQuantumInfo(image_info,image);
673 if (quantum_info == (QuantumInfo *) NULL)
674 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
675 for (y=0; y < (ssize_t) image->rows; y++)
680 register const unsigned char
696 if (status == MagickFalse)
698 pixels=GetQuantumPixels(quantum_info);
700 count=ReadBlob(image,extent,pixels);
701 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
702 (image->previous == (Image *) NULL))
707 proceed=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
709 if (proceed == MagickFalse)
714 if (count != (ssize_t) extent)
716 q=QueueAuthenticPixels(image,0,offset,image->columns,1,exception);
717 if (q == (Quantum *) NULL)
723 if ((image->depth == 8) || (image->depth == 16))
724 (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
725 quantum_type,pixels,exception);
727 if (image->depth <= 8)
732 for (x=0; x < (ssize_t) image->columns; x++)
734 p=PushCharPixel(p,&pixel);
735 SetPixelRed(image,ScaleAnyToQuantum(pixel,range),q);
736 SetPixelGreen(image,GetPixelRed(image,q),q);
737 SetPixelBlue(image,GetPixelRed(image,q),q);
738 q+=GetPixelChannels(image);
746 for (x=0; x < (ssize_t) image->columns; x++)
748 p=PushShortPixel(MSBEndian,p,&pixel);
749 SetPixelRed(image,ScaleAnyToQuantum(pixel,range),q);
750 SetPixelGreen(image,GetPixelRed(image,q),q);
751 SetPixelBlue(image,GetPixelRed(image,q),q);
752 q+=GetPixelChannels(image);
755 sync=SyncAuthenticPixels(image,exception);
756 if (sync == MagickFalse)
759 quantum_info=DestroyQuantumInfo(quantum_info);
760 if (status == MagickFalse)
761 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
762 SetQuantumImageType(image,quantum_type);
774 Convert PNM raster image to pixel packets.
777 quantum_type=RGBQuantum;
778 extent=3*(image->depth <= 8 ? 1 : 2)*image->columns;
779 range=GetQuantumRange(image->depth);
780 quantum_info=AcquireQuantumInfo(image_info,image);
781 if (quantum_info == (QuantumInfo *) NULL)
782 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
783 for (y=0; y < (ssize_t) image->rows; y++)
788 register const unsigned char
804 if (status == MagickFalse)
806 pixels=GetQuantumPixels(quantum_info);
808 count=ReadBlob(image,extent,pixels);
809 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
810 (image->previous == (Image *) NULL))
815 proceed=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
817 if (proceed == MagickFalse)
822 if (count != (ssize_t) extent)
824 q=QueueAuthenticPixels(image,0,offset,image->columns,1,exception);
825 if (q == (Quantum *) NULL)
831 if (image->depth == 8)
832 for (x=0; x < (ssize_t) image->columns; x++)
834 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
835 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
836 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
837 SetPixelAlpha(image,OpaqueAlpha,q);
838 q+=GetPixelChannels(image);
841 if (image->depth == 16)
846 for (x=0; x < (ssize_t) image->columns; x++)
848 p=PushShortPixel(MSBEndian,p,&pixel);
849 SetPixelRed(image,ScaleShortToQuantum(pixel),q);
850 p=PushShortPixel(MSBEndian,p,&pixel);
851 SetPixelGreen(image,ScaleShortToQuantum(pixel),q);
852 p=PushShortPixel(MSBEndian,p,&pixel);
853 SetPixelBlue(image,ScaleShortToQuantum(pixel),q);
854 SetPixelAlpha(image,OpaqueAlpha,q);
855 q+=GetPixelChannels(image);
859 if (image->depth <= 8)
864 for (x=0; x < (ssize_t) image->columns; x++)
866 p=PushCharPixel(p,&pixel);
867 SetPixelRed(image,ScaleAnyToQuantum(pixel,range),q);
868 p=PushCharPixel(p,&pixel);
869 SetPixelGreen(image,ScaleAnyToQuantum(pixel,range),q);
870 p=PushCharPixel(p,&pixel);
871 SetPixelBlue(image,ScaleAnyToQuantum(pixel,range),q);
872 SetPixelAlpha(image,OpaqueAlpha,q);
873 q+=GetPixelChannels(image);
881 for (x=0; x < (ssize_t) image->columns; x++)
883 p=PushShortPixel(MSBEndian,p,&pixel);
884 SetPixelRed(image,ScaleAnyToQuantum(pixel,range),q);
885 p=PushShortPixel(MSBEndian,p,&pixel);
886 SetPixelGreen(image,ScaleAnyToQuantum(pixel,range),q);
887 p=PushShortPixel(MSBEndian,p,&pixel);
888 SetPixelBlue(image,ScaleAnyToQuantum(pixel,range),q);
889 SetPixelAlpha(image,OpaqueAlpha,q);
890 q+=GetPixelChannels(image);
893 if ((type == BilevelType) || (type == GrayscaleType))
895 q=QueueAuthenticPixels(image,0,offset,image->columns,1,exception);
896 for (x=0; x < (ssize_t) image->columns; x++)
898 if ((type == BilevelType) &&
899 (IsPixelMonochrome(image,q) == MagickFalse))
900 type=IsPixelGray(image,q) == MagickFalse ? UndefinedType :
902 if ((type == GrayscaleType) &&
903 (IsPixelGray(image,q) == MagickFalse))
905 if ((type != BilevelType) && (type != GrayscaleType))
907 q+=GetPixelChannels(image);
910 sync=SyncAuthenticPixels(image,exception);
911 if (sync == MagickFalse)
914 quantum_info=DestroyQuantumInfo(quantum_info);
915 if (status == MagickFalse)
916 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
917 if (type != UndefinedType)
930 Convert PAM raster image to pixel packets.
932 range=GetQuantumRange(image->depth);
933 switch (quantum_type)
936 case GrayAlphaQuantum:
953 if (image->matte != MagickFalse)
955 extent=channels*(image->depth <= 8 ? 1 : 2)*image->columns;
956 quantum_info=AcquireQuantumInfo(image_info,image);
957 if (quantum_info == (QuantumInfo *) NULL)
958 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
959 for (y=0; y < (ssize_t) image->rows; y++)
964 register const unsigned char
980 if (status == MagickFalse)
982 pixels=GetQuantumPixels(quantum_info);
984 count=ReadBlob(image,extent,pixels);
985 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
986 (image->previous == (Image *) NULL))
991 proceed=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
993 if (proceed == MagickFalse)
998 if (count != (ssize_t) extent)
1000 q=QueueAuthenticPixels(image,0,offset,image->columns,1,exception);
1001 if (q == (Quantum *) NULL)
1007 if ((image->depth == 8) || (image->depth == 16))
1008 (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1009 quantum_type,pixels,exception);
1011 switch (quantum_type)
1014 case GrayAlphaQuantum:
1016 if (image->depth <= 8)
1021 for (x=0; x < (ssize_t) image->columns; x++)
1023 p=PushCharPixel(p,&pixel);
1024 SetPixelRed(image,ScaleAnyToQuantum(pixel,range),q);
1025 SetPixelGreen(image,GetPixelRed(image,q),q);
1026 SetPixelBlue(image,GetPixelRed(image,q),q);
1027 SetPixelAlpha(image,OpaqueAlpha,q);
1028 if (image->matte != MagickFalse)
1030 p=PushCharPixel(p,&pixel);
1031 SetPixelAlpha(image,ScaleAnyToQuantum(pixel,range),q);
1033 q+=GetPixelChannels(image);
1041 for (x=0; x < (ssize_t) image->columns; x++)
1043 p=PushShortPixel(MSBEndian,p,&pixel);
1044 SetPixelRed(image,ScaleAnyToQuantum(pixel,range),q);
1045 SetPixelGreen(image,GetPixelRed(image,q),q);
1046 SetPixelBlue(image,GetPixelRed(image,q),q);
1047 SetPixelAlpha(image,OpaqueAlpha,q);
1048 if (image->matte != MagickFalse)
1050 p=PushShortPixel(MSBEndian,p,&pixel);
1051 SetPixelAlpha(image,ScaleAnyToQuantum(pixel,range),q);
1053 q+=GetPixelChannels(image);
1061 if (image->depth <= 8)
1066 for (x=0; x < (ssize_t) image->columns; x++)
1068 p=PushCharPixel(p,&pixel);
1069 SetPixelRed(image,ScaleAnyToQuantum(pixel,range),q);
1070 p=PushCharPixel(p,&pixel);
1071 SetPixelGreen(image,ScaleAnyToQuantum(pixel,range),q);
1072 p=PushCharPixel(p,&pixel);
1073 SetPixelBlue(image,ScaleAnyToQuantum(pixel,range),q);
1074 p=PushCharPixel(p,&pixel);
1075 SetPixelBlack(image,ScaleAnyToQuantum(pixel,range),q);
1076 SetPixelAlpha(image,OpaqueAlpha,q);
1077 if (image->matte != MagickFalse)
1079 p=PushCharPixel(p,&pixel);
1080 SetPixelAlpha(image,ScaleAnyToQuantum(pixel,range),q);
1082 q+=GetPixelChannels(image);
1090 for (x=0; x < (ssize_t) image->columns; x++)
1092 p=PushShortPixel(MSBEndian,p,&pixel);
1093 SetPixelRed(image,ScaleAnyToQuantum(pixel,range),q);
1094 p=PushShortPixel(MSBEndian,p,&pixel);
1095 SetPixelGreen(image,ScaleAnyToQuantum(pixel,range),q);
1096 p=PushShortPixel(MSBEndian,p,&pixel);
1097 SetPixelBlue(image,ScaleAnyToQuantum(pixel,range),q);
1098 p=PushShortPixel(MSBEndian,p,&pixel);
1099 SetPixelBlack(image,ScaleAnyToQuantum(pixel,range),q);
1100 SetPixelAlpha(image,OpaqueAlpha,q);
1101 if (image->matte != MagickFalse)
1103 p=PushShortPixel(MSBEndian,p,&pixel);
1104 SetPixelAlpha(image,ScaleAnyToQuantum(pixel,range),q);
1106 q+=GetPixelChannels(image);
1113 if (image->depth <= 8)
1118 for (x=0; x < (ssize_t) image->columns; x++)
1120 p=PushCharPixel(p,&pixel);
1121 SetPixelRed(image,ScaleAnyToQuantum(pixel,range),q);
1122 p=PushCharPixel(p,&pixel);
1123 SetPixelGreen(image,ScaleAnyToQuantum(pixel,range),q);
1124 p=PushCharPixel(p,&pixel);
1125 SetPixelBlue(image,ScaleAnyToQuantum(pixel,range),q);
1126 SetPixelAlpha(image,OpaqueAlpha,q);
1127 if (image->matte != MagickFalse)
1129 p=PushCharPixel(p,&pixel);
1130 SetPixelAlpha(image,ScaleAnyToQuantum(pixel,range),q);
1132 q+=GetPixelChannels(image);
1140 for (x=0; x < (ssize_t) image->columns; x++)
1142 p=PushShortPixel(MSBEndian,p,&pixel);
1143 SetPixelRed(image,ScaleAnyToQuantum(pixel,range),q);
1144 p=PushShortPixel(MSBEndian,p,&pixel);
1145 SetPixelGreen(image,ScaleAnyToQuantum(pixel,range),q);
1146 p=PushShortPixel(MSBEndian,p,&pixel);
1147 SetPixelBlue(image,ScaleAnyToQuantum(pixel,range),q);
1148 SetPixelAlpha(image,OpaqueAlpha,q);
1149 if (image->matte != MagickFalse)
1151 p=PushShortPixel(MSBEndian,p,&pixel);
1152 SetPixelAlpha(image,ScaleAnyToQuantum(pixel,range),q);
1154 q+=GetPixelChannels(image);
1160 sync=SyncAuthenticPixels(image,exception);
1161 if (sync == MagickFalse)
1164 quantum_info=DestroyQuantumInfo(quantum_info);
1165 if (status == MagickFalse)
1166 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
1167 SetQuantumImageType(image,quantum_type);
1174 Convert PFM raster image to pixel packets.
1176 quantum_type=format == 'f' ? GrayQuantum : RGBQuantum;
1177 image->endian=quantum_scale < 0.0 ? LSBEndian : MSBEndian;
1179 quantum_info=AcquireQuantumInfo(image_info,image);
1180 if (quantum_info == (QuantumInfo *) NULL)
1181 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
1182 status=SetQuantumDepth(image,quantum_info,32);
1183 if (status == MagickFalse)
1184 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
1185 status=SetQuantumFormat(image,quantum_info,FloatingPointQuantumFormat);
1186 if (status == MagickFalse)
1187 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
1188 SetQuantumScale(quantum_info,(MagickRealType) QuantumRange*
1189 fabs(quantum_scale));
1190 extent=GetQuantumExtent(image,quantum_info,quantum_type);
1191 for (y=0; y < (ssize_t) image->rows; y++)
1209 if (status == MagickFalse)
1211 pixels=GetQuantumPixels(quantum_info);
1213 count=ReadBlob(image,extent,pixels);
1214 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
1215 (image->previous == (Image *) NULL))
1220 proceed=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
1222 if (proceed == MagickFalse)
1227 if ((size_t) count != extent)
1229 q=QueueAuthenticPixels(image,0,(ssize_t) (image->rows-offset-1),
1230 image->columns,1,exception);
1231 if (q == (Quantum *) NULL)
1236 length=ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1237 quantum_type,pixels,exception);
1238 if (length != extent)
1240 sync=SyncAuthenticPixels(image,exception);
1241 if (sync == MagickFalse)
1244 quantum_info=DestroyQuantumInfo(quantum_info);
1245 if (status == MagickFalse)
1246 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
1247 SetQuantumImageType(image,quantum_type);
1251 ThrowReaderException(CorruptImageError,"ImproperImageHeader");
1253 if (EOFBlob(image) != MagickFalse)
1254 (void) ThrowMagickException(exception,GetMagickModule(),CorruptImageError,
1255 "UnexpectedEndOfFile","`%s'",image->filename);
1257 Proceed to next image.
1259 if (image_info->number_scenes != 0)
1260 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
1262 if ((format == '1') || (format == '2') || (format == '3'))
1266 Skip to end of line.
1268 count=ReadBlob(image,1,(unsigned char *) &format);
1271 if ((count != 0) && (format == 'P'))
1273 } while (format != '\n');
1274 count=ReadBlob(image,1,(unsigned char *) &format);
1275 if ((count == 1) && (format == 'P'))
1278 Allocate next image structure.
1280 AcquireNextImage(image_info,image,exception);
1281 if (GetNextImageInList(image) == (Image *) NULL)
1283 image=DestroyImageList(image);
1284 return((Image *) NULL);
1286 image=SyncNextImageInList(image);
1287 status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
1288 GetBlobSize(image));
1289 if (status == MagickFalse)
1292 } while ((count == 1) && (format == 'P'));
1293 (void) CloseBlob(image);
1294 return(GetFirstImageInList(image));
1298 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1302 % R e g i s t e r P N M I m a g e %
1306 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1308 % RegisterPNMImage() adds properties for the PNM image format to
1309 % the list of supported formats. The properties include the image format
1310 % tag, a method to read and/or write the format, whether the format
1311 % supports the saving of more than one frame to the same file or blob,
1312 % whether the format supports native in-memory I/O, and a brief
1313 % description of the format.
1315 % The format of the RegisterPNMImage method is:
1317 % size_t RegisterPNMImage(void)
1320 ModuleExport size_t RegisterPNMImage(void)
1325 entry=SetMagickInfo("PAM");
1326 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1327 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1328 entry->description=ConstantString("Common 2-dimensional bitmap format");
1329 entry->module=ConstantString("PNM");
1330 (void) RegisterMagickInfo(entry);
1331 entry=SetMagickInfo("PBM");
1332 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1333 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1334 entry->description=ConstantString("Portable bitmap format (black and white)");
1335 entry->module=ConstantString("PNM");
1336 (void) RegisterMagickInfo(entry);
1337 entry=SetMagickInfo("PFM");
1338 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1339 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1340 entry->endian_support=MagickTrue;
1341 entry->description=ConstantString("Portable float format");
1342 entry->module=ConstantString("PFM");
1343 (void) RegisterMagickInfo(entry);
1344 entry=SetMagickInfo("PGM");
1345 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1346 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1347 entry->description=ConstantString("Portable graymap format (gray scale)");
1348 entry->module=ConstantString("PNM");
1349 (void) RegisterMagickInfo(entry);
1350 entry=SetMagickInfo("PNM");
1351 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1352 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1353 entry->magick=(IsImageFormatHandler *) IsPNM;
1354 entry->description=ConstantString("Portable anymap");
1355 entry->module=ConstantString("PNM");
1356 (void) RegisterMagickInfo(entry);
1357 entry=SetMagickInfo("PPM");
1358 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1359 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1360 entry->description=ConstantString("Portable pixmap format (color)");
1361 entry->module=ConstantString("PNM");
1362 (void) RegisterMagickInfo(entry);
1363 return(MagickImageCoderSignature);
1367 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1371 % U n r e g i s t e r P N M I m a g e %
1375 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1377 % UnregisterPNMImage() removes format registrations made by the
1378 % PNM module from the list of supported formats.
1380 % The format of the UnregisterPNMImage method is:
1382 % UnregisterPNMImage(void)
1385 ModuleExport void UnregisterPNMImage(void)
1387 (void) UnregisterMagickInfo("PAM");
1388 (void) UnregisterMagickInfo("PBM");
1389 (void) UnregisterMagickInfo("PGM");
1390 (void) UnregisterMagickInfo("PNM");
1391 (void) UnregisterMagickInfo("PPM");
1395 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1399 % W r i t e P N M I m a g e %
1403 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1405 % WritePNMImage() writes an image to a file in the PNM rasterfile format.
1407 % The format of the WritePNMImage method is:
1409 % MagickBooleanType WritePNMImage(const ImageInfo *image_info,
1410 % Image *image,ExceptionInfo *exception)
1412 % A description of each parameter follows.
1414 % o image_info: the image info.
1416 % o image: The image.
1418 % o exception: return any errors or warnings in this structure.
1421 static MagickBooleanType WritePNMImage(const ImageInfo *image_info,Image *image,
1422 ExceptionInfo *exception)
1425 buffer[MaxTextExtent],
1427 magick[MaxTextExtent];
1450 register unsigned char
1463 Open output image file.
1465 assert(image_info != (const ImageInfo *) NULL);
1466 assert(image_info->signature == MagickSignature);
1467 assert(image != (Image *) NULL);
1468 assert(image->signature == MagickSignature);
1469 if (image->debug != MagickFalse)
1470 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1471 assert(exception != (ExceptionInfo *) NULL);
1472 assert(exception->signature == MagickSignature);
1473 status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
1474 if (status == MagickFalse)
1480 Write PNM file header.
1483 quantum_type=RGBQuantum;
1484 (void) CopyMagickString(magick,image_info->magick,MaxTextExtent);
1497 if (image_info->compression == NoCompression)
1505 if (IsImageGray(image,exception) != MagickFalse)
1513 if (image_info->compression == NoCompression)
1520 if ((image_info->type != TrueColorType) &&
1521 (IsImageGray(image,exception) != MagickFalse))
1524 if (image_info->compression == NoCompression)
1526 if (IsImageMonochrome(image,exception) != MagickFalse)
1529 if (image_info->compression == NoCompression)
1538 if (image_info->compression == NoCompression)
1543 (void) FormatLocaleString(buffer,MaxTextExtent,"P%c\n",format);
1544 (void) WriteBlobString(image,buffer);
1545 value=GetImageProperty(image,"comment",exception);
1546 if (value != (const char *) NULL)
1552 Write comments to file.
1554 (void) WriteBlobByte(image,'#');
1555 for (p=value; *p != '\0'; p++)
1557 (void) WriteBlobByte(image,(unsigned char) *p);
1558 if ((*p == '\r') && (*(p+1) != '\0'))
1559 (void) WriteBlobByte(image,'#');
1560 if ((*p == '\n') && (*(p+1) != '\0'))
1561 (void) WriteBlobByte(image,'#');
1563 (void) WriteBlobByte(image,'\n');
1567 if (IsRGBColorspace(image->colorspace) == MagickFalse)
1568 (void) TransformImageColorspace(image,RGBColorspace,exception);
1569 (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g %.20g\n",
1570 (double) image->columns,(double) image->rows);
1571 (void) WriteBlobString(image,buffer);
1576 type[MaxTextExtent];
1581 (void) FormatLocaleString(buffer,MaxTextExtent,
1582 "WIDTH %.20g\nHEIGHT %.20g\n",(double) image->columns,(double)
1584 (void) WriteBlobString(image,buffer);
1585 quantum_type=GetQuantumType(image,exception);
1586 switch (quantum_type)
1592 (void) CopyMagickString(type,"CMYK",MaxTextExtent);
1596 case GrayAlphaQuantum:
1599 (void) CopyMagickString(type,"GRAYSCALE",MaxTextExtent);
1604 quantum_type=RGBQuantum;
1605 if (image->matte != MagickFalse)
1606 quantum_type=RGBAQuantum;
1608 (void) CopyMagickString(type,"RGB",MaxTextExtent);
1612 if (image->matte != MagickFalse)
1615 (void) ConcatenateMagickString(type,"_ALPHA",MaxTextExtent);
1617 if (image->depth > 16)
1619 (void) FormatLocaleString(buffer,MaxTextExtent,
1620 "DEPTH %.20g\nMAXVAL %.20g\n",(double) packet_size,(double)
1621 ((MagickOffsetType) GetQuantumRange(image->depth)));
1622 (void) WriteBlobString(image,buffer);
1623 (void) FormatLocaleString(buffer,MaxTextExtent,"TUPLTYPE %s\nENDHDR\n",
1625 (void) WriteBlobString(image,buffer);
1628 Convert runextent encoded to PNM raster pixels.
1638 Convert image to a PBM image.
1641 for (y=0; y < (ssize_t) image->rows; y++)
1643 register const Quantum
1649 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1650 if (p == (const Quantum *) NULL)
1652 for (x=0; x < (ssize_t) image->columns; x++)
1654 pixel=GetPixelIntensity(image,p);
1655 *q++=(unsigned char) (pixel >= (Quantum) (QuantumRange/2) ?
1658 if ((q-pixels+2) >= 80)
1661 (void) WriteBlob(image,q-pixels,pixels);
1664 p+=GetPixelChannels(image);
1666 if (image->previous == (Image *) NULL)
1668 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1670 if (status == MagickFalse)
1677 (void) WriteBlob(image,q-pixels,pixels);
1687 Convert image to a PGM image.
1689 if (image->depth <= 8)
1690 (void) WriteBlobString(image,"255\n");
1692 (void) WriteBlobString(image,"65535\n");
1694 for (y=0; y < (ssize_t) image->rows; y++)
1696 register const Quantum
1702 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1703 if (p == (const Quantum *) NULL)
1705 for (x=0; x < (ssize_t) image->columns; x++)
1707 index=GetPixelIntensity(image,p);
1708 if (image->depth <= 8)
1709 count=(ssize_t) FormatLocaleString(buffer,MaxTextExtent,"%u ",
1710 ScaleQuantumToChar(index));
1712 count=(ssize_t) FormatLocaleString(buffer,MaxTextExtent,"%u ",
1713 ScaleQuantumToShort(index));
1714 extent=(size_t) count;
1715 (void) strncpy((char *) q,buffer,extent);
1717 if ((q-pixels+extent) >= 80)
1720 (void) WriteBlob(image,q-pixels,pixels);
1723 p+=GetPixelChannels(image);
1725 if (image->previous == (Image *) NULL)
1727 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1729 if (status == MagickFalse)
1736 (void) WriteBlob(image,q-pixels,pixels);
1746 Convert image to a PNM image.
1748 if (image->depth <= 8)
1749 (void) WriteBlobString(image,"255\n");
1751 (void) WriteBlobString(image,"65535\n");
1753 for (y=0; y < (ssize_t) image->rows; y++)
1755 register const Quantum
1761 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1762 if (p == (const Quantum *) NULL)
1764 for (x=0; x < (ssize_t) image->columns; x++)
1766 if (image->depth <= 8)
1767 count=(ssize_t) FormatLocaleString(buffer,MaxTextExtent,
1768 "%u %u %u ",ScaleQuantumToChar(GetPixelRed(image,p)),
1769 ScaleQuantumToChar(GetPixelGreen(image,p)),
1770 ScaleQuantumToChar(GetPixelBlue(image,p)));
1772 count=(ssize_t) FormatLocaleString(buffer,MaxTextExtent,
1773 "%u %u %u ",ScaleQuantumToShort(GetPixelRed(image,p)),
1774 ScaleQuantumToShort(GetPixelGreen(image,p)),
1775 ScaleQuantumToShort(GetPixelBlue(image,p)));
1776 extent=(size_t) count;
1777 (void) strncpy((char *) q,buffer,extent);
1779 if ((q-pixels+extent) >= 80)
1782 (void) WriteBlob(image,q-pixels,pixels);
1785 p+=GetPixelChannels(image);
1787 if (image->previous == (Image *) NULL)
1789 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1791 if (status == MagickFalse)
1798 (void) WriteBlob(image,q-pixels,pixels);
1805 Convert image to a PBM image.
1808 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
1809 if (quantum_info == (QuantumInfo *) NULL)
1810 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1811 quantum_info->min_is_white=MagickTrue;
1812 pixels=GetQuantumPixels(quantum_info);
1813 for (y=0; y < (ssize_t) image->rows; y++)
1815 register const Quantum
1818 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1819 if (p == (const Quantum *) NULL)
1821 extent=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1822 GrayQuantum,pixels,exception);
1823 count=WriteBlob(image,extent,pixels);
1824 if (count != (ssize_t) extent)
1826 if (image->previous == (Image *) NULL)
1828 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1830 if (status == MagickFalse)
1834 quantum_info=DestroyQuantumInfo(quantum_info);
1843 Convert image to a PGM image.
1845 if (image->depth > 8)
1847 (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g\n",(double)
1848 ((MagickOffsetType) GetQuantumRange(image->depth)));
1849 (void) WriteBlobString(image,buffer);
1850 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
1851 if (quantum_info == (QuantumInfo *) NULL)
1852 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1853 quantum_info->min_is_white=MagickTrue;
1854 pixels=GetQuantumPixels(quantum_info);
1855 extent=GetQuantumExtent(image,quantum_info,GrayQuantum);
1856 range=GetQuantumRange(image->depth);
1857 for (y=0; y < (ssize_t) image->rows; y++)
1859 register const Quantum
1865 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1866 if (p == (const Quantum *) NULL)
1869 if ((image->depth == 8) || (image->depth == 16))
1870 extent=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1871 GrayQuantum,pixels,exception);
1874 if (image->depth <= 8)
1875 for (x=0; x < (ssize_t) image->columns; x++)
1877 if (IsPixelGray(image,p) == MagickFalse)
1878 pixel=ScaleQuantumToAny(GetPixelIntensity(image,p),range);
1881 if (image->depth == 8)
1882 pixel=ScaleQuantumToChar(GetPixelRed(image,p));
1884 pixel=ScaleQuantumToAny(GetPixelRed(image,p),range);
1886 q=PopCharPixel((unsigned char) pixel,q);
1887 p+=GetPixelChannels(image);
1890 for (x=0; x < (ssize_t) image->columns; x++)
1892 if (IsPixelGray(image,p) == MagickFalse)
1893 pixel=ScaleQuantumToAny(GetPixelIntensity(image,p),range);
1896 if (image->depth == 16)
1897 pixel=ScaleQuantumToShort(GetPixelRed(image,p));
1899 pixel=ScaleQuantumToAny(GetPixelRed(image,p),range);
1901 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
1902 p+=GetPixelChannels(image);
1904 extent=(size_t) (q-pixels);
1906 count=WriteBlob(image,extent,pixels);
1907 if (count != (ssize_t) extent)
1909 if (image->previous == (Image *) NULL)
1911 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1913 if (status == MagickFalse)
1917 quantum_info=DestroyQuantumInfo(quantum_info);
1926 Convert image to a PNM image.
1928 if (image->depth > 8)
1930 (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g\n",(double)
1931 ((MagickOffsetType) GetQuantumRange(image->depth)));
1932 (void) WriteBlobString(image,buffer);
1933 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
1934 if (quantum_info == (QuantumInfo *) NULL)
1935 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1936 pixels=GetQuantumPixels(quantum_info);
1937 extent=GetQuantumExtent(image,quantum_info,quantum_type);
1938 range=GetQuantumRange(image->depth);
1939 for (y=0; y < (ssize_t) image->rows; y++)
1941 register const Quantum
1947 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1948 if (p == (const Quantum *) NULL)
1951 if ((image->depth == 8) || (image->depth == 16))
1952 extent=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1953 quantum_type,pixels,exception);
1956 if (image->depth <= 8)
1957 for (x=0; x < (ssize_t) image->columns; x++)
1959 pixel=ScaleQuantumToAny(GetPixelRed(image,p),range);
1960 q=PopCharPixel((unsigned char) pixel,q);
1961 pixel=ScaleQuantumToAny(GetPixelGreen(image,p),range);
1962 q=PopCharPixel((unsigned char) pixel,q);
1963 pixel=ScaleQuantumToAny(GetPixelBlue(image,p),range);
1964 q=PopCharPixel((unsigned char) pixel,q);
1965 p+=GetPixelChannels(image);
1968 for (x=0; x < (ssize_t) image->columns; x++)
1970 pixel=ScaleQuantumToAny(GetPixelRed(image,p),range);
1971 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
1972 pixel=ScaleQuantumToAny(GetPixelGreen(image,p),range);
1973 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
1974 pixel=ScaleQuantumToAny(GetPixelBlue(image,p),range);
1975 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
1976 p+=GetPixelChannels(image);
1978 extent=(size_t) (q-pixels);
1980 count=WriteBlob(image,extent,pixels);
1981 if (count != (ssize_t) extent)
1983 if (image->previous == (Image *) NULL)
1985 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1987 if (status == MagickFalse)
1991 quantum_info=DestroyQuantumInfo(quantum_info);
2000 Convert image to a PAM.
2002 if (image->depth > 16)
2004 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
2005 pixels=GetQuantumPixels(quantum_info);
2006 range=GetQuantumRange(image->depth);
2007 for (y=0; y < (ssize_t) image->rows; y++)
2009 register const Quantum
2015 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
2016 if (p == (const Quantum *) NULL)
2019 if ((image->depth == 8) || (image->depth == 16))
2020 extent=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2021 quantum_type,pixels,exception);
2024 switch (quantum_type)
2027 case GrayAlphaQuantum:
2029 if (image->depth <= 8)
2030 for (x=0; x < (ssize_t) image->columns; x++)
2032 pixel=ScaleQuantumToAny(GetPixelIntensity(image,p),range);
2033 q=PopCharPixel((unsigned char) pixel,q);
2034 if (image->matte != MagickFalse)
2036 pixel=(unsigned char) ScaleQuantumToAny(
2037 GetPixelAlpha(image,p),range);
2038 q=PopCharPixel((unsigned char) pixel,q);
2040 p+=GetPixelChannels(image);
2043 for (x=0; x < (ssize_t) image->columns; x++)
2045 pixel=ScaleQuantumToAny(GetPixelIntensity(image,p),range);
2046 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2047 if (image->matte != MagickFalse)
2049 pixel=(unsigned char) ScaleQuantumToAny(
2050 GetPixelAlpha(image,p),range);
2051 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2053 p+=GetPixelChannels(image);
2060 if (image->depth <= 8)
2061 for (x=0; x < (ssize_t) image->columns; x++)
2063 pixel=ScaleQuantumToAny(GetPixelRed(image,p),range);
2064 q=PopCharPixel((unsigned char) pixel,q);
2065 pixel=ScaleQuantumToAny(GetPixelGreen(image,p),range);
2066 q=PopCharPixel((unsigned char) pixel,q);
2067 pixel=ScaleQuantumToAny(GetPixelBlue(image,p),range);
2068 q=PopCharPixel((unsigned char) pixel,q);
2069 pixel=ScaleQuantumToAny(GetPixelBlack(image,p),range);
2070 q=PopCharPixel((unsigned char) pixel,q);
2071 if (image->matte != MagickFalse)
2073 pixel=ScaleQuantumToAny(GetPixelAlpha(image,p),range);
2074 q=PopCharPixel((unsigned char) pixel,q);
2076 p+=GetPixelChannels(image);
2079 for (x=0; x < (ssize_t) image->columns; x++)
2081 pixel=ScaleQuantumToAny(GetPixelRed(image,p),range);
2082 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2083 pixel=ScaleQuantumToAny(GetPixelGreen(image,p),range);
2084 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2085 pixel=ScaleQuantumToAny(GetPixelBlue(image,p),range);
2086 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2087 pixel=ScaleQuantumToAny(GetPixelBlack(image,p),range);
2088 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2089 if (image->matte != MagickFalse)
2091 pixel=ScaleQuantumToAny(GetPixelAlpha(image,p),range);
2092 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2094 p+=GetPixelChannels(image);
2100 if (image->depth <= 8)
2101 for (x=0; x < (ssize_t) image->columns; x++)
2103 pixel=ScaleQuantumToAny(GetPixelRed(image,p),range);
2104 q=PopCharPixel((unsigned char) pixel,q);
2105 pixel=ScaleQuantumToAny(GetPixelGreen(image,p),range);
2106 q=PopCharPixel((unsigned char) pixel,q);
2107 pixel=ScaleQuantumToAny(GetPixelBlue(image,p),range);
2108 q=PopCharPixel((unsigned char) pixel,q);
2109 if (image->matte != MagickFalse)
2111 pixel=ScaleQuantumToAny(GetPixelAlpha(image,p),range);
2112 q=PopCharPixel((unsigned char) pixel,q);
2114 p+=GetPixelChannels(image);
2117 for (x=0; x < (ssize_t) image->columns; x++)
2119 pixel=ScaleQuantumToAny(GetPixelRed(image,p),range);
2120 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2121 pixel=ScaleQuantumToAny(GetPixelGreen(image,p),range);
2122 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2123 pixel=ScaleQuantumToAny(GetPixelBlue(image,p),range);
2124 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2125 if (image->matte != MagickFalse)
2127 pixel=ScaleQuantumToAny(GetPixelAlpha(image,p),range);
2128 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2130 p+=GetPixelChannels(image);
2135 extent=(size_t) (q-pixels);
2137 count=WriteBlob(image,extent,pixels);
2138 if (count != (ssize_t) extent)
2140 if (image->previous == (Image *) NULL)
2142 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
2144 if (status == MagickFalse)
2148 quantum_info=DestroyQuantumInfo(quantum_info);
2154 (void) WriteBlobString(image,image->endian != LSBEndian ? "1.0\n" :
2157 quantum_type=format == 'f' ? GrayQuantum : RGBQuantum;
2158 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
2159 if (quantum_info == (QuantumInfo *) NULL)
2160 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
2161 status=SetQuantumFormat(image,quantum_info,FloatingPointQuantumFormat);
2162 if (status == MagickFalse)
2163 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
2164 pixels=GetQuantumPixels(quantum_info);
2165 for (y=(ssize_t) image->rows-1; y >= 0; y--)
2167 register const Quantum
2170 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
2171 if (p == (const Quantum *) NULL)
2173 extent=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2174 quantum_type,pixels,exception);
2175 (void) WriteBlob(image,extent,pixels);
2176 if (image->previous == (Image *) NULL)
2178 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
2180 if (status == MagickFalse)
2184 quantum_info=DestroyQuantumInfo(quantum_info);
2188 if (GetNextImageInList(image) == (Image *) NULL)
2190 image=SyncNextImageInList(image);
2191 status=SetImageProgress(image,SaveImagesTag,scene++,
2192 GetImageListLength(image));
2193 if (status == MagickFalse)
2195 } while (image_info->adjoin != MagickFalse);
2196 (void) CloseBlob(image);