]> granicus.if.org Git - imagemagick/blobdiff - coders/pnm.c
(no commit message)
[imagemagick] / coders / pnm.c
index dfb604248987dbc29bbf5568bad2b977cb228004..edb28874ab1fdd7bac5595ab76213697b7a36f9a 100644 (file)
@@ -17,7 +17,7 @@
 %                                 July 1992                                   %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2013 ImageMagick Studio LLC, a non-profit organization      %
 %  dedicated to making software imaging solutions freely available.           %
 %                                                                             %
 %  You may not use this file except in compliance with the License.  You may  %
@@ -195,8 +195,11 @@ static size_t PNMInteger(Image *image,const unsigned int base,
               p=comment+strlen(comment);
             }
           c=ReadBlobByte(image);
-          *p=(char) c;
-          *(p+1)='\0';
+          if (c != (int) '\n')
+            {
+              *p=(char) c;
+              *(p+1)='\0';
+            }
         }
         if (comment == (char *) NULL)
           return(0);
@@ -369,38 +372,42 @@ static Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception)
           if (LocaleCompare(keyword,"TUPLTYPE") == 0)
             {
               if (LocaleCompare(value,"BLACKANDWHITE") == 0)
-                quantum_type=GrayQuantum;
+                {
+                  SetImageColorspace(image,GRAYColorspace,exception);
+                  quantum_type=GrayQuantum;
+                }
               if (LocaleCompare(value,"BLACKANDWHITE_ALPHA") == 0)
                 {
+                  SetImageColorspace(image,GRAYColorspace,exception);
+                  image->alpha_trait=BlendPixelTrait;
                   quantum_type=GrayAlphaQuantum;
-                  image->matte=MagickTrue;
                 }
               if (LocaleCompare(value,"GRAYSCALE") == 0)
                 {
-                  image->colorspace=GRAYColorspace;
                   quantum_type=GrayQuantum;
+                  SetImageColorspace(image,GRAYColorspace,exception);
                 }
               if (LocaleCompare(value,"GRAYSCALE_ALPHA") == 0)
                 {
-                  image->colorspace=GRAYColorspace;
-                  image->matte=MagickTrue;
+                  SetImageColorspace(image,GRAYColorspace,exception);
+                  image->alpha_trait=BlendPixelTrait;
                   quantum_type=GrayAlphaQuantum;
                 }
               if (LocaleCompare(value,"RGB_ALPHA") == 0)
                 {
+                  image->alpha_trait=BlendPixelTrait;
                   quantum_type=RGBAQuantum;
-                  image->matte=MagickTrue;
                 }
               if (LocaleCompare(value,"CMYK") == 0)
                 {
+                  SetImageColorspace(image,CMYKColorspace,exception);
                   quantum_type=CMYKQuantum;
-                  image->colorspace=CMYKColorspace;
                 }
               if (LocaleCompare(value,"CMYK_ALPHA") == 0)
                 {
+                  SetImageColorspace(image,CMYKColorspace,exception);
+                  image->alpha_trait=BlendPixelTrait;
                   quantum_type=CMYKAQuantum;
-                  image->colorspace=CMYKColorspace;
-                  image->matte=MagickTrue;
                 }
             }
           if (LocaleCompare(keyword,"width") == 0)
@@ -428,7 +435,7 @@ static Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception)
         /*
           Convert PBM image to pixel packets.
         */
-        image->colorspace=GRAYColorspace;
+        SetImageColorspace(image,GRAYColorspace,exception);
         for (y=0; y < (ssize_t) image->rows; y++)
         {
           register ssize_t
@@ -467,7 +474,7 @@ static Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception)
         /*
           Convert PGM image to pixel packets.
         */
-        image->colorspace=GRAYColorspace;
+        SetImageColorspace(image,GRAYColorspace,exception);
         scale=(Quantum *) NULL;
         if (max_value != (1U*QuantumRange))
           {
@@ -550,16 +557,16 @@ static Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception)
             break;
           for (x=0; x < (ssize_t) image->columns; x++)
           {
-            pixel.red=(MagickRealType) PNMInteger(image,10,exception);
-            pixel.green=(MagickRealType) PNMInteger(image,10,exception);
-            pixel.blue=(MagickRealType) PNMInteger(image,10,exception);
+            pixel.red=(double) PNMInteger(image,10,exception);
+            pixel.green=(double) PNMInteger(image,10,exception);
+            pixel.blue=(double) PNMInteger(image,10,exception);
             if (scale != (Quantum *) NULL)
               {
-                pixel.red=(MagickRealType) scale[ConstrainPixel(image,(ssize_t)
+                pixel.red=(double) scale[ConstrainPixel(image,(ssize_t)
                   pixel.red,max_value,exception)];
-                pixel.green=(MagickRealType) scale[ConstrainPixel(image,
+                pixel.green=(double) scale[ConstrainPixel(image,
                   (ssize_t) pixel.green,max_value,exception)];
-                pixel.blue=(MagickRealType) scale[ConstrainPixel(image,(ssize_t)
+                pixel.blue=(double) scale[ConstrainPixel(image,(ssize_t)
                   pixel.blue,max_value,exception)];
               }
             SetPixelRed(image,ClampToQuantum(pixel.red),q);
@@ -586,7 +593,7 @@ static Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception)
         /*
           Convert PBM raw image to pixel packets.
         */
-        image->colorspace=GRAYColorspace;
+        SetImageColorspace(image,GRAYColorspace,exception);
         quantum_type=GrayQuantum;
         if (image->storage_class == PseudoClass)
           quantum_type=IndexQuantum;
@@ -661,7 +668,7 @@ static Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception)
         /*
           Convert PGM raw image to pixel packets.
         */
-        image->colorspace=GRAYColorspace;
+        SetImageColorspace(image,GRAYColorspace,exception);
         range=GetQuantumRange(image->depth);
         quantum_type=GrayQuantum;
         extent=(image->depth <= 8 ? 1 : 2)*image->columns;
@@ -756,22 +763,19 @@ static Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception)
       }
       case '6':
       {
-        ImageType
-          type;
-
         QuantumAny
           range;
 
         /*
           Convert PNM raster image to pixel packets.
         */
-        type=BilevelType;
         quantum_type=RGBQuantum;
         extent=3*(image->depth <= 8 ? 1 : 2)*image->columns;
         range=GetQuantumRange(image->depth);
         quantum_info=AcquireQuantumInfo(image_info,image);
         if (quantum_info == (QuantumInfo *) NULL)
           ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
+        (void) SetQuantumEndian(image,quantum_info,MSBEndian);
         for (y=0; y < (ssize_t) image->rows; y++)
         {
           MagickBooleanType
@@ -882,23 +886,6 @@ static Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception)
                     q+=GetPixelChannels(image);
                   }
                 }
-          if ((type == BilevelType) || (type == GrayscaleType))
-            {
-              q=QueueAuthenticPixels(image,0,offset,image->columns,1,exception);
-              for (x=0; x < (ssize_t) image->columns; x++)
-              {
-                if ((type == BilevelType) &&
-                    (IsPixelMonochrome(image,q) == MagickFalse))
-                  type=IsPixelGray(image,q) == MagickFalse ? UndefinedType :
-                    GrayscaleType;
-                if ((type == GrayscaleType) &&
-                    (IsPixelGray(image,q) == MagickFalse))
-                  type=UndefinedType;
-                if ((type != BilevelType) && (type != GrayscaleType))
-                  break;
-                q+=GetPixelChannels(image);
-              }
-            }
           sync=SyncAuthenticPixels(image,exception);
           if (sync == MagickFalse)
             status=MagickFalse;
@@ -906,8 +893,6 @@ static Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception)
         quantum_info=DestroyQuantumInfo(quantum_info);
         if (status == MagickFalse)
           ThrowReaderException(CorruptImageError,"UnableToReadImageData");
-        if (type != UndefinedType)
-          image->type=type;
         break;
       }
       case '7':
@@ -942,7 +927,7 @@ static Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception)
             break;
           }
         }
-        if (image->matte != MagickFalse)
+        if (image->alpha_trait == BlendPixelTrait)
           channels++;
         extent=channels*(image->depth <= 8 ? 1 : 2)*image->columns;
         quantum_info=AcquireQuantumInfo(image_info,image);
@@ -1015,7 +1000,7 @@ static Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception)
                       p=PushCharPixel(p,&pixel);
                       SetPixelGray(image,ScaleAnyToQuantum(pixel,range),q);
                       SetPixelAlpha(image,OpaqueAlpha,q);
-                      if (image->matte != MagickFalse)
+                      if (image->alpha_trait == BlendPixelTrait)
                         {
                           p=PushCharPixel(p,&pixel);
                           SetPixelAlpha(image,ScaleAnyToQuantum(pixel,range),q);
@@ -1033,7 +1018,7 @@ static Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception)
                       p=PushShortPixel(MSBEndian,p,&pixel);
                       SetPixelGray(image,ScaleAnyToQuantum(pixel,range),q);
                       SetPixelAlpha(image,OpaqueAlpha,q);
-                      if (image->matte != MagickFalse)
+                      if (image->alpha_trait == BlendPixelTrait)
                         {
                           p=PushShortPixel(MSBEndian,p,&pixel);
                           SetPixelAlpha(image,ScaleAnyToQuantum(pixel,range),q);
@@ -1062,7 +1047,7 @@ static Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception)
                       p=PushCharPixel(p,&pixel);
                       SetPixelBlack(image,ScaleAnyToQuantum(pixel,range),q);
                       SetPixelAlpha(image,OpaqueAlpha,q);
-                      if (image->matte != MagickFalse)
+                      if (image->alpha_trait == BlendPixelTrait)
                         {
                           p=PushCharPixel(p,&pixel);
                           SetPixelAlpha(image,ScaleAnyToQuantum(pixel,range),q);
@@ -1086,7 +1071,7 @@ static Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception)
                       p=PushShortPixel(MSBEndian,p,&pixel);
                       SetPixelBlack(image,ScaleAnyToQuantum(pixel,range),q);
                       SetPixelAlpha(image,OpaqueAlpha,q);
-                      if (image->matte != MagickFalse)
+                      if (image->alpha_trait == BlendPixelTrait)
                         {
                           p=PushShortPixel(MSBEndian,p,&pixel);
                           SetPixelAlpha(image,ScaleAnyToQuantum(pixel,range),q);
@@ -1112,7 +1097,7 @@ static Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception)
                       p=PushCharPixel(p,&pixel);
                       SetPixelBlue(image,ScaleAnyToQuantum(pixel,range),q);
                       SetPixelAlpha(image,OpaqueAlpha,q);
-                      if (image->matte != MagickFalse)
+                      if (image->alpha_trait == BlendPixelTrait)
                         {
                           p=PushCharPixel(p,&pixel);
                           SetPixelAlpha(image,ScaleAnyToQuantum(pixel,range),q);
@@ -1134,7 +1119,7 @@ static Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception)
                       p=PushShortPixel(MSBEndian,p,&pixel);
                       SetPixelBlue(image,ScaleAnyToQuantum(pixel,range),q);
                       SetPixelAlpha(image,OpaqueAlpha,q);
-                      if (image->matte != MagickFalse)
+                      if (image->alpha_trait == BlendPixelTrait)
                         {
                           p=PushShortPixel(MSBEndian,p,&pixel);
                           SetPixelAlpha(image,ScaleAnyToQuantum(pixel,range),q);
@@ -1161,6 +1146,8 @@ static Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception)
         /*
           Convert PFM raster image to pixel packets.
         */
+        if (format == 'f')
+          SetImageColorspace(image,GRAYColorspace,exception);
         quantum_type=format == 'f' ? GrayQuantum : RGBQuantum;
         image->endian=quantum_scale < 0.0 ? LSBEndian : MSBEndian;
         image->depth=32;
@@ -1173,8 +1160,7 @@ static Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception)
         status=SetQuantumFormat(image,quantum_info,FloatingPointQuantumFormat);
         if (status == MagickFalse)
           ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
-        SetQuantumScale(quantum_info,(MagickRealType) QuantumRange*
-          fabs(quantum_scale));
+        SetQuantumScale(quantum_info,(double) QuantumRange*fabs(quantum_scale));
         extent=GetQuantumExtent(image,quantum_info,quantum_type);
         for (y=0; y < (ssize_t) image->rows; y++)
         {
@@ -1239,8 +1225,11 @@ static Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception)
         ThrowReaderException(CorruptImageError,"ImproperImageHeader");
     }
     if (EOFBlob(image) != MagickFalse)
-      (void) ThrowMagickException(exception,GetMagickModule(),CorruptImageError,
-        "UnexpectedEndOfFile","`%s'",image->filename);
+      {
+        (void) ThrowMagickException(exception,GetMagickModule(),
+          CorruptImageError,"UnexpectedEndOfFile","`%s'",image->filename);
+        break;
+      }
     /*
       Proceed to next image.
     */
@@ -1552,8 +1541,6 @@ static MagickBooleanType WritePNMImage(const ImageInfo *image_info,Image *image,
       }
     if (format != '7')
       {
-        if (IsRGBColorspace(image->colorspace) == MagickFalse)
-          (void) TransformImageColorspace(image,RGBColorspace,exception);
         (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g %.20g\n",
           (double) image->columns,(double) image->rows);
         (void) WriteBlobString(image,buffer);
@@ -1590,14 +1577,14 @@ static MagickBooleanType WritePNMImage(const ImageInfo *image_info,Image *image,
           default:
           {
             quantum_type=RGBQuantum;
-            if (image->matte != MagickFalse)
+            if (image->alpha_trait == BlendPixelTrait)
               quantum_type=RGBAQuantum;
             packet_size=3;
             (void) CopyMagickString(type,"RGB",MaxTextExtent);
             break;
           }
         }
-        if (image->matte != MagickFalse)
+        if (image->alpha_trait == BlendPixelTrait)
           {
             packet_size++;
             (void) ConcatenateMagickString(type,"_ALPHA",MaxTextExtent);
@@ -1625,6 +1612,8 @@ static MagickBooleanType WritePNMImage(const ImageInfo *image_info,Image *image,
         /*
           Convert image to a PBM image.
         */
+        if (IsImageGray(image,exception) == MagickFalse)
+          (void) TransformImageColorspace(image,GRAYColorspace,exception);
         q=pixels;
         for (y=0; y < (ssize_t) image->rows; y++)
         {
@@ -1674,6 +1663,8 @@ static MagickBooleanType WritePNMImage(const ImageInfo *image_info,Image *image,
         /*
           Convert image to a PGM image.
         */
+        if (IsImageGray(image,exception) == MagickFalse)
+          (void) TransformImageColorspace(image,GRAYColorspace,exception);
         if (image->depth <= 8)
           (void) WriteBlobString(image,"255\n");
         else
@@ -1733,6 +1724,8 @@ static MagickBooleanType WritePNMImage(const ImageInfo *image_info,Image *image,
         /*
           Convert image to a PNM image.
         */
+        if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
+          (void) TransformImageColorspace(image,sRGBColorspace,exception);
         if (image->depth <= 8)
           (void) WriteBlobString(image,"255\n");
         else
@@ -1792,6 +1785,8 @@ static MagickBooleanType WritePNMImage(const ImageInfo *image_info,Image *image,
         /*
           Convert image to a PBM image.
         */
+        if (IsImageGray(image,exception) == MagickFalse)
+          (void) TransformImageColorspace(image,GRAYColorspace,exception);
         image->depth=1;
         quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
         if (quantum_info == (QuantumInfo *) NULL)
@@ -1830,6 +1825,8 @@ static MagickBooleanType WritePNMImage(const ImageInfo *image_info,Image *image,
         /*
           Convert image to a PGM image.
         */
+        if (IsImageGray(image,exception) == MagickFalse)
+          (void) TransformImageColorspace(image,GRAYColorspace,exception);
         if (image->depth > 8)
           image->depth=16;
         (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g\n",(double)
@@ -1913,6 +1910,8 @@ static MagickBooleanType WritePNMImage(const ImageInfo *image_info,Image *image,
         /*
           Convert image to a PNM image.
         */
+        if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
+          (void) TransformImageColorspace(image,sRGBColorspace,exception);
         if (image->depth > 8)
           image->depth=16;
         (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g\n",(double)
@@ -1921,6 +1920,7 @@ static MagickBooleanType WritePNMImage(const ImageInfo *image_info,Image *image,
         quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
         if (quantum_info == (QuantumInfo *) NULL)
           ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
+        (void) SetQuantumEndian(image,quantum_info,MSBEndian);
         pixels=GetQuantumPixels(quantum_info);
         extent=GetQuantumExtent(image,quantum_info,quantum_type);
         range=GetQuantumRange(image->depth);
@@ -2019,7 +2019,7 @@ static MagickBooleanType WritePNMImage(const ImageInfo *image_info,Image *image,
                     {
                       pixel=ScaleQuantumToAny(GetPixelIntensity(image,p),range);
                       q=PopCharPixel((unsigned char) pixel,q);
-                      if (image->matte != MagickFalse)
+                      if (image->alpha_trait == BlendPixelTrait)
                         {
                           pixel=(unsigned char) ScaleQuantumToAny(
                             GetPixelAlpha(image,p),range);
@@ -2032,7 +2032,7 @@ static MagickBooleanType WritePNMImage(const ImageInfo *image_info,Image *image,
                     {
                       pixel=ScaleQuantumToAny(GetPixelIntensity(image,p),range);
                       q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
-                      if (image->matte != MagickFalse)
+                      if (image->alpha_trait == BlendPixelTrait)
                         {
                           pixel=(unsigned char) ScaleQuantumToAny(
                             GetPixelAlpha(image,p),range);
@@ -2056,7 +2056,7 @@ static MagickBooleanType WritePNMImage(const ImageInfo *image_info,Image *image,
                       q=PopCharPixel((unsigned char) pixel,q);
                       pixel=ScaleQuantumToAny(GetPixelBlack(image,p),range);
                       q=PopCharPixel((unsigned char) pixel,q);
-                      if (image->matte != MagickFalse)
+                      if (image->alpha_trait == BlendPixelTrait)
                         {
                           pixel=ScaleQuantumToAny(GetPixelAlpha(image,p),range);
                           q=PopCharPixel((unsigned char) pixel,q);
@@ -2074,7 +2074,7 @@ static MagickBooleanType WritePNMImage(const ImageInfo *image_info,Image *image,
                       q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
                       pixel=ScaleQuantumToAny(GetPixelBlack(image,p),range);
                       q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
-                      if (image->matte != MagickFalse)
+                      if (image->alpha_trait == BlendPixelTrait)
                         {
                           pixel=ScaleQuantumToAny(GetPixelAlpha(image,p),range);
                           q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
@@ -2094,7 +2094,7 @@ static MagickBooleanType WritePNMImage(const ImageInfo *image_info,Image *image,
                       q=PopCharPixel((unsigned char) pixel,q);
                       pixel=ScaleQuantumToAny(GetPixelBlue(image,p),range);
                       q=PopCharPixel((unsigned char) pixel,q);
-                      if (image->matte != MagickFalse)
+                      if (image->alpha_trait == BlendPixelTrait)
                         {
                           pixel=ScaleQuantumToAny(GetPixelAlpha(image,p),range);
                           q=PopCharPixel((unsigned char) pixel,q);
@@ -2110,7 +2110,7 @@ static MagickBooleanType WritePNMImage(const ImageInfo *image_info,Image *image,
                       q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
                       pixel=ScaleQuantumToAny(GetPixelBlue(image,p),range);
                       q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
-                      if (image->matte != MagickFalse)
+                      if (image->alpha_trait == BlendPixelTrait)
                         {
                           pixel=ScaleQuantumToAny(GetPixelAlpha(image,p),range);
                           q=PopShortPixel(MSBEndian,(unsigned short) pixel,q);
@@ -2139,8 +2139,8 @@ static MagickBooleanType WritePNMImage(const ImageInfo *image_info,Image *image,
       case 'F':
       case 'f':
       {
-        (void) WriteBlobString(image,image->endian != LSBEndian ? "1.0\n" :
-          "-1.0\n");
+        (void) WriteBlobString(image,image->endian == LSBEndian ? "-1.0\n" :
+          "1.0\n");
         image->depth=32;
         quantum_type=format == 'f' ? GrayQuantum : RGBQuantum;
         quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);