Home | History | Annotate | Download | only in coders
      1 /*
      2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      3 %                                                                             %
      4 %                                                                             %
      5 %                                                                             %
      6 %                            PPPP   N   N  M   M                              %
      7 %                            P   P  NN  N  MM MM                              %
      8 %                            PPPP   N N N  M M M                              %
      9 %                            P      N  NN  M   M                              %
     10 %                            P      N   N  M   M                              %
     11 %                                                                             %
     12 %                                                                             %
     13 %               Read/Write PBMPlus Portable Anymap Image Format               %
     14 %                                                                             %
     15 %                              Software Design                                %
     16 %                                   Cristy                                    %
     17 %                                 July 1992                                   %
     18 %                                                                             %
     19 %                                                                             %
     20 %  Copyright 1999-2019 ImageMagick Studio LLC, a non-profit organization      %
     21 %  dedicated to making software imaging solutions freely available.           %
     22 %                                                                             %
     23 %  You may not use this file except in compliance with the License.  You may  %
     24 %  obtain a copy of the License at                                            %
     25 %                                                                             %
     26 %    https://imagemagick.org/script/license.php                               %
     27 %                                                                             %
     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.                                             %
     33 %                                                                             %
     34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     35 %
     36 %
     37 */
     38 
     39 /*
     41   Include declarations.
     42 */
     43 #include "MagickCore/studio.h"
     44 #include "MagickCore/attribute.h"
     45 #include "MagickCore/blob.h"
     46 #include "MagickCore/blob-private.h"
     47 #include "MagickCore/cache.h"
     48 #include "MagickCore/color.h"
     49 #include "MagickCore/color-private.h"
     50 #include "MagickCore/colorspace.h"
     51 #include "MagickCore/colorspace-private.h"
     52 #include "MagickCore/exception.h"
     53 #include "MagickCore/exception-private.h"
     54 #include "MagickCore/image.h"
     55 #include "MagickCore/image-private.h"
     56 #include "MagickCore/list.h"
     57 #include "MagickCore/magick.h"
     58 #include "MagickCore/memory_.h"
     59 #include "MagickCore/module.h"
     60 #include "MagickCore/monitor.h"
     61 #include "MagickCore/monitor-private.h"
     62 #include "MagickCore/pixel-accessor.h"
     63 #include "MagickCore/property.h"
     64 #include "MagickCore/quantum-private.h"
     65 #include "MagickCore/static.h"
     66 #include "MagickCore/statistic.h"
     67 #include "MagickCore/string_.h"
     68 #include "MagickCore/string-private.h"
     69 
     70 /*
     72   Typedef declarations.
     73 */
     74 typedef struct _CommentInfo
     75 {
     76   char
     77     *comment;
     78 
     79   size_t
     80     extent;
     81 } CommentInfo;
     82 
     83 /*
     85   Forward declarations.
     86 */
     87 static MagickBooleanType
     88   WritePNMImage(const ImageInfo *,Image *,ExceptionInfo *);
     89 
     90 /*
     92 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     93 %                                                                             %
     94 %                                                                             %
     95 %                                                                             %
     96 %   I s P N M                                                                 %
     97 %                                                                             %
     98 %                                                                             %
     99 %                                                                             %
    100 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    101 %
    102 %  IsPNM() returns MagickTrue if the image format type, identified by the
    103 %  magick string, is PNM.
    104 %
    105 %  The format of the IsPNM method is:
    106 %
    107 %      MagickBooleanType IsPNM(const unsigned char *magick,const size_t extent)
    108 %
    109 %  A description of each parameter follows:
    110 %
    111 %    o magick: compare image format pattern against these bytes.
    112 %
    113 %    o extent: Specifies the extent of the magick string.
    114 %
    115 */
    116 static MagickBooleanType IsPNM(const unsigned char *magick,const size_t extent)
    117 {
    118   if (extent < 2)
    119     return(MagickFalse);
    120   if ((*magick == (unsigned char) 'P') &&
    121       ((magick[1] == '1') || (magick[1] == '2') || (magick[1] == '3') ||
    122        (magick[1] == '4') || (magick[1] == '5') || (magick[1] == '6') ||
    123        (magick[1] == '7') || (magick[1] == 'F') || (magick[1] == 'f')))
    124     return(MagickTrue);
    125   return(MagickFalse);
    126 }
    127 
    128 /*
    130 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    131 %                                                                             %
    132 %                                                                             %
    133 %                                                                             %
    134 %   R e a d P N M I m a g e                                                   %
    135 %                                                                             %
    136 %                                                                             %
    137 %                                                                             %
    138 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    139 %
    140 %  ReadPNMImage() reads a Portable Anymap image file and returns it.
    141 %  It allocates the memory necessary for the new Image structure and returns
    142 %  a pointer to the new image.
    143 %
    144 %  The format of the ReadPNMImage method is:
    145 %
    146 %      Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception)
    147 %
    148 %  A description of each parameter follows:
    149 %
    150 %    o image_info: the image info.
    151 %
    152 %    o exception: return any errors or warnings in this structure.
    153 %
    154 */
    155 
    156 static int PNMComment(Image *image,CommentInfo *comment_info,
    157   ExceptionInfo *exception)
    158 {
    159   int
    160     c;
    161 
    162   register char
    163     *p;
    164 
    165   /*
    166     Read comment.
    167   */
    168   p=comment_info->comment+strlen(comment_info->comment);
    169   for (c='#'; (c != EOF) && (c != (int) '\n') && (c != (int) '\r'); p++)
    170   {
    171     if ((size_t) (p-comment_info->comment+1) >= comment_info->extent)
    172       {
    173         comment_info->extent<<=1;
    174         comment_info->comment=(char *) ResizeQuantumMemory(
    175           comment_info->comment,comment_info->extent,
    176           sizeof(*comment_info->comment));
    177         if (comment_info->comment == (char *) NULL)
    178           return(-1);
    179         p=comment_info->comment+strlen(comment_info->comment);
    180       }
    181     c=ReadBlobByte(image);
    182     if (c != EOF)
    183       {
    184         *p=(char) c;
    185         *(p+1)='\0';
    186       }
    187   }
    188   return(c);
    189 }
    190 
    191 static unsigned int PNMInteger(Image *image,CommentInfo *comment_info,
    192   const unsigned int base,ExceptionInfo *exception)
    193 {
    194   int
    195     c;
    196 
    197   unsigned int
    198     value;
    199 
    200   /*
    201     Skip any leading whitespace.
    202   */
    203   do
    204   {
    205     c=ReadBlobByte(image);
    206     if (c == EOF)
    207       return(0);
    208     if (c == (int) '#')
    209       c=PNMComment(image,comment_info,exception);
    210   } while ((c == ' ') || (c == '\t') || (c == '\n') || (c == '\r'));
    211   if (base == 2)
    212     return((unsigned int) (c-(int) '0'));
    213   /*
    214     Evaluate number.
    215   */
    216   value=0;
    217   while (isdigit(c) != 0)
    218   {
    219     if (value <= (unsigned int) (INT_MAX/10))
    220       {
    221         value*=10;
    222         if (value <= (unsigned int) (INT_MAX-(c-(int) '0')))
    223           value+=c-(int) '0';
    224       }
    225     c=ReadBlobByte(image);
    226     if (c == EOF)
    227       return(0);
    228   }
    229   if (c == (int) '#')
    230     c=PNMComment(image,comment_info,exception);
    231   return(value);
    232 }
    233 
    234 static Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception)
    235 {
    236 #define ThrowPNMException(exception,message) \
    237 { \
    238   if (comment_info.comment != (char *) NULL)  \
    239     comment_info.comment=DestroyString(comment_info.comment); \
    240   ThrowReaderException((exception),(message)); \
    241 }
    242 
    243   char
    244     format;
    245 
    246   CommentInfo
    247     comment_info;
    248 
    249   double
    250     quantum_scale;
    251 
    252   Image
    253     *image;
    254 
    255   MagickBooleanType
    256     status;
    257 
    258   QuantumAny
    259     max_value;
    260 
    261   QuantumInfo
    262     *quantum_info;
    263 
    264   QuantumType
    265     quantum_type;
    266 
    267   size_t
    268     depth,
    269     extent,
    270     packet_size;
    271 
    272   ssize_t
    273     count,
    274     row,
    275     y;
    276 
    277   /*
    278     Open image file.
    279   */
    280   assert(image_info != (const ImageInfo *) NULL);
    281   assert(image_info->signature == MagickCoreSignature);
    282   if (image_info->debug != MagickFalse)
    283     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
    284       image_info->filename);
    285   assert(exception != (ExceptionInfo *) NULL);
    286   assert(exception->signature == MagickCoreSignature);
    287   image=AcquireImage(image_info,exception);
    288   status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
    289   if (status == MagickFalse)
    290     {
    291       image=DestroyImageList(image);
    292       return((Image *) NULL);
    293     }
    294   /*
    295     Read PNM image.
    296   */
    297   count=ReadBlob(image,1,(unsigned char *) &format);
    298   do
    299   {
    300     /*
    301       Initialize image structure.
    302     */
    303     comment_info.comment=AcquireString(NULL);
    304     comment_info.extent=MagickPathExtent;
    305     if ((count != 1) || (format != 'P'))
    306       ThrowPNMException(CorruptImageError,"ImproperImageHeader");
    307     max_value=1;
    308     quantum_type=RGBQuantum;
    309     quantum_scale=1.0;
    310     format=(char) ReadBlobByte(image);
    311     if (format != '7')
    312       {
    313         /*
    314           PBM, PGM, PPM, and PNM.
    315         */
    316         image->columns=(size_t) PNMInteger(image,&comment_info,10,exception);
    317         image->rows=(size_t) PNMInteger(image,&comment_info,10,exception);
    318         if ((format == 'f') || (format == 'F'))
    319           {
    320             char
    321               scale[MagickPathExtent];
    322 
    323             if (ReadBlobString(image,scale) != (char *) NULL)
    324               quantum_scale=StringToDouble(scale,(char **) NULL);
    325           }
    326         else
    327           {
    328             if ((format == '1') || (format == '4'))
    329               max_value=1;  /* bitmap */
    330             else
    331               max_value=(QuantumAny) PNMInteger(image,&comment_info,10,
    332                 exception);
    333           }
    334       }
    335     else
    336       {
    337         char
    338           keyword[MagickPathExtent],
    339           value[MagickPathExtent];
    340 
    341         int
    342           c;
    343 
    344         register char
    345           *p;
    346 
    347         /*
    348           PAM.
    349         */
    350         for (c=ReadBlobByte(image); c != EOF; c=ReadBlobByte(image))
    351         {
    352           while (isspace((int) ((unsigned char) c)) != 0)
    353             c=ReadBlobByte(image);
    354           if (c == '#')
    355             {
    356               /*
    357                 Comment.
    358               */
    359               c=PNMComment(image,&comment_info,exception);
    360               c=ReadBlobByte(image);
    361               while (isspace((int) ((unsigned char) c)) != 0)
    362                 c=ReadBlobByte(image);
    363             }
    364           p=keyword;
    365           do
    366           {
    367             if ((size_t) (p-keyword) < (MagickPathExtent-1))
    368               *p++=c;
    369             c=ReadBlobByte(image);
    370           } while (isalnum(c));
    371           *p='\0';
    372           if (LocaleCompare(keyword,"endhdr") == 0)
    373             break;
    374           while (isspace((int) ((unsigned char) c)) != 0)
    375             c=ReadBlobByte(image);
    376           p=value;
    377           while (isalnum(c) || (c == '_'))
    378           {
    379             if ((size_t) (p-value) < (MagickPathExtent-1))
    380               *p++=c;
    381             c=ReadBlobByte(image);
    382           }
    383           *p='\0';
    384           /*
    385             Assign a value to the specified keyword.
    386           */
    387           if (LocaleCompare(keyword,"depth") == 0)
    388             packet_size=StringToUnsignedLong(value);
    389           (void) packet_size;
    390           if (LocaleCompare(keyword,"height") == 0)
    391             image->rows=StringToUnsignedLong(value);
    392           if (LocaleCompare(keyword,"maxval") == 0)
    393             max_value=StringToUnsignedLong(value);
    394           if (LocaleCompare(keyword,"TUPLTYPE") == 0)
    395             {
    396               if (LocaleCompare(value,"BLACKANDWHITE") == 0)
    397                 {
    398                   (void) SetImageColorspace(image,GRAYColorspace,exception);
    399                   quantum_type=GrayQuantum;
    400                 }
    401               if (LocaleCompare(value,"BLACKANDWHITE_ALPHA") == 0)
    402                 {
    403                   (void) SetImageColorspace(image,GRAYColorspace,exception);
    404                   image->alpha_trait=BlendPixelTrait;
    405                   quantum_type=GrayAlphaQuantum;
    406                 }
    407               if (LocaleCompare(value,"GRAYSCALE") == 0)
    408                 {
    409                   quantum_type=GrayQuantum;
    410                   (void) SetImageColorspace(image,GRAYColorspace,exception);
    411                 }
    412               if (LocaleCompare(value,"GRAYSCALE_ALPHA") == 0)
    413                 {
    414                   (void) SetImageColorspace(image,GRAYColorspace,exception);
    415                   image->alpha_trait=BlendPixelTrait;
    416                   quantum_type=GrayAlphaQuantum;
    417                 }
    418               if (LocaleCompare(value,"RGB_ALPHA") == 0)
    419                 {
    420                   image->alpha_trait=BlendPixelTrait;
    421                   quantum_type=RGBAQuantum;
    422                 }
    423               if (LocaleCompare(value,"CMYK") == 0)
    424                 {
    425                   (void) SetImageColorspace(image,CMYKColorspace,exception);
    426                   quantum_type=CMYKQuantum;
    427                 }
    428               if (LocaleCompare(value,"CMYK_ALPHA") == 0)
    429                 {
    430                   (void) SetImageColorspace(image,CMYKColorspace,exception);
    431                   image->alpha_trait=BlendPixelTrait;
    432                   quantum_type=CMYKAQuantum;
    433                 }
    434             }
    435           if (LocaleCompare(keyword,"width") == 0)
    436             image->columns=StringToUnsignedLong(value);
    437         }
    438       }
    439     if ((image->columns == 0) || (image->rows == 0))
    440       ThrowPNMException(CorruptImageError,"NegativeOrZeroImageSize");
    441     if ((max_value == 0) || (max_value > 4294967295UL))
    442       ThrowPNMException(CorruptImageError,"ImproperImageHeader");
    443     for (depth=1; GetQuantumRange(depth) < max_value; depth++) ;
    444     image->depth=depth;
    445     if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
    446       if (image->scene >= (image_info->scene+image_info->number_scenes-1))
    447         break;
    448     if ((MagickSizeType) (image->columns*image->rows/8) > GetBlobSize(image))
    449       ThrowPNMException(CorruptImageError,"InsufficientImageDataInFile");
    450     status=SetImageExtent(image,image->columns,image->rows,exception);
    451     if (status == MagickFalse)
    452       {
    453         comment_info.comment=DestroyString(comment_info.comment); \
    454         return(DestroyImageList(image));
    455       }
    456     (void) SetImageBackgroundColor(image,exception);
    457     /*
    458       Convert PNM pixels to runextent-encoded MIFF packets.
    459     */
    460     row=0;
    461     y=0;
    462     switch (format)
    463     {
    464       case '1':
    465       {
    466         /*
    467           Convert PBM image to pixel packets.
    468         */
    469         (void) SetImageColorspace(image,GRAYColorspace,exception);
    470         for (y=0; y < (ssize_t) image->rows; y++)
    471         {
    472           register ssize_t
    473             x;
    474 
    475           register Quantum
    476             *magick_restrict q;
    477 
    478           q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
    479           if (q == (Quantum *) NULL)
    480             break;
    481           for (x=0; x < (ssize_t) image->columns; x++)
    482           {
    483             SetPixelGray(image,PNMInteger(image,&comment_info,2,exception) ==
    484               0 ? QuantumRange : 0,q);
    485             if (EOFBlob(image) != MagickFalse)
    486               break;
    487             q+=GetPixelChannels(image);
    488           }
    489           if (SyncAuthenticPixels(image,exception) == MagickFalse)
    490             break;
    491           if (image->previous == (Image *) NULL)
    492             {
    493               status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
    494                 image->rows);
    495               if (status == MagickFalse)
    496                 break;
    497             }
    498           if (EOFBlob(image) != MagickFalse)
    499             break;
    500         }
    501         image->type=BilevelType;
    502         break;
    503       }
    504       case '2':
    505       {
    506         Quantum
    507           intensity;
    508 
    509         /*
    510           Convert PGM image to pixel packets.
    511         */
    512         (void) SetImageColorspace(image,GRAYColorspace,exception);
    513         for (y=0; y < (ssize_t) image->rows; y++)
    514         {
    515           register ssize_t
    516             x;
    517 
    518           register Quantum
    519             *magick_restrict q;
    520 
    521           q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
    522           if (q == (Quantum *) NULL)
    523             break;
    524           for (x=0; x < (ssize_t) image->columns; x++)
    525           {
    526             intensity=ScaleAnyToQuantum(PNMInteger(image,&comment_info,10,
    527               exception),max_value);
    528             if (EOFBlob(image) != MagickFalse)
    529               break;
    530             SetPixelGray(image,intensity,q);
    531             q+=GetPixelChannels(image);
    532           }
    533           if (SyncAuthenticPixels(image,exception) == MagickFalse)
    534             break;
    535           if (image->previous == (Image *) NULL)
    536             {
    537               status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
    538                 image->rows);
    539               if (status == MagickFalse)
    540                 break;
    541             }
    542           if (EOFBlob(image) != MagickFalse)
    543             break;
    544         }
    545         image->type=GrayscaleType;
    546         break;
    547       }
    548       case '3':
    549       {
    550         /*
    551           Convert PNM image to pixel packets.
    552         */
    553         for (y=0; y < (ssize_t) image->rows; y++)
    554         {
    555           register ssize_t
    556             x;
    557 
    558           register Quantum
    559             *magick_restrict q;
    560 
    561           q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
    562           if (q == (Quantum *) NULL)
    563             break;
    564           for (x=0; x < (ssize_t) image->columns; x++)
    565           {
    566             Quantum
    567               pixel;
    568 
    569             pixel=ScaleAnyToQuantum(PNMInteger(image,&comment_info,10,
    570               exception),max_value);
    571             if (EOFBlob(image) != MagickFalse)
    572               break;
    573             SetPixelRed(image,pixel,q);
    574             pixel=ScaleAnyToQuantum(PNMInteger(image,&comment_info,10,
    575               exception),max_value);
    576             SetPixelGreen(image,pixel,q);
    577             pixel=ScaleAnyToQuantum(PNMInteger(image,&comment_info,10,
    578               exception),max_value);
    579             SetPixelBlue(image,pixel,q);
    580             q+=GetPixelChannels(image);
    581           }
    582           if (SyncAuthenticPixels(image,exception) == MagickFalse)
    583             break;
    584           if (image->previous == (Image *) NULL)
    585             {
    586               status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
    587                 image->rows);
    588               if (status == MagickFalse)
    589                 break;
    590             }
    591           if (EOFBlob(image) != MagickFalse)
    592             break;
    593         }
    594         break;
    595       }
    596       case '4':
    597       {
    598         /*
    599           Convert PBM raw image to pixel packets.
    600         */
    601         (void) SetImageColorspace(image,GRAYColorspace,exception);
    602         quantum_type=GrayQuantum;
    603         if (image->storage_class == PseudoClass)
    604           quantum_type=IndexQuantum;
    605         quantum_info=AcquireQuantumInfo(image_info,image);
    606         if (quantum_info == (QuantumInfo *) NULL)
    607           ThrowPNMException(ResourceLimitError,"MemoryAllocationFailed");
    608         SetQuantumMinIsWhite(quantum_info,MagickTrue);
    609         extent=GetQuantumExtent(image,quantum_info,quantum_type);
    610         for (y=0; y < (ssize_t) image->rows; y++)
    611         {
    612           const unsigned char
    613             *pixels;
    614 
    615           MagickBooleanType
    616             sync;
    617 
    618           register Quantum
    619             *magick_restrict q;
    620 
    621           ssize_t
    622             offset;
    623 
    624           size_t
    625             length;
    626 
    627           pixels=(unsigned char *) ReadBlobStream(image,extent,
    628             GetQuantumPixels(quantum_info),&count);
    629           if (count != (ssize_t) extent)
    630             break;
    631           if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
    632               (image->previous == (Image *) NULL))
    633             {
    634               MagickBooleanType
    635                 proceed;
    636 
    637               proceed=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
    638                 row,image->rows);
    639               if (proceed == MagickFalse)
    640                 break;
    641             }
    642           offset=row++;
    643           q=QueueAuthenticPixels(image,0,offset,image->columns,1,exception);
    644           if (q == (Quantum *) NULL)
    645             break;
    646           length=ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
    647             quantum_type,pixels,exception);
    648           if (length != extent)
    649             break;
    650           sync=SyncAuthenticPixels(image,exception);
    651           if (sync == MagickFalse)
    652             break;
    653         }
    654         quantum_info=DestroyQuantumInfo(quantum_info);
    655         SetQuantumImageType(image,quantum_type);
    656         break;
    657       }
    658       case '5':
    659       {
    660         /*
    661           Convert PGM raw image to pixel packets.
    662         */
    663         (void) SetImageColorspace(image,GRAYColorspace,exception);
    664         quantum_type=GrayQuantum;
    665         extent=(image->depth <= 8 ? 1 : image->depth <= 16 ? 2 : 4)*
    666           image->columns;
    667         quantum_info=AcquireQuantumInfo(image_info,image);
    668         if (quantum_info == (QuantumInfo *) NULL)
    669           ThrowPNMException(ResourceLimitError,"MemoryAllocationFailed");
    670         for (y=0; y < (ssize_t) image->rows; y++)
    671         {
    672           const unsigned char
    673             *pixels;
    674 
    675           MagickBooleanType
    676             sync;
    677 
    678           register const unsigned char
    679             *magick_restrict p;
    680 
    681           register ssize_t
    682             x;
    683 
    684           register Quantum
    685             *magick_restrict q;
    686 
    687           ssize_t
    688             offset;
    689 
    690           pixels=(unsigned char *) ReadBlobStream(image,extent,
    691             GetQuantumPixels(quantum_info),&count);
    692           if (count != (ssize_t) extent)
    693             break;
    694           if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
    695               (image->previous == (Image *) NULL))
    696             {
    697               MagickBooleanType
    698                 proceed;
    699 
    700               proceed=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
    701                 row,image->rows);
    702               if (proceed == MagickFalse)
    703                 break;
    704             }
    705           offset=row++;
    706           q=QueueAuthenticPixels(image,0,offset,image->columns,1,exception);
    707           if (q == (Quantum *) NULL)
    708             break;
    709           p=pixels;
    710           switch (image->depth)
    711           {
    712             case 8:
    713             case 16:
    714             case 32:
    715             {
    716               (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
    717                 quantum_type,pixels,exception);
    718               break;
    719             }
    720             default:
    721             {
    722               if (image->depth <= 8)
    723                 {
    724                   unsigned char
    725                     pixel;
    726 
    727                   for (x=0; x < (ssize_t) image->columns; x++)
    728                   {
    729                     p=PushCharPixel(p,&pixel);
    730                     SetPixelGray(image,ScaleAnyToQuantum(pixel,max_value),q);
    731                     q+=GetPixelChannels(image);
    732                   }
    733                 }
    734               else if (image->depth <= 16)
    735                 {
    736                   unsigned short
    737                     pixel;
    738 
    739                   for (x=0; x < (ssize_t) image->columns; x++)
    740                   {
    741                     p=PushShortPixel(MSBEndian,p,&pixel);
    742                     SetPixelGray(image,ScaleAnyToQuantum(pixel,max_value),q);
    743                     q+=GetPixelChannels(image);
    744                   }
    745                 }
    746               else
    747                 {
    748                   unsigned int
    749                     pixel;
    750 
    751                   for (x=0; x < (ssize_t) image->columns; x++)
    752                   {
    753                     p=PushLongPixel(MSBEndian,p,&pixel);
    754                     SetPixelGray(image,ScaleAnyToQuantum(pixel,max_value),q);
    755                     q+=GetPixelChannels(image);
    756                   }
    757                 }
    758               break;
    759             }
    760           }
    761           sync=SyncAuthenticPixels(image,exception);
    762           if (sync == MagickFalse)
    763             break;
    764         }
    765         quantum_info=DestroyQuantumInfo(quantum_info);
    766         SetQuantumImageType(image,quantum_type);
    767         break;
    768       }
    769       case '6':
    770       {
    771         /*
    772           Convert PNM raster image to pixel packets.
    773         */
    774         quantum_type=RGBQuantum;
    775         extent=3*(image->depth <= 8 ? 1 : image->depth <= 16 ? 2 : 4)*
    776           image->columns;
    777         quantum_info=AcquireQuantumInfo(image_info,image);
    778         if (quantum_info == (QuantumInfo *) NULL)
    779           ThrowPNMException(ResourceLimitError,"MemoryAllocationFailed");
    780         (void) SetQuantumEndian(image,quantum_info,MSBEndian);
    781         for (y=0; y < (ssize_t) image->rows; y++)
    782         {
    783           const unsigned char
    784             *pixels;
    785 
    786           MagickBooleanType
    787             sync;
    788 
    789           register const unsigned char
    790             *magick_restrict p;
    791 
    792           register ssize_t
    793             x;
    794 
    795           register Quantum
    796             *magick_restrict q;
    797 
    798           ssize_t
    799             offset;
    800 
    801           pixels=(unsigned char *) ReadBlobStream(image,extent,
    802             GetQuantumPixels(quantum_info),&count);
    803           if (count != (ssize_t) extent)
    804             break;
    805           if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
    806               (image->previous == (Image *) NULL))
    807             {
    808               MagickBooleanType
    809                 proceed;
    810 
    811               proceed=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
    812                 row,image->rows);
    813               if (proceed == MagickFalse)
    814                 break;
    815             }
    816           offset=row++;
    817           q=QueueAuthenticPixels(image,0,offset,image->columns,1,exception);
    818           if (q == (Quantum *) NULL)
    819             break;
    820           p=pixels;
    821           switch (image->depth)
    822           {
    823             case 8:
    824             {
    825               for (x=0; x < (ssize_t) image->columns; x++)
    826               {
    827                 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
    828                 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
    829                 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
    830                 SetPixelAlpha(image,OpaqueAlpha,q);
    831                 q+=GetPixelChannels(image);
    832               }
    833               break;
    834             }
    835             case 16:
    836             {
    837               unsigned short
    838                 pixel;
    839 
    840               for (x=0; x < (ssize_t) image->columns; x++)
    841               {
    842                 p=PushShortPixel(MSBEndian,p,&pixel);
    843                 SetPixelRed(image,ScaleShortToQuantum(pixel),q);
    844                 p=PushShortPixel(MSBEndian,p,&pixel);
    845                 SetPixelGreen(image,ScaleShortToQuantum(pixel),q);
    846                 p=PushShortPixel(MSBEndian,p,&pixel);
    847                 SetPixelBlue(image,ScaleShortToQuantum(pixel),q);
    848                 SetPixelAlpha(image,OpaqueAlpha,q);
    849                 q+=GetPixelChannels(image);
    850               }
    851               break;
    852             }
    853             case 32:
    854             {
    855               unsigned int
    856                 pixel;
    857 
    858               for (x=0; x < (ssize_t) image->columns; x++)
    859               {
    860                 p=PushLongPixel(MSBEndian,p,&pixel);
    861                 SetPixelRed(image,ScaleLongToQuantum(pixel),q);
    862                 p=PushLongPixel(MSBEndian,p,&pixel);
    863                 SetPixelGreen(image,ScaleLongToQuantum(pixel),q);
    864                 p=PushLongPixel(MSBEndian,p,&pixel);
    865                 SetPixelBlue(image,ScaleLongToQuantum(pixel),q);
    866                 SetPixelAlpha(image,OpaqueAlpha,q);
    867                 q+=GetPixelChannels(image);
    868               }
    869               break;
    870             }
    871             default:
    872             {
    873               if (image->depth <= 8)
    874                 {
    875                   unsigned char
    876                     pixel;
    877 
    878                   for (x=0; x < (ssize_t) image->columns; x++)
    879                   {
    880                     p=PushCharPixel(p,&pixel);
    881                     SetPixelRed(image,ScaleAnyToQuantum(pixel,max_value),q);
    882                     p=PushCharPixel(p,&pixel);
    883                     SetPixelGreen(image,ScaleAnyToQuantum(pixel,max_value),q);
    884                     p=PushCharPixel(p,&pixel);
    885                     SetPixelBlue(image,ScaleAnyToQuantum(pixel,max_value),q);
    886                     SetPixelAlpha(image,OpaqueAlpha,q);
    887                     q+=GetPixelChannels(image);
    888                   }
    889                 }
    890               else if (image->depth <= 16)
    891                 {
    892                   unsigned short
    893                     pixel;
    894 
    895                   for (x=0; x < (ssize_t) image->columns; x++)
    896                   {
    897                     p=PushShortPixel(MSBEndian,p,&pixel);
    898                     SetPixelRed(image,ScaleAnyToQuantum(pixel,max_value),q);
    899                     p=PushShortPixel(MSBEndian,p,&pixel);
    900                     SetPixelGreen(image,ScaleAnyToQuantum(pixel,max_value),q);
    901                     p=PushShortPixel(MSBEndian,p,&pixel);
    902                     SetPixelBlue(image,ScaleAnyToQuantum(pixel,max_value),q);
    903                     SetPixelAlpha(image,OpaqueAlpha,q);
    904                     q+=GetPixelChannels(image);
    905                   }
    906                 }
    907               else
    908                 {
    909                   unsigned int
    910                     pixel;
    911 
    912                   for (x=0; x < (ssize_t) image->columns; x++)
    913                   {
    914                     p=PushLongPixel(MSBEndian,p,&pixel);
    915                     SetPixelRed(image,ScaleAnyToQuantum(pixel,max_value),q);
    916                     p=PushLongPixel(MSBEndian,p,&pixel);
    917                     SetPixelGreen(image,ScaleAnyToQuantum(pixel,max_value),q);
    918                     p=PushLongPixel(MSBEndian,p,&pixel);
    919                     SetPixelBlue(image,ScaleAnyToQuantum(pixel,max_value),q);
    920                     SetPixelAlpha(image,OpaqueAlpha,q);
    921                     q+=GetPixelChannels(image);
    922                   }
    923                 }
    924               break;
    925             }
    926           }
    927           sync=SyncAuthenticPixels(image,exception);
    928           if (sync == MagickFalse)
    929             break;
    930         }
    931         quantum_info=DestroyQuantumInfo(quantum_info);
    932         break;
    933       }
    934       case '7':
    935       {
    936         size_t
    937           channels;
    938 
    939         /*
    940           Convert PAM raster image to pixel packets.
    941         */
    942         switch (quantum_type)
    943         {
    944           case GrayQuantum:
    945           case GrayAlphaQuantum:
    946           {
    947             channels=1;
    948             break;
    949           }
    950           case CMYKQuantum:
    951           case CMYKAQuantum:
    952           {
    953             channels=4;
    954             break;
    955           }
    956           default:
    957           {
    958             channels=3;
    959             break;
    960           }
    961         }
    962         if (image->alpha_trait != UndefinedPixelTrait)
    963           channels++;
    964         extent=channels*(image->depth <= 8 ? 1 : image->depth <= 16 ? 2 : 4)*
    965           image->columns;
    966         quantum_info=AcquireQuantumInfo(image_info,image);
    967         if (quantum_info == (QuantumInfo *) NULL)
    968           ThrowPNMException(ResourceLimitError,"MemoryAllocationFailed");
    969         for (y=0; y < (ssize_t) image->rows; y++)
    970         {
    971           const unsigned char
    972             *pixels;
    973 
    974           MagickBooleanType
    975             sync;
    976 
    977           register const unsigned char
    978             *magick_restrict p;
    979 
    980           register ssize_t
    981             x;
    982 
    983           register Quantum
    984             *magick_restrict q;
    985 
    986           ssize_t
    987             offset;
    988 
    989           pixels=(unsigned char *) ReadBlobStream(image,extent,
    990             GetQuantumPixels(quantum_info),&count);
    991           if (count != (ssize_t) extent)
    992             break;
    993           if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
    994               (image->previous == (Image *) NULL))
    995             {
    996               MagickBooleanType
    997                 proceed;
    998 
    999               proceed=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
   1000                 row,image->rows);
   1001               if (proceed == MagickFalse)
   1002                 break;
   1003             }
   1004           offset=row++;
   1005           q=QueueAuthenticPixels(image,0,offset,image->columns,1,exception);
   1006           if (q == (Quantum *) NULL)
   1007             break;
   1008           p=pixels;
   1009           switch (image->depth)
   1010           {
   1011             case 8:
   1012             case 16:
   1013             case 32:
   1014             {
   1015               (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
   1016                 quantum_type,pixels,exception);
   1017               break;
   1018             }
   1019             default:
   1020             {
   1021               switch (quantum_type)
   1022               {
   1023                 case GrayQuantum:
   1024                 case GrayAlphaQuantum:
   1025                 {
   1026                   if (image->depth <= 8)
   1027                     {
   1028                       unsigned char
   1029                         pixel;
   1030 
   1031                       for (x=0; x < (ssize_t) image->columns; x++)
   1032                       {
   1033                         p=PushCharPixel(p,&pixel);
   1034                         SetPixelGray(image,ScaleAnyToQuantum(pixel,max_value),
   1035                           q);
   1036                         SetPixelAlpha(image,OpaqueAlpha,q);
   1037                         if (image->alpha_trait != UndefinedPixelTrait)
   1038                           {
   1039                             p=PushCharPixel(p,&pixel);
   1040                             if (image->depth != 1)
   1041                               SetPixelAlpha(image,ScaleAnyToQuantum(pixel,
   1042                                 max_value),q);
   1043                             else
   1044                               SetPixelAlpha(image,QuantumRange-
   1045                                 ScaleAnyToQuantum(pixel,max_value),q);
   1046                           }
   1047                         q+=GetPixelChannels(image);
   1048                       }
   1049                     }
   1050                   else if (image->depth <= 16)
   1051                     {
   1052                       unsigned short
   1053                         pixel;
   1054 
   1055                       for (x=0; x < (ssize_t) image->columns; x++)
   1056                       {
   1057                         p=PushShortPixel(MSBEndian,p,&pixel);
   1058                         SetPixelGray(image,ScaleAnyToQuantum(pixel,max_value),
   1059                           q);
   1060                         SetPixelAlpha(image,OpaqueAlpha,q);
   1061                         if (image->alpha_trait != UndefinedPixelTrait)
   1062                           {
   1063                             p=PushShortPixel(MSBEndian,p,&pixel);
   1064                             SetPixelAlpha(image,ScaleAnyToQuantum(pixel,
   1065                               max_value),q);
   1066                           }
   1067                         q+=GetPixelChannels(image);
   1068                       }
   1069                     }
   1070                   else
   1071                     {
   1072                       unsigned int
   1073                         pixel;
   1074 
   1075                       for (x=0; x < (ssize_t) image->columns; x++)
   1076                       {
   1077                         p=PushLongPixel(MSBEndian,p,&pixel);
   1078                         SetPixelGray(image,ScaleAnyToQuantum(pixel,max_value),
   1079                           q);
   1080                         SetPixelAlpha(image,OpaqueAlpha,q);
   1081                         if (image->alpha_trait != UndefinedPixelTrait)
   1082                           {
   1083                             p=PushLongPixel(MSBEndian,p,&pixel);
   1084                             SetPixelAlpha(image,ScaleAnyToQuantum(pixel,
   1085                               max_value),q);
   1086                           }
   1087                         q+=GetPixelChannels(image);
   1088                       }
   1089                     }
   1090                   break;
   1091                 }
   1092                 case CMYKQuantum:
   1093                 case CMYKAQuantum:
   1094                 {
   1095                   if (image->depth <= 8)
   1096                     {
   1097                       unsigned char
   1098                         pixel;
   1099 
   1100                       for (x=0; x < (ssize_t) image->columns; x++)
   1101                       {
   1102                         p=PushCharPixel(p,&pixel);
   1103                         SetPixelRed(image,ScaleAnyToQuantum(pixel,max_value),q);
   1104                         p=PushCharPixel(p,&pixel);
   1105                         SetPixelGreen(image,ScaleAnyToQuantum(pixel,max_value),
   1106                           q);
   1107                         p=PushCharPixel(p,&pixel);
   1108                         SetPixelBlue(image,ScaleAnyToQuantum(pixel,max_value),
   1109                           q);
   1110                         p=PushCharPixel(p,&pixel);
   1111                         SetPixelBlack(image,ScaleAnyToQuantum(pixel,max_value),
   1112                           q);
   1113                         SetPixelAlpha(image,OpaqueAlpha,q);
   1114                         if (image->alpha_trait != UndefinedPixelTrait)
   1115                           {
   1116                             p=PushCharPixel(p,&pixel);
   1117                             SetPixelAlpha(image,ScaleAnyToQuantum(pixel,
   1118                               max_value),q);
   1119                           }
   1120                         q+=GetPixelChannels(image);
   1121                       }
   1122                     }
   1123                   else if (image->depth <= 16)
   1124                     {
   1125                       unsigned short
   1126                         pixel;
   1127 
   1128                       for (x=0; x < (ssize_t) image->columns; x++)
   1129                       {
   1130                         p=PushShortPixel(MSBEndian,p,&pixel);
   1131                         SetPixelRed(image,ScaleAnyToQuantum(pixel,max_value),q);
   1132                         p=PushShortPixel(MSBEndian,p,&pixel);
   1133                         SetPixelGreen(image,ScaleAnyToQuantum(pixel,max_value),
   1134                           q);
   1135                         p=PushShortPixel(MSBEndian,p,&pixel);
   1136                         SetPixelBlue(image,ScaleAnyToQuantum(pixel,max_value),
   1137                           q);
   1138                         p=PushShortPixel(MSBEndian,p,&pixel);
   1139                         SetPixelBlack(image,ScaleAnyToQuantum(pixel,max_value),
   1140                           q);
   1141                         SetPixelAlpha(image,OpaqueAlpha,q);
   1142                         if (image->alpha_trait != UndefinedPixelTrait)
   1143                           {
   1144                             p=PushShortPixel(MSBEndian,p,&pixel);
   1145                             SetPixelAlpha(image,ScaleAnyToQuantum(pixel,
   1146                               max_value),q);
   1147                           }
   1148                         q+=GetPixelChannels(image);
   1149                       }
   1150                     }
   1151                   else
   1152                     {
   1153                       unsigned int
   1154                         pixel;
   1155 
   1156                       for (x=0; x < (ssize_t) image->columns; x++)
   1157                       {
   1158                         p=PushLongPixel(MSBEndian,p,&pixel);
   1159                         SetPixelRed(image,ScaleAnyToQuantum(pixel,max_value),
   1160                           q);
   1161                         p=PushLongPixel(MSBEndian,p,&pixel);
   1162                         SetPixelGreen(image,ScaleAnyToQuantum(pixel,max_value),
   1163                           q);
   1164                         p=PushLongPixel(MSBEndian,p,&pixel);
   1165                         SetPixelBlue(image,ScaleAnyToQuantum(pixel,max_value),
   1166                           q);
   1167                         p=PushLongPixel(MSBEndian,p,&pixel);
   1168                         SetPixelBlack(image,ScaleAnyToQuantum(pixel,max_value),
   1169                           q);
   1170                         SetPixelAlpha(image,OpaqueAlpha,q);
   1171                         if (image->alpha_trait != UndefinedPixelTrait)
   1172                           {
   1173                             p=PushLongPixel(MSBEndian,p,&pixel);
   1174                             SetPixelAlpha(image,ScaleAnyToQuantum(pixel,
   1175                               max_value),q);
   1176                           }
   1177                         q+=GetPixelChannels(image);
   1178                     }
   1179                   }
   1180                   break;
   1181                 }
   1182                 default:
   1183                 {
   1184                   if (image->depth <= 8)
   1185                     {
   1186                       unsigned char
   1187                         pixel;
   1188 
   1189                       for (x=0; x < (ssize_t) image->columns; x++)
   1190                       {
   1191                         p=PushCharPixel(p,&pixel);
   1192                         SetPixelRed(image,ScaleAnyToQuantum(pixel,max_value),q);
   1193                         p=PushCharPixel(p,&pixel);
   1194                         SetPixelGreen(image,ScaleAnyToQuantum(pixel,max_value),
   1195                           q);
   1196                         p=PushCharPixel(p,&pixel);
   1197                         SetPixelBlue(image,ScaleAnyToQuantum(pixel,max_value),
   1198                           q);
   1199                         SetPixelAlpha(image,OpaqueAlpha,q);
   1200                         if (image->alpha_trait != UndefinedPixelTrait)
   1201                           {
   1202                             p=PushCharPixel(p,&pixel);
   1203                             SetPixelAlpha(image,ScaleAnyToQuantum(pixel,
   1204                               max_value),q);
   1205                           }
   1206                         q+=GetPixelChannels(image);
   1207                       }
   1208                     }
   1209                   else if (image->depth <= 16)
   1210                     {
   1211                       unsigned short
   1212                         pixel;
   1213 
   1214                       for (x=0; x < (ssize_t) image->columns; x++)
   1215                       {
   1216                         p=PushShortPixel(MSBEndian,p,&pixel);
   1217                         SetPixelRed(image,ScaleAnyToQuantum(pixel,max_value),q);
   1218                         p=PushShortPixel(MSBEndian,p,&pixel);
   1219                         SetPixelGreen(image,ScaleAnyToQuantum(pixel,max_value),
   1220                           q);
   1221                         p=PushShortPixel(MSBEndian,p,&pixel);
   1222                         SetPixelBlue(image,ScaleAnyToQuantum(pixel,max_value),
   1223                           q);
   1224                         SetPixelAlpha(image,OpaqueAlpha,q);
   1225                         if (image->alpha_trait != UndefinedPixelTrait)
   1226                           {
   1227                             p=PushShortPixel(MSBEndian,p,&pixel);
   1228                             SetPixelAlpha(image,ScaleAnyToQuantum(pixel,
   1229                               max_value),q);
   1230                           }
   1231                         q+=GetPixelChannels(image);
   1232                       }
   1233                     }
   1234                   else
   1235                     {
   1236                       unsigned int
   1237                         pixel;
   1238 
   1239                       for (x=0; x < (ssize_t) image->columns; x++)
   1240                       {
   1241                         p=PushLongPixel(MSBEndian,p,&pixel);
   1242                         SetPixelRed(image,ScaleAnyToQuantum(pixel,max_value),
   1243                           q);
   1244                         p=PushLongPixel(MSBEndian,p,&pixel);
   1245                         SetPixelGreen(image,ScaleAnyToQuantum(pixel,max_value),
   1246                           q);
   1247                         p=PushLongPixel(MSBEndian,p,&pixel);
   1248                         SetPixelBlue(image,ScaleAnyToQuantum(pixel,max_value),
   1249                           q);
   1250                         SetPixelAlpha(image,OpaqueAlpha,q);
   1251                         if (image->alpha_trait != UndefinedPixelTrait)
   1252                           {
   1253                             p=PushLongPixel(MSBEndian,p,&pixel);
   1254                             SetPixelAlpha(image,ScaleAnyToQuantum(pixel,
   1255                               max_value),q);
   1256                           }
   1257                         q+=GetPixelChannels(image);
   1258                       }
   1259                     }
   1260                   break;
   1261                 }
   1262               }
   1263             }
   1264           }
   1265           sync=SyncAuthenticPixels(image,exception);
   1266           if (sync == MagickFalse)
   1267             break;
   1268         }
   1269         quantum_info=DestroyQuantumInfo(quantum_info);
   1270         SetQuantumImageType(image,quantum_type);
   1271         break;
   1272       }
   1273       case 'F':
   1274       case 'f':
   1275       {
   1276         /*
   1277           Convert PFM raster image to pixel packets.
   1278         */
   1279         if (format == 'f')
   1280           (void) SetImageColorspace(image,GRAYColorspace,exception);
   1281         quantum_type=format == 'f' ? GrayQuantum : RGBQuantum;
   1282         image->endian=quantum_scale < 0.0 ? LSBEndian : MSBEndian;
   1283         image->depth=32;
   1284         quantum_info=AcquireQuantumInfo(image_info,image);
   1285         if (quantum_info == (QuantumInfo *) NULL)
   1286           ThrowPNMException(ResourceLimitError,"MemoryAllocationFailed");
   1287         status=SetQuantumDepth(image,quantum_info,32);
   1288         if (status == MagickFalse)
   1289           ThrowPNMException(ResourceLimitError,"MemoryAllocationFailed");
   1290         status=SetQuantumFormat(image,quantum_info,FloatingPointQuantumFormat);
   1291         if (status == MagickFalse)
   1292           ThrowPNMException(ResourceLimitError,"MemoryAllocationFailed");
   1293         SetQuantumScale(quantum_info,(double) QuantumRange*fabs(quantum_scale));
   1294         extent=GetQuantumExtent(image,quantum_info,quantum_type);
   1295         for (y=0; y < (ssize_t) image->rows; y++)
   1296         {
   1297           const unsigned char
   1298             *pixels;
   1299 
   1300           MagickBooleanType
   1301             sync;
   1302 
   1303           register Quantum
   1304             *magick_restrict q;
   1305 
   1306           ssize_t
   1307             offset;
   1308 
   1309           size_t
   1310             length;
   1311 
   1312           pixels=(unsigned char *) ReadBlobStream(image,extent,
   1313             GetQuantumPixels(quantum_info),&count);
   1314           if (count != (ssize_t) extent)
   1315             break;
   1316           if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
   1317               (image->previous == (Image *) NULL))
   1318             {
   1319               MagickBooleanType
   1320                 proceed;
   1321 
   1322               proceed=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
   1323                 row,image->rows);
   1324               if (proceed == MagickFalse)
   1325                 break;
   1326             }
   1327           offset=row++;
   1328           q=QueueAuthenticPixels(image,0,(ssize_t) (image->rows-offset-1),
   1329             image->columns,1,exception);
   1330           if (q == (Quantum *) NULL)
   1331             break;
   1332           length=ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
   1333             quantum_type,pixels,exception);
   1334           if (length != extent)
   1335             break;
   1336           sync=SyncAuthenticPixels(image,exception);
   1337           if (sync == MagickFalse)
   1338             break;
   1339         }
   1340         quantum_info=DestroyQuantumInfo(quantum_info);
   1341         SetQuantumImageType(image,quantum_type);
   1342         break;
   1343       }
   1344       default:
   1345         ThrowPNMException(CorruptImageError,"ImproperImageHeader");
   1346     }
   1347     if (*comment_info.comment != '\0')
   1348       (void) SetImageProperty(image,"comment",comment_info.comment,exception);
   1349     comment_info.comment=DestroyString(comment_info.comment);
   1350     if (y < (ssize_t) image->rows)
   1351       ThrowPNMException(CorruptImageError,"UnableToReadImageData");
   1352     if (EOFBlob(image) != MagickFalse)
   1353       {
   1354         (void) ThrowMagickException(exception,GetMagickModule(),
   1355           CorruptImageError,"UnexpectedEndOfFile","`%s'",image->filename);
   1356         break;
   1357       }
   1358     /*
   1359       Proceed to next image.
   1360     */
   1361     if (image_info->number_scenes != 0)
   1362       if (image->scene >= (image_info->scene+image_info->number_scenes-1))
   1363         break;
   1364     if ((format == '1') || (format == '2') || (format == '3'))
   1365       do
   1366       {
   1367         /*
   1368           Skip to end of line.
   1369         */
   1370         count=ReadBlob(image,1,(unsigned char *) &format);
   1371         if (count != 1)
   1372           break;
   1373         if (format == 'P')
   1374           break;
   1375       } while (format != '\n');
   1376     count=ReadBlob(image,1,(unsigned char *) &format);
   1377     if ((count == 1) && (format == 'P'))
   1378       {
   1379         /*
   1380           Allocate next image structure.
   1381         */
   1382         AcquireNextImage(image_info,image,exception);
   1383         if (GetNextImageInList(image) == (Image *) NULL)
   1384           {
   1385             status=MagickFalse;
   1386             break;
   1387           }
   1388         image=SyncNextImageInList(image);
   1389         status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
   1390           GetBlobSize(image));
   1391         if (status == MagickFalse)
   1392           break;
   1393       }
   1394   } while ((count == 1) && (format == 'P'));
   1395   (void) CloseBlob(image);
   1396   if (status == MagickFalse)
   1397     return(DestroyImageList(image));
   1398   return(GetFirstImageInList(image));
   1399 }
   1400 
   1401 /*
   1403 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1404 %                                                                             %
   1405 %                                                                             %
   1406 %                                                                             %
   1407 %   R e g i s t e r P N M I m a g e                                           %
   1408 %                                                                             %
   1409 %                                                                             %
   1410 %                                                                             %
   1411 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1412 %
   1413 %  RegisterPNMImage() adds properties for the PNM image format to
   1414 %  the list of supported formats.  The properties include the image format
   1415 %  tag, a method to read and/or write the format, whether the format
   1416 %  supports the saving of more than one frame to the same file or blob,
   1417 %  whether the format supports native in-memory I/O, and a brief
   1418 %  description of the format.
   1419 %
   1420 %  The format of the RegisterPNMImage method is:
   1421 %
   1422 %      size_t RegisterPNMImage(void)
   1423 %
   1424 */
   1425 ModuleExport size_t RegisterPNMImage(void)
   1426 {
   1427   MagickInfo
   1428     *entry;
   1429 
   1430   entry=AcquireMagickInfo("PNM","PAM","Common 2-dimensional bitmap format");
   1431   entry->decoder=(DecodeImageHandler *) ReadPNMImage;
   1432   entry->encoder=(EncodeImageHandler *) WritePNMImage;
   1433   entry->mime_type=ConstantString("image/x-portable-pixmap");
   1434   entry->flags|=CoderDecoderSeekableStreamFlag;
   1435   (void) RegisterMagickInfo(entry);
   1436   entry=AcquireMagickInfo("PNM","PBM",
   1437     "Portable bitmap format (black and white)");
   1438   entry->decoder=(DecodeImageHandler *) ReadPNMImage;
   1439   entry->encoder=(EncodeImageHandler *) WritePNMImage;
   1440   entry->mime_type=ConstantString("image/x-portable-bitmap");
   1441   entry->flags|=CoderDecoderSeekableStreamFlag;
   1442   (void) RegisterMagickInfo(entry);
   1443   entry=AcquireMagickInfo("PNM","PFM","Portable float format");
   1444   entry->decoder=(DecodeImageHandler *) ReadPNMImage;
   1445   entry->encoder=(EncodeImageHandler *) WritePNMImage;
   1446   entry->flags|=CoderEndianSupportFlag;
   1447   entry->flags|=CoderDecoderSeekableStreamFlag;
   1448   (void) RegisterMagickInfo(entry);
   1449   entry=AcquireMagickInfo("PNM","PGM","Portable graymap format (gray scale)");
   1450   entry->decoder=(DecodeImageHandler *) ReadPNMImage;
   1451   entry->encoder=(EncodeImageHandler *) WritePNMImage;
   1452   entry->mime_type=ConstantString("image/x-portable-greymap");
   1453   entry->flags|=CoderDecoderSeekableStreamFlag;
   1454   (void) RegisterMagickInfo(entry);
   1455   entry=AcquireMagickInfo("PNM","PNM","Portable anymap");
   1456   entry->decoder=(DecodeImageHandler *) ReadPNMImage;
   1457   entry->encoder=(EncodeImageHandler *) WritePNMImage;
   1458   entry->magick=(IsImageFormatHandler *) IsPNM;
   1459   entry->mime_type=ConstantString("image/x-portable-pixmap");
   1460   entry->flags|=CoderDecoderSeekableStreamFlag;
   1461   (void) RegisterMagickInfo(entry);
   1462   entry=AcquireMagickInfo("PNM","PPM","Portable pixmap format (color)");
   1463   entry->decoder=(DecodeImageHandler *) ReadPNMImage;
   1464   entry->encoder=(EncodeImageHandler *) WritePNMImage;
   1465   entry->mime_type=ConstantString("image/x-portable-pixmap");
   1466   entry->flags|=CoderDecoderSeekableStreamFlag;
   1467   (void) RegisterMagickInfo(entry);
   1468   return(MagickImageCoderSignature);
   1469 }
   1470 
   1471 /*
   1473 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1474 %                                                                             %
   1475 %                                                                             %
   1476 %                                                                             %
   1477 %   U n r e g i s t e r P N M I m a g e                                       %
   1478 %                                                                             %
   1479 %                                                                             %
   1480 %                                                                             %
   1481 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1482 %
   1483 %  UnregisterPNMImage() removes format registrations made by the
   1484 %  PNM module from the list of supported formats.
   1485 %
   1486 %  The format of the UnregisterPNMImage method is:
   1487 %
   1488 %      UnregisterPNMImage(void)
   1489 %
   1490 */
   1491 ModuleExport void UnregisterPNMImage(void)
   1492 {
   1493   (void) UnregisterMagickInfo("PAM");
   1494   (void) UnregisterMagickInfo("PBM");
   1495   (void) UnregisterMagickInfo("PGM");
   1496   (void) UnregisterMagickInfo("PNM");
   1497   (void) UnregisterMagickInfo("PPM");
   1498 }
   1499 
   1500 /*
   1502 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1503 %                                                                             %
   1504 %                                                                             %
   1505 %                                                                             %
   1506 %   W r i t e P N M I m a g e                                                 %
   1507 %                                                                             %
   1508 %                                                                             %
   1509 %                                                                             %
   1510 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1511 %
   1512 %  WritePNMImage() writes an image to a file in the PNM rasterfile format.
   1513 %
   1514 %  The format of the WritePNMImage method is:
   1515 %
   1516 %      MagickBooleanType WritePNMImage(const ImageInfo *image_info,
   1517 %        Image *image,ExceptionInfo *exception)
   1518 %
   1519 %  A description of each parameter follows.
   1520 %
   1521 %    o image_info: the image info.
   1522 %
   1523 %    o image:  The image.
   1524 %
   1525 %    o exception: return any errors or warnings in this structure.
   1526 %
   1527 */
   1528 static MagickBooleanType WritePNMImage(const ImageInfo *image_info,Image *image,
   1529   ExceptionInfo *exception)
   1530 {
   1531   char
   1532     buffer[MagickPathExtent],
   1533     format,
   1534     magick[MagickPathExtent];
   1535 
   1536   const char
   1537     *value;
   1538 
   1539   MagickBooleanType
   1540     status;
   1541 
   1542   MagickOffsetType
   1543     scene;
   1544 
   1545   Quantum
   1546     index;
   1547 
   1548   QuantumAny
   1549     pixel;
   1550 
   1551   QuantumInfo
   1552     *quantum_info;
   1553 
   1554   QuantumType
   1555     quantum_type;
   1556 
   1557   register unsigned char
   1558     *q;
   1559 
   1560   size_t
   1561     extent,
   1562     imageListLength,
   1563     packet_size;
   1564 
   1565   ssize_t
   1566     count,
   1567     y;
   1568 
   1569   /*
   1570     Open output image file.
   1571   */
   1572   assert(image_info != (const ImageInfo *) NULL);
   1573   assert(image_info->signature == MagickCoreSignature);
   1574   assert(image != (Image *) NULL);
   1575   assert(image->signature == MagickCoreSignature);
   1576   if (image->debug != MagickFalse)
   1577     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   1578   assert(exception != (ExceptionInfo *) NULL);
   1579   assert(exception->signature == MagickCoreSignature);
   1580   status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
   1581   if (status == MagickFalse)
   1582     return(status);
   1583   scene=0;
   1584   imageListLength=GetImageListLength(image);
   1585   do
   1586   {
   1587     QuantumAny
   1588       max_value;
   1589 
   1590     /*
   1591       Write PNM file header.
   1592     */
   1593     packet_size=3;
   1594     quantum_type=RGBQuantum;
   1595     (void) CopyMagickString(magick,image_info->magick,MagickPathExtent);
   1596     max_value=GetQuantumRange(image->depth);
   1597     switch (magick[1])
   1598     {
   1599       case 'A':
   1600       case 'a':
   1601       {
   1602         format='7';
   1603         break;
   1604       }
   1605       case 'B':
   1606       case 'b':
   1607       {
   1608         format='4';
   1609         if (image_info->compression == NoCompression)
   1610           format='1';
   1611         break;
   1612       }
   1613       case 'F':
   1614       case 'f':
   1615       {
   1616         format='F';
   1617         if (SetImageGray(image,exception) != MagickFalse)
   1618           format='f';
   1619         break;
   1620       }
   1621       case 'G':
   1622       case 'g':
   1623       {
   1624         format='5';
   1625         if (image_info->compression == NoCompression)
   1626           format='2';
   1627         break;
   1628       }
   1629       case 'N':
   1630       case 'n':
   1631       {
   1632         if ((image_info->type != TrueColorType) &&
   1633             (SetImageGray(image,exception) != MagickFalse))
   1634           {
   1635             format='5';
   1636             if (image_info->compression == NoCompression)
   1637               format='2';
   1638             if (SetImageMonochrome(image,exception) != MagickFalse)
   1639               {
   1640                 format='4';
   1641                 if (image_info->compression == NoCompression)
   1642                   format='1';
   1643               }
   1644             break;
   1645           }
   1646       }
   1647       default:
   1648       {
   1649         format='6';
   1650         if (image_info->compression == NoCompression)
   1651           format='3';
   1652         break;
   1653       }
   1654     }
   1655     (void) FormatLocaleString(buffer,MagickPathExtent,"P%c\n",format);
   1656     (void) WriteBlobString(image,buffer);
   1657     value=GetImageProperty(image,"comment",exception);
   1658     if (value != (const char *) NULL)
   1659       {
   1660         register const char
   1661           *p;
   1662 
   1663         /*
   1664           Write comments to file.
   1665         */
   1666         (void) WriteBlobByte(image,'#');
   1667         for (p=value; *p != '\0'; p++)
   1668         {
   1669           (void) WriteBlobByte(image,(unsigned char) *p);
   1670           if ((*p == '\n') || (*p == '\r'))
   1671             (void) WriteBlobByte(image,'#');
   1672         }
   1673         (void) WriteBlobByte(image,'\n');
   1674       }
   1675     if (format != '7')
   1676       {
   1677         (void) FormatLocaleString(buffer,MagickPathExtent,"%.20g %.20g\n",
   1678           (double) image->columns,(double) image->rows);
   1679         (void) WriteBlobString(image,buffer);
   1680       }
   1681     else
   1682       {
   1683         char
   1684           type[MagickPathExtent];
   1685 
   1686         /*
   1687           PAM header.
   1688         */
   1689         (void) FormatLocaleString(buffer,MagickPathExtent,
   1690           "WIDTH %.20g\nHEIGHT %.20g\n",(double) image->columns,(double)
   1691           image->rows);
   1692         (void) WriteBlobString(image,buffer);
   1693         quantum_type=GetQuantumType(image,exception);
   1694         switch (quantum_type)
   1695         {
   1696           case CMYKQuantum:
   1697           case CMYKAQuantum:
   1698           {
   1699             packet_size=4;
   1700             (void) CopyMagickString(type,"CMYK",MagickPathExtent);
   1701             break;
   1702           }
   1703           case GrayQuantum:
   1704           case GrayAlphaQuantum:
   1705           {
   1706             packet_size=1;
   1707             (void) CopyMagickString(type,"GRAYSCALE",MagickPathExtent);
   1708             if (IdentifyImageMonochrome(image,exception) != MagickFalse)
   1709               (void) CopyMagickString(type,"BLACKANDWHITE",MagickPathExtent);
   1710             break;
   1711           }
   1712           default:
   1713           {
   1714             quantum_type=RGBQuantum;
   1715             if (image->alpha_trait != UndefinedPixelTrait)
   1716               quantum_type=RGBAQuantum;
   1717             packet_size=3;
   1718             (void) CopyMagickString(type,"RGB",MagickPathExtent);
   1719             break;
   1720           }
   1721         }
   1722         if (image->alpha_trait != UndefinedPixelTrait)
   1723           {
   1724             packet_size++;
   1725             (void) ConcatenateMagickString(type,"_ALPHA",MagickPathExtent);
   1726           }
   1727         if (image->depth > 32)
   1728           image->depth=32;
   1729         (void) FormatLocaleString(buffer,MagickPathExtent,
   1730           "DEPTH %.20g\nMAXVAL %.20g\n",(double) packet_size,(double)
   1731           ((MagickOffsetType) GetQuantumRange(image->depth)));
   1732         (void) WriteBlobString(image,buffer);
   1733         (void) FormatLocaleString(buffer,MagickPathExtent,
   1734           "TUPLTYPE %s\nENDHDR\n",type);
   1735         (void) WriteBlobString(image,buffer);
   1736       }
   1737     /*
   1738       Convert runextent encoded to PNM raster pixels.
   1739     */
   1740     switch (format)
   1741     {
   1742       case '1':
   1743       {
   1744         unsigned char
   1745           pixels[2048];
   1746 
   1747         /*
   1748           Convert image to a PBM image.
   1749         */
   1750         (void) SetImageType(image,BilevelType,exception);
   1751         q=pixels;
   1752         for (y=0; y < (ssize_t) image->rows; y++)
   1753         {
   1754           register const Quantum
   1755             *magick_restrict p;
   1756 
   1757           register ssize_t
   1758             x;
   1759 
   1760           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
   1761           if (p == (const Quantum *) NULL)
   1762             break;
   1763           for (x=0; x < (ssize_t) image->columns; x++)
   1764           {
   1765             *q++=(unsigned char) (GetPixelLuma(image,p) >= (QuantumRange/2.0) ?
   1766               '0' : '1');
   1767             *q++=' ';
   1768             if ((q-pixels+1) >= (ssize_t) sizeof(pixels))
   1769               {
   1770                 *q++='\n';
   1771                 (void) WriteBlob(image,q-pixels,pixels);
   1772                 q=pixels;
   1773               }
   1774             p+=GetPixelChannels(image);
   1775           }
   1776           *q++='\n';
   1777           (void) WriteBlob(image,q-pixels,pixels);
   1778           q=pixels;
   1779           if (image->previous == (Image *) NULL)
   1780             {
   1781               status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
   1782                 image->rows);
   1783               if (status == MagickFalse)
   1784                 break;
   1785             }
   1786         }
   1787         if (q != pixels)
   1788           {
   1789             *q++='\n';
   1790             (void) WriteBlob(image,q-pixels,pixels);
   1791           }
   1792         break;
   1793       }
   1794       case '2':
   1795       {
   1796         unsigned char
   1797           pixels[2048];
   1798 
   1799         /*
   1800           Convert image to a PGM image.
   1801         */
   1802         if (image->depth <= 8)
   1803           (void) WriteBlobString(image,"255\n");
   1804         else
   1805           if (image->depth <= 16)
   1806             (void) WriteBlobString(image,"65535\n");
   1807           else
   1808             (void) WriteBlobString(image,"4294967295\n");
   1809         q=pixels;
   1810         for (y=0; y < (ssize_t) image->rows; y++)
   1811         {
   1812           register const Quantum
   1813             *magick_restrict p;
   1814 
   1815           register ssize_t
   1816             x;
   1817 
   1818           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
   1819           if (p == (const Quantum *) NULL)
   1820             break;
   1821           for (x=0; x < (ssize_t) image->columns; x++)
   1822           {
   1823             index=ClampToQuantum(GetPixelLuma(image,p));
   1824             if (image->depth <= 8)
   1825               count=(ssize_t) FormatLocaleString(buffer,MagickPathExtent,"%u ",
   1826                 ScaleQuantumToChar(index));
   1827             else
   1828               if (image->depth <= 16)
   1829                 count=(ssize_t) FormatLocaleString(buffer,MagickPathExtent,
   1830                   "%u ",ScaleQuantumToShort(index));
   1831               else
   1832                 count=(ssize_t) FormatLocaleString(buffer,MagickPathExtent,
   1833                   "%u ",ScaleQuantumToLong(index));
   1834             extent=(size_t) count;
   1835             (void) strncpy((char *) q,buffer,extent);
   1836             q+=extent;
   1837             if ((q-pixels+extent+1) >= sizeof(pixels))
   1838               {
   1839                 *q++='\n';
   1840                 (void) WriteBlob(image,q-pixels,pixels);
   1841                 q=pixels;
   1842               }
   1843             p+=GetPixelChannels(image);
   1844           }
   1845           *q++='\n';
   1846           (void) WriteBlob(image,q-pixels,pixels);
   1847           q=pixels;
   1848           if (image->previous == (Image *) NULL)
   1849             {
   1850               status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
   1851                 image->rows);
   1852               if (status == MagickFalse)
   1853                 break;
   1854             }
   1855         }
   1856         if (q != pixels)
   1857           {
   1858             *q++='\n';
   1859             (void) WriteBlob(image,q-pixels,pixels);
   1860           }
   1861         break;
   1862       }
   1863       case '3':
   1864       {
   1865         unsigned char
   1866           pixels[2048];
   1867 
   1868         /*
   1869           Convert image to a PNM image.
   1870         */
   1871         (void) TransformImageColorspace(image,sRGBColorspace,exception);
   1872         if (image->depth <= 8)
   1873           (void) WriteBlobString(image,"255\n");
   1874         else
   1875           if (image->depth <= 16)
   1876             (void) WriteBlobString(image,"65535\n");
   1877           else
   1878             (void) WriteBlobString(image,"4294967295\n");
   1879         q=pixels;
   1880         for (y=0; y < (ssize_t) image->rows; y++)
   1881         {
   1882           register const Quantum
   1883             *magick_restrict p;
   1884 
   1885           register ssize_t
   1886             x;
   1887 
   1888           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
   1889           if (p == (const Quantum *) NULL)
   1890             break;
   1891           for (x=0; x < (ssize_t) image->columns; x++)
   1892           {
   1893             if (image->depth <= 8)
   1894               count=(ssize_t) FormatLocaleString(buffer,MagickPathExtent,
   1895                 "%u %u %u ",ScaleQuantumToChar(GetPixelRed(image,p)),
   1896                 ScaleQuantumToChar(GetPixelGreen(image,p)),
   1897                 ScaleQuantumToChar(GetPixelBlue(image,p)));
   1898             else
   1899               if (image->depth <= 16)
   1900                 count=(ssize_t) FormatLocaleString(buffer,MagickPathExtent,
   1901                   "%u %u %u ",ScaleQuantumToShort(GetPixelRed(image,p)),
   1902                   ScaleQuantumToShort(GetPixelGreen(image,p)),
   1903                   ScaleQuantumToShort(GetPixelBlue(image,p)));
   1904               else
   1905                 count=(ssize_t) FormatLocaleString(buffer,MagickPathExtent,
   1906                   "%u %u %u ",ScaleQuantumToLong(GetPixelRed(image,p)),
   1907                   ScaleQuantumToLong(GetPixelGreen(image,p)),
   1908                   ScaleQuantumToLong(GetPixelBlue(image,p)));
   1909             extent=(size_t) count;
   1910             (void) strncpy((char *) q,buffer,extent);
   1911             q+=extent;
   1912             if ((q-pixels+extent+1) >= sizeof(pixels))
   1913               {
   1914                 *q++='\n';
   1915                 (void) WriteBlob(image,q-pixels,pixels);
   1916                 q=pixels;
   1917               }
   1918             p+=GetPixelChannels(image);
   1919           }
   1920           *q++='\n';
   1921           (void) WriteBlob(image,q-pixels,pixels);
   1922           q=pixels;
   1923           if (image->previous == (Image *) NULL)
   1924             {
   1925               status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
   1926                 image->rows);
   1927               if (status == MagickFalse)
   1928                 break;
   1929             }
   1930         }
   1931         if (q != pixels)
   1932           {
   1933             *q++='\n';
   1934             (void) WriteBlob(image,q-pixels,pixels);
   1935           }
   1936         break;
   1937       }
   1938       case '4':
   1939       {
   1940         register unsigned char
   1941           *pixels;
   1942 
   1943         /*
   1944           Convert image to a PBM image.
   1945         */
   1946         (void) SetImageType(image,BilevelType,exception);
   1947         image->depth=1;
   1948         quantum_info=AcquireQuantumInfo(image_info,image);
   1949         if (quantum_info == (QuantumInfo *) NULL)
   1950           ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
   1951         (void) SetQuantumEndian(image,quantum_info,MSBEndian);
   1952         quantum_info->min_is_white=MagickTrue;
   1953         pixels=GetQuantumPixels(quantum_info);
   1954         for (y=0; y < (ssize_t) image->rows; y++)
   1955         {
   1956           register const Quantum
   1957             *magick_restrict p;
   1958 
   1959           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
   1960           if (p == (const Quantum *) NULL)
   1961             break;
   1962           extent=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
   1963             GrayQuantum,pixels,exception);
   1964           count=WriteBlob(image,extent,pixels);
   1965           if (count != (ssize_t) extent)
   1966             break;
   1967           if (image->previous == (Image *) NULL)
   1968             {
   1969               status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
   1970                 image->rows);
   1971               if (status == MagickFalse)
   1972                 break;
   1973             }
   1974         }
   1975         quantum_info=DestroyQuantumInfo(quantum_info);
   1976         break;
   1977       }
   1978       case '5':
   1979       {
   1980         register unsigned char
   1981           *pixels;
   1982 
   1983         /*
   1984           Convert image to a PGM image.
   1985         */
   1986         if (image->depth > 32)
   1987           image->depth=32;
   1988         (void) FormatLocaleString(buffer,MagickPathExtent,"%.20g\n",(double)
   1989           ((MagickOffsetType) GetQuantumRange(image->depth)));
   1990         (void) WriteBlobString(image,buffer);
   1991         quantum_info=AcquireQuantumInfo(image_info,image);
   1992         if (quantum_info == (QuantumInfo *) NULL)
   1993           ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
   1994         (void) SetQuantumEndian(image,quantum_info,MSBEndian);
   1995         quantum_info->min_is_white=MagickTrue;
   1996         pixels=GetQuantumPixels(quantum_info);
   1997         extent=GetQuantumExtent(image,quantum_info,GrayQuantum);
   1998         for (y=0; y < (ssize_t) image->rows; y++)
   1999         {
   2000           register const Quantum
   2001             *magick_restrict p;
   2002 
   2003           register ssize_t
   2004             x;
   2005 
   2006           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
   2007           if (p == (const Quantum *) NULL)
   2008             break;
   2009           q=pixels;
   2010           switch (image->depth)
   2011           {
   2012             case 8:
   2013             case 16:
   2014             case 32:
   2015             {
   2016               extent=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
   2017                 GrayQuantum,pixels,exception);
   2018               break;
   2019             }
   2020             default:
   2021             {
   2022               if (image->depth <= 8)
   2023                 {
   2024                   for (x=0; x < (ssize_t) image->columns; x++)
   2025                   {
   2026                     if (IsPixelGray(image,p) == MagickFalse)
   2027                       pixel=ScaleQuantumToAny(ClampToQuantum(GetPixelLuma(
   2028                         image,p)),max_value);
   2029                     else
   2030                       {
   2031                         if (image->depth == 8)
   2032                           pixel=ScaleQuantumToChar(GetPixelRed(image,p));
   2033                         else
   2034                           pixel=ScaleQuantumToAny(GetPixelRed(image,p),
   2035                             max_value);
   2036                       }
   2037                     q=PopCharPixel((unsigned char) pixel,q);
   2038                     p+=GetPixelChannels(image);
   2039                   }
   2040                   extent=(size_t) (q-pixels);
   2041                   break;
   2042                 }
   2043               if (image->depth <= 16)
   2044                 {
   2045                   for (x=0; x < (ssize_t) image->columns; x++)
   2046                   {
   2047                     if (IsPixelGray(image,p) == MagickFalse)
   2048                       pixel=ScaleQuantumToAny(ClampToQuantum(GetPixelLuma(image,
   2049                         p)),max_value);
   2050                     else
   2051                       {
   2052                         if (image->depth == 16)
   2053                           pixel=ScaleQuantumToShort(GetPixelRed(image,p));
   2054                         else
   2055                           pixel=ScaleQuantumToAny(GetPixelRed(image,p),
   2056                             max_value);
   2057                       }
   2058                     q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
   2059                     p+=GetPixelChannels(image);
   2060                   }
   2061                   extent=(size_t) (q-pixels);
   2062                   break;
   2063                 }
   2064               for (x=0; x < (ssize_t) image->columns; x++)
   2065               {
   2066                 if (IsPixelGray(image,p) == MagickFalse)
   2067                   pixel=ScaleQuantumToAny(ClampToQuantum(GetPixelLuma(image,p)),
   2068                     max_value);
   2069                 else
   2070                   {
   2071                     if (image->depth == 16)
   2072                       pixel=ScaleQuantumToLong(GetPixelRed(image,p));
   2073                     else
   2074                       pixel=ScaleQuantumToAny(GetPixelRed(image,p),max_value);
   2075                   }
   2076                 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
   2077                 p+=GetPixelChannels(image);
   2078               }
   2079               extent=(size_t) (q-pixels);
   2080               break;
   2081             }
   2082           }
   2083           count=WriteBlob(image,extent,pixels);
   2084           if (count != (ssize_t) extent)
   2085             break;
   2086           if (image->previous == (Image *) NULL)
   2087             {
   2088               status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
   2089                 image->rows);
   2090               if (status == MagickFalse)
   2091                 break;
   2092             }
   2093         }
   2094         quantum_info=DestroyQuantumInfo(quantum_info);
   2095         break;
   2096       }
   2097       case '6':
   2098       {
   2099         register unsigned char
   2100           *pixels;
   2101 
   2102         /*
   2103           Convert image to a PNM image.
   2104         */
   2105         (void) TransformImageColorspace(image,sRGBColorspace,exception);
   2106         if (image->depth > 32)
   2107           image->depth=32;
   2108         (void) FormatLocaleString(buffer,MagickPathExtent,"%.20g\n",(double)
   2109           ((MagickOffsetType) GetQuantumRange(image->depth)));
   2110         (void) WriteBlobString(image,buffer);
   2111         quantum_info=AcquireQuantumInfo(image_info,image);
   2112         if (quantum_info == (QuantumInfo *) NULL)
   2113           ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
   2114         (void) SetQuantumEndian(image,quantum_info,MSBEndian);
   2115         pixels=GetQuantumPixels(quantum_info);
   2116         extent=GetQuantumExtent(image,quantum_info,quantum_type);
   2117         for (y=0; y < (ssize_t) image->rows; y++)
   2118         {
   2119           register const Quantum
   2120             *magick_restrict p;
   2121 
   2122           register ssize_t
   2123             x;
   2124 
   2125           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
   2126           if (p == (const Quantum *) NULL)
   2127             break;
   2128           q=pixels;
   2129           switch (image->depth)
   2130           {
   2131             case 8:
   2132             case 16:
   2133             case 32:
   2134             {
   2135               extent=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
   2136                 quantum_type,pixels,exception);
   2137               break;
   2138             }
   2139             default:
   2140             {
   2141               if (image->depth <= 8)
   2142                 {
   2143                   for (x=0; x < (ssize_t) image->columns; x++)
   2144                   {
   2145                     pixel=ScaleQuantumToAny(GetPixelRed(image,p),max_value);
   2146                     q=PopCharPixel((unsigned char) pixel,q);
   2147                     pixel=ScaleQuantumToAny(GetPixelGreen(image,p),max_value);
   2148                     q=PopCharPixel((unsigned char) pixel,q);
   2149                     pixel=ScaleQuantumToAny(GetPixelBlue(image,p),max_value);
   2150                     q=PopCharPixel((unsigned char) pixel,q);
   2151                     p+=GetPixelChannels(image);
   2152                   }
   2153                   extent=(size_t) (q-pixels);
   2154                   break;
   2155                 }
   2156               if (image->depth <= 16)
   2157                 {
   2158                   for (x=0; x < (ssize_t) image->columns; x++)
   2159                   {
   2160                     pixel=ScaleQuantumToAny(GetPixelRed(image,p),max_value);
   2161                     q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
   2162                     pixel=ScaleQuantumToAny(GetPixelGreen(image,p),max_value);
   2163                     q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
   2164                     pixel=ScaleQuantumToAny(GetPixelBlue(image,p),max_value);
   2165                     q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
   2166                     p+=GetPixelChannels(image);
   2167                   }
   2168                   extent=(size_t) (q-pixels);
   2169                   break;
   2170                 }
   2171               for (x=0; x < (ssize_t) image->columns; x++)
   2172               {
   2173                 pixel=ScaleQuantumToAny(GetPixelRed(image,p),max_value);
   2174                 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
   2175                 pixel=ScaleQuantumToAny(GetPixelGreen(image,p),max_value);
   2176                 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
   2177                 pixel=ScaleQuantumToAny(GetPixelBlue(image,p),max_value);
   2178                 q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
   2179                 p+=GetPixelChannels(image);
   2180               }
   2181               extent=(size_t) (q-pixels);
   2182               break;
   2183             }
   2184           }
   2185           count=WriteBlob(image,extent,pixels);
   2186           if (count != (ssize_t) extent)
   2187             break;
   2188           if (image->previous == (Image *) NULL)
   2189             {
   2190               status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
   2191                 image->rows);
   2192               if (status == MagickFalse)
   2193                 break;
   2194             }
   2195         }
   2196         quantum_info=DestroyQuantumInfo(quantum_info);
   2197         break;
   2198       }
   2199       case '7':
   2200       {
   2201         register unsigned char
   2202           *pixels;
   2203 
   2204         /*
   2205           Convert image to a PAM.
   2206         */
   2207         if (image->depth > 32)
   2208           image->depth=32;
   2209         quantum_info=AcquireQuantumInfo(image_info,image);
   2210         if (quantum_info == (QuantumInfo *) NULL)
   2211           ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
   2212         (void) SetQuantumEndian(image,quantum_info,MSBEndian);
   2213         pixels=GetQuantumPixels(quantum_info);
   2214         for (y=0; y < (ssize_t) image->rows; y++)
   2215         {
   2216           register const Quantum
   2217             *magick_restrict p;
   2218 
   2219           register ssize_t
   2220             x;
   2221 
   2222           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
   2223           if (p == (const Quantum *) NULL)
   2224             break;
   2225           q=pixels;
   2226           switch (image->depth)
   2227           {
   2228             case 8:
   2229             case 16:
   2230             case 32:
   2231             {
   2232               extent=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
   2233                 quantum_type,pixels,exception);
   2234               break;
   2235             }
   2236             default:
   2237             {
   2238               switch (quantum_type)
   2239               {
   2240                 case GrayQuantum:
   2241                 case GrayAlphaQuantum:
   2242                 {
   2243                   if (image->depth <= 8)
   2244                     {
   2245                       for (x=0; x < (ssize_t) image->columns; x++)
   2246                       {
   2247                         pixel=ScaleQuantumToAny(ClampToQuantum(GetPixelLuma(
   2248                           image,p)),max_value);
   2249                         q=PopCharPixel((unsigned char) pixel,q);
   2250                         if (image->alpha_trait != UndefinedPixelTrait)
   2251                           {
   2252                             pixel=(unsigned char) ScaleQuantumToAny(
   2253                               GetPixelAlpha(image,p),max_value);
   2254                             q=PopCharPixel((unsigned char) pixel,q);
   2255                           }
   2256                         p+=GetPixelChannels(image);
   2257                       }
   2258                       break;
   2259                     }
   2260                   if (image->depth <= 16)
   2261                     {
   2262                       for (x=0; x < (ssize_t) image->columns; x++)
   2263                       {
   2264                         pixel=ScaleQuantumToAny(ClampToQuantum(GetPixelLuma(
   2265                           image,p)),max_value);
   2266                         q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
   2267                         if (image->alpha_trait != UndefinedPixelTrait)
   2268                           {
   2269                             pixel=(unsigned char) ScaleQuantumToAny(
   2270                               GetPixelAlpha(image,p),max_value);
   2271                             q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
   2272                           }
   2273                         p+=GetPixelChannels(image);
   2274                       }
   2275                       break;
   2276                     }
   2277                   for (x=0; x < (ssize_t) image->columns; x++)
   2278                   {
   2279                     pixel=ScaleQuantumToAny(ClampToQuantum(GetPixelLuma(image,
   2280                       p)),max_value);
   2281                     q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
   2282                     if (image->alpha_trait != UndefinedPixelTrait)
   2283                       {
   2284                         pixel=(unsigned char) ScaleQuantumToAny(
   2285                           GetPixelAlpha(image,p),max_value);
   2286                         q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
   2287                       }
   2288                     p+=GetPixelChannels(image);
   2289                   }
   2290                   break;
   2291                 }
   2292                 case CMYKQuantum:
   2293                 case CMYKAQuantum:
   2294                 {
   2295                   if (image->depth <= 8)
   2296                     {
   2297                       for (x=0; x < (ssize_t) image->columns; x++)
   2298                       {
   2299                         pixel=ScaleQuantumToAny(GetPixelRed(image,p),max_value);
   2300                         q=PopCharPixel((unsigned char) pixel,q);
   2301                         pixel=ScaleQuantumToAny(GetPixelGreen(image,p),
   2302                           max_value);
   2303                         q=PopCharPixel((unsigned char) pixel,q);
   2304                         pixel=ScaleQuantumToAny(GetPixelBlue(image,p),
   2305                           max_value);
   2306                         q=PopCharPixel((unsigned char) pixel,q);
   2307                         pixel=ScaleQuantumToAny(GetPixelBlack(image,p),
   2308                           max_value);
   2309                         q=PopCharPixel((unsigned char) pixel,q);
   2310                         if (image->alpha_trait != UndefinedPixelTrait)
   2311                           {
   2312                             pixel=ScaleQuantumToAny(GetPixelAlpha(image,p),
   2313                               max_value);
   2314                             q=PopCharPixel((unsigned char) pixel,q);
   2315                           }
   2316                         p+=GetPixelChannels(image);
   2317                       }
   2318                       break;
   2319                     }
   2320                   if (image->depth <= 16)
   2321                     {
   2322                       for (x=0; x < (ssize_t) image->columns; x++)
   2323                       {
   2324                         pixel=ScaleQuantumToAny(GetPixelRed(image,p),max_value);
   2325                         q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
   2326                         pixel=ScaleQuantumToAny(GetPixelGreen(image,p),
   2327                           max_value);
   2328                         q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
   2329                         pixel=ScaleQuantumToAny(GetPixelBlue(image,p),
   2330                           max_value);
   2331                         q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
   2332                         pixel=ScaleQuantumToAny(GetPixelBlack(image,p),
   2333                           max_value);
   2334                         q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
   2335                         if (image->alpha_trait != UndefinedPixelTrait)
   2336                           {
   2337                             pixel=ScaleQuantumToAny(GetPixelAlpha(image,p),
   2338                               max_value);
   2339                             q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
   2340                           }
   2341                         p+=GetPixelChannels(image);
   2342                       }
   2343                       break;
   2344                     }
   2345                   for (x=0; x < (ssize_t) image->columns; x++)
   2346                   {
   2347                     pixel=ScaleQuantumToAny(GetPixelRed(image,p),max_value);
   2348                     q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
   2349                     pixel=ScaleQuantumToAny(GetPixelGreen(image,p),max_value);
   2350                     q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
   2351                     pixel=ScaleQuantumToAny(GetPixelBlue(image,p),max_value);
   2352                     q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
   2353                     pixel=ScaleQuantumToAny(GetPixelBlack(image,p),max_value);
   2354                     q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
   2355                     if (image->alpha_trait != UndefinedPixelTrait)
   2356                       {
   2357                         pixel=ScaleQuantumToAny(GetPixelAlpha(image,p),
   2358                           max_value);
   2359                         q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
   2360                       }
   2361                     p+=GetPixelChannels(image);
   2362                   }
   2363                   break;
   2364                 }
   2365                 default:
   2366                 {
   2367                   if (image->depth <= 8)
   2368                     {
   2369                       for (x=0; x < (ssize_t) image->columns; x++)
   2370                       {
   2371                         pixel=ScaleQuantumToAny(GetPixelRed(image,p),max_value);
   2372                         q=PopCharPixel((unsigned char) pixel,q);
   2373                         pixel=ScaleQuantumToAny(GetPixelGreen(image,p),
   2374                           max_value);
   2375                         q=PopCharPixel((unsigned char) pixel,q);
   2376                         pixel=ScaleQuantumToAny(GetPixelBlue(image,p),
   2377                           max_value);
   2378                         q=PopCharPixel((unsigned char) pixel,q);
   2379                         if (image->alpha_trait != UndefinedPixelTrait)
   2380                           {
   2381                             pixel=ScaleQuantumToAny(GetPixelAlpha(image,p),
   2382                               max_value);
   2383                             q=PopCharPixel((unsigned char) pixel,q);
   2384                           }
   2385                         p+=GetPixelChannels(image);
   2386                       }
   2387                       break;
   2388                     }
   2389                   if (image->depth <= 16)
   2390                     {
   2391                       for (x=0; x < (ssize_t) image->columns; x++)
   2392                       {
   2393                         pixel=ScaleQuantumToAny(GetPixelRed(image,p),max_value);
   2394                         q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
   2395                         pixel=ScaleQuantumToAny(GetPixelGreen(image,p),
   2396                           max_value);
   2397                         q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
   2398                         pixel=ScaleQuantumToAny(GetPixelBlue(image,p),
   2399                           max_value);
   2400                         q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
   2401                         if (image->alpha_trait != UndefinedPixelTrait)
   2402                           {
   2403                             pixel=ScaleQuantumToAny(GetPixelAlpha(image,p),
   2404                               max_value);
   2405                             q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
   2406                           }
   2407                         p+=GetPixelChannels(image);
   2408                       }
   2409                       break;
   2410                     }
   2411                   for (x=0; x < (ssize_t) image->columns; x++)
   2412                   {
   2413                     pixel=ScaleQuantumToAny(GetPixelRed(image,p),max_value);
   2414                     q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
   2415                     pixel=ScaleQuantumToAny(GetPixelGreen(image,p),max_value);
   2416                     q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
   2417                     pixel=ScaleQuantumToAny(GetPixelBlue(image,p),max_value);
   2418                     q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
   2419                     if (image->alpha_trait != UndefinedPixelTrait)
   2420                       {
   2421                         pixel=ScaleQuantumToAny(GetPixelAlpha(image,p),
   2422                           max_value);
   2423                         q=PopLongPixel(MSBEndian,(unsigned int) pixel,q);
   2424                       }
   2425                     p+=GetPixelChannels(image);
   2426                   }
   2427                   break;
   2428                 }
   2429               }
   2430               extent=(size_t) (q-pixels);
   2431               break;
   2432             }
   2433           }
   2434           count=WriteBlob(image,extent,pixels);
   2435           if (count != (ssize_t) extent)
   2436             break;
   2437           if (image->previous == (Image *) NULL)
   2438             {
   2439               status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
   2440                 image->rows);
   2441               if (status == MagickFalse)
   2442                 break;
   2443             }
   2444         }
   2445         quantum_info=DestroyQuantumInfo(quantum_info);
   2446         break;
   2447       }
   2448       case 'F':
   2449       case 'f':
   2450       {
   2451         register unsigned char
   2452           *pixels;
   2453 
   2454         (void) WriteBlobString(image,image->endian == LSBEndian ? "-1.0\n" :
   2455           "1.0\n");
   2456         image->depth=32;
   2457         quantum_type=format == 'f' ? GrayQuantum : RGBQuantum;
   2458         quantum_info=AcquireQuantumInfo(image_info,image);
   2459         if (quantum_info == (QuantumInfo *) NULL)
   2460           ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
   2461         status=SetQuantumFormat(image,quantum_info,FloatingPointQuantumFormat);
   2462         if (status == MagickFalse)
   2463           ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
   2464         pixels=GetQuantumPixels(quantum_info);
   2465         for (y=(ssize_t) image->rows-1; y >= 0; y--)
   2466         {
   2467           register const Quantum
   2468             *magick_restrict p;
   2469 
   2470           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
   2471           if (p == (const Quantum *) NULL)
   2472             break;
   2473           extent=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
   2474             quantum_type,pixels,exception);
   2475           (void) WriteBlob(image,extent,pixels);
   2476           if (image->previous == (Image *) NULL)
   2477             {
   2478               status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
   2479                 image->rows);
   2480               if (status == MagickFalse)
   2481                 break;
   2482             }
   2483         }
   2484         quantum_info=DestroyQuantumInfo(quantum_info);
   2485         break;
   2486       }
   2487     }
   2488     if (GetNextImageInList(image) == (Image *) NULL)
   2489       break;
   2490     image=SyncNextImageInList(image);
   2491     status=SetImageProgress(image,SaveImagesTag,scene++,imageListLength);
   2492     if (status == MagickFalse)
   2493       break;
   2494   } while (image_info->adjoin != MagickFalse);
   2495   (void) CloseBlob(image);
   2496   return(MagickTrue);
   2497 }
   2498