]> granicus.if.org Git - imagemagick/blobdiff - coders/tiff.c
(no commit message)
[imagemagick] / coders / tiff.c
index 54828f388762b12f4cad69a8b1960568af888feb..190ffa5f226ccb280483d60043eea6f1b95853bd 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  %
@@ -66,6 +66,7 @@
 #include "MagickCore/monitor-private.h"
 #include "MagickCore/option.h"
 #include "MagickCore/pixel-accessor.h"
+#include "MagickCore/pixel-private.h"
 #include "MagickCore/property.h"
 #include "MagickCore/quantum.h"
 #include "MagickCore/quantum-private.h"
@@ -601,6 +602,8 @@ static void TIFFGetProfiles(TIFF *tiff,Image *image,ExceptionInfo *exception)
   length=0;
   if (TIFFGetField(tiff,37724,&length,&profile) == 1)
     (void) ReadProfile(image,"tiff:37724",profile,(ssize_t) length,exception);
+  if (TIFFGetField(tiff,34118,&length,&profile) == 1)
+    (void) ReadProfile(image,"tiff:34118",profile,(ssize_t) length,exception);
 }
 
 static void TIFFGetProperties(TIFF *tiff,Image *image,ExceptionInfo *exception)
@@ -1069,6 +1072,11 @@ static Image *ReadTIFFImage(const ImageInfo *image_info,
       SetImageColorspace(image,CMYKColorspace,exception);
     if (photometric == PHOTOMETRIC_CIELAB)
       SetImageColorspace(image,LabColorspace,exception);
+    TIFFGetProfiles(tiff,image,exception);
+    TIFFGetProperties(tiff,image,exception);
+    option=GetImageOption(image_info,"tiff:exif-properties");
+    if (IfMagickTrue(IsStringNotFalse(option))) /* enabled by default */
+      TIFFGetEXIFProperties(tiff,image,exception);
     (void) TIFFGetFieldDefaulted(tiff,TIFFTAG_SAMPLESPERPIXEL,
       &samples_per_pixel);
     (void) TIFFGetFieldDefaulted(tiff,TIFFTAG_RESOLUTIONUNIT,&units);
@@ -1078,8 +1086,8 @@ static Image *ReadTIFFImage(const ImageInfo *image_info,
     (void) TIFFGetFieldDefaulted(tiff,TIFFTAG_YRESOLUTION,&y_resolution);
     image->resolution.x=x_resolution;
     image->resolution.y=y_resolution;
-    x_position=(float) image->page.x/x_resolution;
-    y_position=(float) image->page.y/y_resolution;
+    x_position=(float) PerceptibleReciprocal(x_resolution)*image->page.x;
+    y_position=(float) PerceptibleReciprocal(y_resolution)*image->page.y;
     (void) TIFFGetFieldDefaulted(tiff,TIFFTAG_XPOSITION,&x_position);
     (void) TIFFGetFieldDefaulted(tiff,TIFFTAG_YPOSITION,&y_position);
     image->page.x=(ssize_t) ceil(x_position*x_resolution-0.5);
@@ -1136,12 +1144,6 @@ static Image *ReadTIFFImage(const ImageInfo *image_info,
              sampling_factor,exception);
            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
              "Sampling Factors: %s",sampling_factor);
-           if ((samples_per_pixel > 1) && (photometric == PHOTOMETRIC_YCBCR))
-             {
-               (void) TIFFSetField(tiff,TIFFTAG_JPEGCOLORMODE,
-                 JPEGCOLORMODE_RGB);
-               photometric=PHOTOMETRIC_RGB;
-             }
          }
 #endif
         break;
@@ -1155,11 +1157,6 @@ static Image *ReadTIFFImage(const ImageInfo *image_info,
       case COMPRESSION_ADOBE_DEFLATE: image->compression=ZipCompression; break;
       default: image->compression=RLECompression; break;
     }
-    TIFFGetProfiles(tiff,image,exception);
-    TIFFGetProperties(tiff,image,exception);
-    option=GetImageOption(image_info,"tiff:exif-properties");
-    if (IfMagickTrue(IsStringNotFalse(option))) /* enabled by default */
-      TIFFGetEXIFProperties(tiff,image,exception);
     /*
       Allocate memory for the image and pixel buffer.
     */
@@ -1204,12 +1201,12 @@ static Image *ReadTIFFImage(const ImageInfo *image_info,
     if (extra_samples == 0)
       {
         if ((samples_per_pixel == 4) && (photometric == PHOTOMETRIC_RGB))
-          image->matte=MagickTrue;
+          image->alpha_trait=BlendPixelTrait;
       }
     else
       for (i=0; i < extra_samples; i++)
       {
-        image->matte=MagickTrue;
+        image->alpha_trait=BlendPixelTrait;
         if (sample_info[i] == EXTRASAMPLE_ASSOCALPHA)
           SetQuantumAlphaType(quantum_info,DisassociatedQuantumAlpha);
       }
@@ -1217,7 +1214,7 @@ static Image *ReadTIFFImage(const ImageInfo *image_info,
     if (option != (const char *) NULL)
       associated_alpha=LocaleCompare(option,"associated") == 0 ? MagickTrue :
         MagickFalse;
-    if (image->matte != MagickFalse)
+    if (image->alpha_trait == BlendPixelTrait)
       (void) SetImageProperty(image,"tiff:alpha",
         associated_alpha != MagickFalse ? "associated" : "unassociated",
         exception);
@@ -1301,29 +1298,37 @@ static Image *ReadTIFFImage(const ImageInfo *image_info,
             /*
               Initialize colormap.
             */
+            red_colormap=(uint16 *) NULL;
+            green_colormap=(uint16 *) NULL;
+            blue_colormap=(uint16 *) NULL;
             (void) TIFFGetField(tiff,TIFFTAG_COLORMAP,&red_colormap,
               &green_colormap,&blue_colormap);
-            range=255;  /* might be old style 8-bit colormap */
-            for (i=0; i < (ssize_t) image->colors; i++)
-              if ((red_colormap[i] >= 256) || (green_colormap[i] >= 256) ||
-                  (blue_colormap[i] >= 256))
+            if ((red_colormap != (uint16 *) NULL) &&
+                (green_colormap != (uint16 *) NULL) &&
+                (blue_colormap != (uint16 *) NULL))
+              {
+                range=255;  /* might be old style 8-bit colormap */
+                for (i=0; i < (ssize_t) image->colors; i++)
+                  if ((red_colormap[i] >= 256) || (green_colormap[i] >= 256) ||
+                      (blue_colormap[i] >= 256))
+                    {
+                      range=65535;
+                      break;
+                    }
+                for (i=0; i < (ssize_t) image->colors; i++)
                 {
-                  range=65535;
-                  break;
+                  image->colormap[i].red=ClampToQuantum(((double)
+                    QuantumRange*red_colormap[i])/range);
+                  image->colormap[i].green=ClampToQuantum(((double)
+                    QuantumRange*green_colormap[i])/range);
+                  image->colormap[i].blue=ClampToQuantum(((double)
+                    QuantumRange*blue_colormap[i])/range);
                 }
-            for (i=0; i < (ssize_t) image->colors; i++)
-            {
-              image->colormap[i].red=ClampToQuantum(((double) QuantumRange*
-                red_colormap[i])/range);
-              image->colormap[i].green=ClampToQuantum(((double) QuantumRange*
-                green_colormap[i])/range);
-              image->colormap[i].blue=ClampToQuantum(((double) QuantumRange*
-                blue_colormap[i])/range);
-            }
+              }
           }
         quantum_type=IndexQuantum;
         pad=(size_t) MagickMax((size_t) samples_per_pixel-1,0);
-        if (image->matte != MagickFalse)
+        if (image->alpha_trait == BlendPixelTrait)
           {
             if (image->storage_class != PseudoClass)
               {
@@ -1386,7 +1391,7 @@ static Image *ReadTIFFImage(const ImageInfo *image_info,
         */
         pad=(size_t) MagickMax((size_t) samples_per_pixel-3,0);
         quantum_type=RGBQuantum;
-        if (image->matte != MagickFalse)
+        if (image->alpha_trait == BlendPixelTrait)
           {
             quantum_type=RGBAQuantum;
             pad=(size_t) MagickMax((size_t) samples_per_pixel-4,0);
@@ -1395,7 +1400,7 @@ static Image *ReadTIFFImage(const ImageInfo *image_info,
           {
             pad=(size_t) MagickMax((size_t) samples_per_pixel-4,0);
             quantum_type=CMYKQuantum;
-            if (image->matte != MagickFalse)
+            if (image->alpha_trait == BlendPixelTrait)
               {
                 quantum_type=CMYKAQuantum;
                 pad=(size_t) MagickMax((size_t) samples_per_pixel-5,0);
@@ -1530,7 +1535,7 @@ static Image *ReadTIFFImage(const ImageInfo *image_info,
               (TIFFGetG(*p))),q);
             SetPixelBlue(image,ScaleCharToQuantum((unsigned char)
               (TIFFGetB(*p))),q);
-            if (image->matte != MagickFalse)
+            if (image->alpha_trait == BlendPixelTrait)
               SetPixelAlpha(image,ScaleCharToQuantum((unsigned char)
                 (TIFFGetA(*p))),q);
             p++;
@@ -1615,7 +1620,7 @@ static Image *ReadTIFFImage(const ImageInfo *image_info,
               x);
             for (row=rows_remaining; row > 0; row--)
             {
-              if (image->matte != MagickFalse)
+              if (image->alpha_trait == BlendPixelTrait)
                 for (column=columns_remaining; column > 0; column--)
                 {
                   SetPixelRed(image,ScaleCharToQuantum((unsigned char)
@@ -1710,7 +1715,7 @@ static Image *ReadTIFFImage(const ImageInfo *image_info,
               TIFFGetG(*p)),q);
             SetPixelBlue(image,ScaleCharToQuantum((unsigned char)
               TIFFGetB(*p)),q);
-            if (image->matte != MagickFalse)
+            if (image->alpha_trait == BlendPixelTrait)
               SetPixelAlpha(image,ScaleCharToQuantum((unsigned char)
                 TIFFGetA(*p)),q);
             p--;
@@ -1745,14 +1750,6 @@ static Image *ReadTIFFImage(const ImageInfo *image_info,
       }
     if (image->storage_class == PseudoClass)
       image->depth=GetImageDepth(image,exception);
-    if ((photometric == PHOTOMETRIC_LOGL) ||
-        (photometric == PHOTOMETRIC_MINISBLACK) ||
-        (photometric == PHOTOMETRIC_MINISWHITE))
-      {
-         image->type=GrayscaleType;
-         if (bits_per_sample == 1)
-           image->type=BilevelType;
-      }
     /*
       Proceed to next image.
     */
@@ -1818,10 +1815,10 @@ static void TIFFTagExtender(TIFF *tiff)
   static const TIFFFieldInfo
     TIFFExtensions[] =
     {
-      {
-        37724, -3, -3, TIFF_UNDEFINED, FIELD_CUSTOM, 1, 1,
-          (char *) "PhotoshopLayerData"
-      }
+      { 37724, -3, -3, TIFF_UNDEFINED, FIELD_CUSTOM, 1, 1,
+        (char *) "PhotoshopLayerData" },
+      { 34118, -3, -3, TIFF_UNDEFINED, FIELD_CUSTOM, 1, 1,
+        (char *) "Microscope" }
     };
 
   TIFFMergeFieldInfo(tiff,TIFFExtensions,sizeof(TIFFExtensions)/
@@ -2475,6 +2472,11 @@ static void TIFFSetProfiles(TIFF *tiff,Image *image)
   for (name=GetNextImageProfile(image); name != (const char *) NULL; )
   {
     profile=GetImageProfile(image,name);
+    if (GetStringInfoLength(profile) == 0)
+      {
+        name=GetNextImageProfile(image);
+        continue;
+      }
 #if defined(TIFFTAG_XMLPACKET)
     if (LocaleCompare(name,"xmp") == 0)
       (void) TIFFSetField(tiff,TIFFTAG_XMLPACKET,(uint32) GetStringInfoLength(
@@ -2512,6 +2514,9 @@ static void TIFFSetProfiles(TIFF *tiff,Image *image)
     if (LocaleCompare(name,"tiff:37724") == 0)
       (void) TIFFSetField(tiff,37724,(uint32) GetStringInfoLength(profile),
         GetStringInfoDatum(profile));
+    if (LocaleCompare(name,"tiff:34118") == 0)
+      (void) TIFFSetField(tiff,34118,(uint32) GetStringInfoLength(profile),
+        GetStringInfoDatum(profile));
     name=GetNextImageProfile(image);
   }
 }
@@ -2924,7 +2929,8 @@ static MagickBooleanType WriteTIFFImage(const ImageInfo *image_info,
                   MagickFalse ? PHOTOMETRIC_MINISWHITE :
                   PHOTOMETRIC_MINISBLACK);
                 (void) TIFFSetField(tiff,TIFFTAG_SAMPLESPERPIXEL,1);
-                if ((image_info->depth == 0) && (image->matte == MagickFalse) &&
+                if ((image_info->depth == 0) &&
+                    (image->alpha_trait != BlendPixelTrait) &&
                     (IsImageMonochrome(image,exception) != MagickFalse))
                   {
                     status=SetQuantumDepth(image,quantum_info,1);
@@ -3000,7 +3006,7 @@ static MagickBooleanType WriteTIFFImage(const ImageInfo *image_info,
     (void) TIFFSetField(tiff,TIFFTAG_COMPRESSION,compress_tag);
     (void) TIFFSetField(tiff,TIFFTAG_FILLORDER,endian);
     (void) TIFFSetField(tiff,TIFFTAG_BITSPERSAMPLE,quantum_info->depth);
-    if (image->matte != MagickFalse)
+    if (image->alpha_trait == BlendPixelTrait)
       {
         uint16
           extra_samples,
@@ -3185,7 +3191,7 @@ static MagickBooleanType WriteTIFFImage(const ImageInfo *image_info,
         (void) TIFFSetField(tiff,TIFFTAG_RESOLUTIONUNIT,(uint16) units);
         (void) TIFFSetField(tiff,TIFFTAG_XRESOLUTION,image->resolution.x);
         (void) TIFFSetField(tiff,TIFFTAG_YRESOLUTION,image->resolution.y);
-        if ((image->page.x != 0) || (image->page.y != 0))
+        if ((image->page.x > 0) && (image->page.y > 0))
           {
             /*
               Set image position.
@@ -3264,7 +3270,7 @@ static MagickBooleanType WriteTIFFImage(const ImageInfo *image_info,
           default:
           {
             quantum_type=RGBQuantum;
-            if (image->matte != MagickFalse)
+            if (image->alpha_trait == BlendPixelTrait)
               quantum_type=RGBAQuantum;
             for (y=0; y < (ssize_t) image->rows; y++)
             {
@@ -3352,7 +3358,7 @@ static MagickBooleanType WriteTIFFImage(const ImageInfo *image_info,
                 if (status == MagickFalse)
                   break;
               }
-            if (image->matte != MagickFalse)
+            if (image->alpha_trait == BlendPixelTrait)
               for (y=0; y < (ssize_t) image->rows; y++)
               {
                 register const Quantum
@@ -3383,7 +3389,7 @@ static MagickBooleanType WriteTIFFImage(const ImageInfo *image_info,
           CMYK TIFF image.
         */
         quantum_type=CMYKQuantum;
-        if (image->matte != MagickFalse)
+        if (image->alpha_trait == BlendPixelTrait)
           quantum_type=CMYKAQuantum;
         if (image->colorspace != CMYKColorspace)
           (void) TransformImageColorspace(image,CMYKColorspace,exception);
@@ -3448,7 +3454,7 @@ static MagickBooleanType WriteTIFFImage(const ImageInfo *image_info,
           Convert PseudoClass packets to contiguous grayscale scanlines.
         */
         quantum_type=IndexQuantum;
-        if (image->matte != MagickFalse)
+        if (image->alpha_trait == BlendPixelTrait)
           {
             if (photometric != PHOTOMETRIC_PALETTE)
               quantum_type=GrayAlphaQuantum;