2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13 % Read/Write PBMPlus Portable Anymap Image Format %
20 % Copyright 1999-2009 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/monitor.h"
57 #include "magick/monitor-private.h"
58 #include "magick/pixel-private.h"
59 #include "magick/property.h"
60 #include "magick/quantum-private.h"
61 #include "magick/static.h"
62 #include "magick/statistic.h"
63 #include "magick/string_.h"
64 #include "magick/module.h"
69 static MagickBooleanType
70 WritePNMImage(const ImageInfo *,Image *);
73 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
81 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
83 % IsPNM() returns MagickTrue if the image format type, identified by the
84 % magick string, is PNM.
86 % The format of the IsPNM method is:
88 % MagickBooleanType IsPNM(const unsigned char *magick,const size_t extent)
90 % A description of each parameter follows:
92 % o magick: compare image format pattern against these bytes.
94 % o extent: Specifies the extent of the magick string.
97 static MagickBooleanType IsPNM(const unsigned char *magick,const size_t extent)
101 if ((*magick == (unsigned char) 'P') &&
102 ((magick[1] == '1') || (magick[1] == '2') || (magick[1] == '3') ||
103 (magick[1] == '4') || (magick[1] == '5') || (magick[1] == '6') ||
104 (magick[1] == '7') || (magick[1] == 'F') || (magick[1] == 'f')))
110 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
114 % R e a d P N M I m a g e %
118 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
120 % ReadPNMImage() reads a Portable Anymap image file and returns it.
121 % It allocates the memory necessary for the new Image structure and returns
122 % a pointer to the new image.
124 % The format of the ReadPNMImage method is:
126 % Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception)
128 % A description of each parameter follows:
130 % o image_info: the image info.
132 % o exception: return any errors or warnings in this structure.
136 static inline long ConstrainPixel(Image *image,const long offset,
137 const unsigned long extent)
139 if ((offset < 0) || (offset > (long) extent))
141 (void) ThrowMagickException(&image->exception,GetMagickModule(),
142 CorruptImageError,"InvalidPixel","`%s'",image->filename);
148 static unsigned long PNMInteger(Image *image,const unsigned int base)
166 Skip any leading whitespace.
168 extent=MaxTextExtent;
169 comment=(char *) NULL;
173 c=ReadBlobByte(image);
181 if (comment == (char *) NULL)
182 comment=AcquireString((char *) NULL);
183 p=comment+strlen(comment);
184 for ( ; (c != EOF) && (c != (int) '\n'); p++)
186 if ((size_t) (p-comment+1) >= extent)
189 comment=(char *) ResizeQuantumMemory(comment,extent+MaxTextExtent,
191 if (comment == (char *) NULL)
193 p=comment+strlen(comment);
195 c=ReadBlobByte(image);
199 if (comment == (char *) NULL)
203 } while (isdigit(c) == MagickFalse);
204 if (comment != (char *) NULL)
206 (void) SetImageProperty(image,"comment",comment);
207 comment=DestroyString(comment);
210 return((unsigned long) (c-(int) '0'));
219 c=ReadBlobByte(image);
222 } while (isdigit(c) != MagickFalse);
226 static Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception)
273 assert(image_info != (const ImageInfo *) NULL);
274 assert(image_info->signature == MagickSignature);
275 if (image_info->debug != MagickFalse)
276 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
277 image_info->filename);
278 assert(exception != (ExceptionInfo *) NULL);
279 assert(exception->signature == MagickSignature);
280 image=AcquireImage(image_info);
281 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
282 if (status == MagickFalse)
284 image=DestroyImageList(image);
285 return((Image *) NULL);
290 count=ReadBlob(image,1,(unsigned char *) &format);
294 Initialize image structure.
296 if ((count != 1) || (format != 'P'))
297 ThrowReaderException(CorruptImageError,"ImproperImageHeader");
299 quantum_type=RGBQuantum;
301 format=(char) ReadBlobByte(image);
305 PBM, PGM, PPM, and PNM.
307 image->columns=PNMInteger(image,10);
308 image->rows=PNMInteger(image,10);
309 if ((format == 'f') || (format == 'F'))
312 scale[MaxTextExtent];
314 (void) ReadBlobString(image,scale);
315 quantum_scale=atof(scale);
319 if ((format == '1') || (format == '4'))
320 max_value=1; /* bitmap */
322 max_value=PNMInteger(image,10);
328 keyword[MaxTextExtent],
329 value[MaxTextExtent];
340 for (c=ReadBlobByte(image); c != EOF; c=ReadBlobByte(image))
342 while (isspace((int) ((unsigned char) c)) != 0)
343 c=ReadBlobByte(image);
347 if ((size_t) (p-keyword) < (MaxTextExtent-1))
349 c=ReadBlobByte(image);
350 } while (isalnum(c));
352 if (LocaleCompare(keyword,"endhdr") == 0)
354 while (isspace((int) ((unsigned char) c)) != 0)
355 c=ReadBlobByte(image);
357 while (isalnum(c) || (c == '_'))
359 if ((size_t) (p-value) < (MaxTextExtent-1))
361 c=ReadBlobByte(image);
365 Assign a value to the specified keyword.
367 if (LocaleCompare(keyword,"depth") == 0)
368 packet_size=(unsigned long) atol(value);
369 if (LocaleCompare(keyword,"height") == 0)
370 image->rows=(unsigned long) atol(value);
371 if (LocaleCompare(keyword,"maxval") == 0)
372 max_value=(unsigned long) atol(value);
373 if (LocaleCompare(keyword,"TUPLTYPE") == 0)
375 if (LocaleCompare(value,"BLACKANDWHITE") == 0)
376 quantum_type=GrayQuantum;
377 if (LocaleCompare(value,"BLACKANDWHITE_ALPHA") == 0)
379 quantum_type=GrayAlphaQuantum;
380 image->matte=MagickTrue;
382 if (LocaleCompare(value,"GRAYSCALE") == 0)
383 quantum_type=GrayQuantum;
384 if (LocaleCompare(value,"GRAYSCALE_ALPHA") == 0)
386 quantum_type=GrayAlphaQuantum;
387 image->matte=MagickTrue;
389 if (LocaleCompare(value,"RGB_ALPHA") == 0)
391 quantum_type=RGBAQuantum;
392 image->matte=MagickTrue;
394 if (LocaleCompare(value,"CMYK") == 0)
396 quantum_type=CMYKQuantum;
397 image->colorspace=CMYKColorspace;
399 if (LocaleCompare(value,"CMYK_ALPHA") == 0)
401 quantum_type=CMYKAQuantum;
402 image->colorspace=CMYKColorspace;
403 image->matte=MagickTrue;
406 if (LocaleCompare(keyword,"width") == 0)
407 image->columns=(unsigned long) atol(value);
410 if ((image->columns == 0) || (image->rows == 0))
411 ThrowReaderException(CorruptImageError,"NegativeOrZeroImageSize");
412 if (max_value >= 65536)
413 ThrowReaderException(CorruptImageError,"ImproperImageHeader");
414 for (depth=1; GetQuantumRange(depth) < max_value; depth++) ;
416 if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
417 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
420 Convert PNM pixels to runextent-encoded MIFF packets.
429 Convert PBM image to pixel packets.
431 for (y=0; y < (long) image->rows; y++)
439 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
440 if (q == (PixelPacket *) NULL)
442 for (x=0; x < (long) image->columns; x++)
444 q->red=(Quantum) (PNMInteger(image,2) == 0 ? QuantumRange : 0);
449 if (SyncAuthenticPixels(image,exception) == MagickFalse)
451 if (image->previous == (Image *) NULL)
453 status=SetImageProgress(image,LoadImageTag,y,image->rows);
454 if (status == MagickFalse)
458 image->type=BilevelType;
467 Convert PGM image to pixel packets.
469 scale=(Quantum *) NULL;
470 if (max_value != (1U*QuantumRange))
473 Compute pixel scaling table.
475 scale=(Quantum *) AcquireQuantumMemory((size_t) max_value+1UL,
477 if (scale == (Quantum *) NULL)
478 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
479 for (i=0; i <= (long) max_value; i++)
480 scale[i]=(Quantum) (((double) QuantumRange*i)/max_value+0.5);
482 for (y=0; y < (long) image->rows; y++)
490 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
491 if (q == (PixelPacket *) NULL)
493 for (x=0; x < (long) image->columns; x++)
495 intensity=PNMInteger(image,10);
496 if (scale != (Quantum *) NULL)
497 intensity=(unsigned long) scale[ConstrainPixel(image,(long)
498 intensity,max_value)];
499 q->red=(Quantum) intensity;
504 if (SyncAuthenticPixels(image,exception) == MagickFalse)
506 if (image->previous == (Image *) NULL)
508 status=SetImageProgress(image,LoadImageTag,y,image->rows);
509 if (status == MagickFalse)
513 image->type=GrayscaleType;
514 if (scale != (Quantum *) NULL)
515 scale=(Quantum *) RelinquishMagickMemory(scale);
524 Convert PNM image to pixel packets.
526 scale=(Quantum *) NULL;
527 if (max_value != (1U*QuantumRange))
530 Compute pixel scaling table.
532 scale=(Quantum *) AcquireQuantumMemory((size_t) max_value+1UL,
534 if (scale == (Quantum *) NULL)
535 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
536 for (i=0; i <= (long) max_value; i++)
537 scale[i]=(Quantum) (((double) QuantumRange*i)/max_value+0.5);
539 for (y=0; y < (long) image->rows; y++)
547 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
548 if (q == (PixelPacket *) NULL)
550 for (x=0; x < (long) image->columns; x++)
552 pixel.red=(MagickRealType) PNMInteger(image,10);
553 pixel.green=(MagickRealType) PNMInteger(image,10);
554 pixel.blue=(MagickRealType) PNMInteger(image,10);
555 if (scale != (Quantum *) NULL)
557 pixel.red=(MagickRealType) scale[ConstrainPixel(image,(long)
558 pixel.red,max_value)];
559 pixel.green=(MagickRealType) scale[ConstrainPixel(image,(long)
560 pixel.green,max_value)];
561 pixel.blue=(MagickRealType) scale[ConstrainPixel(image,(long)
562 pixel.blue,max_value)];
564 q->red=(Quantum) pixel.red;
565 q->green=(Quantum) pixel.green;
566 q->blue=(Quantum) pixel.blue;
569 if (SyncAuthenticPixels(image,exception) == MagickFalse)
571 if (image->previous == (Image *) NULL)
573 status=SetImageProgress(image,LoadImageTag,y,image->rows);
574 if (status == MagickFalse)
578 if (scale != (Quantum *) NULL)
579 scale=(Quantum *) RelinquishMagickMemory(scale);
585 Convert PBM raw image to pixel packets.
587 quantum_type=GrayQuantum;
588 if (image->storage_class == PseudoClass)
589 quantum_type=IndexQuantum;
590 quantum_info=AcquireQuantumInfo(image_info,image);
591 if (quantum_info == (QuantumInfo *) NULL)
592 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
593 SetQuantumMinIsWhite(quantum_info,MagickTrue);
594 extent=GetQuantumExtent(image,quantum_info,quantum_type);
595 image_view=AcquireCacheView(image);
596 #if defined(MAGICKCORE_OPENMP_SUPPORT) && (_OPENMP > 200505)
597 #pragma omp parallel for schedule(dynamic,1) shared(row,status,quantum_type)
599 for (y=0; y < (long) image->rows; y++)
619 if (status == MagickFalse)
621 pixels=GetQuantumPixels(quantum_info);
622 #if defined(MAGICKCORE_OPENMP_SUPPORT) && (_OPENMP > 200505)
623 #pragma omp critical (MagickCore_ReadPNMImage)
626 count=ReadBlob(image,extent,pixels);
627 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
628 (image->previous == (Image *) NULL))
633 proceed=SetImageProgress(image,LoadImageTag,row,image->rows);
634 if (proceed == MagickFalse)
639 if (count != (ssize_t) extent)
641 q=QueueCacheViewAuthenticPixels(image_view,0,offset,image->columns,1,
643 if (q == (PixelPacket *) NULL)
648 length=ImportQuantumPixels(image,image_view,quantum_info,quantum_type,
650 if (length != extent)
652 sync=SyncCacheViewAuthenticPixels(image_view,exception);
653 if (sync == MagickFalse)
656 image_view=DestroyCacheView(image_view);
657 quantum_info=DestroyQuantumInfo(quantum_info);
658 if (status == MagickFalse)
659 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
660 SetQuantumImageType(image,quantum_type);
669 Convert PGM raw image to pixel packets.
671 range=GetQuantumRange(image->depth);
672 quantum_type=GrayQuantum;
673 extent=(image->depth <= 8 ? 1 : 2)*image->columns;
674 quantum_info=AcquireQuantumInfo(image_info,image);
675 if (quantum_info == (QuantumInfo *) NULL)
676 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
677 image_view=AcquireCacheView(image);
678 #if defined(MAGICKCORE_OPENMP_SUPPORT) && (_OPENMP > 200505)
679 #pragma omp parallel for schedule(dynamic,1) shared(row,status,quantum_type)
681 for (y=0; y < (long) image->rows; y++)
689 register const unsigned char
704 if (status == MagickFalse)
706 pixels=GetQuantumPixels(quantum_info);
707 #if defined(MAGICKCORE_OPENMP_SUPPORT) && (_OPENMP > 200505)
708 #pragma omp critical (MagickCore_ReadPNMImage)
711 count=ReadBlob(image,extent,pixels);
712 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
713 (image->previous == (Image *) NULL))
718 proceed=SetImageProgress(image,LoadImageTag,row,image->rows);
719 if (proceed == MagickFalse)
724 if (count != (ssize_t) extent)
726 q=QueueCacheViewAuthenticPixels(image_view,0,offset,image->columns,1,
728 if (q == (PixelPacket *) NULL)
734 if ((image->depth == 8) || (image->depth == 16))
735 (void) ImportQuantumPixels(image,image_view,quantum_info,
736 quantum_type,pixels,exception);
738 if (image->depth <= 8)
743 for (x=0; x < (long) image->columns; x++)
745 p=PushCharPixel(p,&pixel);
746 q->red=ScaleAnyToQuantum(pixel,range);
757 for (x=0; x < (long) image->columns; x++)
759 p=PushShortPixel(MSBEndian,p,&pixel);
760 q->red=ScaleAnyToQuantum(pixel,range);
766 sync=SyncCacheViewAuthenticPixels(image_view,exception);
767 if (sync == MagickFalse)
770 image_view=DestroyCacheView(image_view);
771 quantum_info=DestroyQuantumInfo(quantum_info);
772 if (status == MagickFalse)
773 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
774 SetQuantumImageType(image,quantum_type);
786 Convert PNM raster image to pixel packets.
789 quantum_type=RGBQuantum;
790 extent=3*(image->depth <= 8 ? 1 : 2)*image->columns;
791 range=GetQuantumRange(image->depth);
792 quantum_info=AcquireQuantumInfo(image_info,image);
793 if (quantum_info == (QuantumInfo *) NULL)
794 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
795 image_view=AcquireCacheView(image);
796 #if defined(MAGICKCORE_OPENMP_SUPPORT) && (_OPENMP > 200505)
797 #pragma omp parallel for schedule(dynamic,1) shared(row,status,type)
799 for (y=0; y < (long) image->rows; y++)
807 register const unsigned char
825 if (status == MagickFalse)
827 pixels=GetQuantumPixels(quantum_info);
828 #if defined(MAGICKCORE_OPENMP_SUPPORT) && (_OPENMP > 200505)
829 #pragma omp critical (MagickCore_ReadPNMImage)
832 count=ReadBlob(image,extent,pixels);
833 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
834 (image->previous == (Image *) NULL))
839 proceed=SetImageProgress(image,LoadImageTag,row,image->rows);
840 if (proceed == MagickFalse)
845 if (count != (ssize_t) extent)
847 q=QueueCacheViewAuthenticPixels(image_view,0,offset,image->columns,1,
849 if (q == (PixelPacket *) NULL)
855 if ((image->depth == 8) || (image->depth == 16))
857 length=ImportQuantumPixels(image,image_view,quantum_info,
858 quantum_type,pixels,exception);
859 if (length != extent)
863 if (image->depth <= 8)
872 for (x=0; x < (long) image->columns; x++)
874 p=PushCharPixel(p,&pixel);
875 r->red=ScaleAnyToQuantum(pixel,range);
876 p=PushCharPixel(p,&pixel);
877 r->green=ScaleAnyToQuantum(pixel,range);
878 p=PushCharPixel(p,&pixel);
879 r->blue=ScaleAnyToQuantum(pixel,range);
892 for (x=0; x < (long) image->columns; x++)
894 p=PushShortPixel(MSBEndian,p,&pixel);
895 r->red=ScaleAnyToQuantum(pixel,range);
896 p=PushShortPixel(MSBEndian,p,&pixel);
897 r->green=ScaleAnyToQuantum(pixel,range);
898 p=PushShortPixel(MSBEndian,p,&pixel);
899 r->blue=ScaleAnyToQuantum(pixel,range);
903 if ((type == BilevelType) || (type == GrayscaleType))
904 for (x=0; x < (long) image->columns; x++)
906 if ((type == BilevelType) &&
907 (IsMonochromePixel(q) == MagickFalse))
908 type=IsGrayPixel(q) == MagickFalse ? UndefinedType :
910 if ((type == GrayscaleType) && (IsGrayPixel(q) == MagickFalse))
912 if ((type != BilevelType) && (type != GrayscaleType))
916 sync=SyncCacheViewAuthenticPixels(image_view,exception);
917 if (sync == MagickFalse)
920 image_view=DestroyCacheView(image_view);
921 quantum_info=DestroyQuantumInfo(quantum_info);
922 if (status == MagickFalse)
923 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
924 if (type != UndefinedType)
940 Convert PAM raster image to pixel packets.
942 range=GetQuantumRange(image->depth);
943 switch (quantum_type)
946 case GrayAlphaQuantum:
963 if (image->matte != MagickFalse)
965 extent=channels*(image->depth <= 8 ? 1 : 2)*image->columns;
966 quantum_info=AcquireQuantumInfo(image_info,image);
967 if (quantum_info == (QuantumInfo *) NULL)
968 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
969 image_view=AcquireCacheView(image);
970 #if defined(MAGICKCORE_OPENMP_SUPPORT) && (_OPENMP > 200505)
971 #pragma omp parallel for schedule(dynamic,1) shared(row,status,quantum_type)
973 for (y=0; y < (long) image->rows; y++)
981 register const unsigned char
996 if (status == MagickFalse)
998 pixels=GetQuantumPixels(quantum_info);
999 #if defined(MAGICKCORE_OPENMP_SUPPORT) && (_OPENMP > 200505)
1000 #pragma omp critical (MagickCore_ReadPNMImage)
1003 count=ReadBlob(image,extent,pixels);
1004 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
1005 (image->previous == (Image *) NULL))
1010 proceed=SetImageProgress(image,LoadImageTag,row,image->rows);
1011 if (proceed == MagickFalse)
1016 if (count != (ssize_t) extent)
1018 q=QueueCacheViewAuthenticPixels(image_view,0,offset,image->columns,1,
1020 if (q == (PixelPacket *) NULL)
1025 indexes=GetCacheViewAuthenticIndexQueue(image_view);
1027 if ((image->depth == 8) || (image->depth == 16))
1028 (void) ImportQuantumPixels(image,image_view,quantum_info,
1029 quantum_type,pixels,exception);
1031 switch (quantum_type)
1034 case GrayAlphaQuantum:
1036 if (image->depth <= 8)
1041 for (x=0; x < (long) image->columns; x++)
1043 p=PushCharPixel(p,&pixel);
1044 q->red=ScaleAnyToQuantum(pixel,range);
1047 q->opacity=OpaqueOpacity;
1048 if (image->matte != MagickFalse)
1050 p=PushCharPixel(p,&pixel);
1051 q->opacity=ScaleAnyToQuantum(pixel,range);
1061 for (x=0; x < (long) image->columns; x++)
1063 p=PushShortPixel(MSBEndian,p,&pixel);
1064 q->red=ScaleAnyToQuantum(pixel,range);
1067 q->opacity=OpaqueOpacity;
1068 if (image->matte != MagickFalse)
1070 p=PushShortPixel(MSBEndian,p,&pixel);
1071 q->opacity=ScaleAnyToQuantum(pixel,range);
1081 if (image->depth <= 8)
1086 for (x=0; x < (long) image->columns; x++)
1088 p=PushCharPixel(p,&pixel);
1089 q->red=ScaleAnyToQuantum(pixel,range);
1090 p=PushCharPixel(p,&pixel);
1091 q->green=ScaleAnyToQuantum(pixel,range);
1092 p=PushCharPixel(p,&pixel);
1093 q->blue=ScaleAnyToQuantum(pixel,range);
1094 p=PushCharPixel(p,&pixel);
1095 indexes[x]=ScaleAnyToQuantum(pixel,range);
1096 q->opacity=OpaqueOpacity;
1097 if (image->matte != MagickFalse)
1099 p=PushCharPixel(p,&pixel);
1100 q->opacity=ScaleAnyToQuantum(pixel,range);
1110 for (x=0; x < (long) image->columns; x++)
1112 p=PushShortPixel(MSBEndian,p,&pixel);
1113 q->red=ScaleAnyToQuantum(pixel,range);
1114 p=PushShortPixel(MSBEndian,p,&pixel);
1115 q->green=ScaleAnyToQuantum(pixel,range);
1116 p=PushShortPixel(MSBEndian,p,&pixel);
1117 q->blue=ScaleAnyToQuantum(pixel,range);
1118 p=PushShortPixel(MSBEndian,p,&pixel);
1119 indexes[x]=ScaleAnyToQuantum(pixel,range);
1120 q->opacity=OpaqueOpacity;
1121 if (image->matte != MagickFalse)
1123 p=PushShortPixel(MSBEndian,p,&pixel);
1124 q->opacity=ScaleAnyToQuantum(pixel,range);
1133 if (image->depth <= 8)
1138 for (x=0; x < (long) image->columns; x++)
1140 p=PushCharPixel(p,&pixel);
1141 q->red=ScaleAnyToQuantum(pixel,range);
1142 p=PushCharPixel(p,&pixel);
1143 q->green=ScaleAnyToQuantum(pixel,range);
1144 p=PushCharPixel(p,&pixel);
1145 q->blue=ScaleAnyToQuantum(pixel,range);
1146 q->opacity=OpaqueOpacity;
1147 if (image->matte != MagickFalse)
1149 p=PushCharPixel(p,&pixel);
1150 q->opacity=ScaleAnyToQuantum(pixel,range);
1160 for (x=0; x < (long) image->columns; x++)
1162 p=PushShortPixel(MSBEndian,p,&pixel);
1163 q->red=ScaleAnyToQuantum(pixel,range);
1164 p=PushShortPixel(MSBEndian,p,&pixel);
1165 q->green=ScaleAnyToQuantum(pixel,range);
1166 p=PushShortPixel(MSBEndian,p,&pixel);
1167 q->blue=ScaleAnyToQuantum(pixel,range);
1168 q->opacity=OpaqueOpacity;
1169 if (image->matte != MagickFalse)
1171 p=PushShortPixel(MSBEndian,p,&pixel);
1172 q->opacity=ScaleAnyToQuantum(pixel,range);
1180 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1181 if (sync == MagickFalse)
1184 image_view=DestroyCacheView(image_view);
1185 quantum_info=DestroyQuantumInfo(quantum_info);
1186 if (status == MagickFalse)
1187 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
1188 SetQuantumImageType(image,quantum_type);
1195 Convert PFM raster image to pixel packets.
1197 quantum_type=format == 'f' ? GrayQuantum : RGBQuantum;
1198 image->endian=quantum_scale < 0.0 ? LSBEndian : MSBEndian;
1200 quantum_info=AcquireQuantumInfo(image_info,image);
1201 if (quantum_info == (QuantumInfo *) NULL)
1202 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
1203 status=SetQuantumDepth(image,quantum_info,32);
1204 if (status == MagickFalse)
1205 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
1206 status=SetQuantumFormat(image,quantum_info,FloatingPointQuantumFormat);
1207 if (status == MagickFalse)
1208 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
1209 SetQuantumScale(quantum_info,(MagickRealType) QuantumRange*
1210 fabs(quantum_scale));
1211 extent=GetQuantumExtent(image,quantum_info,quantum_type);
1212 image_view=AcquireCacheView(image);
1213 #if defined(MAGICKCORE_OPENMP_SUPPORT) && (_OPENMP > 200505)
1214 #pragma omp parallel for schedule(dynamic,1) shared(row,status,quantum_type)
1216 for (y=0; y < (long) image->rows; y++)
1224 register PixelPacket
1236 if (status == MagickFalse)
1238 pixels=GetQuantumPixels(quantum_info);
1239 #if defined(MAGICKCORE_OPENMP_SUPPORT) && (_OPENMP > 200505)
1240 #pragma omp critical (MagickCore_ReadPNMImage)
1243 count=ReadBlob(image,extent,pixels);
1244 if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
1245 (image->previous == (Image *) NULL))
1250 proceed=SetImageProgress(image,LoadImageTag,row,image->rows);
1251 if (proceed == MagickFalse)
1256 if ((size_t) count != extent)
1258 q=QueueCacheViewAuthenticPixels(image_view,0,(long) (image->rows-
1259 offset-1),image->columns,1,exception);
1260 if (q == (PixelPacket *) NULL)
1265 length=ImportQuantumPixels(image,image_view,quantum_info,quantum_type,
1267 if (length != extent)
1269 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1270 if (sync == MagickFalse)
1273 image_view=DestroyCacheView(image_view);
1274 quantum_info=DestroyQuantumInfo(quantum_info);
1275 if (status == MagickFalse)
1276 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
1277 SetQuantumImageType(image,quantum_type);
1281 ThrowReaderException(CorruptImageError,"ImproperImageHeader");
1283 if (EOFBlob(image) != MagickFalse)
1284 (void) ThrowMagickException(exception,GetMagickModule(),CorruptImageError,
1285 "UnexpectedEndOfFile","`%s'",image->filename);
1287 Proceed to next image.
1289 if (image_info->number_scenes != 0)
1290 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
1292 if ((format == '1') || (format == '2') || (format == '3'))
1296 Skip to end of line.
1298 count=ReadBlob(image,1,(unsigned char *) &format);
1301 if ((count != 0) && (format == 'P'))
1303 } while (format != '\n');
1304 count=ReadBlob(image,1,(unsigned char *) &format);
1305 if ((count == 1) && (format == 'P'))
1308 Allocate next image structure.
1310 AcquireNextImage(image_info,image);
1311 if (GetNextImageInList(image) == (Image *) NULL)
1313 image=DestroyImageList(image);
1314 return((Image *) NULL);
1316 image=SyncNextImageInList(image);
1317 status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
1318 GetBlobSize(image));
1319 if (status == MagickFalse)
1322 } while ((count == 1) && (format == 'P'));
1323 (void) CloseBlob(image);
1324 return(GetFirstImageInList(image));
1328 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1332 % R e g i s t e r P N M I m a g e %
1336 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1338 % RegisterPNMImage() adds properties for the PNM image format to
1339 % the list of supported formats. The properties include the image format
1340 % tag, a method to read and/or write the format, whether the format
1341 % supports the saving of more than one frame to the same file or blob,
1342 % whether the format supports native in-memory I/O, and a brief
1343 % description of the format.
1345 % The format of the RegisterPNMImage method is:
1347 % unsigned long RegisterPNMImage(void)
1350 ModuleExport unsigned long RegisterPNMImage(void)
1355 entry=SetMagickInfo("PAM");
1356 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1357 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1358 entry->description=ConstantString("Common 2-dimensional bitmap format");
1359 entry->module=ConstantString("PNM");
1360 (void) RegisterMagickInfo(entry);
1361 entry=SetMagickInfo("PBM");
1362 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1363 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1364 entry->description=ConstantString("Portable bitmap format (black and white)");
1365 entry->module=ConstantString("PNM");
1366 (void) RegisterMagickInfo(entry);
1367 entry=SetMagickInfo("PFM");
1368 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1369 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1370 entry->description=ConstantString("Portable float format");
1371 entry->module=ConstantString("PFM");
1372 (void) RegisterMagickInfo(entry);
1373 entry=SetMagickInfo("PGM");
1374 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1375 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1376 entry->description=ConstantString("Portable graymap format (gray scale)");
1377 entry->module=ConstantString("PNM");
1378 (void) RegisterMagickInfo(entry);
1379 entry=SetMagickInfo("PNM");
1380 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1381 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1382 entry->magick=(IsImageFormatHandler *) IsPNM;
1383 entry->description=ConstantString("Portable anymap");
1384 entry->module=ConstantString("PNM");
1385 (void) RegisterMagickInfo(entry);
1386 entry=SetMagickInfo("PPM");
1387 entry->decoder=(DecodeImageHandler *) ReadPNMImage;
1388 entry->encoder=(EncodeImageHandler *) WritePNMImage;
1389 entry->description=ConstantString("Portable pixmap format (color)");
1390 entry->module=ConstantString("PNM");
1391 (void) RegisterMagickInfo(entry);
1392 return(MagickImageCoderSignature);
1396 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1400 % U n r e g i s t e r P N M I m a g e %
1404 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1406 % UnregisterPNMImage() removes format registrations made by the
1407 % PNM module from the list of supported formats.
1409 % The format of the UnregisterPNMImage method is:
1411 % UnregisterPNMImage(void)
1414 ModuleExport void UnregisterPNMImage(void)
1416 (void) UnregisterMagickInfo("PAM");
1417 (void) UnregisterMagickInfo("PBM");
1418 (void) UnregisterMagickInfo("PGM");
1419 (void) UnregisterMagickInfo("PNM");
1420 (void) UnregisterMagickInfo("PPM");
1424 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1428 % W r i t e P N M I m a g e %
1432 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1434 % Procedure WritePNMImage() writes an image to a file in the PNM rasterfile
1437 % The format of the WritePNMImage method is:
1439 % MagickBooleanType WritePNMImage(const ImageInfo *image_info,Image *image)
1441 % A description of each parameter follows.
1443 % o image_info: the image info.
1445 % o image: The image.
1448 static MagickBooleanType WritePNMImage(const ImageInfo *image_info,Image *image)
1451 buffer[MaxTextExtent],
1453 magick[MaxTextExtent];
1482 register unsigned char
1494 Open output image file.
1496 assert(image_info != (const ImageInfo *) NULL);
1497 assert(image_info->signature == MagickSignature);
1498 assert(image != (Image *) NULL);
1499 assert(image->signature == MagickSignature);
1500 if (image->debug != MagickFalse)
1501 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1502 status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
1503 if (status == MagickFalse)
1509 Write PNM file header.
1512 quantum_type=RGBQuantum;
1513 (void) CopyMagickString(magick,image_info->magick,MaxTextExtent);
1526 if (image_info->compression == NoCompression)
1534 if (IsGrayImage(image,&image->exception) != MagickFalse)
1542 if (image_info->compression == NoCompression)
1549 if ((image_info->type != TrueColorType) &&
1550 (IsGrayImage(image,&image->exception) != MagickFalse))
1553 if (image_info->compression == NoCompression)
1555 if (IsMonochromeImage(image,&image->exception) != MagickFalse)
1558 if (image_info->compression == NoCompression)
1567 if (image_info->compression == NoCompression)
1572 (void) FormatMagickString(buffer,MaxTextExtent,"P%c\n",format);
1573 (void) WriteBlobString(image,buffer);
1574 value=GetImageProperty(image,"comment");
1575 if (value != (const char *) NULL)
1581 Write comments to file.
1583 (void) WriteBlobByte(image,'#');
1584 for (p=value; *p != '\0'; p++)
1586 (void) WriteBlobByte(image,(unsigned char) *p);
1587 if ((*p == '\r') && (*(p+1) != '\0'))
1588 (void) WriteBlobByte(image,'#');
1589 if ((*p == '\n') && (*(p+1) != '\0'))
1590 (void) WriteBlobByte(image,'#');
1592 (void) WriteBlobByte(image,'\n');
1596 if (image->colorspace != RGBColorspace)
1597 (void) TransformImageColorspace(image,RGBColorspace);
1598 (void) FormatMagickString(buffer,MaxTextExtent,"%lu %lu\n",
1599 image->columns,image->rows);
1600 (void) WriteBlobString(image,buffer);
1605 type[MaxTextExtent];
1610 (void) FormatMagickString(buffer,MaxTextExtent,
1611 "WIDTH %lu\nHEIGHT %lu\n",image->columns,image->rows);
1612 (void) WriteBlobString(image,buffer);
1613 quantum_type=GetQuantumType(image,&image->exception);
1614 switch (quantum_type)
1620 (void) CopyMagickString(type,"CMYK",MaxTextExtent);
1624 case GrayAlphaQuantum:
1627 (void) CopyMagickString(type,"GRAYSCALE",MaxTextExtent);
1632 quantum_type=RGBQuantum;
1633 if (image->matte != MagickFalse)
1634 quantum_type=RGBAQuantum;
1636 (void) CopyMagickString(type,"RGB",MaxTextExtent);
1640 if (image->matte != MagickFalse)
1643 (void) ConcatenateMagickString(type,"_ALPHA",MaxTextExtent);
1645 if (image->depth > 16)
1647 (void) FormatMagickString(buffer,MaxTextExtent,
1648 "DEPTH %lu\nMAXVAL %lu\n",(unsigned long) packet_size,(unsigned long)
1649 GetQuantumRange(image->depth));
1650 (void) WriteBlobString(image,buffer);
1651 (void) FormatMagickString(buffer,MaxTextExtent,"TUPLTYPE %s\nENDHDR\n",
1653 (void) WriteBlobString(image,buffer);
1656 Convert runextent encoded to PNM raster pixels.
1666 Convert image to a PBM image.
1669 for (y=0; y < (long) image->rows; y++)
1671 register const IndexPacket
1672 *__restrict indexes;
1674 register const PixelPacket
1680 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1681 if (p == (const PixelPacket *) NULL)
1683 indexes=GetVirtualIndexQueue(image);
1684 for (x=0; x < (long) image->columns; x++)
1686 pixel=PixelIntensityToQuantum(p);
1687 *q++=(unsigned char) (pixel >= (Quantum) (QuantumRange/2) ?
1690 if ((q-pixels+2) >= 80)
1693 (void) WriteBlob(image,q-pixels,pixels);
1699 if (image->previous == (Image *) NULL)
1701 status=SetImageProgress(image,SaveImageTag,y,image->rows);
1702 if (status == MagickFalse)
1709 (void) WriteBlob(image,q-pixels,pixels);
1719 Convert image to a PGM image.
1721 if (image->depth <= 8)
1722 (void) WriteBlobString(image,"255\n");
1724 (void) WriteBlobString(image,"65535\n");
1726 for (y=0; y < (long) image->rows; y++)
1728 register const PixelPacket
1734 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1735 if (p == (const PixelPacket *) NULL)
1737 for (x=0; x < (long) image->columns; x++)
1739 index=PixelIntensityToQuantum(p);
1740 if (image->depth <= 8)
1741 count=(ssize_t) FormatMagickString(buffer,MaxTextExtent,"%u ",
1742 ScaleQuantumToChar(index));
1744 count=(ssize_t) FormatMagickString(buffer,MaxTextExtent,"%u ",
1745 ScaleQuantumToShort(index));
1746 extent=(size_t) count;
1747 (void) strncpy((char *) q,buffer,extent);
1749 if ((q-pixels+extent) >= 80)
1752 (void) WriteBlob(image,q-pixels,pixels);
1757 if (image->previous == (Image *) NULL)
1759 status=SetImageProgress(image,SaveImageTag,y,image->rows);
1760 if (status == MagickFalse)
1767 (void) WriteBlob(image,q-pixels,pixels);
1777 Convert image to a PNM image.
1779 if (image->depth <= 8)
1780 (void) WriteBlobString(image,"255\n");
1782 (void) WriteBlobString(image,"65535\n");
1784 for (y=0; y < (long) image->rows; y++)
1786 register const PixelPacket
1792 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1793 if (p == (const PixelPacket *) NULL)
1795 for (x=0; x < (long) image->columns; x++)
1797 if (image->depth <= 8)
1798 count=(ssize_t) FormatMagickString(buffer,MaxTextExtent,
1799 "%u %u %u ",ScaleQuantumToChar(p->red),
1800 ScaleQuantumToChar(p->green),ScaleQuantumToChar(p->blue));
1802 count=(ssize_t) FormatMagickString(buffer,MaxTextExtent,
1803 "%u %u %u ",ScaleQuantumToShort(p->red),
1804 ScaleQuantumToShort(p->green),ScaleQuantumToShort(p->blue));
1805 extent=(size_t) count;
1806 (void) strncpy((char *) q,buffer,extent);
1808 if ((q-pixels+extent) >= 80)
1811 (void) WriteBlob(image,q-pixels,pixels);
1816 if (image->previous == (Image *) NULL)
1818 status=SetImageProgress(image,SaveImageTag,y,image->rows);
1819 if (status == MagickFalse)
1826 (void) WriteBlob(image,q-pixels,pixels);
1833 Convert image to a PBM image.
1836 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
1837 if (quantum_info == (QuantumInfo *) NULL)
1838 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1839 quantum_info->min_is_white=MagickTrue;
1840 pixels=GetQuantumPixels(quantum_info);
1841 for (y=0; y < (long) image->rows; y++)
1843 register const PixelPacket
1846 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1847 if (p == (const PixelPacket *) NULL)
1849 extent=ExportQuantumPixels(image,(const CacheView *) NULL,
1850 quantum_info,GrayQuantum,pixels,&image->exception);
1851 count=WriteBlob(image,extent,pixels);
1852 if (count != (ssize_t) extent)
1854 if (image->previous == (Image *) NULL)
1856 status=SetImageProgress(image,SaveImageTag,y,image->rows);
1857 if (status == MagickFalse)
1861 quantum_info=DestroyQuantumInfo(quantum_info);
1870 Convert image to a PGM image.
1872 if (image->depth > 8)
1874 (void) FormatMagickString(buffer,MaxTextExtent,"%lu\n",(unsigned long)
1875 GetQuantumRange(image->depth));
1876 (void) WriteBlobString(image,buffer);
1877 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
1878 if (quantum_info == (QuantumInfo *) NULL)
1879 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1880 quantum_info->min_is_white=MagickTrue;
1881 pixels=GetQuantumPixels(quantum_info);
1882 extent=GetQuantumExtent(image,quantum_info,GrayQuantum);
1883 range=GetQuantumRange(image->depth);
1884 for (y=0; y < (long) image->rows; y++)
1886 register const PixelPacket
1892 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1893 if (p == (const PixelPacket *) NULL)
1896 if ((image->depth == 8) || (image->depth == 16))
1897 extent=ExportQuantumPixels(image,(const CacheView *) NULL,
1898 quantum_info,GrayQuantum,pixels,&image->exception);
1901 if (image->depth <= 8)
1902 for (x=0; x < (long) image->columns; x++)
1904 if (IsGrayPixel(p) == MagickFalse)
1905 pixel=ScaleQuantumToAny(PixelIntensityToQuantum(p),range);
1908 if (image->depth == 8)
1909 pixel=ScaleQuantumToChar(p->red);
1911 pixel=ScaleQuantumToAny(p->red,range);
1913 q=PopCharPixel((unsigned char) pixel,q);
1917 for (x=0; x < (long) image->columns; x++)
1919 if (IsGrayPixel(p) == MagickFalse)
1920 pixel=ScaleQuantumToAny(PixelIntensityToQuantum(p),range);
1923 if (image->depth == 16)
1924 pixel=ScaleQuantumToShort(p->red);
1926 pixel=ScaleQuantumToAny(p->red,range);
1928 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
1931 extent=(size_t) (q-pixels);
1933 count=WriteBlob(image,extent,pixels);
1934 if (count != (ssize_t) extent)
1936 if (image->previous == (Image *) NULL)
1938 status=SetImageProgress(image,SaveImageTag,y,image->rows);
1939 if (status == MagickFalse)
1943 quantum_info=DestroyQuantumInfo(quantum_info);
1952 Convert image to a PNM image.
1954 if (image->depth > 8)
1956 (void) FormatMagickString(buffer,MaxTextExtent,"%lu\n",(unsigned long)
1957 GetQuantumRange(image->depth));
1958 (void) WriteBlobString(image,buffer);
1959 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
1960 if (quantum_info == (QuantumInfo *) NULL)
1961 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1962 pixels=GetQuantumPixels(quantum_info);
1963 extent=GetQuantumExtent(image,quantum_info,quantum_type);
1964 range=GetQuantumRange(image->depth);
1965 for (y=0; y < (long) image->rows; y++)
1967 register const PixelPacket
1973 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1974 if (p == (const PixelPacket *) NULL)
1977 if ((image->depth == 8) || (image->depth == 16))
1978 extent=ExportQuantumPixels(image,(const CacheView *) NULL,
1979 quantum_info,quantum_type,pixels,&image->exception);
1982 if (image->depth <= 8)
1983 for (x=0; x < (long) image->columns; x++)
1985 pixel=ScaleQuantumToAny(p->red,range);
1986 q=PopCharPixel((unsigned char) pixel,q);
1987 pixel=ScaleQuantumToAny(p->green,range);
1988 q=PopCharPixel((unsigned char) pixel,q);
1989 pixel=ScaleQuantumToAny(p->blue,range);
1990 q=PopCharPixel((unsigned char) pixel,q);
1991 if (image->matte != MagickFalse)
1993 pixel=ScaleQuantumToAny((Quantum) (QuantumRange-
1995 q=PopCharPixel((unsigned char) pixel,q);
2000 for (x=0; x < (long) image->columns; x++)
2002 pixel=ScaleQuantumToAny(p->red,range);
2003 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2004 pixel=ScaleQuantumToAny(p->green,range);
2005 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2006 pixel=ScaleQuantumToAny(p->blue,range);
2007 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2008 if (image->matte != MagickFalse)
2010 pixel=ScaleQuantumToAny((Quantum) (QuantumRange-
2012 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2016 extent=(size_t) (q-pixels);
2018 count=WriteBlob(image,extent,pixels);
2019 if (count != (ssize_t) extent)
2021 if (image->previous == (Image *) NULL)
2023 status=SetImageProgress(image,SaveImageTag,y,image->rows);
2024 if (status == MagickFalse)
2028 quantum_info=DestroyQuantumInfo(quantum_info);
2037 Convert image to a PAM.
2039 if (image->depth > 16)
2041 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
2042 pixels=GetQuantumPixels(quantum_info);
2043 range=GetQuantumRange(image->depth);
2044 for (y=0; y < (long) image->rows; y++)
2046 register const IndexPacket
2047 *__restrict indexes;
2049 register const PixelPacket
2055 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
2056 if (p == (const PixelPacket *) NULL)
2058 indexes=GetVirtualIndexQueue(image);
2060 if ((image->depth == 8) || (image->depth == 16))
2061 extent=ExportQuantumPixels(image,(const CacheView *) NULL,
2062 quantum_info,quantum_type,pixels,&image->exception);
2065 switch (quantum_type)
2068 case GrayAlphaQuantum:
2070 if (image->depth <= 8)
2071 for (x=0; x < (long) image->columns; x++)
2073 pixel=ScaleQuantumToAny(PixelIntensityToQuantum(p),range);
2074 q=PopCharPixel((unsigned char) pixel,q);
2075 if (image->matte != MagickFalse)
2077 pixel=(unsigned char) ScaleQuantumToAny(p->opacity,
2079 q=PopCharPixel((unsigned char) pixel,q);
2084 for (x=0; x < (long) image->columns; x++)
2086 pixel=ScaleQuantumToAny(PixelIntensityToQuantum(p),range);
2087 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2088 if (image->matte != MagickFalse)
2090 pixel=(unsigned char) ScaleQuantumToAny(p->opacity,
2092 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2101 if (image->depth <= 8)
2102 for (x=0; x < (long) image->columns; x++)
2104 pixel=ScaleQuantumToAny(p->red,range);
2105 q=PopCharPixel((unsigned char) pixel,q);
2106 pixel=ScaleQuantumToAny(p->green,range);
2107 q=PopCharPixel((unsigned char) pixel,q);
2108 pixel=ScaleQuantumToAny(p->blue,range);
2109 q=PopCharPixel((unsigned char) pixel,q);
2110 pixel=ScaleQuantumToAny(indexes[x],range);
2111 q=PopCharPixel((unsigned char) pixel,q);
2112 if (image->matte != MagickFalse)
2114 pixel=ScaleQuantumToAny((Quantum) (QuantumRange-
2116 q=PopCharPixel((unsigned char) pixel,q);
2121 for (x=0; x < (long) image->columns; x++)
2123 pixel=ScaleQuantumToAny(p->red,range);
2124 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2125 pixel=ScaleQuantumToAny(p->green,range);
2126 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2127 pixel=ScaleQuantumToAny(p->blue,range);
2128 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2129 pixel=ScaleQuantumToAny(indexes[x],range);
2130 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2131 if (image->matte != MagickFalse)
2133 pixel=ScaleQuantumToAny((Quantum) (QuantumRange-
2135 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2143 if (image->depth <= 8)
2144 for (x=0; x < (long) image->columns; x++)
2146 pixel=ScaleQuantumToAny(p->red,range);
2147 q=PopCharPixel((unsigned char) pixel,q);
2148 pixel=ScaleQuantumToAny(p->green,range);
2149 q=PopCharPixel((unsigned char) pixel,q);
2150 pixel=ScaleQuantumToAny(p->blue,range);
2151 q=PopCharPixel((unsigned char) pixel,q);
2152 if (image->matte != MagickFalse)
2154 pixel=ScaleQuantumToAny((Quantum) (QuantumRange-
2156 q=PopCharPixel((unsigned char) pixel,q);
2161 for (x=0; x < (long) image->columns; x++)
2163 pixel=ScaleQuantumToAny(p->red,range);
2164 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2165 pixel=ScaleQuantumToAny(p->green,range);
2166 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2167 pixel=ScaleQuantumToAny(p->blue,range);
2168 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2169 if (image->matte != MagickFalse)
2171 pixel=ScaleQuantumToAny((Quantum) (QuantumRange-
2173 q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
2180 extent=(size_t) (q-pixels);
2182 count=WriteBlob(image,extent,pixels);
2183 if (count != (ssize_t) extent)
2185 if (image->previous == (Image *) NULL)
2187 status=SetImageProgress(image,SaveImageTag,y,image->rows);
2188 if (status == MagickFalse)
2192 quantum_info=DestroyQuantumInfo(quantum_info);
2198 (void) WriteBlobString(image,image->endian != LSBEndian ? "1.0\n" :
2201 quantum_type=format == 'f' ? GrayQuantum : RGBQuantum;
2202 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
2203 if (quantum_info == (QuantumInfo *) NULL)
2204 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
2205 status=SetQuantumFormat(image,quantum_info,FloatingPointQuantumFormat);
2206 if (status == MagickFalse)
2207 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
2208 pixels=GetQuantumPixels(quantum_info);
2209 for (y=(long) image->rows-1; y >= 0; y--)
2211 register const PixelPacket
2214 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
2215 if (p == (const PixelPacket *) NULL)
2217 extent=ExportQuantumPixels(image,(const CacheView *) NULL,
2218 quantum_info,quantum_type,pixels,&image->exception);
2219 (void) WriteBlob(image,extent,pixels);
2220 if (image->previous == (Image *) NULL)
2222 status=SetImageProgress(image,SaveImageTag,y,image->rows);
2223 if (status == MagickFalse)
2227 quantum_info=DestroyQuantumInfo(quantum_info);
2231 if (GetNextImageInList(image) == (Image *) NULL)
2233 image=SyncNextImageInList(image);
2234 status=SetImageProgress(image,SaveImagesTag,scene++,
2235 GetImageListLength(image));
2236 if (status == MagickFalse)
2238 } while (image_info->adjoin != MagickFalse);
2239 (void) CloseBlob(image);