2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13 % Read/Write PBMPlus Portable Anymap Image Format %
20 % Copyright 1999-2010 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 "magick/studio.h"
43 #include "magick/blob.h"
44 #include "magick/blob-private.h"
45 #include "magick/cache.h"
46 #include "magick/color.h"
47 #include "magick/color-private.h"
48 #include "magick/colorspace.h"
49 #include "magick/exception.h"
50 #include "magick/exception-private.h"
51 #include "magick/image.h"
52 #include "magick/image-private.h"
53 #include "magick/list.h"
54 #include "magick/magick.h"
55 #include "magick/memory_.h"
56 #include "magick/module.h"
57 #include "magick/monitor.h"
58 #include "magick/monitor-private.h"
59 #include "magick/pixel-private.h"
60 #include "magick/property.h"
61 #include "magick/quantum-private.h"
62 #include "magick/static.h"
63 #include "magick/statistic.h"
64 #include "magick/string_.h"
65 #include "magick/string-private.h"
70 static MagickBooleanType
71 WritePNMImage(const ImageInfo *,Image *);
74 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
82 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
84 % IsPNM() returns MagickTrue if the image format type, identified by the
85 % magick string, is PNM.
87 % The format of the IsPNM method is:
89 % MagickBooleanType IsPNM(const unsigned char *magick,const size_t extent)
91 % A description of each parameter follows:
93 % o magick: compare image format pattern against these bytes.
95 % o extent: Specifies the extent of the magick string.
98 static MagickBooleanType IsPNM(const unsigned char *magick,const size_t extent)
102 if ((*magick == (unsigned char) 'P') &&
103 ((magick[1] == '1') || (magick[1] == '2') || (magick[1] == '3') ||
104 (magick[1] == '4') || (magick[1] == '5') || (magick[1] == '6') ||
105 (magick[1] == '7') || (magick[1] == 'F') || (magick[1] == 'f')))
111 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
115 % R e a d P N M I m a g e %
119 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
121 % ReadPNMImage() reads a Portable Anymap image file and returns it.
122 % It allocates the memory necessary for the new Image structure and returns
123 % a pointer to the new image.
125 % The format of the ReadPNMImage method is:
127 % Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception)
129 % A description of each parameter follows:
131 % o image_info: the image info.
133 % o exception: return any errors or warnings in this structure.
137 static inline long ConstrainPixel(Image *image,const long offset,
138 const unsigned long extent)
140 if ((offset < 0) || (offset > (long) extent))
142 (void) ThrowMagickException(&image->exception,GetMagickModule(),
143 CorruptImageError,"InvalidPixel","`%s'",image->filename);
149 static unsigned long PNMInteger(Image *image,const unsigned int base)
167 Skip any leading whitespace.
169 extent=MaxTextExtent;
170 comment=(char *) NULL;
174 c=ReadBlobByte(image);
182 if (comment == (char *) NULL)
183 comment=AcquireString((char *) NULL);
184 p=comment+strlen(comment);
185 for ( ; (c != EOF) && (c != (int) '\n'); p++)
187 if ((size_t) (p-comment+1) >= extent)
190 comment=(char *) ResizeQuantumMemory(comment,extent+MaxTextExtent,
192 if (comment == (char *) NULL)
194 p=comment+strlen(comment);
196 c=ReadBlobByte(image);
200 if (comment == (char *) NULL)
204 } while (isdigit(c) == MagickFalse);
205 if (comment != (char *) NULL)
207 (void) SetImageProperty(image,"comment",comment);
208 comment=DestroyString(comment);
211 return((unsigned long) (c-(int) '0'));
220 c=ReadBlobByte(image);
223 } while (isdigit(c) != MagickFalse);
227 static Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception)
274 assert(image_info != (const ImageInfo *) NULL);
275 assert(image_info->signature == MagickSignature);
276 if (image_info->debug != MagickFalse)
277 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
278 image_info->filename);
279 assert(exception != (ExceptionInfo *) NULL);
280 assert(exception->signature == MagickSignature);
281 image=AcquireImage(image_info);
282 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
283 if (status == MagickFalse)
285 image=DestroyImageList(image);
286 return((Image *) NULL);
291 count=ReadBlob(image,1,(unsigned char *) &format);
295 Initialize image structure.
297 if ((count != 1) || (format != 'P'))
298 ThrowReaderException(CorruptImageError,"ImproperImageHeader");
300 quantum_type=RGBQuantum;
302 format=(char) ReadBlobByte(image);
306 PBM, PGM, PPM, and PNM.
308 image->columns=PNMInteger(image,10);
309 image->rows=PNMInteger(image,10);
310 if ((format == 'f') || (format == 'F'))
313 scale[MaxTextExtent];
315 (void) ReadBlobString(image,scale);
316 quantum_scale=StringToDouble(scale);
320 if ((format == '1') || (format == '4'))
321 max_value=1; /* bitmap */
323 max_value=PNMInteger(image,10);
329 keyword[MaxTextExtent],
330 value[MaxTextExtent];
341 for (c=ReadBlobByte(image); c != EOF; c=ReadBlobByte(image))
343 while (isspace((int) ((unsigned char) c)) != 0)
344 c=ReadBlobByte(image);
348 if ((size_t) (p-keyword) < (MaxTextExtent-1))
350 c=ReadBlobByte(image);
351 } while (isalnum(c));
353 if (LocaleCompare(keyword,"endhdr") == 0)
355 while (isspace((int) ((unsigned char) c)) != 0)
356 c=ReadBlobByte(image);
358 while (isalnum(c) || (c == '_'))
360 if ((size_t) (p-value) < (MaxTextExtent-1))
362 c=ReadBlobByte(image);
366 Assign a value to the specified keyword.
368 if (LocaleCompare(keyword,"depth") == 0)
369 packet_size=StringToUnsignedLong(value);
370 if (LocaleCompare(keyword,"height") == 0)
371 image->rows=StringToUnsignedLong(value);
372 if (LocaleCompare(keyword,"maxval") == 0)
373 max_value=StringToUnsignedLong(value);
374 if (LocaleCompare(keyword,"TUPLTYPE") == 0)
376 if (LocaleCompare(value,"BLACKANDWHITE") == 0)
377 quantum_type=GrayQuantum;
378 if (LocaleCompare(value,"BLACKANDWHITE_ALPHA") == 0)
380 quantum_type=GrayAlphaQuantum;
381 image->matte=MagickTrue;
383 if (LocaleCompare(value,"GRAYSCALE") == 0)
384 quantum_type=GrayQuantum;
385 if (LocaleCompare(value,"GRAYSCALE_ALPHA") == 0)
387 quantum_type=GrayAlphaQuantum;
388 image->matte=MagickTrue;
390 if (LocaleCompare(value,"RGB_ALPHA") == 0)
392 quantum_type=RGBAQuantum;
393 image->matte=MagickTrue;
395 if (LocaleCompare(value,"CMYK") == 0)
397 quantum_type=CMYKQuantum;
398 image->colorspace=CMYKColorspace;
400 if (LocaleCompare(value,"CMYK_ALPHA") == 0)
402 quantum_type=CMYKAQuantum;
403 image->colorspace=CMYKColorspace;
404 image->matte=MagickTrue;
407 if (LocaleCompare(keyword,"width") == 0)
408 image->columns=StringToUnsignedLong(value);
411 if ((image->columns == 0) || (image->rows == 0))
412 ThrowReaderException(CorruptImageError,"NegativeOrZeroImageSize");
413 if (max_value >= 65536)
414 ThrowReaderException(CorruptImageError,"ImproperImageHeader");
415 for (depth=1; GetQuantumRange(depth) < max_value; depth++) ;
417 if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
418 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
421 Convert PNM pixels to runextent-encoded MIFF packets.
430 Convert PBM image to pixel packets.
432 for (y=0; y < (long) image->rows; y++)
440 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
441 if (q == (PixelPacket *) NULL)
443 for (x=0; x < (long) image->columns; x++)
445 q->red=(Quantum) (PNMInteger(image,2) == 0 ? QuantumRange : 0);
450 if (SyncAuthenticPixels(image,exception) == MagickFalse)
452 if (image->previous == (Image *) NULL)
454 status=SetImageProgress(image,LoadImageTag,y,image->rows);
455 if (status == MagickFalse)
459 image->type=BilevelType;
468 Convert PGM image to pixel packets.
470 scale=(Quantum *) NULL;
471 if (max_value != (1U*QuantumRange))
474 Compute pixel scaling table.
476 scale=(Quantum *) AcquireQuantumMemory((size_t) max_value+1UL,
478 if (scale == (Quantum *) NULL)
479 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
480 for (i=0; i <= (long) max_value; i++)
481 scale[i]=(Quantum) (((double) QuantumRange*i)/max_value+0.5);
483 for (y=0; y < (long) image->rows; y++)
491 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
492 if (q == (PixelPacket *) NULL)
494 for (x=0; x < (long) image->columns; x++)
496 intensity=PNMInteger(image,10);
497 if (scale != (Quantum *) NULL)
498 intensity=(unsigned long) scale[ConstrainPixel(image,(long)
499 intensity,max_value)];
500 q->red=(Quantum) intensity;
505 if (SyncAuthenticPixels(image,exception) == MagickFalse)
507 if (image->previous == (Image *) NULL)
509 status=SetImageProgress(image,LoadImageTag,y,image->rows);
510 if (status == MagickFalse)
514 image->type=GrayscaleType;
515 if (scale != (Quantum *) NULL)
516 scale=(Quantum *) RelinquishMagickMemory(scale);
525 Convert PNM image to pixel packets.
527 scale=(Quantum *) NULL;
528 if (max_value != (1U*QuantumRange))
531 Compute pixel scaling table.
533 scale=(Quantum *) AcquireQuantumMemory((size_t) max_value+1UL,
535 if (scale == (Quantum *) NULL)
536 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
537 for (i=0; i <= (long) max_value; i++)
538 scale[i]=(Quantum) (((double) QuantumRange*i)/max_value+0.5);
540 for (y=0; y < (long) image->rows; y++)
548 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
549 if (q == (PixelPacket *) NULL)
551 for (x=0; x < (long) image->columns; x++)
553 pixel.red=(MagickRealType) PNMInteger(image,10);
554 pixel.green=(MagickRealType) PNMInteger(image,10);
555 pixel.blue=(MagickRealType) PNMInteger(image,10);
556 if (scale != (Quantum *) NULL)
558 pixel.red=(MagickRealType) scale[ConstrainPixel(image,(long)
559 pixel.red,max_value)];
560 pixel.green=(MagickRealType) scale[ConstrainPixel(image,(long)
561 pixel.green,max_value)];
562 pixel.blue=(MagickRealType) scale[ConstrainPixel(image,(long)
563 pixel.blue,max_value)];
565 q->red=(Quantum) pixel.red;
566 q->green=(Quantum) pixel.green;
567 q->blue=(Quantum) pixel.blue;
570 if (SyncAuthenticPixels(image,exception) == MagickFalse)
572 if (image->previous == (Image *) NULL)
574 status=SetImageProgress(image,LoadImageTag,y,image->rows);
575 if (status == MagickFalse)
579 if (scale != (Quantum *) NULL)
580 scale=(Quantum *) RelinquishMagickMemory(scale);
586 Convert PBM raw image to pixel packets.
588 quantum_type=GrayQuantum;
589 if (image->storage_class == PseudoClass)
590 quantum_type=IndexQuantum;
591 quantum_info=AcquireQuantumInfo(image_info,image);
592 if (quantum_info == (QuantumInfo *) NULL)
593 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
594 SetQuantumMinIsWhite(quantum_info,MagickTrue);
595 extent=GetQuantumExtent(image,quantum_info,quantum_type);
596 image_view=AcquireCacheView(image);
597 #if defined(MAGICKCORE_OPENMP_SUPPORT) && (_OPENMP > 202001)
598 #pragma omp parallel for schedule(static,1) shared(row,status,quantum_type)
600 for (y=0; y < (long) image->rows; y++)
620 if (status == MagickFalse)
622 pixels=GetQuantumPixels(quantum_info);
623 #if defined(MAGICKCORE_OPENMP_SUPPORT) && (_OPENMP > 202001)
624 #pragma omp critical (MagickCore_ReadPNMImage)
627 count=ReadBlob(image,extent,pixels);
628 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
629 (image->previous == (Image *) NULL))
634 proceed=SetImageProgress(image,LoadImageTag,row,image->rows);
635 if (proceed == MagickFalse)
640 if (count != (ssize_t) extent)
642 q=QueueCacheViewAuthenticPixels(image_view,0,offset,image->columns,1,
644 if (q == (PixelPacket *) NULL)
649 length=ImportQuantumPixels(image,image_view,quantum_info,quantum_type,
651 if (length != extent)
653 sync=SyncCacheViewAuthenticPixels(image_view,exception);
654 if (sync == MagickFalse)
657 image_view=DestroyCacheView(image_view);
658 quantum_info=DestroyQuantumInfo(quantum_info);
659 if (status == MagickFalse)
660 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
661 SetQuantumImageType(image,quantum_type);
670 Convert PGM raw image to pixel packets.
672 range=GetQuantumRange(image->depth);
673 quantum_type=GrayQuantum;
674 extent=(image->depth <= 8 ? 1 : 2)*image->columns;
675 quantum_info=AcquireQuantumInfo(image_info,image);
676 if (quantum_info == (QuantumInfo *) NULL)
677 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
678 image_view=AcquireCacheView(image);
679 #if defined(MAGICKCORE_OPENMP_SUPPORT) && (_OPENMP > 202001)
680 #pragma omp parallel for schedule(static,1) shared(row,status,quantum_type)
682 for (y=0; y < (long) image->rows; y++)
690 register const unsigned char
705 if (status == MagickFalse)
707 pixels=GetQuantumPixels(quantum_info);
708 #if defined(MAGICKCORE_OPENMP_SUPPORT) && (_OPENMP > 202001)
709 #pragma omp critical (MagickCore_ReadPNMImage)
712 count=ReadBlob(image,extent,pixels);
713 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
714 (image->previous == (Image *) NULL))
719 proceed=SetImageProgress(image,LoadImageTag,row,image->rows);
720 if (proceed == MagickFalse)
725 if (count != (ssize_t) extent)
727 q=QueueCacheViewAuthenticPixels(image_view,0,offset,image->columns,1,
729 if (q == (PixelPacket *) NULL)
735 if ((image->depth == 8) || (image->depth == 16))
736 (void) ImportQuantumPixels(image,image_view,quantum_info,
737 quantum_type,pixels,exception);
739 if (image->depth <= 8)
744 for (x=0; x < (long) image->columns; x++)
746 p=PushCharPixel(p,&pixel);
747 SetRedPixelComponent(q,ScaleAnyToQuantum(pixel,range));
758 for (x=0; x < (long) image->columns; x++)
760 p=PushShortPixel(MSBEndian,p,&pixel);
761 SetRedPixelComponent(q,ScaleAnyToQuantum(pixel,range));
767 sync=SyncCacheViewAuthenticPixels(image_view,exception);
768 if (sync == MagickFalse)
771 image_view=DestroyCacheView(image_view);
772 quantum_info=DestroyQuantumInfo(quantum_info);
773 if (status == MagickFalse)
774 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
775 SetQuantumImageType(image,quantum_type);
787 Convert PNM raster image to pixel packets.
790 quantum_type=RGBQuantum;
791 extent=3*(image->depth <= 8 ? 1 : 2)*image->columns;
792 range=GetQuantumRange(image->depth);
793 quantum_info=AcquireQuantumInfo(image_info,image);
794 if (quantum_info == (QuantumInfo *) NULL)
795 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
796 image_view=AcquireCacheView(image);
797 #if defined(MAGICKCORE_OPENMP_SUPPORT) && (_OPENMP > 202001)
798 #pragma omp parallel for schedule(static,1) shared(row,status,type)
800 for (y=0; y < (long) image->rows; y++)
808 register const unsigned char
823 if (status == MagickFalse)
825 pixels=GetQuantumPixels(quantum_info);
826 #if defined(MAGICKCORE_OPENMP_SUPPORT) && (_OPENMP > 202001)
827 #pragma omp critical (MagickCore_ReadPNMImage)
830 count=ReadBlob(image,extent,pixels);
831 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
832 (image->previous == (Image *) NULL))
837 proceed=SetImageProgress(image,LoadImageTag,row,image->rows);
838 if (proceed == MagickFalse)
843 if (count != (ssize_t) extent)
845 q=QueueCacheViewAuthenticPixels(image_view,0,offset,image->columns,1,
847 if (q == (PixelPacket *) NULL)
853 if (image->depth == 8)
854 for (x=0; x < (long) image->columns; x++)
856 q->red=ScaleCharToQuantum(*p++);
857 q->green=ScaleCharToQuantum(*p++);
858 q->blue=ScaleCharToQuantum(*p++);
859 q->opacity=OpaqueOpacity;
863 if (image->depth == 16)
868 for (x=0; x < (long) image->columns; x++)
870 p=PushShortPixel(MSBEndian,p,&pixel);
871 q->red=ScaleShortToQuantum(pixel);
872 p=PushShortPixel(MSBEndian,p,&pixel);
873 q->green=ScaleShortToQuantum(pixel);
874 p=PushShortPixel(MSBEndian,p,&pixel);
875 q->blue=ScaleShortToQuantum(pixel);
876 q->opacity=OpaqueOpacity;
881 if (image->depth <= 8)
886 for (x=0; x < (long) image->columns; x++)
888 p=PushCharPixel(p,&pixel);
889 q->red=ScaleAnyToQuantum(pixel,range);
890 p=PushCharPixel(p,&pixel);
891 q->green=ScaleAnyToQuantum(pixel,range);
892 p=PushCharPixel(p,&pixel);
893 q->blue=ScaleAnyToQuantum(pixel,range);
894 q->opacity=OpaqueOpacity;
903 for (x=0; x < (long) image->columns; x++)
905 p=PushShortPixel(MSBEndian,p,&pixel);
906 q->red=ScaleAnyToQuantum(pixel,range);
907 p=PushShortPixel(MSBEndian,p,&pixel);
908 q->green=ScaleAnyToQuantum(pixel,range);
909 p=PushShortPixel(MSBEndian,p,&pixel);
910 q->blue=ScaleAnyToQuantum(pixel,range);
911 q->opacity=OpaqueOpacity;
915 if ((type == BilevelType) || (type == GrayscaleType))
917 q=QueueCacheViewAuthenticPixels(image_view,0,offset,
918 image->columns,1,exception);
919 for (x=0; x < (long) image->columns; x++)
921 if ((type == BilevelType) &&
922 (IsMonochromePixel(q) == MagickFalse))
923 type=IsGrayPixel(q) == MagickFalse ? UndefinedType :
925 if ((type == GrayscaleType) && (IsGrayPixel(q) == MagickFalse))
927 if ((type != BilevelType) && (type != GrayscaleType))
932 sync=SyncCacheViewAuthenticPixels(image_view,exception);
933 if (sync == MagickFalse)
936 image_view=DestroyCacheView(image_view);
937 quantum_info=DestroyQuantumInfo(quantum_info);
938 if (status == MagickFalse)
939 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
940 if (type != UndefinedType)
956 Convert PAM raster image to pixel packets.
958 range=GetQuantumRange(image->depth);
959 switch (quantum_type)
962 case GrayAlphaQuantum:
979 if (image->matte != MagickFalse)
981 extent=channels*(image->depth <= 8 ? 1 : 2)*image->columns;
982 quantum_info=AcquireQuantumInfo(image_info,image);
983 if (quantum_info == (QuantumInfo *) NULL)
984 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
985 image_view=AcquireCacheView(image);
986 #if defined(MAGICKCORE_OPENMP_SUPPORT) && (_OPENMP > 202001)
987 #pragma omp parallel for schedule(static,1) shared(row,status,quantum_type)
989 for (y=0; y < (long) image->rows; y++)
997 register const unsigned char
1003 register PixelPacket
1012 if (status == MagickFalse)
1014 pixels=GetQuantumPixels(quantum_info);
1015 #if defined(MAGICKCORE_OPENMP_SUPPORT) && (_OPENMP > 202001)
1016 #pragma omp critical (MagickCore_ReadPNMImage)
1019 count=ReadBlob(image,extent,pixels);
1020 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
1021 (image->previous == (Image *) NULL))
1026 proceed=SetImageProgress(image,LoadImageTag,row,image->rows);
1027 if (proceed == MagickFalse)
1032 if (count != (ssize_t) extent)
1034 q=QueueCacheViewAuthenticPixels(image_view,0,offset,image->columns,1,
1036 if (q == (PixelPacket *) NULL)
1041 indexes=GetCacheViewAuthenticIndexQueue(image_view);
1043 if ((image->depth == 8) || (image->depth == 16))
1044 (void) ImportQuantumPixels(image,image_view,quantum_info,
1045 quantum_type,pixels,exception);
1047 switch (quantum_type)
1050 case GrayAlphaQuantum:
1052 if (image->depth <= 8)
1057 for (x=0; x < (long) image->columns; x++)
1059 p=PushCharPixel(p,&pixel);
1060 SetRedPixelComponent(q,ScaleAnyToQuantum(pixel,range));
1063 SetOpacityPixelComponent(q,OpaqueOpacity);
1064 if (image->matte != MagickFalse)
1066 p=PushCharPixel(p,&pixel);
1067 SetOpacityPixelComponent(q,ScaleAnyToQuantum(pixel,range));
1077 for (x=0; x < (long) image->columns; x++)
1079 p=PushShortPixel(MSBEndian,p,&pixel);
1080 SetRedPixelComponent(q,ScaleAnyToQuantum(pixel,range));
1083 SetOpacityPixelComponent(q,OpaqueOpacity);
1084 if (image->matte != MagickFalse)
1086 p=PushShortPixel(MSBEndian,p,&pixel);
1087 SetOpacityPixelComponent(q,ScaleAnyToQuantum(pixel,range));
1097 if (image->depth <= 8)
1102 for (x=0; x < (long) image->columns; x++)
1104 p=PushCharPixel(p,&pixel);
1105 SetRedPixelComponent(q,ScaleAnyToQuantum(pixel,range));
1106 p=PushCharPixel(p,&pixel);
1107 SetGreenPixelComponent(q,ScaleAnyToQuantum(pixel,range));
1108 p=PushCharPixel(p,&pixel);
1109 SetBluePixelComponent(q,ScaleAnyToQuantum(pixel,range));
1110 p=PushCharPixel(p,&pixel);
1111 indexes[x]=ScaleAnyToQuantum(pixel,range);
1112 SetOpacityPixelComponent(q,OpaqueOpacity);
1113 if (image->matte != MagickFalse)
1115 p=PushCharPixel(p,&pixel);
1116 SetOpacityPixelComponent(q,ScaleAnyToQuantum(pixel,range));
1126 for (x=0; x < (long) image->columns; x++)
1128 p=PushShortPixel(MSBEndian,p,&pixel);
1129 SetRedPixelComponent(q,ScaleAnyToQuantum(pixel,range));
1130 p=PushShortPixel(MSBEndian,p,&pixel);
1131 SetGreenPixelComponent(q,ScaleAnyToQuantum(pixel,range));
1132 p=PushShortPixel(MSBEndian,p,&pixel);
1133 SetBluePixelComponent(q,ScaleAnyToQuantum(pixel,range));
1134 p=PushShortPixel(MSBEndian,p,&pixel);
1135 indexes[x]=ScaleAnyToQuantum(pixel,range);
1136 SetOpacityPixelComponent(q,OpaqueOpacity);
1137 if (image->matte != MagickFalse)
1139 p=PushShortPixel(MSBEndian,p,&pixel);
1140 SetOpacityPixelComponent(q,ScaleAnyToQuantum(pixel,range));
1149 if (image->depth <= 8)
1154 for (x=0; x < (long) image->columns; x++)
1156 p=PushCharPixel(p,&pixel);
1157 SetRedPixelComponent(q,ScaleAnyToQuantum(pixel,range));
1158 p=PushCharPixel(p,&pixel);
1159 SetGreenPixelComponent(q,ScaleAnyToQuantum(pixel,range));
1160 p=PushCharPixel(p,&pixel);
1161 SetBluePixelComponent(q,ScaleAnyToQuantum(pixel,range));
1162 SetOpacityPixelComponent(q,OpaqueOpacity);
1163 if (image->matte != MagickFalse)
1165 p=PushCharPixel(p,&pixel);
1166 SetOpacityPixelComponent(q,ScaleAnyToQuantum(pixel,range));
1176 for (x=0; x < (long) image->columns; x++)
1178 p=PushShortPixel(MSBEndian,p,&pixel);
1179 SetRedPixelComponent(q,ScaleAnyToQuantum(pixel,range));
1180 p=PushShortPixel(MSBEndian,p,&pixel);
1181 SetGreenPixelComponent(q,ScaleAnyToQuantum(pixel,range));
1182 p=PushShortPixel(MSBEndian,p,&pixel);
1183 SetBluePixelComponent(q,ScaleAnyToQuantum(pixel,range));
1184 SetOpacityPixelComponent(q,OpaqueOpacity);
1185 if (image->matte != MagickFalse)
1187 p=PushShortPixel(MSBEndian,p,&pixel);
1188 SetOpacityPixelComponent(q,ScaleAnyToQuantum(pixel,range));
1196 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1197 if (sync == MagickFalse)
1200 image_view=DestroyCacheView(image_view);
1201 quantum_info=DestroyQuantumInfo(quantum_info);
1202 if (status == MagickFalse)
1203 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
1204 SetQuantumImageType(image,quantum_type);
1211 Convert PFM raster image to pixel packets.
1213 quantum_type=format == 'f' ? GrayQuantum : RGBQuantum;
1214 image->endian=quantum_scale < 0.0 ? LSBEndian : MSBEndian;
1216 quantum_info=AcquireQuantumInfo(image_info,image);
1217 if (quantum_info == (QuantumInfo *) NULL)
1218 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
1219 status=SetQuantumDepth(image,quantum_info,32);
1220 if (status == MagickFalse)
1221 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
1222 status=SetQuantumFormat(image,quantum_info,FloatingPointQuantumFormat);
1223 if (status == MagickFalse)
1224 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
1225 SetQuantumScale(quantum_info,(MagickRealType) QuantumRange*
1226 fabs(quantum_scale));
1227 extent=GetQuantumExtent(image,quantum_info,quantum_type);
1228 image_view=AcquireCacheView(image);
1229 #if defined(MAGICKCORE_OPENMP_SUPPORT) && (_OPENMP > 202001)
1230 #pragma omp parallel for schedule(static,1) shared(row,status,quantum_type)
1232 for (y=0; y < (long) image->rows; y++)
1240 register PixelPacket
1252 if (status == MagickFalse)
1254 pixels=GetQuantumPixels(quantum_info);
1255 #if defined(MAGICKCORE_OPENMP_SUPPORT) && (_OPENMP > 202001)
1256 #pragma omp critical (MagickCore_ReadPNMImage)
1259 count=ReadBlob(image,extent,pixels);
1260 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
1261 (image->previous == (Image *) NULL))
1266 proceed=SetImageProgress(image,LoadImageTag,row,image->rows);
1267 if (proceed == MagickFalse)
1272 if ((size_t) count != extent)
1274 q=QueueCacheViewAuthenticPixels(image_view,0,(long) (image->rows-
1275 offset-1),image->columns,1,exception);
1276 if (q == (PixelPacket *) NULL)
1281 length=ImportQuantumPixels(image,image_view,quantum_info,quantum_type,
1283 if (length != extent)
1285 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1286 if (sync == MagickFalse)
1289 image_view=DestroyCacheView(image_view);
1290 quantum_info=DestroyQuantumInfo(quantum_info);
1291 if (status == MagickFalse)
1292 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
1293 SetQuantumImageType(image,quantum_type);
1297 ThrowReaderException(CorruptImageError,"ImproperImageHeader");
1299 if (EOFBlob(image) != MagickFalse)
1300 (void) ThrowMagickException(exception,GetMagickModule(),CorruptImageError,
1301 "UnexpectedEndOfFile","`%s'",image->filename);
1303 Proceed to next image.
1305 if (image_info->number_scenes != 0)
1306 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
1308 if ((format == '1') || (format == '2') || (format == '3'))
1312 Skip to end of line.
1314 count=ReadBlob(image,1,(unsigned char *) &format);
1317 if ((count != 0) && (format == 'P'))
1319 } while (format != '\n');
1320 count=ReadBlob(image,1,(unsigned char *) &format);
1321 if ((count == 1) && (format == 'P'))
1324 Allocate next image structure.
1326 AcquireNextImage(image_info,image);
1327 if (GetNextImageInList(image) == (Image *) NULL)
1329 image=DestroyImageList(image);
1330 return((Image *) NULL);
1332 image=SyncNextImageInList(image);
1333 status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
1334 GetBlobSize(image));
1335 if (status == MagickFalse)
1338 } while ((count == 1) && (format == 'P'));
1339 (void) CloseBlob(image);
1340 return(GetFirstImageInList(image));
1344 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1348 % R e g i s t e r P N M I m a g e %
1352 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1354 % RegisterPNMImage() adds properties for the PNM image format to
1355 % the list of supported formats. The properties include the image format
1356 % tag, a method to read and/or write the format, whether the format
1357 % supports the saving of more than one frame to the same file or blob,
1358 % whether the format supports native in-memory I/O, and a brief
1359 % description of the format.
1361 % The format of the RegisterPNMImage method is:
1363 % unsigned long RegisterPNMImage(void)
1366 ModuleExport unsigned long RegisterPNMImage(void)
1371 entry=SetMagickInfo("PAM");
1372 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1373 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1374 entry->description=ConstantString("Common 2-dimensional bitmap format");
1375 entry->module=ConstantString("PNM");
1376 (void) RegisterMagickInfo(entry);
1377 entry=SetMagickInfo("PBM");
1378 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1379 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1380 entry->description=ConstantString("Portable bitmap format (black and white)");
1381 entry->module=ConstantString("PNM");
1382 (void) RegisterMagickInfo(entry);
1383 entry=SetMagickInfo("PFM");
1384 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1385 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1386 entry->description=ConstantString("Portable float format");
1387 entry->module=ConstantString("PFM");
1388 (void) RegisterMagickInfo(entry);
1389 entry=SetMagickInfo("PGM");
1390 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1391 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1392 entry->description=ConstantString("Portable graymap format (gray scale)");
1393 entry->module=ConstantString("PNM");
1394 (void) RegisterMagickInfo(entry);
1395 entry=SetMagickInfo("PNM");
1396 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1397 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1398 entry->magick=(IsImageFormatHandler *) IsPNM;
1399 entry->description=ConstantString("Portable anymap");
1400 entry->module=ConstantString("PNM");
1401 (void) RegisterMagickInfo(entry);
1402 entry=SetMagickInfo("PPM");
1403 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1404 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1405 entry->description=ConstantString("Portable pixmap format (color)");
1406 entry->module=ConstantString("PNM");
1407 (void) RegisterMagickInfo(entry);
1408 return(MagickImageCoderSignature);
1412 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1416 % U n r e g i s t e r P N M I m a g e %
1420 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1422 % UnregisterPNMImage() removes format registrations made by the
1423 % PNM module from the list of supported formats.
1425 % The format of the UnregisterPNMImage method is:
1427 % UnregisterPNMImage(void)
1430 ModuleExport void UnregisterPNMImage(void)
1432 (void) UnregisterMagickInfo("PAM");
1433 (void) UnregisterMagickInfo("PBM");
1434 (void) UnregisterMagickInfo("PGM");
1435 (void) UnregisterMagickInfo("PNM");
1436 (void) UnregisterMagickInfo("PPM");
1440 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1444 % W r i t e P N M I m a g e %
1448 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1450 % WritePNMImage() writes an image to a file in the PNM rasterfile format.
1452 % The format of the WritePNMImage method is:
1454 % MagickBooleanType WritePNMImage(const ImageInfo *image_info,Image *image)
1456 % A description of each parameter follows.
1458 % o image_info: the image info.
1460 % o image: The image.
1463 static MagickBooleanType WritePNMImage(const ImageInfo *image_info,Image *image)
1466 buffer[MaxTextExtent],
1468 magick[MaxTextExtent];
1497 register unsigned char
1509 Open output image file.
1511 assert(image_info != (const ImageInfo *) NULL);
1512 assert(image_info->signature == MagickSignature);
1513 assert(image != (Image *) NULL);
1514 assert(image->signature == MagickSignature);
1515 if (image->debug != MagickFalse)
1516 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1517 status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
1518 if (status == MagickFalse)
1524 Write PNM file header.
1527 quantum_type=RGBQuantum;
1528 (void) CopyMagickString(magick,image_info->magick,MaxTextExtent);
1541 if (image_info->compression == NoCompression)
1549 if (IsGrayImage(image,&image->exception) != MagickFalse)
1557 if (image_info->compression == NoCompression)
1564 if ((image_info->type != TrueColorType) &&
1565 (IsGrayImage(image,&image->exception) != MagickFalse))
1568 if (image_info->compression == NoCompression)
1570 if (IsMonochromeImage(image,&image->exception) != MagickFalse)
1573 if (image_info->compression == NoCompression)
1582 if (image_info->compression == NoCompression)
1587 (void) FormatMagickString(buffer,MaxTextExtent,"P%c\n",format);
1588 (void) WriteBlobString(image,buffer);
1589 value=GetImageProperty(image,"comment");
1590 if (value != (const char *) NULL)
1596 Write comments to file.
1598 (void) WriteBlobByte(image,'#');
1599 for (p=value; *p != '\0'; p++)
1601 (void) WriteBlobByte(image,(unsigned char) *p);
1602 if ((*p == '\r') && (*(p+1) != '\0'))
1603 (void) WriteBlobByte(image,'#');
1604 if ((*p == '\n') && (*(p+1) != '\0'))
1605 (void) WriteBlobByte(image,'#');
1607 (void) WriteBlobByte(image,'\n');
1611 if (image->colorspace != RGBColorspace)
1612 (void) TransformImageColorspace(image,RGBColorspace);
1613 (void) FormatMagickString(buffer,MaxTextExtent,"%lu %lu\n",
1614 image->columns,image->rows);
1615 (void) WriteBlobString(image,buffer);
1620 type[MaxTextExtent];
1625 (void) FormatMagickString(buffer,MaxTextExtent,
1626 "WIDTH %lu\nHEIGHT %lu\n",image->columns,image->rows);
1627 (void) WriteBlobString(image,buffer);
1628 quantum_type=GetQuantumType(image,&image->exception);
1629 switch (quantum_type)
1635 (void) CopyMagickString(type,"CMYK",MaxTextExtent);
1639 case GrayAlphaQuantum:
1642 (void) CopyMagickString(type,"GRAYSCALE",MaxTextExtent);
1647 quantum_type=RGBQuantum;
1648 if (image->matte != MagickFalse)
1649 quantum_type=RGBAQuantum;
1651 (void) CopyMagickString(type,"RGB",MaxTextExtent);
1655 if (image->matte != MagickFalse)
1658 (void) ConcatenateMagickString(type,"_ALPHA",MaxTextExtent);
1660 if (image->depth > 16)
1662 (void) FormatMagickString(buffer,MaxTextExtent,
1663 "DEPTH %lu\nMAXVAL %lu\n",(unsigned long) packet_size,(unsigned long)
1664 GetQuantumRange(image->depth));
1665 (void) WriteBlobString(image,buffer);
1666 (void) FormatMagickString(buffer,MaxTextExtent,"TUPLTYPE %s\nENDHDR\n",
1668 (void) WriteBlobString(image,buffer);
1671 Convert runextent encoded to PNM raster pixels.
1681 Convert image to a PBM image.
1684 for (y=0; y < (long) image->rows; y++)
1686 register const IndexPacket
1689 register const PixelPacket
1695 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1696 if (p == (const PixelPacket *) NULL)
1698 indexes=GetVirtualIndexQueue(image);
1699 for (x=0; x < (long) image->columns; x++)
1701 pixel=PixelIntensityToQuantum(p);
1702 *q++=(unsigned char) (pixel >= (Quantum) (QuantumRange/2) ?
1705 if ((q-pixels+2) >= 80)
1708 (void) WriteBlob(image,q-pixels,pixels);
1714 if (image->previous == (Image *) NULL)
1716 status=SetImageProgress(image,SaveImageTag,y,image->rows);
1717 if (status == MagickFalse)
1724 (void) WriteBlob(image,q-pixels,pixels);
1734 Convert image to a PGM image.
1736 if (image->depth <= 8)
1737 (void) WriteBlobString(image,"255\n");
1739 (void) WriteBlobString(image,"65535\n");
1741 for (y=0; y < (long) image->rows; y++)
1743 register const PixelPacket
1749 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1750 if (p == (const PixelPacket *) NULL)
1752 for (x=0; x < (long) image->columns; x++)
1754 index=PixelIntensityToQuantum(p);
1755 if (image->depth <= 8)
1756 count=(ssize_t) FormatMagickString(buffer,MaxTextExtent,"%u ",
1757 ScaleQuantumToChar(index));
1759 count=(ssize_t) FormatMagickString(buffer,MaxTextExtent,"%u ",
1760 ScaleQuantumToShort(index));
1761 extent=(size_t) count;
1762 (void) strncpy((char *) q,buffer,extent);
1764 if ((q-pixels+extent) >= 80)
1767 (void) WriteBlob(image,q-pixels,pixels);
1772 if (image->previous == (Image *) NULL)
1774 status=SetImageProgress(image,SaveImageTag,y,image->rows);
1775 if (status == MagickFalse)
1782 (void) WriteBlob(image,q-pixels,pixels);
1792 Convert image to a PNM image.
1794 if (image->depth <= 8)
1795 (void) WriteBlobString(image,"255\n");
1797 (void) WriteBlobString(image,"65535\n");
1799 for (y=0; y < (long) image->rows; y++)
1801 register const PixelPacket
1807 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1808 if (p == (const PixelPacket *) NULL)
1810 for (x=0; x < (long) image->columns; x++)
1812 if (image->depth <= 8)
1813 count=(ssize_t) FormatMagickString(buffer,MaxTextExtent,
1814 "%u %u %u ",ScaleQuantumToChar(GetRedPixelComponent(p)),
1815 ScaleQuantumToChar(GetGreenPixelComponent(p)),
1816 ScaleQuantumToChar(GetBluePixelComponent(p)));
1818 count=(ssize_t) FormatMagickString(buffer,MaxTextExtent,
1819 "%u %u %u ",ScaleQuantumToShort(GetRedPixelComponent(p)),
1820 ScaleQuantumToShort(GetGreenPixelComponent(p)),
1821 ScaleQuantumToShort(GetBluePixelComponent(p)));
1822 extent=(size_t) count;
1823 (void) strncpy((char *) q,buffer,extent);
1825 if ((q-pixels+extent) >= 80)
1828 (void) WriteBlob(image,q-pixels,pixels);
1833 if (image->previous == (Image *) NULL)
1835 status=SetImageProgress(image,SaveImageTag,y,image->rows);
1836 if (status == MagickFalse)
1843 (void) WriteBlob(image,q-pixels,pixels);
1850 Convert image to a PBM image.
1853 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
1854 if (quantum_info == (QuantumInfo *) NULL)
1855 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1856 quantum_info->min_is_white=MagickTrue;
1857 pixels=GetQuantumPixels(quantum_info);
1858 for (y=0; y < (long) image->rows; y++)
1860 register const PixelPacket
1863 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1864 if (p == (const PixelPacket *) NULL)
1866 extent=ExportQuantumPixels(image,(const CacheView *) NULL,
1867 quantum_info,GrayQuantum,pixels,&image->exception);
1868 count=WriteBlob(image,extent,pixels);
1869 if (count != (ssize_t) extent)
1871 if (image->previous == (Image *) NULL)
1873 status=SetImageProgress(image,SaveImageTag,y,image->rows);
1874 if (status == MagickFalse)
1878 quantum_info=DestroyQuantumInfo(quantum_info);
1887 Convert image to a PGM image.
1889 if (image->depth > 8)
1891 (void) FormatMagickString(buffer,MaxTextExtent,"%lu\n",(unsigned long)
1892 GetQuantumRange(image->depth));
1893 (void) WriteBlobString(image,buffer);
1894 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
1895 if (quantum_info == (QuantumInfo *) NULL)
1896 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1897 quantum_info->min_is_white=MagickTrue;
1898 pixels=GetQuantumPixels(quantum_info);
1899 extent=GetQuantumExtent(image,quantum_info,GrayQuantum);
1900 range=GetQuantumRange(image->depth);
1901 for (y=0; y < (long) image->rows; y++)
1903 register const PixelPacket
1909 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1910 if (p == (const PixelPacket *) NULL)
1913 if ((image->depth == 8) || (image->depth == 16))
1914 extent=ExportQuantumPixels(image,(const CacheView *) NULL,
1915 quantum_info,GrayQuantum,pixels,&image->exception);
1918 if (image->depth <= 8)
1919 for (x=0; x < (long) image->columns; x++)
1921 if (IsGrayPixel(p) == MagickFalse)
1922 pixel=ScaleQuantumToAny(PixelIntensityToQuantum(p),range);
1925 if (image->depth == 8)
1926 pixel=ScaleQuantumToChar(GetRedPixelComponent(p));
1928 pixel=ScaleQuantumToAny(p->red,range);
1930 q=PopCharPixel((unsigned char) pixel,q);
1934 for (x=0; x < (long) image->columns; x++)
1936 if (IsGrayPixel(p) == MagickFalse)
1937 pixel=ScaleQuantumToAny(PixelIntensityToQuantum(p),range);
1940 if (image->depth == 16)
1941 pixel=ScaleQuantumToShort(GetRedPixelComponent(p));
1943 pixel=ScaleQuantumToAny(p->red,range);
1945 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
1948 extent=(size_t) (q-pixels);
1950 count=WriteBlob(image,extent,pixels);
1951 if (count != (ssize_t) extent)
1953 if (image->previous == (Image *) NULL)
1955 status=SetImageProgress(image,SaveImageTag,y,image->rows);
1956 if (status == MagickFalse)
1960 quantum_info=DestroyQuantumInfo(quantum_info);
1969 Convert image to a PNM image.
1971 if (image->depth > 8)
1973 (void) FormatMagickString(buffer,MaxTextExtent,"%lu\n",(unsigned long)
1974 GetQuantumRange(image->depth));
1975 (void) WriteBlobString(image,buffer);
1976 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
1977 if (quantum_info == (QuantumInfo *) NULL)
1978 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1979 pixels=GetQuantumPixels(quantum_info);
1980 extent=GetQuantumExtent(image,quantum_info,quantum_type);
1981 range=GetQuantumRange(image->depth);
1982 for (y=0; y < (long) image->rows; y++)
1984 register const PixelPacket
1990 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1991 if (p == (const PixelPacket *) NULL)
1994 if ((image->depth == 8) || (image->depth == 16))
1995 extent=ExportQuantumPixels(image,(const CacheView *) NULL,
1996 quantum_info,quantum_type,pixels,&image->exception);
1999 if (image->depth <= 8)
2000 for (x=0; x < (long) image->columns; x++)
2002 pixel=ScaleQuantumToAny(p->red,range);
2003 q=PopCharPixel((unsigned char) pixel,q);
2004 pixel=ScaleQuantumToAny(p->green,range);
2005 q=PopCharPixel((unsigned char) pixel,q);
2006 pixel=ScaleQuantumToAny(p->blue,range);
2007 q=PopCharPixel((unsigned char) pixel,q);
2011 for (x=0; x < (long) image->columns; x++)
2013 pixel=ScaleQuantumToAny(p->red,range);
2014 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2015 pixel=ScaleQuantumToAny(p->green,range);
2016 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2017 pixel=ScaleQuantumToAny(p->blue,range);
2018 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2021 extent=(size_t) (q-pixels);
2023 count=WriteBlob(image,extent,pixels);
2024 if (count != (ssize_t) extent)
2026 if (image->previous == (Image *) NULL)
2028 status=SetImageProgress(image,SaveImageTag,y,image->rows);
2029 if (status == MagickFalse)
2033 quantum_info=DestroyQuantumInfo(quantum_info);
2042 Convert image to a PAM.
2044 if (image->depth > 16)
2046 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
2047 pixels=GetQuantumPixels(quantum_info);
2048 range=GetQuantumRange(image->depth);
2049 for (y=0; y < (long) image->rows; y++)
2051 register const IndexPacket
2054 register const PixelPacket
2060 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
2061 if (p == (const PixelPacket *) NULL)
2063 indexes=GetVirtualIndexQueue(image);
2065 if ((image->depth == 8) || (image->depth == 16))
2066 extent=ExportQuantumPixels(image,(const CacheView *) NULL,
2067 quantum_info,quantum_type,pixels,&image->exception);
2070 switch (quantum_type)
2073 case GrayAlphaQuantum:
2075 if (image->depth <= 8)
2076 for (x=0; x < (long) image->columns; x++)
2078 pixel=ScaleQuantumToAny(PixelIntensityToQuantum(p),range);
2079 q=PopCharPixel((unsigned char) pixel,q);
2080 if (image->matte != MagickFalse)
2082 pixel=(unsigned char) ScaleQuantumToAny(p->opacity,
2084 q=PopCharPixel((unsigned char) pixel,q);
2089 for (x=0; x < (long) image->columns; x++)
2091 pixel=ScaleQuantumToAny(PixelIntensityToQuantum(p),range);
2092 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2093 if (image->matte != MagickFalse)
2095 pixel=(unsigned char) ScaleQuantumToAny(p->opacity,
2097 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2106 if (image->depth <= 8)
2107 for (x=0; x < (long) image->columns; x++)
2109 pixel=ScaleQuantumToAny(p->red,range);
2110 q=PopCharPixel((unsigned char) pixel,q);
2111 pixel=ScaleQuantumToAny(p->green,range);
2112 q=PopCharPixel((unsigned char) pixel,q);
2113 pixel=ScaleQuantumToAny(p->blue,range);
2114 q=PopCharPixel((unsigned char) pixel,q);
2115 pixel=ScaleQuantumToAny(indexes[x],range);
2116 q=PopCharPixel((unsigned char) pixel,q);
2117 if (image->matte != MagickFalse)
2119 pixel=ScaleQuantumToAny((Quantum) (QuantumRange-
2120 GetOpacityPixelComponent(p)),range);
2121 q=PopCharPixel((unsigned char) pixel,q);
2126 for (x=0; x < (long) image->columns; x++)
2128 pixel=ScaleQuantumToAny(p->red,range);
2129 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2130 pixel=ScaleQuantumToAny(p->green,range);
2131 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2132 pixel=ScaleQuantumToAny(p->blue,range);
2133 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2134 pixel=ScaleQuantumToAny(indexes[x],range);
2135 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2136 if (image->matte != MagickFalse)
2138 pixel=ScaleQuantumToAny((Quantum) (QuantumRange-
2139 GetOpacityPixelComponent(p)),range);
2140 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2148 if (image->depth <= 8)
2149 for (x=0; x < (long) image->columns; x++)
2151 pixel=ScaleQuantumToAny(p->red,range);
2152 q=PopCharPixel((unsigned char) pixel,q);
2153 pixel=ScaleQuantumToAny(p->green,range);
2154 q=PopCharPixel((unsigned char) pixel,q);
2155 pixel=ScaleQuantumToAny(p->blue,range);
2156 q=PopCharPixel((unsigned char) pixel,q);
2157 if (image->matte != MagickFalse)
2159 pixel=ScaleQuantumToAny((Quantum) (QuantumRange-
2160 GetOpacityPixelComponent(p)),range);
2161 q=PopCharPixel((unsigned char) pixel,q);
2166 for (x=0; x < (long) image->columns; x++)
2168 pixel=ScaleQuantumToAny(p->red,range);
2169 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2170 pixel=ScaleQuantumToAny(p->green,range);
2171 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2172 pixel=ScaleQuantumToAny(p->blue,range);
2173 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2174 if (image->matte != MagickFalse)
2176 pixel=ScaleQuantumToAny((Quantum) (QuantumRange-
2177 GetOpacityPixelComponent(p)),range);
2178 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2185 extent=(size_t) (q-pixels);
2187 count=WriteBlob(image,extent,pixels);
2188 if (count != (ssize_t) extent)
2190 if (image->previous == (Image *) NULL)
2192 status=SetImageProgress(image,SaveImageTag,y,image->rows);
2193 if (status == MagickFalse)
2197 quantum_info=DestroyQuantumInfo(quantum_info);
2203 (void) WriteBlobString(image,image->endian != LSBEndian ? "1.0\n" :
2206 quantum_type=format == 'f' ? GrayQuantum : RGBQuantum;
2207 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
2208 if (quantum_info == (QuantumInfo *) NULL)
2209 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
2210 status=SetQuantumFormat(image,quantum_info,FloatingPointQuantumFormat);
2211 if (status == MagickFalse)
2212 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
2213 pixels=GetQuantumPixels(quantum_info);
2214 for (y=(long) image->rows-1; y >= 0; y--)
2216 register const PixelPacket
2219 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
2220 if (p == (const PixelPacket *) NULL)
2222 extent=ExportQuantumPixels(image,(const CacheView *) NULL,
2223 quantum_info,quantum_type,pixels,&image->exception);
2224 (void) WriteBlob(image,extent,pixels);
2225 if (image->previous == (Image *) NULL)
2227 status=SetImageProgress(image,SaveImageTag,y,image->rows);
2228 if (status == MagickFalse)
2232 quantum_info=DestroyQuantumInfo(quantum_info);
2236 if (GetNextImageInList(image) == (Image *) NULL)
2238 image=SyncNextImageInList(image);
2239 status=SetImageProgress(image,SaveImagesTag,scene++,
2240 GetImageListLength(image));
2241 if (status == MagickFalse)
2243 } while (image_info->adjoin != MagickFalse);
2244 (void) CloseBlob(image);