2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13 % Read/Write PBMPlus Portable Anymap Image Format %
20 % Copyright 1999-2013 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 void PNMComment(Image *image,ExceptionInfo *exception)
168 comment=AcquireString(GetImageProperty(image,"comment",exception));
169 extent=strlen(comment);
170 p=comment+strlen(comment);
171 for (c='#'; (c != EOF) && (c != (int) '\n'); p++)
173 if ((size_t) (p-comment+1) >= extent)
176 comment=(char *) ResizeQuantumMemory(comment,extent+MaxTextExtent,
178 if (comment == (char *) NULL)
180 p=comment+strlen(comment);
182 c=ReadBlobByte(image);
189 if (comment == (char *) NULL)
191 (void) SetImageProperty(image,"comment",comment,exception);
192 comment=DestroyString(comment);
195 static size_t PNMInteger(Image *image,const unsigned int base,
196 ExceptionInfo *exception)
205 Skip any leading whitespace.
209 c=ReadBlobByte(image);
213 PNMComment(image,exception);
214 } while (isdigit(c) == MagickFalse);
216 return((size_t) (c-(int) '0'));
225 c=ReadBlobByte(image);
228 } while (isdigit(c) != MagickFalse);
232 static Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception)
272 assert(image_info != (const ImageInfo *) NULL);
273 assert(image_info->signature == MagickSignature);
274 if (image_info->debug != MagickFalse)
275 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
276 image_info->filename);
277 assert(exception != (ExceptionInfo *) NULL);
278 assert(exception->signature == MagickSignature);
279 image=AcquireImage(image_info,exception);
280 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
281 if (status == MagickFalse)
283 image=DestroyImageList(image);
284 return((Image *) NULL);
289 count=ReadBlob(image,1,(unsigned char *) &format);
293 Initialize image structure.
295 if ((count != 1) || (format != 'P'))
296 ThrowReaderException(CorruptImageError,"ImproperImageHeader");
298 quantum_type=RGBQuantum;
300 format=(char) ReadBlobByte(image);
304 PBM, PGM, PPM, and PNM.
306 image->columns=PNMInteger(image,10,exception);
307 image->rows=PNMInteger(image,10,exception);
308 if ((format == 'f') || (format == 'F'))
311 scale[MaxTextExtent];
313 (void) ReadBlobString(image,scale);
314 quantum_scale=StringToDouble(scale,(char **) NULL);
318 if ((format == '1') || (format == '4'))
319 max_value=1; /* bitmap */
321 max_value=PNMInteger(image,10,exception);
327 keyword[MaxTextExtent],
328 value[MaxTextExtent];
339 for (c=ReadBlobByte(image); c != EOF; c=ReadBlobByte(image))
341 while (isspace((int) ((unsigned char) c)) != 0)
342 c=ReadBlobByte(image);
348 PNMComment(image,exception);
349 c=ReadBlobByte(image);
350 while (isspace((int) ((unsigned char) c)) != 0)
351 c=ReadBlobByte(image);
356 if ((size_t) (p-keyword) < (MaxTextExtent-1))
358 c=ReadBlobByte(image);
359 } while (isalnum(c));
361 if (LocaleCompare(keyword,"endhdr") == 0)
363 while (isspace((int) ((unsigned char) c)) != 0)
364 c=ReadBlobByte(image);
366 while (isalnum(c) || (c == '_'))
368 if ((size_t) (p-value) < (MaxTextExtent-1))
370 c=ReadBlobByte(image);
374 Assign a value to the specified keyword.
376 if (LocaleCompare(keyword,"depth") == 0)
377 packet_size=StringToUnsignedLong(value);
379 if (LocaleCompare(keyword,"height") == 0)
380 image->rows=StringToUnsignedLong(value);
381 if (LocaleCompare(keyword,"maxval") == 0)
382 max_value=StringToUnsignedLong(value);
383 if (LocaleCompare(keyword,"TUPLTYPE") == 0)
385 if (LocaleCompare(value,"BLACKANDWHITE") == 0)
387 (void) SetImageColorspace(image,GRAYColorspace,exception);
388 quantum_type=GrayQuantum;
390 if (LocaleCompare(value,"BLACKANDWHITE_ALPHA") == 0)
392 (void) SetImageColorspace(image,GRAYColorspace,exception);
393 image->alpha_trait=BlendPixelTrait;
394 quantum_type=GrayAlphaQuantum;
396 if (LocaleCompare(value,"GRAYSCALE") == 0)
398 quantum_type=GrayQuantum;
399 (void) SetImageColorspace(image,GRAYColorspace,exception);
401 if (LocaleCompare(value,"GRAYSCALE_ALPHA") == 0)
403 (void) SetImageColorspace(image,GRAYColorspace,exception);
404 image->alpha_trait=BlendPixelTrait;
405 quantum_type=GrayAlphaQuantum;
407 if (LocaleCompare(value,"RGB_ALPHA") == 0)
409 image->alpha_trait=BlendPixelTrait;
410 quantum_type=RGBAQuantum;
412 if (LocaleCompare(value,"CMYK") == 0)
414 (void) SetImageColorspace(image,CMYKColorspace,exception);
415 quantum_type=CMYKQuantum;
417 if (LocaleCompare(value,"CMYK_ALPHA") == 0)
419 (void) SetImageColorspace(image,CMYKColorspace,exception);
420 image->alpha_trait=BlendPixelTrait;
421 quantum_type=CMYKAQuantum;
424 if (LocaleCompare(keyword,"width") == 0)
425 image->columns=StringToUnsignedLong(value);
428 if ((image->columns == 0) || (image->rows == 0))
429 ThrowReaderException(CorruptImageError,"NegativeOrZeroImageSize");
430 if (max_value >= 65536)
431 ThrowReaderException(CorruptImageError,"ImproperImageHeader");
432 for (depth=1; GetQuantumRange(depth) < max_value; depth++) ;
434 if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
435 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
438 Convert PNM pixels to runextent-encoded MIFF packets.
447 Convert PBM image to pixel packets.
449 (void) SetImageColorspace(image,GRAYColorspace,exception);
450 for (y=0; y < (ssize_t) image->rows; y++)
458 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
459 if (q == (Quantum *) NULL)
461 for (x=0; x < (ssize_t) image->columns; x++)
463 SetPixelGray(image,PNMInteger(image,2,exception) == 0 ?
465 q+=GetPixelChannels(image);
467 if (SyncAuthenticPixels(image,exception) == MagickFalse)
469 if (image->previous == (Image *) NULL)
471 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
473 if (status == MagickFalse)
477 image->type=BilevelType;
486 Convert PGM image to pixel packets.
488 (void) SetImageColorspace(image,GRAYColorspace,exception);
489 scale=(Quantum *) NULL;
490 if (max_value != (1U*QuantumRange))
493 Compute pixel scaling table.
495 scale=(Quantum *) AcquireQuantumMemory((size_t) max_value+1UL,
497 if (scale == (Quantum *) NULL)
498 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
499 for (i=0; i <= (ssize_t) max_value; i++)
500 scale[i]=(Quantum) (((double) QuantumRange*i)/max_value+0.5);
502 for (y=0; y < (ssize_t) image->rows; y++)
510 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
511 if (q == (Quantum *) NULL)
513 for (x=0; x < (ssize_t) image->columns; x++)
515 intensity=PNMInteger(image,10,exception);
516 SetPixelGray(image,intensity,q);
517 if (scale != (Quantum *) NULL)
518 SetPixelGray(image,scale[ConstrainPixel(image,(ssize_t) intensity,
519 max_value,exception)],q);
520 q+=GetPixelChannels(image);
522 if (SyncAuthenticPixels(image,exception) == MagickFalse)
524 if (image->previous == (Image *) NULL)
526 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
528 if (status == MagickFalse)
532 image->type=GrayscaleType;
533 if (scale != (Quantum *) NULL)
534 scale=(Quantum *) RelinquishMagickMemory(scale);
543 Convert PNM image to pixel packets.
545 scale=(Quantum *) NULL;
546 if (max_value != (1U*QuantumRange))
549 Compute pixel scaling table.
551 scale=(Quantum *) AcquireQuantumMemory((size_t) max_value+1UL,
553 if (scale == (Quantum *) NULL)
554 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
555 for (i=0; i <= (ssize_t) max_value; i++)
556 scale[i]=(Quantum) (((double) QuantumRange*i)/max_value+0.5);
558 for (y=0; y < (ssize_t) image->rows; y++)
566 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
567 if (q == (Quantum *) NULL)
569 for (x=0; x < (ssize_t) image->columns; x++)
571 pixel.red=(double) PNMInteger(image,10,exception);
572 pixel.green=(double) PNMInteger(image,10,exception);
573 pixel.blue=(double) PNMInteger(image,10,exception);
574 if (scale != (Quantum *) NULL)
576 pixel.red=(double) scale[ConstrainPixel(image,(ssize_t)
577 pixel.red,max_value,exception)];
578 pixel.green=(double) scale[ConstrainPixel(image,
579 (ssize_t) pixel.green,max_value,exception)];
580 pixel.blue=(double) scale[ConstrainPixel(image,(ssize_t)
581 pixel.blue,max_value,exception)];
583 SetPixelRed(image,ClampToQuantum(pixel.red),q);
584 SetPixelGreen(image,ClampToQuantum(pixel.green),q);
585 SetPixelBlue(image,ClampToQuantum(pixel.blue),q);
586 q+=GetPixelChannels(image);
588 if (SyncAuthenticPixels(image,exception) == MagickFalse)
590 if (image->previous == (Image *) NULL)
592 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
594 if (status == MagickFalse)
598 if (scale != (Quantum *) NULL)
599 scale=(Quantum *) RelinquishMagickMemory(scale);
605 Convert PBM raw image to pixel packets.
607 (void) SetImageColorspace(image,GRAYColorspace,exception);
608 quantum_type=GrayQuantum;
609 if (image->storage_class == PseudoClass)
610 quantum_type=IndexQuantum;
611 quantum_info=AcquireQuantumInfo(image_info,image);
612 if (quantum_info == (QuantumInfo *) NULL)
613 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
614 SetQuantumMinIsWhite(quantum_info,MagickTrue);
615 extent=GetQuantumExtent(image,quantum_info,quantum_type);
616 for (y=0; y < (ssize_t) image->rows; y++)
634 if (status == MagickFalse)
636 pixels=GetQuantumPixels(quantum_info);
638 count=ReadBlob(image,extent,pixels);
639 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
640 (image->previous == (Image *) NULL))
645 proceed=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
647 if (proceed == MagickFalse)
652 if (count != (ssize_t) extent)
654 q=QueueAuthenticPixels(image,0,offset,image->columns,1,exception);
655 if (q == (Quantum *) NULL)
660 length=ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
661 quantum_type,pixels,exception);
662 if (length != extent)
664 sync=SyncAuthenticPixels(image,exception);
665 if (sync == MagickFalse)
668 quantum_info=DestroyQuantumInfo(quantum_info);
669 if (status == MagickFalse)
670 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
671 SetQuantumImageType(image,quantum_type);
680 Convert PGM raw image to pixel packets.
682 (void) SetImageColorspace(image,GRAYColorspace,exception);
683 range=GetQuantumRange(image->depth);
684 quantum_type=GrayQuantum;
685 extent=(image->depth <= 8 ? 1 : 2)*image->columns;
686 quantum_info=AcquireQuantumInfo(image_info,image);
687 if (quantum_info == (QuantumInfo *) NULL)
688 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
689 for (y=0; y < (ssize_t) image->rows; y++)
694 register const unsigned char
710 if (status == MagickFalse)
712 pixels=GetQuantumPixels(quantum_info);
714 count=ReadBlob(image,extent,pixels);
715 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
716 (image->previous == (Image *) NULL))
721 proceed=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
723 if (proceed == MagickFalse)
728 if (count != (ssize_t) extent)
730 q=QueueAuthenticPixels(image,0,offset,image->columns,1,exception);
731 if (q == (Quantum *) NULL)
737 if ((image->depth == 8) || (image->depth == 16))
738 (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
739 quantum_type,pixels,exception);
741 if (image->depth <= 8)
746 for (x=0; x < (ssize_t) image->columns; x++)
748 p=PushCharPixel(p,&pixel);
749 SetPixelGray(image,ScaleAnyToQuantum(pixel,range),q);
750 q+=GetPixelChannels(image);
758 for (x=0; x < (ssize_t) image->columns; x++)
760 p=PushShortPixel(MSBEndian,p,&pixel);
761 SetPixelGray(image,ScaleAnyToQuantum(pixel,range),q);
762 q+=GetPixelChannels(image);
765 sync=SyncAuthenticPixels(image,exception);
766 if (sync == MagickFalse)
769 quantum_info=DestroyQuantumInfo(quantum_info);
770 if (status == MagickFalse)
771 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
772 SetQuantumImageType(image,quantum_type);
781 Convert PNM raster image to pixel packets.
783 quantum_type=RGBQuantum;
784 extent=3*(image->depth <= 8 ? 1 : 2)*image->columns;
785 range=GetQuantumRange(image->depth);
786 quantum_info=AcquireQuantumInfo(image_info,image);
787 if (quantum_info == (QuantumInfo *) NULL)
788 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
789 (void) SetQuantumEndian(image,quantum_info,MSBEndian);
790 for (y=0; y < (ssize_t) image->rows; y++)
795 register const unsigned char
811 if (status == MagickFalse)
813 pixels=GetQuantumPixels(quantum_info);
815 count=ReadBlob(image,extent,pixels);
816 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
817 (image->previous == (Image *) NULL))
822 proceed=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
824 if (proceed == MagickFalse)
829 if (count != (ssize_t) extent)
831 q=QueueAuthenticPixels(image,0,offset,image->columns,1,exception);
832 if (q == (Quantum *) NULL)
838 if (image->depth == 8)
839 for (x=0; x < (ssize_t) image->columns; x++)
841 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
842 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
843 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
844 SetPixelAlpha(image,OpaqueAlpha,q);
845 q+=GetPixelChannels(image);
848 if (image->depth == 16)
853 for (x=0; x < (ssize_t) image->columns; x++)
855 p=PushShortPixel(MSBEndian,p,&pixel);
856 SetPixelRed(image,ScaleShortToQuantum(pixel),q);
857 p=PushShortPixel(MSBEndian,p,&pixel);
858 SetPixelGreen(image,ScaleShortToQuantum(pixel),q);
859 p=PushShortPixel(MSBEndian,p,&pixel);
860 SetPixelBlue(image,ScaleShortToQuantum(pixel),q);
861 SetPixelAlpha(image,OpaqueAlpha,q);
862 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,range),q);
875 p=PushCharPixel(p,&pixel);
876 SetPixelGreen(image,ScaleAnyToQuantum(pixel,range),q);
877 p=PushCharPixel(p,&pixel);
878 SetPixelBlue(image,ScaleAnyToQuantum(pixel,range),q);
879 SetPixelAlpha(image,OpaqueAlpha,q);
880 q+=GetPixelChannels(image);
888 for (x=0; x < (ssize_t) image->columns; x++)
890 p=PushShortPixel(MSBEndian,p,&pixel);
891 SetPixelRed(image,ScaleAnyToQuantum(pixel,range),q);
892 p=PushShortPixel(MSBEndian,p,&pixel);
893 SetPixelGreen(image,ScaleAnyToQuantum(pixel,range),q);
894 p=PushShortPixel(MSBEndian,p,&pixel);
895 SetPixelBlue(image,ScaleAnyToQuantum(pixel,range),q);
896 SetPixelAlpha(image,OpaqueAlpha,q);
897 q+=GetPixelChannels(image);
900 sync=SyncAuthenticPixels(image,exception);
901 if (sync == MagickFalse)
904 quantum_info=DestroyQuantumInfo(quantum_info);
905 if (status == MagickFalse)
906 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
918 Convert PAM raster image to pixel packets.
920 range=GetQuantumRange(image->depth);
921 switch (quantum_type)
924 case GrayAlphaQuantum:
941 if (image->alpha_trait == BlendPixelTrait)
943 extent=channels*(image->depth <= 8 ? 1 : 2)*image->columns;
944 quantum_info=AcquireQuantumInfo(image_info,image);
945 if (quantum_info == (QuantumInfo *) NULL)
946 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
947 for (y=0; y < (ssize_t) image->rows; y++)
952 register const unsigned char
968 if (status == MagickFalse)
970 pixels=GetQuantumPixels(quantum_info);
972 count=ReadBlob(image,extent,pixels);
973 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
974 (image->previous == (Image *) NULL))
979 proceed=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
981 if (proceed == MagickFalse)
986 if (count != (ssize_t) extent)
988 q=QueueAuthenticPixels(image,0,offset,image->columns,1,exception);
989 if (q == (Quantum *) NULL)
995 if ((image->depth == 8) || (image->depth == 16))
996 (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
997 quantum_type,pixels,exception);
999 switch (quantum_type)
1002 case GrayAlphaQuantum:
1004 if (image->depth <= 8)
1009 for (x=0; x < (ssize_t) image->columns; x++)
1011 p=PushCharPixel(p,&pixel);
1012 SetPixelGray(image,ScaleAnyToQuantum(pixel,range),q);
1013 SetPixelAlpha(image,OpaqueAlpha,q);
1014 if (image->alpha_trait == BlendPixelTrait)
1016 p=PushCharPixel(p,&pixel);
1017 SetPixelAlpha(image,ScaleAnyToQuantum(pixel,range),q);
1019 q+=GetPixelChannels(image);
1027 for (x=0; x < (ssize_t) image->columns; x++)
1029 p=PushShortPixel(MSBEndian,p,&pixel);
1030 SetPixelGray(image,ScaleAnyToQuantum(pixel,range),q);
1031 SetPixelAlpha(image,OpaqueAlpha,q);
1032 if (image->alpha_trait == BlendPixelTrait)
1034 p=PushShortPixel(MSBEndian,p,&pixel);
1035 SetPixelAlpha(image,ScaleAnyToQuantum(pixel,range),q);
1037 q+=GetPixelChannels(image);
1045 if (image->depth <= 8)
1050 for (x=0; x < (ssize_t) image->columns; x++)
1052 p=PushCharPixel(p,&pixel);
1053 SetPixelRed(image,ScaleAnyToQuantum(pixel,range),q);
1054 p=PushCharPixel(p,&pixel);
1055 SetPixelGreen(image,ScaleAnyToQuantum(pixel,range),q);
1056 p=PushCharPixel(p,&pixel);
1057 SetPixelBlue(image,ScaleAnyToQuantum(pixel,range),q);
1058 p=PushCharPixel(p,&pixel);
1059 SetPixelBlack(image,ScaleAnyToQuantum(pixel,range),q);
1060 SetPixelAlpha(image,OpaqueAlpha,q);
1061 if (image->alpha_trait == BlendPixelTrait)
1063 p=PushCharPixel(p,&pixel);
1064 SetPixelAlpha(image,ScaleAnyToQuantum(pixel,range),q);
1066 q+=GetPixelChannels(image);
1074 for (x=0; x < (ssize_t) image->columns; x++)
1076 p=PushShortPixel(MSBEndian,p,&pixel);
1077 SetPixelRed(image,ScaleAnyToQuantum(pixel,range),q);
1078 p=PushShortPixel(MSBEndian,p,&pixel);
1079 SetPixelGreen(image,ScaleAnyToQuantum(pixel,range),q);
1080 p=PushShortPixel(MSBEndian,p,&pixel);
1081 SetPixelBlue(image,ScaleAnyToQuantum(pixel,range),q);
1082 p=PushShortPixel(MSBEndian,p,&pixel);
1083 SetPixelBlack(image,ScaleAnyToQuantum(pixel,range),q);
1084 SetPixelAlpha(image,OpaqueAlpha,q);
1085 if (image->alpha_trait == BlendPixelTrait)
1087 p=PushShortPixel(MSBEndian,p,&pixel);
1088 SetPixelAlpha(image,ScaleAnyToQuantum(pixel,range),q);
1090 q+=GetPixelChannels(image);
1097 if (image->depth <= 8)
1102 for (x=0; x < (ssize_t) image->columns; x++)
1104 p=PushCharPixel(p,&pixel);
1105 SetPixelRed(image,ScaleAnyToQuantum(pixel,range),q);
1106 p=PushCharPixel(p,&pixel);
1107 SetPixelGreen(image,ScaleAnyToQuantum(pixel,range),q);
1108 p=PushCharPixel(p,&pixel);
1109 SetPixelBlue(image,ScaleAnyToQuantum(pixel,range),q);
1110 SetPixelAlpha(image,OpaqueAlpha,q);
1111 if (image->alpha_trait == BlendPixelTrait)
1113 p=PushCharPixel(p,&pixel);
1114 SetPixelAlpha(image,ScaleAnyToQuantum(pixel,range),q);
1116 q+=GetPixelChannels(image);
1124 for (x=0; x < (ssize_t) image->columns; x++)
1126 p=PushShortPixel(MSBEndian,p,&pixel);
1127 SetPixelRed(image,ScaleAnyToQuantum(pixel,range),q);
1128 p=PushShortPixel(MSBEndian,p,&pixel);
1129 SetPixelGreen(image,ScaleAnyToQuantum(pixel,range),q);
1130 p=PushShortPixel(MSBEndian,p,&pixel);
1131 SetPixelBlue(image,ScaleAnyToQuantum(pixel,range),q);
1132 SetPixelAlpha(image,OpaqueAlpha,q);
1133 if (image->alpha_trait == BlendPixelTrait)
1135 p=PushShortPixel(MSBEndian,p,&pixel);
1136 SetPixelAlpha(image,ScaleAnyToQuantum(pixel,range),q);
1138 q+=GetPixelChannels(image);
1144 sync=SyncAuthenticPixels(image,exception);
1145 if (sync == MagickFalse)
1148 quantum_info=DestroyQuantumInfo(quantum_info);
1149 if (status == MagickFalse)
1150 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
1151 SetQuantumImageType(image,quantum_type);
1158 Convert PFM raster image to pixel packets.
1161 (void) SetImageColorspace(image,GRAYColorspace,exception);
1162 quantum_type=format == 'f' ? GrayQuantum : RGBQuantum;
1163 image->endian=quantum_scale < 0.0 ? LSBEndian : MSBEndian;
1165 quantum_info=AcquireQuantumInfo(image_info,image);
1166 if (quantum_info == (QuantumInfo *) NULL)
1167 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
1168 status=SetQuantumDepth(image,quantum_info,32);
1169 if (status == MagickFalse)
1170 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
1171 status=SetQuantumFormat(image,quantum_info,FloatingPointQuantumFormat);
1172 if (status == MagickFalse)
1173 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
1174 SetQuantumScale(quantum_info,(double) QuantumRange*fabs(quantum_scale));
1175 extent=GetQuantumExtent(image,quantum_info,quantum_type);
1176 for (y=0; y < (ssize_t) image->rows; y++)
1194 if (status == MagickFalse)
1196 pixels=GetQuantumPixels(quantum_info);
1198 count=ReadBlob(image,extent,pixels);
1199 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
1200 (image->previous == (Image *) NULL))
1205 proceed=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
1207 if (proceed == MagickFalse)
1212 if ((size_t) count != extent)
1214 q=QueueAuthenticPixels(image,0,(ssize_t) (image->rows-offset-1),
1215 image->columns,1,exception);
1216 if (q == (Quantum *) NULL)
1221 length=ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1222 quantum_type,pixels,exception);
1223 if (length != extent)
1225 sync=SyncAuthenticPixels(image,exception);
1226 if (sync == MagickFalse)
1229 quantum_info=DestroyQuantumInfo(quantum_info);
1230 if (status == MagickFalse)
1231 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
1232 SetQuantumImageType(image,quantum_type);
1236 ThrowReaderException(CorruptImageError,"ImproperImageHeader");
1238 if (EOFBlob(image) != MagickFalse)
1240 (void) ThrowMagickException(exception,GetMagickModule(),
1241 CorruptImageError,"UnexpectedEndOfFile","`%s'",image->filename);
1245 Proceed to next image.
1247 if (image_info->number_scenes != 0)
1248 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
1250 if ((format == '1') || (format == '2') || (format == '3'))
1254 Skip to end of line.
1256 count=ReadBlob(image,1,(unsigned char *) &format);
1259 if ((count != 0) && (format == 'P'))
1261 } while (format != '\n');
1262 count=ReadBlob(image,1,(unsigned char *) &format);
1263 if ((count == 1) && (format == 'P'))
1266 Allocate next image structure.
1268 AcquireNextImage(image_info,image,exception);
1269 if (GetNextImageInList(image) == (Image *) NULL)
1271 image=DestroyImageList(image);
1272 return((Image *) NULL);
1274 image=SyncNextImageInList(image);
1275 status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
1276 GetBlobSize(image));
1277 if (status == MagickFalse)
1280 } while ((count == 1) && (format == 'P'));
1281 (void) CloseBlob(image);
1282 return(GetFirstImageInList(image));
1286 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1290 % R e g i s t e r P N M I m a g e %
1294 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1296 % RegisterPNMImage() adds properties for the PNM image format to
1297 % the list of supported formats. The properties include the image format
1298 % tag, a method to read and/or write the format, whether the format
1299 % supports the saving of more than one frame to the same file or blob,
1300 % whether the format supports native in-memory I/O, and a brief
1301 % description of the format.
1303 % The format of the RegisterPNMImage method is:
1305 % size_t RegisterPNMImage(void)
1308 ModuleExport size_t RegisterPNMImage(void)
1313 entry=SetMagickInfo("PAM");
1314 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1315 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1316 entry->description=ConstantString("Common 2-dimensional bitmap format");
1317 entry->mime_type=ConstantString("image/x-portable-pixmap");
1318 entry->module=ConstantString("PNM");
1319 (void) RegisterMagickInfo(entry);
1320 entry=SetMagickInfo("PBM");
1321 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1322 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1323 entry->description=ConstantString("Portable bitmap format (black and white)");
1324 entry->mime_type=ConstantString("image/x-portable-bitmap");
1325 entry->module=ConstantString("PNM");
1326 (void) RegisterMagickInfo(entry);
1327 entry=SetMagickInfo("PFM");
1328 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1329 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1330 entry->endian_support=MagickTrue;
1331 entry->description=ConstantString("Portable float format");
1332 entry->module=ConstantString("PFM");
1333 (void) RegisterMagickInfo(entry);
1334 entry=SetMagickInfo("PGM");
1335 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1336 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1337 entry->description=ConstantString("Portable graymap format (gray scale)");
1338 entry->mime_type=ConstantString("image/x-portable-greymap");
1339 entry->module=ConstantString("PNM");
1340 (void) RegisterMagickInfo(entry);
1341 entry=SetMagickInfo("PNM");
1342 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1343 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1344 entry->magick=(IsImageFormatHandler *) IsPNM;
1345 entry->description=ConstantString("Portable anymap");
1346 entry->mime_type=ConstantString("image/x-portable-pixmap");
1347 entry->module=ConstantString("PNM");
1348 (void) RegisterMagickInfo(entry);
1349 entry=SetMagickInfo("PPM");
1350 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1351 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1352 entry->description=ConstantString("Portable pixmap format (color)");
1353 entry->mime_type=ConstantString("image/x-portable-pixmap");
1354 entry->module=ConstantString("PNM");
1355 (void) RegisterMagickInfo(entry);
1356 return(MagickImageCoderSignature);
1360 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1364 % U n r e g i s t e r P N M I m a g e %
1368 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1370 % UnregisterPNMImage() removes format registrations made by the
1371 % PNM module from the list of supported formats.
1373 % The format of the UnregisterPNMImage method is:
1375 % UnregisterPNMImage(void)
1378 ModuleExport void UnregisterPNMImage(void)
1380 (void) UnregisterMagickInfo("PAM");
1381 (void) UnregisterMagickInfo("PBM");
1382 (void) UnregisterMagickInfo("PGM");
1383 (void) UnregisterMagickInfo("PNM");
1384 (void) UnregisterMagickInfo("PPM");
1388 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1392 % W r i t e P N M I m a g e %
1396 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1398 % WritePNMImage() writes an image to a file in the PNM rasterfile format.
1400 % The format of the WritePNMImage method is:
1402 % MagickBooleanType WritePNMImage(const ImageInfo *image_info,
1403 % Image *image,ExceptionInfo *exception)
1405 % A description of each parameter follows.
1407 % o image_info: the image info.
1409 % o image: The image.
1411 % o exception: return any errors or warnings in this structure.
1414 static MagickBooleanType WritePNMImage(const ImageInfo *image_info,Image *image,
1415 ExceptionInfo *exception)
1418 buffer[MaxTextExtent],
1420 magick[MaxTextExtent];
1443 register unsigned char
1456 Open output image file.
1458 assert(image_info != (const ImageInfo *) NULL);
1459 assert(image_info->signature == MagickSignature);
1460 assert(image != (Image *) NULL);
1461 assert(image->signature == MagickSignature);
1462 if (image->debug != MagickFalse)
1463 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1464 assert(exception != (ExceptionInfo *) NULL);
1465 assert(exception->signature == MagickSignature);
1466 status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
1467 if (status == MagickFalse)
1473 Write PNM file header.
1476 quantum_type=RGBQuantum;
1477 (void) CopyMagickString(magick,image_info->magick,MaxTextExtent);
1490 if (image_info->compression == NoCompression)
1498 if (IsImageGray(image,exception) != MagickFalse)
1506 if (image_info->compression == NoCompression)
1513 if ((image_info->type != TrueColorType) &&
1514 (IsImageGray(image,exception) != MagickFalse))
1517 if (image_info->compression == NoCompression)
1519 if (IsImageMonochrome(image,exception) != MagickFalse)
1522 if (image_info->compression == NoCompression)
1531 if (image_info->compression == NoCompression)
1536 (void) FormatLocaleString(buffer,MaxTextExtent,"P%c\n",format);
1537 (void) WriteBlobString(image,buffer);
1538 value=GetImageProperty(image,"comment",exception);
1539 if (value != (const char *) NULL)
1545 Write comments to file.
1547 (void) WriteBlobByte(image,'#');
1548 for (p=value; *p != '\0'; p++)
1550 (void) WriteBlobByte(image,(unsigned char) *p);
1551 if ((*p == '\n') || (*p == '\r'))
1552 (void) WriteBlobByte(image,'#');
1554 (void) WriteBlobByte(image,'\n');
1558 (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g %.20g\n",
1559 (double) image->columns,(double) image->rows);
1560 (void) WriteBlobString(image,buffer);
1565 type[MaxTextExtent];
1570 (void) FormatLocaleString(buffer,MaxTextExtent,
1571 "WIDTH %.20g\nHEIGHT %.20g\n",(double) image->columns,(double)
1573 (void) WriteBlobString(image,buffer);
1574 quantum_type=GetQuantumType(image,exception);
1575 switch (quantum_type)
1581 (void) CopyMagickString(type,"CMYK",MaxTextExtent);
1585 case GrayAlphaQuantum:
1588 (void) CopyMagickString(type,"GRAYSCALE",MaxTextExtent);
1593 quantum_type=RGBQuantum;
1594 if (image->alpha_trait == BlendPixelTrait)
1595 quantum_type=RGBAQuantum;
1597 (void) CopyMagickString(type,"RGB",MaxTextExtent);
1601 if (image->alpha_trait == BlendPixelTrait)
1604 (void) ConcatenateMagickString(type,"_ALPHA",MaxTextExtent);
1606 if (image->depth > 16)
1608 (void) FormatLocaleString(buffer,MaxTextExtent,
1609 "DEPTH %.20g\nMAXVAL %.20g\n",(double) packet_size,(double)
1610 ((MagickOffsetType) GetQuantumRange(image->depth)));
1611 (void) WriteBlobString(image,buffer);
1612 (void) FormatLocaleString(buffer,MaxTextExtent,"TUPLTYPE %s\nENDHDR\n",
1614 (void) WriteBlobString(image,buffer);
1617 Convert runextent encoded to PNM raster pixels.
1627 Convert image to a PBM image.
1630 for (y=0; y < (ssize_t) image->rows; y++)
1632 register const Quantum
1638 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1639 if (p == (const Quantum *) NULL)
1641 for (x=0; x < (ssize_t) image->columns; x++)
1643 pixel=ClampToQuantum(GetPixelLuma(image,p));
1644 *q++=(unsigned char) (pixel >= (Quantum) (QuantumRange/2) ?
1647 if ((q-pixels+2) >= 80)
1650 (void) WriteBlob(image,q-pixels,pixels);
1653 p+=GetPixelChannels(image);
1655 if (image->previous == (Image *) NULL)
1657 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1659 if (status == MagickFalse)
1666 (void) WriteBlob(image,q-pixels,pixels);
1676 Convert image to a PGM image.
1678 if (image->depth <= 8)
1679 (void) WriteBlobString(image,"255\n");
1681 (void) WriteBlobString(image,"65535\n");
1683 for (y=0; y < (ssize_t) image->rows; y++)
1685 register const Quantum
1691 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1692 if (p == (const Quantum *) NULL)
1694 for (x=0; x < (ssize_t) image->columns; x++)
1696 index=ClampToQuantum(GetPixelLuma(image,p));
1697 if (image->depth <= 8)
1698 count=(ssize_t) FormatLocaleString(buffer,MaxTextExtent,"%u ",
1699 ScaleQuantumToChar(index));
1701 count=(ssize_t) FormatLocaleString(buffer,MaxTextExtent,"%u ",
1702 ScaleQuantumToShort(index));
1703 extent=(size_t) count;
1704 (void) strncpy((char *) q,buffer,extent);
1706 if ((q-pixels+extent) >= 80)
1709 (void) WriteBlob(image,q-pixels,pixels);
1712 p+=GetPixelChannels(image);
1714 if (image->previous == (Image *) NULL)
1716 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1718 if (status == MagickFalse)
1725 (void) WriteBlob(image,q-pixels,pixels);
1735 Convert image to a PNM image.
1737 if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
1738 (void) TransformImageColorspace(image,sRGBColorspace,exception);
1739 if (image->depth <= 8)
1740 (void) WriteBlobString(image,"255\n");
1742 (void) WriteBlobString(image,"65535\n");
1744 for (y=0; y < (ssize_t) image->rows; y++)
1746 register const Quantum
1752 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1753 if (p == (const Quantum *) NULL)
1755 for (x=0; x < (ssize_t) image->columns; x++)
1757 if (image->depth <= 8)
1758 count=(ssize_t) FormatLocaleString(buffer,MaxTextExtent,
1759 "%u %u %u ",ScaleQuantumToChar(GetPixelRed(image,p)),
1760 ScaleQuantumToChar(GetPixelGreen(image,p)),
1761 ScaleQuantumToChar(GetPixelBlue(image,p)));
1763 count=(ssize_t) FormatLocaleString(buffer,MaxTextExtent,
1764 "%u %u %u ",ScaleQuantumToShort(GetPixelRed(image,p)),
1765 ScaleQuantumToShort(GetPixelGreen(image,p)),
1766 ScaleQuantumToShort(GetPixelBlue(image,p)));
1767 extent=(size_t) count;
1768 (void) strncpy((char *) q,buffer,extent);
1770 if ((q-pixels+extent) >= 80)
1773 (void) WriteBlob(image,q-pixels,pixels);
1776 p+=GetPixelChannels(image);
1778 if (image->previous == (Image *) NULL)
1780 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1782 if (status == MagickFalse)
1789 (void) WriteBlob(image,q-pixels,pixels);
1796 Convert image to a PBM image.
1799 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
1800 if (quantum_info == (QuantumInfo *) NULL)
1801 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1802 quantum_info->min_is_white=MagickTrue;
1803 pixels=GetQuantumPixels(quantum_info);
1804 for (y=0; y < (ssize_t) image->rows; y++)
1806 register const Quantum
1809 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1810 if (p == (const Quantum *) NULL)
1812 extent=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1813 GrayQuantum,pixels,exception);
1814 count=WriteBlob(image,extent,pixels);
1815 if (count != (ssize_t) extent)
1817 if (image->previous == (Image *) NULL)
1819 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1821 if (status == MagickFalse)
1825 quantum_info=DestroyQuantumInfo(quantum_info);
1834 Convert image to a PGM image.
1836 if (image->depth > 8)
1838 (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g\n",(double)
1839 ((MagickOffsetType) GetQuantumRange(image->depth)));
1840 (void) WriteBlobString(image,buffer);
1841 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
1842 if (quantum_info == (QuantumInfo *) NULL)
1843 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1844 quantum_info->min_is_white=MagickTrue;
1845 pixels=GetQuantumPixels(quantum_info);
1846 extent=GetQuantumExtent(image,quantum_info,GrayQuantum);
1847 range=GetQuantumRange(image->depth);
1848 for (y=0; y < (ssize_t) image->rows; y++)
1850 register const Quantum
1856 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1857 if (p == (const Quantum *) NULL)
1860 if ((image->depth == 8) || (image->depth == 16))
1861 extent=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1862 GrayQuantum,pixels,exception);
1865 if (image->depth <= 8)
1866 for (x=0; x < (ssize_t) image->columns; x++)
1868 if (IsPixelGray(image,p) == MagickFalse)
1869 pixel=ScaleQuantumToAny(ClampToQuantum(GetPixelLuma(
1873 if (image->depth == 8)
1874 pixel=ScaleQuantumToChar(GetPixelRed(image,p));
1876 pixel=ScaleQuantumToAny(GetPixelRed(image,p),range);
1878 q=PopCharPixel((unsigned char) pixel,q);
1879 p+=GetPixelChannels(image);
1882 for (x=0; x < (ssize_t) image->columns; x++)
1884 if (IsPixelGray(image,p) == MagickFalse)
1885 pixel=ScaleQuantumToAny(ClampToQuantum(GetPixelLuma(
1889 if (image->depth == 16)
1890 pixel=ScaleQuantumToShort(GetPixelRed(image,p));
1892 pixel=ScaleQuantumToAny(GetPixelRed(image,p),range);
1894 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
1895 p+=GetPixelChannels(image);
1897 extent=(size_t) (q-pixels);
1899 count=WriteBlob(image,extent,pixels);
1900 if (count != (ssize_t) extent)
1902 if (image->previous == (Image *) NULL)
1904 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1906 if (status == MagickFalse)
1910 quantum_info=DestroyQuantumInfo(quantum_info);
1919 Convert image to a PNM image.
1921 if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
1922 (void) TransformImageColorspace(image,sRGBColorspace,exception);
1923 if (image->depth > 8)
1925 (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g\n",(double)
1926 ((MagickOffsetType) GetQuantumRange(image->depth)));
1927 (void) WriteBlobString(image,buffer);
1928 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
1929 if (quantum_info == (QuantumInfo *) NULL)
1930 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1931 (void) SetQuantumEndian(image,quantum_info,MSBEndian);
1932 pixels=GetQuantumPixels(quantum_info);
1933 extent=GetQuantumExtent(image,quantum_info,quantum_type);
1934 range=GetQuantumRange(image->depth);
1935 for (y=0; y < (ssize_t) image->rows; y++)
1937 register const Quantum
1943 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1944 if (p == (const Quantum *) NULL)
1947 if ((image->depth == 8) || (image->depth == 16))
1948 extent=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1949 quantum_type,pixels,exception);
1952 if (image->depth <= 8)
1953 for (x=0; x < (ssize_t) image->columns; x++)
1955 pixel=ScaleQuantumToAny(GetPixelRed(image,p),range);
1956 q=PopCharPixel((unsigned char) pixel,q);
1957 pixel=ScaleQuantumToAny(GetPixelGreen(image,p),range);
1958 q=PopCharPixel((unsigned char) pixel,q);
1959 pixel=ScaleQuantumToAny(GetPixelBlue(image,p),range);
1960 q=PopCharPixel((unsigned char) pixel,q);
1961 p+=GetPixelChannels(image);
1964 for (x=0; x < (ssize_t) image->columns; x++)
1966 pixel=ScaleQuantumToAny(GetPixelRed(image,p),range);
1967 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
1968 pixel=ScaleQuantumToAny(GetPixelGreen(image,p),range);
1969 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
1970 pixel=ScaleQuantumToAny(GetPixelBlue(image,p),range);
1971 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
1972 p+=GetPixelChannels(image);
1974 extent=(size_t) (q-pixels);
1976 count=WriteBlob(image,extent,pixels);
1977 if (count != (ssize_t) extent)
1979 if (image->previous == (Image *) NULL)
1981 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1983 if (status == MagickFalse)
1987 quantum_info=DestroyQuantumInfo(quantum_info);
1996 Convert image to a PAM.
1998 if (image->depth > 16)
2000 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
2001 pixels=GetQuantumPixels(quantum_info);
2002 range=GetQuantumRange(image->depth);
2003 for (y=0; y < (ssize_t) image->rows; y++)
2005 register const Quantum
2011 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
2012 if (p == (const Quantum *) NULL)
2015 if ((image->depth == 8) || (image->depth == 16))
2016 extent=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2017 quantum_type,pixels,exception);
2020 switch (quantum_type)
2023 case GrayAlphaQuantum:
2025 if (image->depth <= 8)
2026 for (x=0; x < (ssize_t) image->columns; x++)
2028 pixel=ScaleQuantumToAny(ClampToQuantum(GetPixelLuma(
2030 q=PopCharPixel((unsigned char) pixel,q);
2031 if (image->alpha_trait == BlendPixelTrait)
2033 pixel=(unsigned char) ScaleQuantumToAny(
2034 ClampToQuantum(GetPixelAlpha(image,p)),range);
2035 q=PopCharPixel((unsigned char) pixel,q);
2037 p+=GetPixelChannels(image);
2040 for (x=0; x < (ssize_t) image->columns; x++)
2042 pixel=ScaleQuantumToAny(ClampToQuantum(GetPixelLuma(
2044 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2045 if (image->alpha_trait == BlendPixelTrait)
2047 pixel=(unsigned char) ScaleQuantumToAny(
2048 GetPixelAlpha(image,p),range);
2049 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2051 p+=GetPixelChannels(image);
2058 if (image->depth <= 8)
2059 for (x=0; x < (ssize_t) image->columns; x++)
2061 pixel=ScaleQuantumToAny(GetPixelRed(image,p),range);
2062 q=PopCharPixel((unsigned char) pixel,q);
2063 pixel=ScaleQuantumToAny(GetPixelGreen(image,p),range);
2064 q=PopCharPixel((unsigned char) pixel,q);
2065 pixel=ScaleQuantumToAny(GetPixelBlue(image,p),range);
2066 q=PopCharPixel((unsigned char) pixel,q);
2067 pixel=ScaleQuantumToAny(GetPixelBlack(image,p),range);
2068 q=PopCharPixel((unsigned char) pixel,q);
2069 if (image->alpha_trait == BlendPixelTrait)
2071 pixel=ScaleQuantumToAny(GetPixelAlpha(image,p),range);
2072 q=PopCharPixel((unsigned char) pixel,q);
2074 p+=GetPixelChannels(image);
2077 for (x=0; x < (ssize_t) image->columns; x++)
2079 pixel=ScaleQuantumToAny(GetPixelRed(image,p),range);
2080 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2081 pixel=ScaleQuantumToAny(GetPixelGreen(image,p),range);
2082 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2083 pixel=ScaleQuantumToAny(GetPixelBlue(image,p),range);
2084 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2085 pixel=ScaleQuantumToAny(GetPixelBlack(image,p),range);
2086 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2087 if (image->alpha_trait == BlendPixelTrait)
2089 pixel=ScaleQuantumToAny(GetPixelAlpha(image,p),range);
2090 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2092 p+=GetPixelChannels(image);
2098 if (image->depth <= 8)
2099 for (x=0; x < (ssize_t) image->columns; x++)
2101 pixel=ScaleQuantumToAny(GetPixelRed(image,p),range);
2102 q=PopCharPixel((unsigned char) pixel,q);
2103 pixel=ScaleQuantumToAny(GetPixelGreen(image,p),range);
2104 q=PopCharPixel((unsigned char) pixel,q);
2105 pixel=ScaleQuantumToAny(GetPixelBlue(image,p),range);
2106 q=PopCharPixel((unsigned char) pixel,q);
2107 if (image->alpha_trait == BlendPixelTrait)
2109 pixel=ScaleQuantumToAny(GetPixelAlpha(image,p),range);
2110 q=PopCharPixel((unsigned char) pixel,q);
2112 p+=GetPixelChannels(image);
2115 for (x=0; x < (ssize_t) image->columns; x++)
2117 pixel=ScaleQuantumToAny(GetPixelRed(image,p),range);
2118 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2119 pixel=ScaleQuantumToAny(GetPixelGreen(image,p),range);
2120 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2121 pixel=ScaleQuantumToAny(GetPixelBlue(image,p),range);
2122 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2123 if (image->alpha_trait == BlendPixelTrait)
2125 pixel=ScaleQuantumToAny(GetPixelAlpha(image,p),range);
2126 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2128 p+=GetPixelChannels(image);
2133 extent=(size_t) (q-pixels);
2135 count=WriteBlob(image,extent,pixels);
2136 if (count != (ssize_t) extent)
2138 if (image->previous == (Image *) NULL)
2140 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
2142 if (status == MagickFalse)
2146 quantum_info=DestroyQuantumInfo(quantum_info);
2152 (void) WriteBlobString(image,image->endian == LSBEndian ? "-1.0\n" :
2155 quantum_type=format == 'f' ? GrayQuantum : RGBQuantum;
2156 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
2157 if (quantum_info == (QuantumInfo *) NULL)
2158 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
2159 status=SetQuantumFormat(image,quantum_info,FloatingPointQuantumFormat);
2160 if (status == MagickFalse)
2161 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
2162 pixels=GetQuantumPixels(quantum_info);
2163 for (y=(ssize_t) image->rows-1; y >= 0; y--)
2165 register const Quantum
2168 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
2169 if (p == (const Quantum *) NULL)
2171 extent=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2172 quantum_type,pixels,exception);
2173 (void) WriteBlob(image,extent,pixels);
2174 if (image->previous == (Image *) NULL)
2176 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
2178 if (status == MagickFalse)
2182 quantum_info=DestroyQuantumInfo(quantum_info);
2186 if (GetNextImageInList(image) == (Image *) NULL)
2188 image=SyncNextImageInList(image);
2189 status=SetImageProgress(image,SaveImagesTag,scene++,
2190 GetImageListLength(image));
2191 if (status == MagickFalse)
2193 } while (image_info->adjoin != MagickFalse);
2194 (void) CloseBlob(image);