2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13 % Read/Write PBMPlus Portable Anymap Image Format %
20 % Copyright 1999-2018 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 % https://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 typedef struct _CommentInfo
84 static MagickBooleanType
85 WritePNMImage(const ImageInfo *,Image *,ExceptionInfo *);
88 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
96 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
98 % IsPNM() returns MagickTrue if the image format type, identified by the
99 % magick string, is PNM.
101 % The format of the IsPNM method is:
103 % MagickBooleanType IsPNM(const unsigned char *magick,const size_t extent)
105 % A description of each parameter follows:
107 % o magick: compare image format pattern against these bytes.
109 % o extent: Specifies the extent of the magick string.
112 static MagickBooleanType IsPNM(const unsigned char *magick,const size_t extent)
116 if ((*magick == (unsigned char) 'P') &&
117 ((magick[1] == '1') || (magick[1] == '2') || (magick[1] == '3') ||
118 (magick[1] == '4') || (magick[1] == '5') || (magick[1] == '6') ||
119 (magick[1] == '7') || (magick[1] == 'F') || (magick[1] == 'f')))
125 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
129 % R e a d P N M I m a g e %
133 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
135 % ReadPNMImage() reads a Portable Anymap image file and returns it.
136 % It allocates the memory necessary for the new Image structure and returns
137 % a pointer to the new image.
139 % The format of the ReadPNMImage method is:
141 % Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception)
143 % A description of each parameter follows:
145 % o image_info: the image info.
147 % o exception: return any errors or warnings in this structure.
151 static int PNMComment(Image *image,CommentInfo *comment_info,
152 ExceptionInfo *exception)
163 p=comment_info->comment+strlen(comment_info->comment);
164 for (c='#'; (c != EOF) && (c != (int) '\n') && (c != (int) '\r'); p++)
166 if ((size_t) (p-comment_info->comment+1) >= comment_info->extent)
168 comment_info->extent<<=1;
169 comment_info->comment=(char *) ResizeQuantumMemory(
170 comment_info->comment,comment_info->extent,
171 sizeof(*comment_info->comment));
172 if (comment_info->comment == (char *) NULL)
174 p=comment_info->comment+strlen(comment_info->comment);
176 c=ReadBlobByte(image);
177 if ((c != EOF) && (c != (int) '\n') && (c != (int) '\r'))
186 static unsigned int PNMInteger(Image *image,CommentInfo *comment_info,
187 const unsigned int base,ExceptionInfo *exception)
196 Skip any leading whitespace.
200 c=ReadBlobByte(image);
204 c=PNMComment(image,comment_info,exception);
205 } while ((c == ' ') || (c == '\t') || (c == '\n') || (c == '\r'));
207 return((unsigned int) (c-(int) '0'));
212 while (isdigit(c) != 0)
214 if (value <= (unsigned int) (INT_MAX/10))
217 if (value <= (unsigned int) (INT_MAX-(c-(int) '0')))
220 c=ReadBlobByte(image);
225 c=PNMComment(image,comment_info,exception);
229 static Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception)
231 #define ThrowPNMException(exception,message) \
233 if (comment_info.comment != (char *) NULL) \
234 comment_info.comment=DestroyString(comment_info.comment); \
235 ThrowReaderException((exception),(message)); \
275 assert(image_info != (const ImageInfo *) NULL);
276 assert(image_info->signature == MagickCoreSignature);
277 if (image_info->debug != MagickFalse)
278 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
279 image_info->filename);
280 assert(exception != (ExceptionInfo *) NULL);
281 assert(exception->signature == MagickCoreSignature);
282 image=AcquireImage(image_info,exception);
283 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
284 if (status == MagickFalse)
286 image=DestroyImageList(image);
287 return((Image *) NULL);
292 count=ReadBlob(image,1,(unsigned char *) &format);
296 Initialize image structure.
298 comment_info.comment=AcquireString(NULL);
299 comment_info.extent=MagickPathExtent;
300 if ((count != 1) || (format != 'P'))
301 ThrowPNMException(CorruptImageError,"ImproperImageHeader");
303 quantum_type=RGBQuantum;
305 format=(char) ReadBlobByte(image);
309 PBM, PGM, PPM, and PNM.
311 image->columns=(size_t) PNMInteger(image,&comment_info,10,exception);
312 image->rows=(size_t) PNMInteger(image,&comment_info,10,exception);
313 if ((format == 'f') || (format == 'F'))
316 scale[MagickPathExtent];
318 if (ReadBlobString(image,scale) != (char *) NULL)
319 quantum_scale=StringToDouble(scale,(char **) NULL);
323 if ((format == '1') || (format == '4'))
324 max_value=1; /* bitmap */
326 max_value=(QuantumAny) PNMInteger(image,&comment_info,10,
333 keyword[MagickPathExtent],
334 value[MagickPathExtent];
345 for (c=ReadBlobByte(image); c != EOF; c=ReadBlobByte(image))
347 while (isspace((int) ((unsigned char) c)) != 0)
348 c=ReadBlobByte(image);
354 c=PNMComment(image,&comment_info,exception);
355 c=ReadBlobByte(image);
356 while (isspace((int) ((unsigned char) c)) != 0)
357 c=ReadBlobByte(image);
362 if ((size_t) (p-keyword) < (MagickPathExtent-1))
364 c=ReadBlobByte(image);
365 } while (isalnum(c));
367 if (LocaleCompare(keyword,"endhdr") == 0)
369 while (isspace((int) ((unsigned char) c)) != 0)
370 c=ReadBlobByte(image);
372 while (isalnum(c) || (c == '_'))
374 if ((size_t) (p-value) < (MagickPathExtent-1))
376 c=ReadBlobByte(image);
380 Assign a value to the specified keyword.
382 if (LocaleCompare(keyword,"depth") == 0)
383 packet_size=StringToUnsignedLong(value);
385 if (LocaleCompare(keyword,"height") == 0)
386 image->rows=StringToUnsignedLong(value);
387 if (LocaleCompare(keyword,"maxval") == 0)
388 max_value=StringToUnsignedLong(value);
389 if (LocaleCompare(keyword,"TUPLTYPE") == 0)
391 if (LocaleCompare(value,"BLACKANDWHITE") == 0)
393 (void) SetImageColorspace(image,GRAYColorspace,exception);
394 quantum_type=GrayQuantum;
396 if (LocaleCompare(value,"BLACKANDWHITE_ALPHA") == 0)
398 (void) SetImageColorspace(image,GRAYColorspace,exception);
399 image->alpha_trait=BlendPixelTrait;
400 quantum_type=GrayAlphaQuantum;
402 if (LocaleCompare(value,"GRAYSCALE") == 0)
404 quantum_type=GrayQuantum;
405 (void) SetImageColorspace(image,GRAYColorspace,exception);
407 if (LocaleCompare(value,"GRAYSCALE_ALPHA") == 0)
409 (void) SetImageColorspace(image,GRAYColorspace,exception);
410 image->alpha_trait=BlendPixelTrait;
411 quantum_type=GrayAlphaQuantum;
413 if (LocaleCompare(value,"RGB_ALPHA") == 0)
415 image->alpha_trait=BlendPixelTrait;
416 quantum_type=RGBAQuantum;
418 if (LocaleCompare(value,"CMYK") == 0)
420 (void) SetImageColorspace(image,CMYKColorspace,exception);
421 quantum_type=CMYKQuantum;
423 if (LocaleCompare(value,"CMYK_ALPHA") == 0)
425 (void) SetImageColorspace(image,CMYKColorspace,exception);
426 image->alpha_trait=BlendPixelTrait;
427 quantum_type=CMYKAQuantum;
430 if (LocaleCompare(keyword,"width") == 0)
431 image->columns=StringToUnsignedLong(value);
434 if ((image->columns == 0) || (image->rows == 0))
435 ThrowPNMException(CorruptImageError,"NegativeOrZeroImageSize");
436 if ((max_value == 0) || (max_value > 4294967295UL))
437 ThrowPNMException(CorruptImageError,"ImproperImageHeader");
438 for (depth=1; GetQuantumRange(depth) < max_value; depth++) ;
440 if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
441 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
443 status=SetImageExtent(image,image->columns,image->rows,exception);
444 if (status == MagickFalse)
446 comment_info.comment=DestroyString(comment_info.comment); \
447 return(DestroyImageList(image));
449 (void) SetImageBackgroundColor(image,exception);
451 Convert PNM pixels to runextent-encoded MIFF packets.
460 Convert PBM image to pixel packets.
462 (void) SetImageColorspace(image,GRAYColorspace,exception);
463 for (y=0; y < (ssize_t) image->rows; y++)
471 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
472 if (q == (Quantum *) NULL)
474 for (x=0; x < (ssize_t) image->columns; x++)
476 SetPixelGray(image,PNMInteger(image,&comment_info,2,exception) ==
477 0 ? QuantumRange : 0,q);
478 if (EOFBlob(image) != MagickFalse)
480 q+=GetPixelChannels(image);
482 if (SyncAuthenticPixels(image,exception) == MagickFalse)
484 if (image->previous == (Image *) NULL)
486 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
488 if (status == MagickFalse)
491 if (EOFBlob(image) != MagickFalse)
494 image->type=BilevelType;
503 Convert PGM image to pixel packets.
505 (void) SetImageColorspace(image,GRAYColorspace,exception);
506 for (y=0; y < (ssize_t) image->rows; y++)
514 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
515 if (q == (Quantum *) NULL)
517 for (x=0; x < (ssize_t) image->columns; x++)
519 intensity=ScaleAnyToQuantum(PNMInteger(image,&comment_info,10,
520 exception),max_value);
521 if (EOFBlob(image) != MagickFalse)
523 SetPixelGray(image,intensity,q);
524 q+=GetPixelChannels(image);
526 if (SyncAuthenticPixels(image,exception) == MagickFalse)
528 if (image->previous == (Image *) NULL)
530 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
532 if (status == MagickFalse)
535 if (EOFBlob(image) != MagickFalse)
538 image->type=GrayscaleType;
544 Convert PNM image to pixel packets.
546 for (y=0; y < (ssize_t) image->rows; y++)
554 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
555 if (q == (Quantum *) NULL)
557 for (x=0; x < (ssize_t) image->columns; x++)
562 pixel=ScaleAnyToQuantum(PNMInteger(image,&comment_info,10,
563 exception),max_value);
564 if (EOFBlob(image) != MagickFalse)
566 SetPixelRed(image,pixel,q);
567 pixel=ScaleAnyToQuantum(PNMInteger(image,&comment_info,10,
568 exception),max_value);
569 SetPixelGreen(image,pixel,q);
570 pixel=ScaleAnyToQuantum(PNMInteger(image,&comment_info,10,
571 exception),max_value);
572 SetPixelBlue(image,pixel,q);
573 q+=GetPixelChannels(image);
575 if (SyncAuthenticPixels(image,exception) == MagickFalse)
577 if (image->previous == (Image *) NULL)
579 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
581 if (status == MagickFalse)
584 if (EOFBlob(image) != MagickFalse)
592 Convert PBM raw image to pixel packets.
594 (void) SetImageColorspace(image,GRAYColorspace,exception);
595 quantum_type=GrayQuantum;
596 if (image->storage_class == PseudoClass)
597 quantum_type=IndexQuantum;
598 quantum_info=AcquireQuantumInfo(image_info,image);
599 if (quantum_info == (QuantumInfo *) NULL)
600 ThrowPNMException(ResourceLimitError,"MemoryAllocationFailed");
601 SetQuantumMinIsWhite(quantum_info,MagickTrue);
602 extent=GetQuantumExtent(image,quantum_info,quantum_type);
603 for (y=0; y < (ssize_t) image->rows; y++)
620 pixels=(unsigned char *) ReadBlobStream(image,extent,
621 GetQuantumPixels(quantum_info),&count);
622 if (count != (ssize_t) extent)
624 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
625 (image->previous == (Image *) NULL))
630 proceed=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
632 if (proceed == MagickFalse)
636 q=QueueAuthenticPixels(image,0,offset,image->columns,1,exception);
637 if (q == (Quantum *) NULL)
639 length=ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
640 quantum_type,pixels,exception);
641 if (length != extent)
643 sync=SyncAuthenticPixels(image,exception);
644 if (sync == MagickFalse)
647 quantum_info=DestroyQuantumInfo(quantum_info);
648 SetQuantumImageType(image,quantum_type);
654 Convert PGM raw image to pixel packets.
656 (void) SetImageColorspace(image,GRAYColorspace,exception);
657 quantum_type=GrayQuantum;
658 extent=(image->depth <= 8 ? 1 : image->depth <= 16 ? 2 : 4)*
660 quantum_info=AcquireQuantumInfo(image_info,image);
661 if (quantum_info == (QuantumInfo *) NULL)
662 ThrowPNMException(ResourceLimitError,"MemoryAllocationFailed");
663 for (y=0; y < (ssize_t) image->rows; y++)
671 register const unsigned char
683 pixels=(unsigned char *) ReadBlobStream(image,extent,
684 GetQuantumPixels(quantum_info),&count);
685 if (count != (ssize_t) extent)
687 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
688 (image->previous == (Image *) NULL))
693 proceed=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
695 if (proceed == MagickFalse)
699 q=QueueAuthenticPixels(image,0,offset,image->columns,1,exception);
700 if (q == (Quantum *) NULL)
703 switch (image->depth)
709 (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
710 quantum_type,pixels,exception);
715 if (image->depth <= 8)
720 for (x=0; x < (ssize_t) image->columns; x++)
722 p=PushCharPixel(p,&pixel);
723 SetPixelGray(image,ScaleAnyToQuantum(pixel,max_value),q);
724 q+=GetPixelChannels(image);
727 else if (image->depth <= 16)
732 for (x=0; x < (ssize_t) image->columns; x++)
734 p=PushShortPixel(MSBEndian,p,&pixel);
735 SetPixelGray(image,ScaleAnyToQuantum(pixel,max_value),q);
736 q+=GetPixelChannels(image);
744 for (x=0; x < (ssize_t) image->columns; x++)
746 p=PushLongPixel(MSBEndian,p,&pixel);
747 SetPixelGray(image,ScaleAnyToQuantum(pixel,max_value),q);
748 q+=GetPixelChannels(image);
754 sync=SyncAuthenticPixels(image,exception);
755 if (sync == MagickFalse)
758 quantum_info=DestroyQuantumInfo(quantum_info);
759 SetQuantumImageType(image,quantum_type);
765 Convert PNM raster image to pixel packets.
767 quantum_type=RGBQuantum;
768 extent=3*(image->depth <= 8 ? 1 : image->depth <= 16 ? 2 : 4)*
770 quantum_info=AcquireQuantumInfo(image_info,image);
771 if (quantum_info == (QuantumInfo *) NULL)
772 ThrowPNMException(ResourceLimitError,"MemoryAllocationFailed");
773 (void) SetQuantumEndian(image,quantum_info,MSBEndian);
774 for (y=0; y < (ssize_t) image->rows; y++)
782 register const unsigned char
794 pixels=(unsigned char *) ReadBlobStream(image,extent,
795 GetQuantumPixels(quantum_info),&count);
796 if (count != (ssize_t) extent)
798 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
799 (image->previous == (Image *) NULL))
804 proceed=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
806 if (proceed == MagickFalse)
810 q=QueueAuthenticPixels(image,0,offset,image->columns,1,exception);
811 if (q == (Quantum *) NULL)
814 switch (image->depth)
818 for (x=0; x < (ssize_t) image->columns; x++)
820 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
821 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
822 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
823 SetPixelAlpha(image,OpaqueAlpha,q);
824 q+=GetPixelChannels(image);
833 for (x=0; x < (ssize_t) image->columns; x++)
835 p=PushShortPixel(MSBEndian,p,&pixel);
836 SetPixelRed(image,ScaleShortToQuantum(pixel),q);
837 p=PushShortPixel(MSBEndian,p,&pixel);
838 SetPixelGreen(image,ScaleShortToQuantum(pixel),q);
839 p=PushShortPixel(MSBEndian,p,&pixel);
840 SetPixelBlue(image,ScaleShortToQuantum(pixel),q);
841 SetPixelAlpha(image,OpaqueAlpha,q);
842 q+=GetPixelChannels(image);
851 for (x=0; x < (ssize_t) image->columns; x++)
853 p=PushLongPixel(MSBEndian,p,&pixel);
854 SetPixelRed(image,ScaleLongToQuantum(pixel),q);
855 p=PushLongPixel(MSBEndian,p,&pixel);
856 SetPixelGreen(image,ScaleLongToQuantum(pixel),q);
857 p=PushLongPixel(MSBEndian,p,&pixel);
858 SetPixelBlue(image,ScaleLongToQuantum(pixel),q);
859 SetPixelAlpha(image,OpaqueAlpha,q);
860 q+=GetPixelChannels(image);
866 if (image->depth <= 8)
871 for (x=0; x < (ssize_t) image->columns; x++)
873 p=PushCharPixel(p,&pixel);
874 SetPixelRed(image,ScaleAnyToQuantum(pixel,max_value),q);
875 p=PushCharPixel(p,&pixel);
876 SetPixelGreen(image,ScaleAnyToQuantum(pixel,max_value),q);
877 p=PushCharPixel(p,&pixel);
878 SetPixelBlue(image,ScaleAnyToQuantum(pixel,max_value),q);
879 SetPixelAlpha(image,OpaqueAlpha,q);
880 q+=GetPixelChannels(image);
883 else if (image->depth <= 16)
888 for (x=0; x < (ssize_t) image->columns; x++)
890 p=PushShortPixel(MSBEndian,p,&pixel);
891 SetPixelRed(image,ScaleAnyToQuantum(pixel,max_value),q);
892 p=PushShortPixel(MSBEndian,p,&pixel);
893 SetPixelGreen(image,ScaleAnyToQuantum(pixel,max_value),q);
894 p=PushShortPixel(MSBEndian,p,&pixel);
895 SetPixelBlue(image,ScaleAnyToQuantum(pixel,max_value),q);
896 SetPixelAlpha(image,OpaqueAlpha,q);
897 q+=GetPixelChannels(image);
905 for (x=0; x < (ssize_t) image->columns; x++)
907 p=PushLongPixel(MSBEndian,p,&pixel);
908 SetPixelRed(image,ScaleAnyToQuantum(pixel,max_value),q);
909 p=PushLongPixel(MSBEndian,p,&pixel);
910 SetPixelGreen(image,ScaleAnyToQuantum(pixel,max_value),q);
911 p=PushLongPixel(MSBEndian,p,&pixel);
912 SetPixelBlue(image,ScaleAnyToQuantum(pixel,max_value),q);
913 SetPixelAlpha(image,OpaqueAlpha,q);
914 q+=GetPixelChannels(image);
920 sync=SyncAuthenticPixels(image,exception);
921 if (sync == MagickFalse)
924 quantum_info=DestroyQuantumInfo(quantum_info);
933 Convert PAM raster image to pixel packets.
935 switch (quantum_type)
938 case GrayAlphaQuantum:
955 if (image->alpha_trait != UndefinedPixelTrait)
957 extent=channels*(image->depth <= 8 ? 1 : image->depth <= 16 ? 2 : 4)*
959 quantum_info=AcquireQuantumInfo(image_info,image);
960 if (quantum_info == (QuantumInfo *) NULL)
961 ThrowPNMException(ResourceLimitError,"MemoryAllocationFailed");
962 for (y=0; y < (ssize_t) image->rows; y++)
970 register const unsigned char
982 pixels=(unsigned char *) ReadBlobStream(image,extent,
983 GetQuantumPixels(quantum_info),&count);
984 if (count != (ssize_t) extent)
986 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
987 (image->previous == (Image *) NULL))
992 proceed=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
994 if (proceed == MagickFalse)
998 q=QueueAuthenticPixels(image,0,offset,image->columns,1,exception);
999 if (q == (Quantum *) NULL)
1002 switch (image->depth)
1008 (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1009 quantum_type,pixels,exception);
1014 switch (quantum_type)
1017 case GrayAlphaQuantum:
1019 if (image->depth <= 8)
1024 for (x=0; x < (ssize_t) image->columns; x++)
1026 p=PushCharPixel(p,&pixel);
1027 SetPixelGray(image,ScaleAnyToQuantum(pixel,max_value),
1029 SetPixelAlpha(image,OpaqueAlpha,q);
1030 if (image->alpha_trait != UndefinedPixelTrait)
1032 p=PushCharPixel(p,&pixel);
1033 if (image->depth != 1)
1034 SetPixelAlpha(image,ScaleAnyToQuantum(pixel,
1037 SetPixelAlpha(image,QuantumRange-
1038 ScaleAnyToQuantum(pixel,max_value),q);
1040 q+=GetPixelChannels(image);
1043 else if (image->depth <= 16)
1048 for (x=0; x < (ssize_t) image->columns; x++)
1050 p=PushShortPixel(MSBEndian,p,&pixel);
1051 SetPixelGray(image,ScaleAnyToQuantum(pixel,max_value),
1053 SetPixelAlpha(image,OpaqueAlpha,q);
1054 if (image->alpha_trait != UndefinedPixelTrait)
1056 p=PushShortPixel(MSBEndian,p,&pixel);
1057 SetPixelAlpha(image,ScaleAnyToQuantum(pixel,
1060 q+=GetPixelChannels(image);
1068 for (x=0; x < (ssize_t) image->columns; x++)
1070 p=PushLongPixel(MSBEndian,p,&pixel);
1071 SetPixelGray(image,ScaleAnyToQuantum(pixel,max_value),
1073 SetPixelAlpha(image,OpaqueAlpha,q);
1074 if (image->alpha_trait != UndefinedPixelTrait)
1076 p=PushLongPixel(MSBEndian,p,&pixel);
1077 SetPixelAlpha(image,ScaleAnyToQuantum(pixel,
1080 q+=GetPixelChannels(image);
1088 if (image->depth <= 8)
1093 for (x=0; x < (ssize_t) image->columns; x++)
1095 p=PushCharPixel(p,&pixel);
1096 SetPixelRed(image,ScaleAnyToQuantum(pixel,max_value),q);
1097 p=PushCharPixel(p,&pixel);
1098 SetPixelGreen(image,ScaleAnyToQuantum(pixel,max_value),
1100 p=PushCharPixel(p,&pixel);
1101 SetPixelBlue(image,ScaleAnyToQuantum(pixel,max_value),
1103 p=PushCharPixel(p,&pixel);
1104 SetPixelBlack(image,ScaleAnyToQuantum(pixel,max_value),
1106 SetPixelAlpha(image,OpaqueAlpha,q);
1107 if (image->alpha_trait != UndefinedPixelTrait)
1109 p=PushCharPixel(p,&pixel);
1110 SetPixelAlpha(image,ScaleAnyToQuantum(pixel,
1113 q+=GetPixelChannels(image);
1116 else if (image->depth <= 16)
1121 for (x=0; x < (ssize_t) image->columns; x++)
1123 p=PushShortPixel(MSBEndian,p,&pixel);
1124 SetPixelRed(image,ScaleAnyToQuantum(pixel,max_value),q);
1125 p=PushShortPixel(MSBEndian,p,&pixel);
1126 SetPixelGreen(image,ScaleAnyToQuantum(pixel,max_value),
1128 p=PushShortPixel(MSBEndian,p,&pixel);
1129 SetPixelBlue(image,ScaleAnyToQuantum(pixel,max_value),
1131 p=PushShortPixel(MSBEndian,p,&pixel);
1132 SetPixelBlack(image,ScaleAnyToQuantum(pixel,max_value),
1134 SetPixelAlpha(image,OpaqueAlpha,q);
1135 if (image->alpha_trait != UndefinedPixelTrait)
1137 p=PushShortPixel(MSBEndian,p,&pixel);
1138 SetPixelAlpha(image,ScaleAnyToQuantum(pixel,
1141 q+=GetPixelChannels(image);
1149 for (x=0; x < (ssize_t) image->columns; x++)
1151 p=PushLongPixel(MSBEndian,p,&pixel);
1152 SetPixelRed(image,ScaleAnyToQuantum(pixel,max_value),
1154 p=PushLongPixel(MSBEndian,p,&pixel);
1155 SetPixelGreen(image,ScaleAnyToQuantum(pixel,max_value),
1157 p=PushLongPixel(MSBEndian,p,&pixel);
1158 SetPixelBlue(image,ScaleAnyToQuantum(pixel,max_value),
1160 p=PushLongPixel(MSBEndian,p,&pixel);
1161 SetPixelBlack(image,ScaleAnyToQuantum(pixel,max_value),
1163 SetPixelAlpha(image,OpaqueAlpha,q);
1164 if (image->alpha_trait != UndefinedPixelTrait)
1166 p=PushLongPixel(MSBEndian,p,&pixel);
1167 SetPixelAlpha(image,ScaleAnyToQuantum(pixel,
1170 q+=GetPixelChannels(image);
1177 if (image->depth <= 8)
1182 for (x=0; x < (ssize_t) image->columns; x++)
1184 p=PushCharPixel(p,&pixel);
1185 SetPixelRed(image,ScaleAnyToQuantum(pixel,max_value),q);
1186 p=PushCharPixel(p,&pixel);
1187 SetPixelGreen(image,ScaleAnyToQuantum(pixel,max_value),
1189 p=PushCharPixel(p,&pixel);
1190 SetPixelBlue(image,ScaleAnyToQuantum(pixel,max_value),
1192 SetPixelAlpha(image,OpaqueAlpha,q);
1193 if (image->alpha_trait != UndefinedPixelTrait)
1195 p=PushCharPixel(p,&pixel);
1196 SetPixelAlpha(image,ScaleAnyToQuantum(pixel,
1199 q+=GetPixelChannels(image);
1202 else if (image->depth <= 16)
1207 for (x=0; x < (ssize_t) image->columns; x++)
1209 p=PushShortPixel(MSBEndian,p,&pixel);
1210 SetPixelRed(image,ScaleAnyToQuantum(pixel,max_value),q);
1211 p=PushShortPixel(MSBEndian,p,&pixel);
1212 SetPixelGreen(image,ScaleAnyToQuantum(pixel,max_value),
1214 p=PushShortPixel(MSBEndian,p,&pixel);
1215 SetPixelBlue(image,ScaleAnyToQuantum(pixel,max_value),
1217 SetPixelAlpha(image,OpaqueAlpha,q);
1218 if (image->alpha_trait != UndefinedPixelTrait)
1220 p=PushShortPixel(MSBEndian,p,&pixel);
1221 SetPixelAlpha(image,ScaleAnyToQuantum(pixel,
1224 q+=GetPixelChannels(image);
1232 for (x=0; x < (ssize_t) image->columns; x++)
1234 p=PushLongPixel(MSBEndian,p,&pixel);
1235 SetPixelRed(image,ScaleAnyToQuantum(pixel,max_value),
1237 p=PushLongPixel(MSBEndian,p,&pixel);
1238 SetPixelGreen(image,ScaleAnyToQuantum(pixel,max_value),
1240 p=PushLongPixel(MSBEndian,p,&pixel);
1241 SetPixelBlue(image,ScaleAnyToQuantum(pixel,max_value),
1243 SetPixelAlpha(image,OpaqueAlpha,q);
1244 if (image->alpha_trait != UndefinedPixelTrait)
1246 p=PushLongPixel(MSBEndian,p,&pixel);
1247 SetPixelAlpha(image,ScaleAnyToQuantum(pixel,
1250 q+=GetPixelChannels(image);
1258 sync=SyncAuthenticPixels(image,exception);
1259 if (sync == MagickFalse)
1262 quantum_info=DestroyQuantumInfo(quantum_info);
1263 SetQuantumImageType(image,quantum_type);
1270 Convert PFM raster image to pixel packets.
1273 (void) SetImageColorspace(image,GRAYColorspace,exception);
1274 quantum_type=format == 'f' ? GrayQuantum : RGBQuantum;
1275 image->endian=quantum_scale < 0.0 ? LSBEndian : MSBEndian;
1277 quantum_info=AcquireQuantumInfo(image_info,image);
1278 if (quantum_info == (QuantumInfo *) NULL)
1279 ThrowPNMException(ResourceLimitError,"MemoryAllocationFailed");
1280 status=SetQuantumDepth(image,quantum_info,32);
1281 if (status == MagickFalse)
1282 ThrowPNMException(ResourceLimitError,"MemoryAllocationFailed");
1283 status=SetQuantumFormat(image,quantum_info,FloatingPointQuantumFormat);
1284 if (status == MagickFalse)
1285 ThrowPNMException(ResourceLimitError,"MemoryAllocationFailed");
1286 SetQuantumScale(quantum_info,(double) QuantumRange*fabs(quantum_scale));
1287 extent=GetQuantumExtent(image,quantum_info,quantum_type);
1288 for (y=0; y < (ssize_t) image->rows; y++)
1305 pixels=(unsigned char *) ReadBlobStream(image,extent,
1306 GetQuantumPixels(quantum_info),&count);
1307 if (count != (ssize_t) extent)
1309 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
1310 (image->previous == (Image *) NULL))
1315 proceed=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
1317 if (proceed == MagickFalse)
1321 q=QueueAuthenticPixels(image,0,(ssize_t) (image->rows-offset-1),
1322 image->columns,1,exception);
1323 if (q == (Quantum *) NULL)
1325 length=ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1326 quantum_type,pixels,exception);
1327 if (length != extent)
1329 sync=SyncAuthenticPixels(image,exception);
1330 if (sync == MagickFalse)
1333 quantum_info=DestroyQuantumInfo(quantum_info);
1334 SetQuantumImageType(image,quantum_type);
1338 ThrowPNMException(CorruptImageError,"ImproperImageHeader");
1340 if (*comment_info.comment != '\0')
1341 (void) SetImageProperty(image,"comment",comment_info.comment,exception);
1342 comment_info.comment=DestroyString(comment_info.comment);
1343 if (y < (ssize_t) image->rows)
1344 ThrowPNMException(CorruptImageError,"UnableToReadImageData");
1345 if (EOFBlob(image) != MagickFalse)
1347 (void) ThrowMagickException(exception,GetMagickModule(),
1348 CorruptImageError,"UnexpectedEndOfFile","`%s'",image->filename);
1352 Proceed to next image.
1354 if (image_info->number_scenes != 0)
1355 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
1357 if ((format == '1') || (format == '2') || (format == '3'))
1361 Skip to end of line.
1363 count=ReadBlob(image,1,(unsigned char *) &format);
1368 } while (format != '\n');
1369 count=ReadBlob(image,1,(unsigned char *) &format);
1370 if ((count == 1) && (format == 'P'))
1373 Allocate next image structure.
1375 AcquireNextImage(image_info,image,exception);
1376 if (GetNextImageInList(image) == (Image *) NULL)
1381 image=SyncNextImageInList(image);
1382 status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
1383 GetBlobSize(image));
1384 if (status == MagickFalse)
1387 } while ((count == 1) && (format == 'P'));
1388 (void) CloseBlob(image);
1389 if (status == MagickFalse)
1390 return(DestroyImageList(image));
1391 return(GetFirstImageInList(image));
1395 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1399 % R e g i s t e r P N M I m a g e %
1403 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1405 % RegisterPNMImage() adds properties for the PNM image format to
1406 % the list of supported formats. The properties include the image format
1407 % tag, a method to read and/or write the format, whether the format
1408 % supports the saving of more than one frame to the same file or blob,
1409 % whether the format supports native in-memory I/O, and a brief
1410 % description of the format.
1412 % The format of the RegisterPNMImage method is:
1414 % size_t RegisterPNMImage(void)
1417 ModuleExport size_t RegisterPNMImage(void)
1422 entry=AcquireMagickInfo("PNM","PAM","Common 2-dimensional bitmap format");
1423 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1424 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1425 entry->mime_type=ConstantString("image/x-portable-pixmap");
1426 (void) RegisterMagickInfo(entry);
1427 entry=AcquireMagickInfo("PNM","PBM",
1428 "Portable bitmap format (black and white)");
1429 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1430 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1431 entry->mime_type=ConstantString("image/x-portable-bitmap");
1432 (void) RegisterMagickInfo(entry);
1433 entry=AcquireMagickInfo("PNM","PFM","Portable float format");
1434 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1435 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1436 entry->flags|=CoderEndianSupportFlag;
1437 (void) RegisterMagickInfo(entry);
1438 entry=AcquireMagickInfo("PNM","PGM","Portable graymap format (gray scale)");
1439 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1440 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1441 entry->mime_type=ConstantString("image/x-portable-greymap");
1442 (void) RegisterMagickInfo(entry);
1443 entry=AcquireMagickInfo("PNM","PNM","Portable anymap");
1444 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1445 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1446 entry->magick=(IsImageFormatHandler *) IsPNM;
1447 entry->mime_type=ConstantString("image/x-portable-pixmap");
1448 (void) RegisterMagickInfo(entry);
1449 entry=AcquireMagickInfo("PNM","PPM","Portable pixmap format (color)");
1450 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1451 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1452 entry->mime_type=ConstantString("image/x-portable-pixmap");
1453 (void) RegisterMagickInfo(entry);
1454 return(MagickImageCoderSignature);
1458 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1462 % U n r e g i s t e r P N M I m a g e %
1466 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1468 % UnregisterPNMImage() removes format registrations made by the
1469 % PNM module from the list of supported formats.
1471 % The format of the UnregisterPNMImage method is:
1473 % UnregisterPNMImage(void)
1476 ModuleExport void UnregisterPNMImage(void)
1478 (void) UnregisterMagickInfo("PAM");
1479 (void) UnregisterMagickInfo("PBM");
1480 (void) UnregisterMagickInfo("PGM");
1481 (void) UnregisterMagickInfo("PNM");
1482 (void) UnregisterMagickInfo("PPM");
1486 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1490 % W r i t e P N M I m a g e %
1494 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1496 % WritePNMImage() writes an image to a file in the PNM rasterfile format.
1498 % The format of the WritePNMImage method is:
1500 % MagickBooleanType WritePNMImage(const ImageInfo *image_info,
1501 % Image *image,ExceptionInfo *exception)
1503 % A description of each parameter follows.
1505 % o image_info: the image info.
1507 % o image: The image.
1509 % o exception: return any errors or warnings in this structure.
1512 static MagickBooleanType WritePNMImage(const ImageInfo *image_info,Image *image,
1513 ExceptionInfo *exception)
1516 buffer[MagickPathExtent],
1518 magick[MagickPathExtent];
1541 register unsigned char
1554 Open output image file.
1556 assert(image_info != (const ImageInfo *) NULL);
1557 assert(image_info->signature == MagickCoreSignature);
1558 assert(image != (Image *) NULL);
1559 assert(image->signature == MagickCoreSignature);
1560 if (image->debug != MagickFalse)
1561 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1562 assert(exception != (ExceptionInfo *) NULL);
1563 assert(exception->signature == MagickCoreSignature);
1564 status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
1565 if (status == MagickFalse)
1568 imageListLength=GetImageListLength(image);
1575 Write PNM file header.
1578 quantum_type=RGBQuantum;
1579 (void) CopyMagickString(magick,image_info->magick,MagickPathExtent);
1580 max_value=GetQuantumRange(image->depth);
1593 if (image_info->compression == NoCompression)
1601 if (SetImageGray(image,exception) != MagickFalse)
1609 if (image_info->compression == NoCompression)
1616 if ((image_info->type != TrueColorType) &&
1617 (SetImageGray(image,exception) != MagickFalse))
1620 if (image_info->compression == NoCompression)
1622 if (SetImageMonochrome(image,exception) != MagickFalse)
1625 if (image_info->compression == NoCompression)
1634 if (image_info->compression == NoCompression)
1639 (void) FormatLocaleString(buffer,MagickPathExtent,"P%c\n",format);
1640 (void) WriteBlobString(image,buffer);
1641 value=GetImageProperty(image,"comment",exception);
1642 if (value != (const char *) NULL)
1648 Write comments to file.
1650 (void) WriteBlobByte(image,'#');
1651 for (p=value; *p != '\0'; p++)
1653 (void) WriteBlobByte(image,(unsigned char) *p);
1654 if ((*p == '\n') || (*p == '\r'))
1655 (void) WriteBlobByte(image,'#');
1657 (void) WriteBlobByte(image,'\n');
1661 (void) FormatLocaleString(buffer,MagickPathExtent,"%.20g %.20g\n",
1662 (double) image->columns,(double) image->rows);
1663 (void) WriteBlobString(image,buffer);
1668 type[MagickPathExtent];
1673 (void) FormatLocaleString(buffer,MagickPathExtent,
1674 "WIDTH %.20g\nHEIGHT %.20g\n",(double) image->columns,(double)
1676 (void) WriteBlobString(image,buffer);
1677 quantum_type=GetQuantumType(image,exception);
1678 switch (quantum_type)
1684 (void) CopyMagickString(type,"CMYK",MagickPathExtent);
1688 case GrayAlphaQuantum:
1691 (void) CopyMagickString(type,"GRAYSCALE",MagickPathExtent);
1692 if (IdentifyImageMonochrome(image,exception) != MagickFalse)
1693 (void) CopyMagickString(type,"BLACKANDWHITE",MagickPathExtent);
1698 quantum_type=RGBQuantum;
1699 if (image->alpha_trait != UndefinedPixelTrait)
1700 quantum_type=RGBAQuantum;
1702 (void) CopyMagickString(type,"RGB",MagickPathExtent);
1706 if (image->alpha_trait != UndefinedPixelTrait)
1709 (void) ConcatenateMagickString(type,"_ALPHA",MagickPathExtent);
1711 if (image->depth > 32)
1713 (void) FormatLocaleString(buffer,MagickPathExtent,
1714 "DEPTH %.20g\nMAXVAL %.20g\n",(double) packet_size,(double)
1715 ((MagickOffsetType) GetQuantumRange(image->depth)));
1716 (void) WriteBlobString(image,buffer);
1717 (void) FormatLocaleString(buffer,MagickPathExtent,
1718 "TUPLTYPE %s\nENDHDR\n",type);
1719 (void) WriteBlobString(image,buffer);
1722 Convert runextent encoded to PNM raster pixels.
1732 Convert image to a PBM image.
1734 (void) SetImageType(image,BilevelType,exception);
1736 for (y=0; y < (ssize_t) image->rows; y++)
1738 register const Quantum
1744 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1745 if (p == (const Quantum *) NULL)
1747 for (x=0; x < (ssize_t) image->columns; x++)
1749 *q++=(unsigned char) (GetPixelLuma(image,p) >= (QuantumRange/2.0) ?
1752 if ((q-pixels+1) >= (ssize_t) sizeof(pixels))
1755 (void) WriteBlob(image,q-pixels,pixels);
1758 p+=GetPixelChannels(image);
1761 (void) WriteBlob(image,q-pixels,pixels);
1763 if (image->previous == (Image *) NULL)
1765 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1767 if (status == MagickFalse)
1774 (void) WriteBlob(image,q-pixels,pixels);
1784 Convert image to a PGM image.
1786 if (image->depth <= 8)
1787 (void) WriteBlobString(image,"255\n");
1789 if (image->depth <= 16)
1790 (void) WriteBlobString(image,"65535\n");
1792 (void) WriteBlobString(image,"4294967295\n");
1794 for (y=0; y < (ssize_t) image->rows; y++)
1796 register const Quantum
1802 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1803 if (p == (const Quantum *) NULL)
1805 for (x=0; x < (ssize_t) image->columns; x++)
1807 index=ClampToQuantum(GetPixelLuma(image,p));
1808 if (image->depth <= 8)
1809 count=(ssize_t) FormatLocaleString(buffer,MagickPathExtent,"%u ",
1810 ScaleQuantumToChar(index));
1812 if (image->depth <= 16)
1813 count=(ssize_t) FormatLocaleString(buffer,MagickPathExtent,
1814 "%u ",ScaleQuantumToShort(index));
1816 count=(ssize_t) FormatLocaleString(buffer,MagickPathExtent,
1817 "%u ",ScaleQuantumToLong(index));
1818 extent=(size_t) count;
1819 (void) strncpy((char *) q,buffer,extent);
1821 if ((q-pixels+extent+1) >= sizeof(pixels))
1824 (void) WriteBlob(image,q-pixels,pixels);
1827 p+=GetPixelChannels(image);
1830 (void) WriteBlob(image,q-pixels,pixels);
1832 if (image->previous == (Image *) NULL)
1834 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1836 if (status == MagickFalse)
1843 (void) WriteBlob(image,q-pixels,pixels);
1853 Convert image to a PNM image.
1855 (void) TransformImageColorspace(image,sRGBColorspace,exception);
1856 if (image->depth <= 8)
1857 (void) WriteBlobString(image,"255\n");
1859 if (image->depth <= 16)
1860 (void) WriteBlobString(image,"65535\n");
1862 (void) WriteBlobString(image,"4294967295\n");
1864 for (y=0; y < (ssize_t) image->rows; y++)
1866 register const Quantum
1872 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1873 if (p == (const Quantum *) NULL)
1875 for (x=0; x < (ssize_t) image->columns; x++)
1877 if (image->depth <= 8)
1878 count=(ssize_t) FormatLocaleString(buffer,MagickPathExtent,
1879 "%u %u %u ",ScaleQuantumToChar(GetPixelRed(image,p)),
1880 ScaleQuantumToChar(GetPixelGreen(image,p)),
1881 ScaleQuantumToChar(GetPixelBlue(image,p)));
1883 if (image->depth <= 16)
1884 count=(ssize_t) FormatLocaleString(buffer,MagickPathExtent,
1885 "%u %u %u ",ScaleQuantumToShort(GetPixelRed(image,p)),
1886 ScaleQuantumToShort(GetPixelGreen(image,p)),
1887 ScaleQuantumToShort(GetPixelBlue(image,p)));
1889 count=(ssize_t) FormatLocaleString(buffer,MagickPathExtent,
1890 "%u %u %u ",ScaleQuantumToLong(GetPixelRed(image,p)),
1891 ScaleQuantumToLong(GetPixelGreen(image,p)),
1892 ScaleQuantumToLong(GetPixelBlue(image,p)));
1893 extent=(size_t) count;
1894 (void) strncpy((char *) q,buffer,extent);
1896 if ((q-pixels+extent+1) >= sizeof(pixels))
1899 (void) WriteBlob(image,q-pixels,pixels);
1902 p+=GetPixelChannels(image);
1905 (void) WriteBlob(image,q-pixels,pixels);
1907 if (image->previous == (Image *) NULL)
1909 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1911 if (status == MagickFalse)
1918 (void) WriteBlob(image,q-pixels,pixels);
1924 register unsigned char
1928 Convert image to a PBM image.
1930 (void) SetImageType(image,BilevelType,exception);
1932 quantum_info=AcquireQuantumInfo(image_info,image);
1933 if (quantum_info == (QuantumInfo *) NULL)
1934 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1935 (void) SetQuantumEndian(image,quantum_info,MSBEndian);
1936 quantum_info->min_is_white=MagickTrue;
1937 pixels=GetQuantumPixels(quantum_info);
1938 for (y=0; y < (ssize_t) image->rows; y++)
1940 register const Quantum
1943 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1944 if (p == (const Quantum *) NULL)
1946 extent=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1947 GrayQuantum,pixels,exception);
1948 count=WriteBlob(image,extent,pixels);
1949 if (count != (ssize_t) extent)
1951 if (image->previous == (Image *) NULL)
1953 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1955 if (status == MagickFalse)
1959 quantum_info=DestroyQuantumInfo(quantum_info);
1964 register unsigned char
1968 Convert image to a PGM image.
1970 if (image->depth > 32)
1972 (void) FormatLocaleString(buffer,MagickPathExtent,"%.20g\n",(double)
1973 ((MagickOffsetType) GetQuantumRange(image->depth)));
1974 (void) WriteBlobString(image,buffer);
1975 quantum_info=AcquireQuantumInfo(image_info,image);
1976 if (quantum_info == (QuantumInfo *) NULL)
1977 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1978 (void) SetQuantumEndian(image,quantum_info,MSBEndian);
1979 quantum_info->min_is_white=MagickTrue;
1980 pixels=GetQuantumPixels(quantum_info);
1981 extent=GetQuantumExtent(image,quantum_info,GrayQuantum);
1982 for (y=0; y < (ssize_t) image->rows; y++)
1984 register const Quantum
1990 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1991 if (p == (const Quantum *) NULL)
1994 switch (image->depth)
2000 extent=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2001 GrayQuantum,pixels,exception);
2006 if (image->depth <= 8)
2008 for (x=0; x < (ssize_t) image->columns; x++)
2010 if (IsPixelGray(image,p) == MagickFalse)
2011 pixel=ScaleQuantumToAny(ClampToQuantum(GetPixelLuma(
2012 image,p)),max_value);
2015 if (image->depth == 8)
2016 pixel=ScaleQuantumToChar(GetPixelRed(image,p));
2018 pixel=ScaleQuantumToAny(GetPixelRed(image,p),
2021 q=PopCharPixel((unsigned char) pixel,q);
2022 p+=GetPixelChannels(image);
2024 extent=(size_t) (q-pixels);
2027 if (image->depth <= 16)
2029 for (x=0; x < (ssize_t) image->columns; x++)
2031 if (IsPixelGray(image,p) == MagickFalse)
2032 pixel=ScaleQuantumToAny(ClampToQuantum(GetPixelLuma(image,
2036 if (image->depth == 16)
2037 pixel=ScaleQuantumToShort(GetPixelRed(image,p));
2039 pixel=ScaleQuantumToAny(GetPixelRed(image,p),
2042 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2043 p+=GetPixelChannels(image);
2045 extent=(size_t) (q-pixels);
2048 for (x=0; x < (ssize_t) image->columns; x++)
2050 if (IsPixelGray(image,p) == MagickFalse)
2051 pixel=ScaleQuantumToAny(ClampToQuantum(GetPixelLuma(image,p)),
2055 if (image->depth == 16)
2056 pixel=ScaleQuantumToLong(GetPixelRed(image,p));
2058 pixel=ScaleQuantumToAny(GetPixelRed(image,p),max_value);
2060 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2061 p+=GetPixelChannels(image);
2063 extent=(size_t) (q-pixels);
2067 count=WriteBlob(image,extent,pixels);
2068 if (count != (ssize_t) extent)
2070 if (image->previous == (Image *) NULL)
2072 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
2074 if (status == MagickFalse)
2078 quantum_info=DestroyQuantumInfo(quantum_info);
2083 register unsigned char
2087 Convert image to a PNM image.
2089 (void) TransformImageColorspace(image,sRGBColorspace,exception);
2090 if (image->depth > 32)
2092 (void) FormatLocaleString(buffer,MagickPathExtent,"%.20g\n",(double)
2093 ((MagickOffsetType) GetQuantumRange(image->depth)));
2094 (void) WriteBlobString(image,buffer);
2095 quantum_info=AcquireQuantumInfo(image_info,image);
2096 if (quantum_info == (QuantumInfo *) NULL)
2097 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
2098 (void) SetQuantumEndian(image,quantum_info,MSBEndian);
2099 pixels=GetQuantumPixels(quantum_info);
2100 extent=GetQuantumExtent(image,quantum_info,quantum_type);
2101 for (y=0; y < (ssize_t) image->rows; y++)
2103 register const Quantum
2109 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
2110 if (p == (const Quantum *) NULL)
2113 switch (image->depth)
2119 extent=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2120 quantum_type,pixels,exception);
2125 if (image->depth <= 8)
2127 for (x=0; x < (ssize_t) image->columns; x++)
2129 pixel=ScaleQuantumToAny(GetPixelRed(image,p),max_value);
2130 q=PopCharPixel((unsigned char) pixel,q);
2131 pixel=ScaleQuantumToAny(GetPixelGreen(image,p),max_value);
2132 q=PopCharPixel((unsigned char) pixel,q);
2133 pixel=ScaleQuantumToAny(GetPixelBlue(image,p),max_value);
2134 q=PopCharPixel((unsigned char) pixel,q);
2135 p+=GetPixelChannels(image);
2137 extent=(size_t) (q-pixels);
2140 if (image->depth <= 16)
2142 for (x=0; x < (ssize_t) image->columns; x++)
2144 pixel=ScaleQuantumToAny(GetPixelRed(image,p),max_value);
2145 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2146 pixel=ScaleQuantumToAny(GetPixelGreen(image,p),max_value);
2147 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2148 pixel=ScaleQuantumToAny(GetPixelBlue(image,p),max_value);
2149 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2150 p+=GetPixelChannels(image);
2152 extent=(size_t) (q-pixels);
2155 for (x=0; x < (ssize_t) image->columns; x++)
2157 pixel=ScaleQuantumToAny(GetPixelRed(image,p),max_value);
2158 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2159 pixel=ScaleQuantumToAny(GetPixelGreen(image,p),max_value);
2160 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2161 pixel=ScaleQuantumToAny(GetPixelBlue(image,p),max_value);
2162 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2163 p+=GetPixelChannels(image);
2165 extent=(size_t) (q-pixels);
2169 count=WriteBlob(image,extent,pixels);
2170 if (count != (ssize_t) extent)
2172 if (image->previous == (Image *) NULL)
2174 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
2176 if (status == MagickFalse)
2180 quantum_info=DestroyQuantumInfo(quantum_info);
2185 register unsigned char
2189 Convert image to a PAM.
2191 if (image->depth > 32)
2193 quantum_info=AcquireQuantumInfo(image_info,image);
2194 if (quantum_info == (QuantumInfo *) NULL)
2195 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
2196 (void) SetQuantumEndian(image,quantum_info,MSBEndian);
2197 pixels=GetQuantumPixels(quantum_info);
2198 for (y=0; y < (ssize_t) image->rows; y++)
2200 register const Quantum
2206 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
2207 if (p == (const Quantum *) NULL)
2210 switch (image->depth)
2216 extent=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2217 quantum_type,pixels,exception);
2222 switch (quantum_type)
2225 case GrayAlphaQuantum:
2227 if (image->depth <= 8)
2229 for (x=0; x < (ssize_t) image->columns; x++)
2231 pixel=ScaleQuantumToAny(ClampToQuantum(GetPixelLuma(
2232 image,p)),max_value);
2233 q=PopCharPixel((unsigned char) pixel,q);
2234 if (image->alpha_trait != UndefinedPixelTrait)
2236 pixel=(unsigned char) ScaleQuantumToAny(
2237 GetPixelAlpha(image,p),max_value);
2238 q=PopCharPixel((unsigned char) pixel,q);
2240 p+=GetPixelChannels(image);
2244 if (image->depth <= 16)
2246 for (x=0; x < (ssize_t) image->columns; x++)
2248 pixel=ScaleQuantumToAny(ClampToQuantum(GetPixelLuma(
2249 image,p)),max_value);
2250 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2251 if (image->alpha_trait != UndefinedPixelTrait)
2253 pixel=(unsigned char) ScaleQuantumToAny(
2254 GetPixelAlpha(image,p),max_value);
2255 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2257 p+=GetPixelChannels(image);
2261 for (x=0; x < (ssize_t) image->columns; x++)
2263 pixel=ScaleQuantumToAny(ClampToQuantum(GetPixelLuma(image,
2265 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2266 if (image->alpha_trait != UndefinedPixelTrait)
2268 pixel=(unsigned char) ScaleQuantumToAny(
2269 GetPixelAlpha(image,p),max_value);
2270 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2272 p+=GetPixelChannels(image);
2279 if (image->depth <= 8)
2281 for (x=0; x < (ssize_t) image->columns; x++)
2283 pixel=ScaleQuantumToAny(GetPixelRed(image,p),max_value);
2284 q=PopCharPixel((unsigned char) pixel,q);
2285 pixel=ScaleQuantumToAny(GetPixelGreen(image,p),
2287 q=PopCharPixel((unsigned char) pixel,q);
2288 pixel=ScaleQuantumToAny(GetPixelBlue(image,p),
2290 q=PopCharPixel((unsigned char) pixel,q);
2291 pixel=ScaleQuantumToAny(GetPixelBlack(image,p),
2293 q=PopCharPixel((unsigned char) pixel,q);
2294 if (image->alpha_trait != UndefinedPixelTrait)
2296 pixel=ScaleQuantumToAny(GetPixelAlpha(image,p),
2298 q=PopCharPixel((unsigned char) pixel,q);
2300 p+=GetPixelChannels(image);
2304 if (image->depth <= 16)
2306 for (x=0; x < (ssize_t) image->columns; x++)
2308 pixel=ScaleQuantumToAny(GetPixelRed(image,p),max_value);
2309 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2310 pixel=ScaleQuantumToAny(GetPixelGreen(image,p),
2312 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2313 pixel=ScaleQuantumToAny(GetPixelBlue(image,p),
2315 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2316 pixel=ScaleQuantumToAny(GetPixelBlack(image,p),
2318 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2319 if (image->alpha_trait != UndefinedPixelTrait)
2321 pixel=ScaleQuantumToAny(GetPixelAlpha(image,p),
2323 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2325 p+=GetPixelChannels(image);
2329 for (x=0; x < (ssize_t) image->columns; x++)
2331 pixel=ScaleQuantumToAny(GetPixelRed(image,p),max_value);
2332 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2333 pixel=ScaleQuantumToAny(GetPixelGreen(image,p),max_value);
2334 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2335 pixel=ScaleQuantumToAny(GetPixelBlue(image,p),max_value);
2336 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2337 pixel=ScaleQuantumToAny(GetPixelBlack(image,p),max_value);
2338 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2339 if (image->alpha_trait != UndefinedPixelTrait)
2341 pixel=ScaleQuantumToAny(GetPixelAlpha(image,p),
2343 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2345 p+=GetPixelChannels(image);
2351 if (image->depth <= 8)
2353 for (x=0; x < (ssize_t) image->columns; x++)
2355 pixel=ScaleQuantumToAny(GetPixelRed(image,p),max_value);
2356 q=PopCharPixel((unsigned char) pixel,q);
2357 pixel=ScaleQuantumToAny(GetPixelGreen(image,p),
2359 q=PopCharPixel((unsigned char) pixel,q);
2360 pixel=ScaleQuantumToAny(GetPixelBlue(image,p),
2362 q=PopCharPixel((unsigned char) pixel,q);
2363 if (image->alpha_trait != UndefinedPixelTrait)
2365 pixel=ScaleQuantumToAny(GetPixelAlpha(image,p),
2367 q=PopCharPixel((unsigned char) pixel,q);
2369 p+=GetPixelChannels(image);
2373 if (image->depth <= 16)
2375 for (x=0; x < (ssize_t) image->columns; x++)
2377 pixel=ScaleQuantumToAny(GetPixelRed(image,p),max_value);
2378 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2379 pixel=ScaleQuantumToAny(GetPixelGreen(image,p),
2381 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2382 pixel=ScaleQuantumToAny(GetPixelBlue(image,p),
2384 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2385 if (image->alpha_trait != UndefinedPixelTrait)
2387 pixel=ScaleQuantumToAny(GetPixelAlpha(image,p),
2389 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2391 p+=GetPixelChannels(image);
2395 for (x=0; x < (ssize_t) image->columns; x++)
2397 pixel=ScaleQuantumToAny(GetPixelRed(image,p),max_value);
2398 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2399 pixel=ScaleQuantumToAny(GetPixelGreen(image,p),max_value);
2400 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2401 pixel=ScaleQuantumToAny(GetPixelBlue(image,p),max_value);
2402 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2403 if (image->alpha_trait != UndefinedPixelTrait)
2405 pixel=ScaleQuantumToAny(GetPixelAlpha(image,p),
2407 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
2409 p+=GetPixelChannels(image);
2414 extent=(size_t) (q-pixels);
2418 count=WriteBlob(image,extent,pixels);
2419 if (count != (ssize_t) extent)
2421 if (image->previous == (Image *) NULL)
2423 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
2425 if (status == MagickFalse)
2429 quantum_info=DestroyQuantumInfo(quantum_info);
2435 register unsigned char
2438 (void) WriteBlobString(image,image->endian == LSBEndian ? "-1.0\n" :
2441 quantum_type=format == 'f' ? GrayQuantum : RGBQuantum;
2442 quantum_info=AcquireQuantumInfo(image_info,image);
2443 if (quantum_info == (QuantumInfo *) NULL)
2444 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
2445 status=SetQuantumFormat(image,quantum_info,FloatingPointQuantumFormat);
2446 if (status == MagickFalse)
2447 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
2448 pixels=GetQuantumPixels(quantum_info);
2449 for (y=(ssize_t) image->rows-1; y >= 0; y--)
2451 register const Quantum
2454 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
2455 if (p == (const Quantum *) NULL)
2457 extent=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2458 quantum_type,pixels,exception);
2459 (void) WriteBlob(image,extent,pixels);
2460 if (image->previous == (Image *) NULL)
2462 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
2464 if (status == MagickFalse)
2468 quantum_info=DestroyQuantumInfo(quantum_info);
2472 if (GetNextImageInList(image) == (Image *) NULL)
2474 image=SyncNextImageInList(image);
2475 status=SetImageProgress(image,SaveImagesTag,scene++,imageListLength);
2476 if (status == MagickFalse)
2478 } while (image_info->adjoin != MagickFalse);
2479 (void) CloseBlob(image);