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