% Read/Write TIFF Image Format %
% %
% Software Design %
-% John Cristy %
+% Cristy %
% July 1992 %
% %
% %
-% Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization %
+% Copyright 1999-2014 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 %
Include declarations.
*/
#include "MagickCore/studio.h"
+#include "MagickCore/artifact.h"
#include "MagickCore/attribute.h"
#include "MagickCore/blob.h"
#include "MagickCore/blob-private.h"
#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"
#include "MagickCore/string_.h"
#include "MagickCore/string-private.h"
#include "MagickCore/thread_.h"
+#include "MagickCore/token.h"
#include "MagickCore/utility.h"
#if defined(MAGICKCORE_TIFF_DELEGATE)
# if defined(MAGICKCORE_HAVE_TIFFCONF_H)
# define TIFFTAG_COPYRIGHT 33432
# endif
# if !defined(TIFFTAG_OPIIMAGEID)
-# define TIFF_OPIIMAGEID 32781
+# define TIFFTAG_OPIIMAGEID 32781
# endif
\f
/*
{
unsigned int
tag,
- type;
+ type,
+ variable_length;
const char
*property;
static const ExifInfo
exif_info[] = {
- { EXIFTAG_EXPOSURETIME, TIFF_RATIONAL, "exif:ExposureTime" },
- { EXIFTAG_FNUMBER, TIFF_RATIONAL, "exif:FNumber" },
- { EXIFTAG_EXPOSUREPROGRAM, TIFF_SHORT, "exif:ExposureProgram" },
- { EXIFTAG_SPECTRALSENSITIVITY, TIFF_ASCII, "exif:SpectralSensitivity" },
- { EXIFTAG_ISOSPEEDRATINGS, TIFF_SHORT, "exif:ISOSpeedRatings" },
- { EXIFTAG_OECF, TIFF_NOTYPE, "exif:OptoelectricConversionFactor" },
- { EXIFTAG_EXIFVERSION, TIFF_NOTYPE, "exif:ExifVersion" },
- { EXIFTAG_DATETIMEORIGINAL, TIFF_ASCII, "exif:DateTimeOriginal" },
- { EXIFTAG_DATETIMEDIGITIZED, TIFF_ASCII, "exif:DateTimeDigitized" },
- { EXIFTAG_COMPONENTSCONFIGURATION, TIFF_NOTYPE, "exif:ComponentsConfiguration" },
- { EXIFTAG_COMPRESSEDBITSPERPIXEL, TIFF_RATIONAL, "exif:CompressedBitsPerPixel" },
- { EXIFTAG_SHUTTERSPEEDVALUE, TIFF_SRATIONAL, "exif:ShutterSpeedValue" },
- { EXIFTAG_APERTUREVALUE, TIFF_RATIONAL, "exif:ApertureValue" },
- { EXIFTAG_BRIGHTNESSVALUE, TIFF_SRATIONAL, "exif:BrightnessValue" },
- { EXIFTAG_EXPOSUREBIASVALUE, TIFF_SRATIONAL, "exif:ExposureBiasValue" },
- { EXIFTAG_MAXAPERTUREVALUE, TIFF_RATIONAL, "exif:MaxApertureValue" },
- { EXIFTAG_SUBJECTDISTANCE, TIFF_RATIONAL, "exif:SubjectDistance" },
- { EXIFTAG_METERINGMODE, TIFF_SHORT, "exif:MeteringMode" },
- { EXIFTAG_LIGHTSOURCE, TIFF_SHORT, "exif:LightSource" },
- { EXIFTAG_FLASH, TIFF_SHORT, "exif:Flash" },
- { EXIFTAG_FOCALLENGTH, TIFF_RATIONAL, "exif:FocalLength" },
- { EXIFTAG_SUBJECTAREA, TIFF_NOTYPE, "exif:SubjectArea" },
- { EXIFTAG_MAKERNOTE, TIFF_NOTYPE, "exif:MakerNote" },
- { EXIFTAG_USERCOMMENT, TIFF_NOTYPE, "exif:UserComment" },
- { EXIFTAG_SUBSECTIME, TIFF_ASCII, "exif:SubSecTime" },
- { EXIFTAG_SUBSECTIMEORIGINAL, TIFF_ASCII, "exif:SubSecTimeOriginal" },
- { EXIFTAG_SUBSECTIMEDIGITIZED, TIFF_ASCII, "exif:SubSecTimeDigitized" },
- { EXIFTAG_FLASHPIXVERSION, TIFF_NOTYPE, "exif:FlashpixVersion" },
- { EXIFTAG_PIXELXDIMENSION, TIFF_LONG, "exif:PixelXDimension" },
- { EXIFTAG_PIXELXDIMENSION, TIFF_SHORT, "exif:PixelXDimension" },
- { EXIFTAG_PIXELYDIMENSION, TIFF_LONG, "exif:PixelYDimension" },
- { EXIFTAG_PIXELYDIMENSION, TIFF_SHORT, "exif:PixelYDimension" },
- { EXIFTAG_RELATEDSOUNDFILE, TIFF_ASCII, "exif:RelatedSoundFile" },
- { EXIFTAG_FLASHENERGY, TIFF_RATIONAL, "exif:FlashEnergy" },
- { EXIFTAG_SPATIALFREQUENCYRESPONSE, TIFF_NOTYPE, "exif:SpatialFrequencyResponse" },
- { EXIFTAG_FOCALPLANEXRESOLUTION, TIFF_RATIONAL, "exif:FocalPlaneXResolution" },
- { EXIFTAG_FOCALPLANEYRESOLUTION, TIFF_RATIONAL, "exif:FocalPlaneYResolution" },
- { EXIFTAG_FOCALPLANERESOLUTIONUNIT, TIFF_SHORT, "exif:FocalPlaneResolutionUnit" },
- { EXIFTAG_SUBJECTLOCATION, TIFF_SHORT, "exif:SubjectLocation" },
- { EXIFTAG_EXPOSUREINDEX, TIFF_RATIONAL, "exif:ExposureIndex" },
- { EXIFTAG_SENSINGMETHOD, TIFF_SHORT, "exif:SensingMethod" },
- { EXIFTAG_FILESOURCE, TIFF_NOTYPE, "exif:FileSource" },
- { EXIFTAG_SCENETYPE, TIFF_NOTYPE, "exif:SceneType" },
- { EXIFTAG_CFAPATTERN, TIFF_NOTYPE, "exif:CFAPattern" },
- { EXIFTAG_CUSTOMRENDERED, TIFF_SHORT, "exif:CustomRendered" },
- { EXIFTAG_EXPOSUREMODE, TIFF_SHORT, "exif:ExposureMode" },
- { EXIFTAG_WHITEBALANCE, TIFF_SHORT, "exif:WhiteBalance" },
- { EXIFTAG_DIGITALZOOMRATIO, TIFF_RATIONAL, "exif:DigitalZoomRatio" },
- { EXIFTAG_FOCALLENGTHIN35MMFILM, TIFF_SHORT, "exif:FocalLengthIn35mmFilm" },
- { EXIFTAG_SCENECAPTURETYPE, TIFF_SHORT, "exif:SceneCaptureType" },
- { EXIFTAG_GAINCONTROL, TIFF_RATIONAL, "exif:GainControl" },
- { EXIFTAG_CONTRAST, TIFF_SHORT, "exif:Contrast" },
- { EXIFTAG_SATURATION, TIFF_SHORT, "exif:Saturation" },
- { EXIFTAG_SHARPNESS, TIFF_SHORT, "exif:Sharpness" },
- { EXIFTAG_DEVICESETTINGDESCRIPTION, TIFF_NOTYPE, "exif:DeviceSettingDescription" },
- { EXIFTAG_SUBJECTDISTANCERANGE, TIFF_SHORT, "exif:SubjectDistanceRange" },
- { EXIFTAG_IMAGEUNIQUEID, TIFF_ASCII, "exif:ImageUniqueID" },
- { 0, 0, (char *) NULL }
+ { EXIFTAG_EXPOSURETIME, TIFF_RATIONAL, 0, "exif:ExposureTime" },
+ { EXIFTAG_FNUMBER, TIFF_RATIONAL, 0, "exif:FNumber" },
+ { EXIFTAG_EXPOSUREPROGRAM, TIFF_SHORT, 0, "exif:ExposureProgram" },
+ { EXIFTAG_SPECTRALSENSITIVITY, TIFF_ASCII, 0, "exif:SpectralSensitivity" },
+ { EXIFTAG_ISOSPEEDRATINGS, TIFF_SHORT, 1, "exif:ISOSpeedRatings" },
+ { EXIFTAG_OECF, TIFF_NOTYPE, 0, "exif:OptoelectricConversionFactor" },
+ { EXIFTAG_EXIFVERSION, TIFF_NOTYPE, 0, "exif:ExifVersion" },
+ { EXIFTAG_DATETIMEORIGINAL, TIFF_ASCII, 0, "exif:DateTimeOriginal" },
+ { EXIFTAG_DATETIMEDIGITIZED, TIFF_ASCII, 0, "exif:DateTimeDigitized" },
+ { EXIFTAG_COMPONENTSCONFIGURATION, TIFF_NOTYPE, 0, "exif:ComponentsConfiguration" },
+ { EXIFTAG_COMPRESSEDBITSPERPIXEL, TIFF_RATIONAL, 0, "exif:CompressedBitsPerPixel" },
+ { EXIFTAG_SHUTTERSPEEDVALUE, TIFF_SRATIONAL, 0, "exif:ShutterSpeedValue" },
+ { EXIFTAG_APERTUREVALUE, TIFF_RATIONAL, 0, "exif:ApertureValue" },
+ { EXIFTAG_BRIGHTNESSVALUE, TIFF_SRATIONAL, 0, "exif:BrightnessValue" },
+ { EXIFTAG_EXPOSUREBIASVALUE, TIFF_SRATIONAL, 0, "exif:ExposureBiasValue" },
+ { EXIFTAG_MAXAPERTUREVALUE, TIFF_RATIONAL, 0, "exif:MaxApertureValue" },
+ { EXIFTAG_SUBJECTDISTANCE, TIFF_RATIONAL, 0, "exif:SubjectDistance" },
+ { EXIFTAG_METERINGMODE, TIFF_SHORT, 0, "exif:MeteringMode" },
+ { EXIFTAG_LIGHTSOURCE, TIFF_SHORT, 0, "exif:LightSource" },
+ { EXIFTAG_FLASH, TIFF_SHORT, 0, "exif:Flash" },
+ { EXIFTAG_FOCALLENGTH, TIFF_RATIONAL, 0, "exif:FocalLength" },
+ { EXIFTAG_SUBJECTAREA, TIFF_NOTYPE, 0, "exif:SubjectArea" },
+ { EXIFTAG_MAKERNOTE, TIFF_NOTYPE, 0, "exif:MakerNote" },
+ { EXIFTAG_USERCOMMENT, TIFF_NOTYPE, 0, "exif:UserComment" },
+ { EXIFTAG_SUBSECTIME, TIFF_ASCII, 0, "exif:SubSecTime" },
+ { EXIFTAG_SUBSECTIMEORIGINAL, TIFF_ASCII, 0, "exif:SubSecTimeOriginal" },
+ { EXIFTAG_SUBSECTIMEDIGITIZED, TIFF_ASCII, 0, "exif:SubSecTimeDigitized" },
+ { EXIFTAG_FLASHPIXVERSION, TIFF_NOTYPE, 0, "exif:FlashpixVersion" },
+ { EXIFTAG_PIXELXDIMENSION, TIFF_LONG, 0, "exif:PixelXDimension" },
+ { EXIFTAG_PIXELYDIMENSION, TIFF_LONG, 0, "exif:PixelYDimension" },
+ { EXIFTAG_RELATEDSOUNDFILE, TIFF_ASCII, 0, "exif:RelatedSoundFile" },
+ { EXIFTAG_FLASHENERGY, TIFF_RATIONAL, 0, "exif:FlashEnergy" },
+ { EXIFTAG_SPATIALFREQUENCYRESPONSE, TIFF_NOTYPE, 0, "exif:SpatialFrequencyResponse" },
+ { EXIFTAG_FOCALPLANEXRESOLUTION, TIFF_RATIONAL, 0, "exif:FocalPlaneXResolution" },
+ { EXIFTAG_FOCALPLANEYRESOLUTION, TIFF_RATIONAL, 0, "exif:FocalPlaneYResolution" },
+ { EXIFTAG_FOCALPLANERESOLUTIONUNIT, TIFF_SHORT, 0, "exif:FocalPlaneResolutionUnit" },
+ { EXIFTAG_SUBJECTLOCATION, TIFF_SHORT, 0, "exif:SubjectLocation" },
+ { EXIFTAG_EXPOSUREINDEX, TIFF_RATIONAL, 0, "exif:ExposureIndex" },
+ { EXIFTAG_SENSINGMETHOD, TIFF_SHORT, 0, "exif:SensingMethod" },
+ { EXIFTAG_FILESOURCE, TIFF_NOTYPE, 0, "exif:FileSource" },
+ { EXIFTAG_SCENETYPE, TIFF_NOTYPE, 0, "exif:SceneType" },
+ { EXIFTAG_CFAPATTERN, TIFF_NOTYPE, 0, "exif:CFAPattern" },
+ { EXIFTAG_CUSTOMRENDERED, TIFF_SHORT, 0, "exif:CustomRendered" },
+ { EXIFTAG_EXPOSUREMODE, TIFF_SHORT, 0, "exif:ExposureMode" },
+ { EXIFTAG_WHITEBALANCE, TIFF_SHORT, 0, "exif:WhiteBalance" },
+ { EXIFTAG_DIGITALZOOMRATIO, TIFF_RATIONAL, 0, "exif:DigitalZoomRatio" },
+ { EXIFTAG_FOCALLENGTHIN35MMFILM, TIFF_SHORT, 0, "exif:FocalLengthIn35mmFilm" },
+ { EXIFTAG_SCENECAPTURETYPE, TIFF_SHORT, 0, "exif:SceneCaptureType" },
+ { EXIFTAG_GAINCONTROL, TIFF_RATIONAL, 0, "exif:GainControl" },
+ { EXIFTAG_CONTRAST, TIFF_SHORT, 0, "exif:Contrast" },
+ { EXIFTAG_SATURATION, TIFF_SHORT, 0, "exif:Saturation" },
+ { EXIFTAG_SHARPNESS, TIFF_SHORT, 0, "exif:Sharpness" },
+ { EXIFTAG_DEVICESETTINGDESCRIPTION, TIFF_NOTYPE, 0, "exif:DeviceSettingDescription" },
+ { EXIFTAG_SUBJECTDISTANCERANGE, TIFF_SHORT, 0, "exif:SubjectDistanceRange" },
+ { EXIFTAG_IMAGEUNIQUEID, TIFF_ASCII, 0, "exif:ImageUniqueID" },
+ { 0, 0, 0, (char *) NULL }
};
#endif
#endif /* MAGICKCORE_TIFF_DELEGATE */
%
*/
+static MagickBooleanType DecodeLabImage(Image *image,ExceptionInfo *exception)
+{
+ CacheView
+ *image_view;
+
+ MagickBooleanType
+ status;
+
+ ssize_t
+ y;
+
+ status=MagickTrue;
+ image_view=AcquireAuthenticCacheView(image,exception);
+ for (y=0; y < (ssize_t) image->rows; y++)
+ {
+ register Quantum
+ *restrict q;
+
+ register ssize_t
+ x;
+
+ if (status == MagickFalse)
+ continue;
+ q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
+ if (q == (Quantum *) NULL)
+ {
+ status=MagickFalse;
+ continue;
+ }
+ for (x=0; x < (ssize_t) image->columns; x++)
+ {
+ double
+ a,
+ b;
+
+ a=QuantumScale*GetPixela(image,q)+0.5;
+ if (a > 1.0)
+ a-=1.0;
+ b=QuantumScale*GetPixelb(image,q)+0.5;
+ if (b > 1.0)
+ b-=1.0;
+ SetPixela(image,QuantumRange*a,q);
+ SetPixelb(image,QuantumRange*b,q);
+ q+=GetPixelChannels(image);
+ }
+ if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
+ status=MagickFalse;
+ }
+ image_view=DestroyCacheView(image_view);
+ return(status);
+}
+
static inline size_t MagickMax(const size_t x,const size_t y)
{
if (x > y)
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)
/*
Read EXIF properties.
*/
+ offset=0;
if (TIFFGetField(tiff,TIFFTAG_EXIFIFD,&offset) == 0)
return;
directory=TIFFCurrentDirectory(tiff);
if (TIFFReadEXIFDirectory(tiff,offset) == 0)
- return;
+ {
+ directory=TIFFCurrentDirectory(tiff);
+ return;
+ }
sans=NULL;
for (i=0; exif_info[i].tag != 0; i++)
{
*ascii;
ascii=(char *) NULL;
- if ((TIFFGetField(tiff,exif_info[i].tag,&ascii,&sans) != 0) &&
+ if ((TIFFGetField(tiff,exif_info[i].tag,&ascii,&sans,&sans) != 0) &&
(ascii != (char *) NULL) && (*ascii != '\0'))
- (void) CopyMagickMemory(value,ascii,MaxTextExtent);
+ (void) CopyMagickString(value,ascii,MaxTextExtent);
break;
}
case TIFF_SHORT:
{
- uint16
- shorty[2] = { 0, 0};
+ if (exif_info[i].variable_length != 0)
+ {
+ uint16
+ *shorty;
- if (TIFFGetField(tiff,exif_info[i].tag,&shorty,&sans) != 0)
- (void) FormatLocaleString(value,MaxTextExtent,"%d",(int) shorty[0]);
+ if (TIFFGetField(tiff,exif_info[i].tag,&sans,&shorty,&sans,&sans) != 0)
+ (void) FormatLocaleString(value,MaxTextExtent,"%d",shorty[0]);
+ }
+ else
+ {
+ uint16
+ shorty;
+
+ shorty=0;
+ if (TIFFGetField(tiff,exif_info[i].tag,&shorty,&sans,&sans) != 0)
+ (void) FormatLocaleString(value,MaxTextExtent,"%d",shorty);
+ }
break;
}
case TIFF_LONG:
uint32
longy;
- if (TIFFGetField(tiff,exif_info[i].tag,&longy,&sans) != 0)
+ longy=0;
+ if (TIFFGetField(tiff,exif_info[i].tag,&longy,&sans,&sans) != 0)
(void) FormatLocaleString(value,MaxTextExtent,"%d",longy);
break;
}
case TIFF_LONG8:
{
uint64
- longy;
+ long8y;
- if (TIFFGetField(tiff,exif_info[i].tag,&longy,&sans) != 0)
- (void) FormatLocaleString(value,MaxTextExtent,"%lld",longy);
+ long8y=0;
+ if (TIFFGetField(tiff,exif_info[i].tag,&long8y,&sans,&sans) != 0)
+ (void) FormatLocaleString(value,MaxTextExtent,"%.20g",(double)
+ ((MagickOffsetType) long8y));
break;
}
#endif
case TIFF_RATIONAL:
case TIFF_SRATIONAL:
case TIFF_FLOAT:
- case TIFF_DOUBLE:
{
float
- rational[16];
+ floaty;
+
+ floaty=0.0;
+ if (TIFFGetField(tiff,exif_info[i].tag,&floaty,&sans,&sans) != 0)
+ (void) FormatLocaleString(value,MaxTextExtent,"%g",(double) floaty);
+ break;
+ }
+ case TIFF_DOUBLE:
+ {
+ double
+ doubley;
- if (TIFFGetField(tiff,exif_info[i].tag,&rational,&sans) != 0)
- (void) FormatLocaleString(value,MaxTextExtent,"%g",rational[0]);
+ doubley=0.0;
+ if (TIFFGetField(tiff,exif_info[i].tag,&doubley,&sans,&sans) != 0)
+ (void) FormatLocaleString(value,MaxTextExtent,"%g",doubley);
break;
}
default:
size_t
length,
- lsb_first,
pad;
ssize_t
}
do
{
+DisableMSCWarning(4127)
if (0 && (image_info->verbose != MagickFalse))
+RestoreMSCWarning
TIFFPrintDirectory(tiff,stdout,MagickFalse);
#if defined(MAGICKCORE_HAVE_TIFFISBIGENDIAN)
(void) SetImageProperty(image,"tiff:endian",TIFFIsBigEndian(tiff) == 0 ?
if (image->debug != MagickFalse)
(void) LogMagickEvent(CoderEvent,GetMagickModule(),"Image depth: %.20g",
(double) image->depth);
- lsb_first=1;
image->endian=MSBEndian;
- if ((int) (*(char *) &lsb_first) != 0)
+ if (endian == FILLORDER_LSB2MSB)
+ image->endian=LSBEndian;
if ((photometric == PHOTOMETRIC_MINISBLACK) ||
(photometric == PHOTOMETRIC_MINISWHITE))
- image->colorspace=GRAYColorspace;
+ SetImageColorspace(image,GRAYColorspace,exception);
if (photometric == PHOTOMETRIC_SEPARATED)
- image->colorspace=CMYKColorspace;
+ SetImageColorspace(image,CMYKColorspace,exception);
if (photometric == PHOTOMETRIC_CIELAB)
- image->colorspace=LabColorspace;
+ 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);
(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);
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;
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 ((option == (const char *) NULL) ||
- (IsMagickTrue(option) == MagickFalse))
- TIFFGetEXIFProperties(tiff,image,exception);
/*
Allocate memory for the image and pixel buffer.
*/
TIFFClose(tiff);
ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
}
- quantum_info->endian=LSBEndian;
- if (endian == FILLORDER_LSB2MSB)
- quantum_info->endian=MSBEndian;
- image->endian=quantum_info->endian;
if (sample_format == SAMPLEFORMAT_UINT)
status=SetQuantumFormat(image,quantum_info,UnsignedQuantumFormat);
if (sample_format == SAMPLEFORMAT_INT)
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);
}
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);
method=ReadGenericMethod;
if (TIFFIsTiled(tiff) != MagickFalse)
method=ReadTileMethod;
+ quantum_info->endian=LSBEndian;
quantum_type=RGBQuantum;
pixels=GetQuantumPixels(quantum_info);
switch (method)
/*
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)
{
*/
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);
{
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);
}
case ReadStripMethod:
{
- register unsigned char
+ register uint32
*p;
/*
Convert stripped TIFF image to DirectClass MIFF image.
*/
i=0;
- p=(unsigned char *) NULL;
+ p=(uint32 *) NULL;
for (y=0; y < (ssize_t) image->rows; y++)
{
register ssize_t
image->rows-y);
}
i--;
- p=(unsigned char *) (((uint32 *) pixels)+image->columns*i);
+ p=((uint32 *) pixels)+image->columns*i;
for (x=0; x < (ssize_t) image->columns; x++)
{
SetPixelRed(image,ScaleCharToQuantum((unsigned char)
(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++;
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)
case ReadGenericMethod:
default:
{
+ MemoryInfo
+ *pixel_info;
+
register uint32
*p;
TIFFClose(tiff);
ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
}
- pixels=(uint32 *) AcquireQuantumMemory(image->columns,image->rows*
+ pixel_info=AcquireVirtualMemory(image->columns,image->rows*
sizeof(uint32));
- if (pixels == (uint32 *) NULL)
+ if (pixel_info == (MemoryInfo *) NULL)
{
TIFFClose(tiff);
ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
}
+ pixels=(uint32 *) GetVirtualMemoryBlob(pixel_info);
(void) TIFFReadRGBAImage(tiff,(uint32) image->columns,
(uint32) image->rows,(uint32 *) pixels,0);
/*
q+=GetPixelChannels(image)*(image->columns-1);
for (x=0; x < (ssize_t) image->columns; x++)
{
- SetPixelRed(image,ScaleCharToQuantum((unsigned char)
- TIFFGetR(*p)),q);
+ SetPixelRed(image,ScaleCharToQuantum((unsigned char) TIFFGetR(*p)),
+ q);
SetPixelGreen(image,ScaleCharToQuantum((unsigned char)
TIFFGetG(*p)),q);
- SetPixelBlue(image,ScaleCharToQuantum((unsigned char)
- TIFFGetB(*p)),q);
- if (image->matte != MagickFalse)
+ SetPixelBlue(image,ScaleCharToQuantum((unsigned char) TIFFGetB(*p)),
+ q);
+ if (image->alpha_trait == BlendPixelTrait)
SetPixelAlpha(image,ScaleCharToQuantum((unsigned char)
TIFFGetA(*p)),q);
p--;
- q-=GetPixelChannels(image);;
+ q-=GetPixelChannels(image);
}
if (SyncAuthenticPixels(image,exception) == MagickFalse)
break;
break;
}
}
- pixels=(uint32 *) RelinquishMagickMemory(pixels);
+ pixel_info=RelinquishVirtualMemory(pixel_info);
break;
}
}
SetQuantumImageType(image,quantum_type);
next_tiff_frame:
quantum_info=DestroyQuantumInfo(quantum_info);
+ if (photometric == PHOTOMETRIC_CIELAB)
+ DecodeLabImage(image,exception);
if ((photometric == PHOTOMETRIC_LOGL) ||
(photometric == PHOTOMETRIC_MINISBLACK) ||
(photometric == PHOTOMETRIC_MINISWHITE))
}
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.
*/
if (image->scene >= (image_info->scene+image_info->number_scenes-1))
break;
status=TIFFReadDirectory(tiff) != 0 ? MagickTrue : MagickFalse;
- if (status == MagickTrue)
+ if (status != MagickFalse)
{
/*
Allocate next image structure.
if (status == MagickFalse)
break;
}
- } while (status == MagickTrue);
+ } while (status != MagickFalse);
(void) TIFFSetWarningHandler(warning_handler);
(void) TIFFSetErrorHandler(error_handler);
TIFFClose(tiff);
static TIFFExtendProc
tag_extender = (TIFFExtendProc) NULL;
+static void TIFFIgnoreTags(TIFF *tiff)
+{
+ char
+ *q;
+
+ const char
+ *p,
+ *tags;
+
+ Image
+ *image;
+
+ register ssize_t
+ i;
+
+ size_t
+ count;
+
+ TIFFFieldInfo
+ *ignore;
+
+ if (TIFFGetReadProc(tiff) != TIFFReadBlob)
+ return;
+ image=(Image *)TIFFClientdata(tiff);
+ tags=GetImageArtifact(image,"tiff:ignore-tags");
+ if (tags == (const char *) NULL)
+ return;
+ count=0;
+ p=tags;
+ while (*p != '\0')
+ {
+ while ((isspace((int) ((unsigned char) *p)) != 0))
+ p++;
+
+ (void) strtol(p,&q,10);
+ if (p == q)
+ return;
+
+ p=q;
+ count++;
+
+ while ((isspace((int) ((unsigned char) *p)) != 0) || (*p == ','))
+ p++;
+ }
+ if (count == 0)
+ return;
+ i=0;
+ p=tags;
+ ignore=(TIFFFieldInfo *) AcquireQuantumMemory(count,sizeof(*ignore));
+ // This also sets field_bit to 0 (FIELD_IGNORE)
+ ResetMagickMemory(ignore,0,count*sizeof(*ignore));
+ while (*p != '\0')
+ {
+ while ((isspace((int) ((unsigned char) *p)) != 0))
+ p++;
+
+ ignore[i].field_tag=(ttag_t) strtol(p,&q,10);
+
+ p=q;
+ i++;
+
+ while ((isspace((int) ((unsigned char) *p)) != 0) || (*p == ','))
+ p++;
+ }
+ (void) TIFFMergeFieldInfo(tiff,ignore,(uint32) count);
+ ignore=(TIFFFieldInfo *) RelinquishMagickMemory(ignore);
+}
+
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)/
sizeof(*TIFFExtensions));
if (tag_extender != (TIFFExtendProc) NULL)
(*tag_extender)(tiff);
+ TIFFIgnoreTags(tiff);
}
#endif
*entry;
if (tiff_semaphore == (SemaphoreInfo *) NULL)
- tiff_semaphore=AllocateSemaphoreInfo();
+ ActivateSemaphoreInfo(&tiff_semaphore);
LockSemaphoreInfo(tiff_semaphore);
if (instantiate_key == MagickFalse)
{
entry->seekable_stream=MagickTrue;
entry->thread_support=NoThreadSupport;
entry->description=ConstantString("Raw CCITT Group4");
+ entry->mime_type=ConstantString("image/tiff");
entry->module=ConstantString("TIFF");
(void) RegisterMagickInfo(entry);
entry=SetMagickInfo("PTIF");
entry->seekable_stream=MagickTrue;
entry->thread_support=NoThreadSupport;
entry->description=ConstantString("Pyramid encoded TIFF");
+ entry->mime_type=ConstantString("image/tiff");
entry->module=ConstantString("TIFF");
(void) RegisterMagickInfo(entry);
entry=SetMagickInfo("TIF");
entry->description=ConstantString(TIFFDescription);
if (*version != '\0')
entry->version=ConstantString(version);
+ entry->mime_type=ConstantString("image/tiff");
entry->module=ConstantString("TIFF");
(void) RegisterMagickInfo(entry);
entry=SetMagickInfo("TIFF");
entry->description=ConstantString(TIFFDescription);
if (*version != '\0')
entry->version=ConstantString(version);
+ entry->mime_type=ConstantString("image/tiff");
entry->module=ConstantString("TIFF");
(void) RegisterMagickInfo(entry);
entry=SetMagickInfo("TIFF64");
entry->description=ConstantString("Tagged Image File Format (64-bit)");
if (*version != '\0')
entry->version=ConstantString(version);
+ entry->mime_type=ConstantString("image/tiff");
entry->module=ConstantString("TIFF");
(void) RegisterMagickInfo(entry);
return(MagickImageCoderSignature);
(void) UnregisterMagickInfo("TIF");
(void) UnregisterMagickInfo("PTIF");
if (tiff_semaphore == (SemaphoreInfo *) NULL)
- tiff_semaphore=AllocateSemaphoreInfo();
+ ActivateSemaphoreInfo(&tiff_semaphore);
LockSemaphoreInfo(tiff_semaphore);
if (instantiate_key != MagickFalse)
{
instantiate_key=MagickFalse;
}
UnlockSemaphoreInfo(tiff_semaphore);
- DestroySemaphoreInfo(&tiff_semaphore);
+ RelinquishSemaphoreInfo(&tiff_semaphore);
}
\f
#if defined(MAGICKCORE_TIFF_DELEGATE)
rows/=2;
resolution.x/=2;
resolution.y/=2;
- pyramid_image=ResizeImage(next,columns,rows,image->filter,image->blur,
- exception);
+ pyramid_image=ResizeImage(next,columns,rows,image->filter,exception);
if (pyramid_image == (Image *) NULL)
break;
pyramid_image->resolution=resolution;
tiff_info->pixels);
}
-static MagickBooleanType GetTIFFInfo(const ImageInfo *image_info,TIFF *tiff,
- TIFFInfo *tiff_info)
+static MagickBooleanType EncodeLabImage(Image *image,ExceptionInfo *exception)
+{
+ CacheView
+ *image_view;
+
+ MagickBooleanType
+ status;
+
+ ssize_t
+ y;
+
+ status=MagickTrue;
+ image_view=AcquireAuthenticCacheView(image,exception);
+ for (y=0; y < (ssize_t) image->rows; y++)
+ {
+ register Quantum
+ *restrict q;
+
+ register ssize_t
+ x;
+
+ if (status == MagickFalse)
+ continue;
+ q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
+ if (q == (Quantum *) NULL)
+ {
+ status=MagickFalse;
+ continue;
+ }
+ for (x=0; x < (ssize_t) image->columns; x++)
+ {
+ double
+ a,
+ b;
+
+ a=QuantumScale*GetPixela(image,q)-0.5;
+ if (a < 0.0)
+ a+=1.0;
+ b=QuantumScale*GetPixelb(image,q)-0.5;
+ if (b < 0.0)
+ b+=1.0;
+ SetPixela(image,QuantumRange*a,q);
+ SetPixelb(image,QuantumRange*b,q);
+ q+=GetPixelChannels(image);
+ }
+ if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
+ status=MagickFalse;
+ }
+ image_view=DestroyCacheView(image_view);
+ return(status);
+}
+
+static MagickBooleanType GetTIFFInfo(const ImageInfo *image_info,
+ TIFF *tiff,TIFFInfo *tiff_info)
{
const char
*option;
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(
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);
}
}
const char
*value;
- (void) TIFFSetField(tiff,TIFFTAG_DOCUMENTNAME,image->filename);
- value=GetImageProperty(image,"tiff:hostcomputer",exception);
+ value=GetImageArtifact(image,"tiff:document");
+ if (value != (const char *) NULL)
+ (void) TIFFSetField(tiff,TIFFTAG_DOCUMENTNAME,value);
+ value=GetImageArtifact(image,"tiff:hostcomputer");
if (value != (const char *) NULL)
(void) TIFFSetField(tiff,TIFFTAG_HOSTCOMPUTER,value);
- value=GetImageProperty(image,"tiff:artist",exception);
+ value=GetImageArtifact(image,"tiff:artist");
if (value != (const char *) NULL)
(void) TIFFSetField(tiff,TIFFTAG_ARTIST,value);
- value=GetImageProperty(image,"tiff:timestamp",exception);
+ value=GetImageArtifact(image,"tiff:timestamp");
if (value != (const char *) NULL)
(void) TIFFSetField(tiff,TIFFTAG_DATETIME,value);
- value=GetImageProperty(image,"tiff:make",exception);
+ value=GetImageArtifact(image,"tiff:make");
if (value != (const char *) NULL)
(void) TIFFSetField(tiff,TIFFTAG_MAKE,value);
- value=GetImageProperty(image,"tiff:model",exception);
+ value=GetImageArtifact(image,"tiff:model");
if (value != (const char *) NULL)
(void) TIFFSetField(tiff,TIFFTAG_MODEL,value);
- value=GetImageProperty(image,"tiff:software",exception);
+ value=GetImageArtifact(image,"tiff:software");
if (value != (const char *) NULL)
(void) TIFFSetField(tiff,TIFFTAG_SOFTWARE,value);
- value=GetImageProperty(image,"tiff:copyright",exception);
+ value=GetImageArtifact(image,"tiff:copyright");
if (value != (const char *) NULL)
(void) TIFFSetField(tiff,TIFFTAG_COPYRIGHT,value);
- value=GetImageProperty(image,"kodak-33423",exception);
+ value=GetImageArtifact(image,"kodak-33423");
if (value != (const char *) NULL)
(void) TIFFSetField(tiff,33423,value);
- value=GetImageProperty(image,"kodak-36867",exception);
+ value=GetImageArtifact(image,"kodak-36867");
if (value != (const char *) NULL)
(void) TIFFSetField(tiff,36867,value);
- value=GetImageProperty(image,"label",exception);
+ value=GetImageArtifact(image,"label");
if (value != (const char *) NULL)
(void) TIFFSetField(tiff,TIFFTAG_PAGENAME,value);
- value=GetImageProperty(image,"comment",exception);
+ value=GetImageArtifact(image,"comment");
if (value != (const char *) NULL)
(void) TIFFSetField(tiff,TIFFTAG_IMAGEDESCRIPTION,value);
}
case TIFF_SHORT:
{
uint16
- shorty;
+ field;
- shorty=(uint16) StringToLong(value);
- (void) TIFFSetField(tiff,exif_info[i].tag,shorty);
+ field=(uint16) StringToLong(value);
+ (void) TIFFSetField(tiff,exif_info[i].tag,field);
break;
}
case TIFF_LONG:
{
uint16
- ssize_ty;
+ field;
- ssize_ty=(uint16) StringToLong(value);
- (void) TIFFSetField(tiff,exif_info[i].tag,ssize_ty);
+ field=(uint16) StringToLong(value);
+ (void) TIFFSetField(tiff,exif_info[i].tag,field);
break;
}
case TIFF_RATIONAL:
case TIFF_SRATIONAL:
{
float
- rational;
+ field;
- rational=StringToDouble(value,(char **) NULL);
- (void) TIFFSetField(tiff,exif_info[i].tag,rational);
+ field=StringToDouble(value,(char **) NULL);
+ (void) TIFFSetField(tiff,exif_info[i].tag,field);
break;
}
default:
i;
size_t
- length,
- lsb_first;
+ length;
ssize_t
y;
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
assert(exception != (ExceptionInfo *) NULL);
assert(exception->signature == MagickSignature);
- assert(exception != (ExceptionInfo *) NULL);
- assert(exception->signature == MagickSignature);
status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
if (status == MagickFalse)
return(status);
if ((image_info->type != UndefinedType) &&
(image_info->type != OptimizeType))
(void) SetImageType(image,image_info->type,exception);
+ compression=UndefinedCompression;
+ if (image->compression != JPEGCompression)
+ compression=image->compression;
+ if (image_info->compression != UndefinedCompression)
+ compression=image_info->compression;
+ switch (compression)
+ {
+ case FaxCompression:
+ case Group4Compression:
+ {
+ (void) SetImageType(image,BilevelType,exception);
+ break;
+ }
+ case JPEGCompression:
+ {
+ (void) SetImageStorageClass(image,DirectClass,exception);
+ (void) SetImageDepth(image,8,exception);
+ break;
+ }
+ default:
+ break;
+ }
quantum_info=AcquireQuantumInfo(image_info,image);
if (quantum_info == (QuantumInfo *) NULL)
ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
ThrowWriterException(ImageError,"WidthOrHeightExceedsLimit");
(void) TIFFSetField(tiff,TIFFTAG_IMAGELENGTH,(uint32) image->rows);
(void) TIFFSetField(tiff,TIFFTAG_IMAGEWIDTH,(uint32) image->columns);
- compression=image->compression;
- if (image_info->compression != UndefinedCompression)
- compression=image_info->compression;
switch (compression)
{
case FaxCompression:
}
}
#endif
- switch (compression)
- {
- case FaxCompression:
- case Group4Compression:
- {
- (void) SetImageType(image,BilevelType,exception);
- break;
- }
- case JPEGCompression:
- {
- (void) SetImageStorageClass(image,DirectClass,exception);
- (void) SetImageDepth(image,8,exception);
- break;
- }
- default:
- break;
- }
if (image->colorspace == CMYKColorspace)
{
photometric=PHOTOMETRIC_SEPARATED;
Full color TIFF raster.
*/
if (image->colorspace == LabColorspace)
- photometric=PHOTOMETRIC_CIELAB;
+ {
+ photometric=PHOTOMETRIC_CIELAB;
+ EncodeLabImage(image,exception);
+ }
else
if (image->colorspace == YCbCrColorspace)
{
(void) SetImageDepth(image,8,exception);
}
else
- {
- if (IsRGBColorspace(image->colorspace) == MagickFalse)
- (void) TransformImageColorspace(image,RGBColorspace,exception);
- photometric=PHOTOMETRIC_RGB;
- }
+ photometric=PHOTOMETRIC_RGB;
(void) TIFFSetField(tiff,TIFFTAG_SAMPLESPERPIXEL,3);
if ((image_info->type != TrueColorType) &&
(image_info->type != TrueColorMatteType))
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);
break;
}
}
- lsb_first=1;
- image->endian=MSBEndian;
- if ((int) (*(char *) &lsb_first) != 0)
- image->endian=LSBEndian;
if ((compress_tag == COMPRESSION_CCITTFAX3) &&
(photometric != PHOTOMETRIC_MINISWHITE))
{
compress_tag=COMPRESSION_NONE;
endian=FILLORDER_MSB2LSB;
}
- option=GetImageProperty(image,"tiff:fill-order",exception);
+ option=GetImageOption(image_info,"tiff:fill-order");
if (option != (const char *) NULL)
{
if (LocaleNCompare(option,"msb",3) == 0)
(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,
*/
extra_samples=1;
sample_info[0]=EXTRASAMPLE_UNASSALPHA;
- option=GetImageProperty(image,"tiff:alpha",exception);
+ option=GetImageOption(image_info,"tiff:alpha");
if ((option != (const char *) NULL) &&
(LocaleCompare(option,"associated") == 0))
sample_info[0]=EXTRASAMPLE_ASSOCALPHA;
if ((image_info->interlace == PlaneInterlace) ||
(image_info->interlace == PartitionInterlace))
(void) TIFFSetField(tiff,TIFFTAG_PLANARCONFIG,PLANARCONFIG_SEPARATE);
- rows_per_strip=1;
- if (TIFFScanlineSize(tiff) != 0)
- rows_per_strip=(uint32) MagickMax((size_t) TIFFDefaultStripSize(tiff,0),
- 1);
+ rows_per_strip=TIFFDefaultStripSize(tiff,0);
option=GetImageOption(image_info,"tiff:rows-per-strip");
if (option != (const char *) NULL)
rows_per_strip=(size_t) strtol(option,(char **) NULL,10);
flags;
rows_per_strip+=(16-(rows_per_strip % 16));
- if (image->quality != 0)
- (void) TIFFSetField(tiff,TIFFTAG_JPEGQUALITY,image->quality);
if (image_info->quality != UndefinedCompressionQuality)
(void) TIFFSetField(tiff,TIFFTAG_JPEGQUALITY,image_info->quality);
(void) TIFFSetField(tiff,TIFFTAG_JPEGCOLORMODE,JPEGCOLORMODE_RAW);
- if (IsRGBColorspace(image->colorspace) == MagickTrue)
+ if (IssRGBCompatibleColorspace(image->colorspace) != MagickFalse)
{
const char
*value;
default:
break;
}
- option=GetImageOption(image_info,"tiff:tile-geometry");
- if (option == (const char *) NULL)
- (void) TIFFSetField(tiff,TIFFTAG_ROWSPERSTRIP,rows_per_strip);
+ if (rows_per_strip < 1)
+ rows_per_strip=1;
+ if ((image->rows/rows_per_strip) >= (1UL << 15))
+ rows_per_strip=(uint32) (image->rows >> 15);
+ (void) TIFFSetField(tiff,TIFFTAG_ROWSPERSTRIP,rows_per_strip);
if ((image->resolution.x != 0.0) && (image->resolution.y != 0.0))
{
unsigned short
(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))
+ (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
+ "TIFF: negative image positions unsupported","%s",image->filename);
+ if ((image->page.x > 0) && (image->resolution.x > 0.0))
{
/*
- Set image position.
+ Set horizontal image position.
*/
(void) TIFFSetField(tiff,TIFFTAG_XPOSITION,(float) image->page.x/
image->resolution.x);
+ }
+ if ((image->page.y > 0) && (image->resolution.y > 0.0))
+ {
+ /*
+ Set vertical image position.
+ */
(void) TIFFSetField(tiff,TIFFTAG_YPOSITION,(float) image->page.y/
image->resolution.y);
}
(void) TIFFSetField(tiff,TIFFTAG_PAGENUMBER,page,pages);
}
(void) TIFFSetProperties(tiff,image,exception);
+DisableMSCWarning(4127)
if (0)
+RestoreMSCWarning
(void) TIFFSetEXIFProperties(tiff,image,exception);
/*
Write image scanlines.
if (GetTIFFInfo(image_info,tiff,&tiff_info) == MagickFalse)
ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
quantum_info->endian=LSBEndian;
- if (endian == FILLORDER_LSB2MSB)
- quantum_info->endian=MSBEndian;
pixels=GetQuantumPixels(quantum_info);
tiff_info.scanline=GetQuantumPixels(quantum_info);
switch (photometric)
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++)
{
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
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);
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;
}
}
quantum_info=DestroyQuantumInfo(quantum_info);
+ if (image->colorspace == LabColorspace)
+ DecodeLabImage(image,exception);
DestroyTIFFInfo(&tiff_info);
- if (0 && (image_info->verbose == MagickTrue))
+DisableMSCWarning(4127)
+ if (0 && (image_info->verbose != MagickFalse))
+RestoreMSCWarning
TIFFPrintDirectory(tiff,stdout,MagickFalse);
(void) TIFFWriteDirectory(tiff);
- image->endian=MSBEndian;
- if (endian == FILLORDER_LSB2MSB)
- image->endian=LSBEndian;
image=SyncNextImageInList(image);
if (image == (Image *) NULL)
break;