% March 2000 %
% %
% %
-% Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization %
+% Copyright 1999-2012 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 "MagickCore/image.h"
#include "MagickCore/image.h"
#include "MagickCore/layer.h"
+#include "MagickCore/locale-private.h"
#include "MagickCore/list.h"
#include "MagickCore/magick.h"
#include "MagickCore/memory_.h"
#include "MagickCore/quantum.h"
#include "MagickCore/resource_.h"
#include "MagickCore/splay-tree.h"
-#include "MagickCore/signature-private.h"
+#include "MagickCore/signature.h"
#include "MagickCore/statistic.h"
#include "MagickCore/string_.h"
#include "MagickCore/string-private.h"
#include "MagickCore/token.h"
+#include "MagickCore/token-private.h"
#include "MagickCore/utility.h"
+#include "MagickCore/utility-private.h"
#include "MagickCore/version.h"
#include "MagickCore/xml-tree.h"
+#include "MagickCore/xml-tree-private.h"
\f
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
image->directory=(char *) NULL;
(void) CloneString(&image->geometry,clone_image->geometry);
image->offset=clone_image->offset;
- image->x_resolution=clone_image->x_resolution;
- image->y_resolution=clone_image->y_resolution;
+ image->resolution.x=clone_image->resolution.x;
+ image->resolution.y=clone_image->resolution.y;
image->page=clone_image->page;
image->tile_offset=clone_image->tile_offset;
image->extract_info=clone_image->extract_info;
- image->bias=clone_image->bias;
image->filter=clone_image->filter;
- image->blur=clone_image->blur;
image->fuzz=clone_image->fuzz;
image->interlace=clone_image->interlace;
image->interpolate=clone_image->interpolate;
% The format of the DefineImageProperty method is:
%
% MagickBooleanType DefineImageProperty(Image *image,
-% const char *property)
+% const char *property,ExceptionInfo *exception)
%
% A description of each parameter follows:
%
%
% o property: the image property.
%
+% o exception: return any errors or warnings in this structure.
+%
*/
MagickExport MagickBooleanType DefineImageProperty(Image *image,
- const char *property)
+ const char *property,ExceptionInfo *exception)
{
char
key[MaxTextExtent],
if (*p == '=')
(void) CopyMagickString(value,p+1,MaxTextExtent);
*p='\0';
- return(SetImageProperty(image,key,value));
+ return(SetImageProperty(image,key,value,exception));
}
\f
/*
char
value[MaxTextExtent];
+ ExceptionInfo
+ *exception;
+
+ MagickBooleanType
+ status;
+
ssize_t
n;
n=FormatLocaleStringList(value,MaxTextExtent,format,operands);
(void) n;
va_end(operands);
- return(SetImageProperty(image,property,value));
+ exception=AcquireExceptionInfo();
+ status=SetImageProperty(image,property,value,exception);
+ exception=DestroyExceptionInfo(exception);
+ return(status);
}
\f
/*
%
% The format of the GetImageProperty method is:
%
-% const char *GetImageProperty(const Image *image,const char *key)
+% const char *GetImageProperty(const Image *image,const char *key,
+% ExceptionInfo *exception)
%
% A description of each parameter follows:
%
%
% o key: the key.
%
+% o exception: return any errors or warnings in this structure.
+%
*/
static char
*TraceSVGClippath(const unsigned char *,size_t,const size_t,
const size_t);
-static MagickBooleanType GetIPTCProperty(const Image *image,const char *key)
+static MagickBooleanType GetIPTCProperty(const Image *image,const char *key,
+ ExceptionInfo *exception)
{
char
*attribute,
return(MagickFalse);
}
attribute[strlen(attribute)-1]='\0';
- (void) SetImageProperty((Image *) image,key,(const char *) attribute);
+ (void) SetImageProperty((Image *) image,key,(const char *) attribute,
+ exception);
attribute=DestroyString(attribute);
return(MagickTrue);
}
return(y);
}
+static inline ssize_t MagickMin(const ssize_t x,const ssize_t y)
+{
+ if (x < y)
+ return(x);
+ return(y);
+}
+
static inline int ReadPropertyByte(const unsigned char **p,size_t *length)
{
int
return((unsigned short) (value & 0xffff));
}
-static MagickBooleanType Get8BIMProperty(const Image *image,const char *key)
+static MagickBooleanType Get8BIMProperty(const Image *image,const char *key,
+ ExceptionInfo *exception)
{
char
*attribute,
continue;
if (ReadPropertyByte(&info,&length) != (unsigned char) 'M')
continue;
- id=(ssize_t) ReadPropertyMSBShort(&info,&length);
+ id=(ssize_t) ((int) ReadPropertyMSBShort(&info,&length));
if (id < (ssize_t) start)
continue;
if (id > (ssize_t) stop)
No name match, scroll forward and try next.
*/
info+=count;
- length-=count;
+ length-=MagickMin(count,(ssize_t) length);
continue;
}
if ((*name == '#') && (sub_number != 1))
*/
sub_number--;
info+=count;
- length-=count;
+ length-=MagickMin(count,(ssize_t) length);
continue;
}
/*
(void) CopyMagickMemory(attribute,(char *) info,(size_t) count);
attribute[count]='\0';
info+=count;
- length-=count;
+ length-=MagickMin(count,(ssize_t) length);
if ((id <= 1999) || (id >= 2999))
(void) SetImageProperty((Image *) image,key,(const char *)
- attribute);
+ attribute,exception);
else
{
char
else
path=TracePSClippath((unsigned char *) attribute,(size_t) count,
image->columns,image->rows);
- (void) SetImageProperty((Image *) image,key,(const char *) path);
+ (void) SetImageProperty((Image *) image,key,(const char *) path,
+ exception);
path=DestroyString(path);
}
attribute=DestroyString(attribute);
}
static MagickBooleanType GetEXIFProperty(const Image *image,
- const char *property)
+ const char *property,ExceptionInfo *exception)
{
#define MaxDirectoryStack 16
#define EXIF_DELIMITER "\n"
#define TAG_GPS_OFFSET 0x8825
#define TAG_INTEROP_OFFSET 0xa005
-#define EXIFMultipleValues(size, format, arg) \
+#define EXIFMultipleValues(size,format,arg) \
{ \
ssize_t \
component; \
value=AcquireString(buffer); \
}
-#define EXIFMultipleFractions(size, format, arg1, arg2) \
+#define EXIFMultipleFractions(size,format,arg1,arg2) \
{ \
ssize_t \
component; \
for (component=0; component < components; component++) \
{ \
length+=FormatLocaleString(buffer+length,MaxTextExtent-length, \
- format", ",arg1, arg2); \
+ format", ",(arg1),(arg2)); \
if (length >= (MaxTextExtent-1)) \
length=MaxTextExtent-1; \
p1+=size; \
*directory;
size_t
- entry,
+ entry;
+
+ ssize_t
offset;
} DirectoryInfo;
entry,
length,
number_entries,
- tag_offset,
tag;
+ SplayTreeInfo
+ *exif_resources;
+
ssize_t
all,
id,
level,
offset,
+ tag_offset,
tag_value;
static int
}
if (length < 16)
return(MagickFalse);
- id=(ssize_t) ReadPropertyShort(LSBEndian,exif);
+ id=(ssize_t) ((int) ReadPropertyShort(LSBEndian,exif));
endian=LSBEndian;
if (id == 0x4949)
endian=LSBEndian;
This the offset to the first IFD.
*/
offset=(ssize_t) ((int) ReadPropertyLong(endian,exif+4));
- if ((size_t) offset >= length)
+ if ((offset < 0) || (size_t) offset >= length)
return(MagickFalse);
/*
Set the pointer to the first IFD and follow it were it leads.
level=0;
entry=0;
tag_offset=0;
+ exif_resources=NewSplayTree((int (*)(const void *,const void *)) NULL,
+ (void *(*)(void *)) NULL,(void *(*)(void *)) NULL);
do
{
/*
/*
Determine how many entries there are in the current IFD.
*/
- number_entries=ReadPropertyShort(endian,directory);
+ number_entries=(size_t) ((int) ReadPropertyShort(endian,directory));
for ( ; entry < number_entries; entry++)
{
register unsigned char
ssize_t
components;
- q=(unsigned char *) (directory+2+(12*entry));
- tag_value=(ssize_t) (ReadPropertyShort(endian,q)+tag_offset);
- format=(size_t) ReadPropertyShort(endian,q+2);
+ q=(unsigned char *) (directory+(12*entry)+2);
+ if (GetValueFromSplayTree(exif_resources,q) == q)
+ break;
+ (void) AddValueToSplayTree(exif_resources,q,q);
+ tag_value=(ssize_t) ((int) ReadPropertyShort(endian,q)+tag_offset);
+ format=(size_t) ((int) ReadPropertyShort(endian,q+2));
if (format >= (sizeof(tag_bytes)/sizeof(*tag_bytes)))
break;
components=(ssize_t) ((int) ReadPropertyLong(endian,q+4));
number_bytes=(size_t) components*tag_bytes[format];
+ if (number_bytes < components)
+ break; /* prevent overflow */
if (number_bytes <= 4)
p=q+8;
else
offset=(ssize_t) ((int) ReadPropertyLong(endian,q+8));
if ((size_t) (offset+number_bytes) > length)
continue;
+ if (~length < number_bytes)
+ continue; /* prevent overflow */
p=(unsigned char *) (exif+offset);
}
if ((all != 0) || (tag == (size_t) tag_value))
buffer[MaxTextExtent],
*value;
+ value=(char *) NULL;
+ *buffer='\0';
switch (format)
{
case EXIF_FMT_BYTE:
case EXIF_FMT_UNDEFINED:
{
- EXIFMultipleValues(1,"%.20g",(double)
- (*(unsigned char *) p1));
+ EXIFMultipleValues(1,"%.20g",(double) (*(unsigned char *) p1));
break;
}
case EXIF_FMT_SBYTE:
case EXIF_FMT_ULONG:
{
EXIFMultipleValues(4,"%.20g",(double)
- ReadPropertyLong(endian,p1));
+ ((int) ReadPropertyLong(endian,p1)));
break;
}
case EXIF_FMT_SLONG:
{
EXIFMultipleValues(4,"%.20g",(double)
- ReadPropertyLong(endian,p1));
+ ((int) ReadPropertyLong(endian,p1)));
break;
}
case EXIF_FMT_URATIONAL:
{
EXIFMultipleFractions(8,"%.20g/%.20g",(double)
- ReadPropertyLong(endian,p1),(double)
- ReadPropertyLong(endian,p1+4));
+ ((int) ReadPropertyLong(endian,p1)),(double)
+ ((int) ReadPropertyLong(endian,p1+4)));
break;
}
case EXIF_FMT_SRATIONAL:
{
EXIFMultipleFractions(8,"%.20g/%.20g",(double)
- ReadPropertyLong(endian,p1),(double)
- ReadPropertyLong(endian,p1+4));
+ ((int) ReadPropertyLong(endian,p1)),(double)
+ ((int) ReadPropertyLong(endian,p1+4)));
break;
}
case EXIF_FMT_SINGLE:
break;
}
}
- (void) FormatLocaleString(key,MaxTextExtent,"%s",
- description);
+ (void) FormatLocaleString(key,MaxTextExtent,"%s",description);
break;
}
case 2:
p=(const char *) GetValueFromSplayTree((SplayTreeInfo *)
image->properties,key);
if (p == (const char *) NULL)
- (void) SetImageProperty((Image *) image,key,value);
+ (void) SetImageProperty((Image *) image,key,value,exception);
value=DestroyString(value);
status=MagickTrue;
}
}
if ((tag_value == TAG_EXIF_OFFSET) ||
- (tag_value == TAG_INTEROP_OFFSET) ||
- (tag_value == TAG_GPS_OFFSET))
+ (tag_value == TAG_INTEROP_OFFSET) || (tag_value == TAG_GPS_OFFSET))
{
- size_t
+ ssize_t
offset;
- offset=(size_t) ReadPropertyLong(endian,p);
- if ((offset < length) && (level < (MaxDirectoryStack-2)))
+ offset=(ssize_t) ((int) ReadPropertyLong(endian,p));
+ if (((size_t) offset < length) && (level < (MaxDirectoryStack-2)))
{
- size_t
+ ssize_t
tag_offset1;
- tag_offset1=(tag_value == TAG_GPS_OFFSET) ? 0x10000UL : 0UL;
+ tag_offset1=(ssize_t) ((tag_value == TAG_GPS_OFFSET) ? 0x10000 :
+ 0);
directory_stack[level].directory=directory;
entry++;
directory_stack[level].entry=entry;
level++;
if ((directory+2+(12*number_entries)) > (exif+length))
break;
- offset=(size_t) ReadPropertyLong(endian,directory+2+(12*
- number_entries));
- if ((offset != 0) && (offset < length) &&
+ offset=(ssize_t) ((int) ReadPropertyLong(endian,directory+2+(12*
+ number_entries)));
+ if ((offset != 0) && ((size_t) offset < length) &&
(level < (MaxDirectoryStack-2)))
{
directory_stack[level].directory=exif+offset;
}
}
} while (level > 0);
+ exif_resources=DestroySplayTree(exif_resources);
return(status);
}
-static MagickBooleanType GetXMPProperty(const Image *image,
- const char *property)
+static MagickBooleanType GetXMPProperty(const Image *image,const char *property)
{
char
*xmp_profile;
}
static char *TracePSClippath(const unsigned char *blob,size_t length,
- const size_t magick_unused(columns),
- const size_t magick_unused(rows))
+ const size_t magick_unused(columns),const size_t magick_unused(rows))
{
char
*path,
in_subpath=MagickFalse;
while (length > 0)
{
- selector=(ssize_t) ReadPropertyMSBShort(&blob,&length);
+ selector=(ssize_t) ((int) ReadPropertyMSBShort(&blob,&length));
switch (selector)
{
case 0:
if (knot_count != 0)
{
blob+=24;
- length-=24;
+ length-=MagickMin(24,(ssize_t) length);
break;
}
/*
Expected subpath length record.
*/
- knot_count=(ssize_t) ReadPropertyMSBShort(&blob,&length);
+ knot_count=(ssize_t) ((int) ReadPropertyMSBShort(&blob,&length));
blob+=22;
- length-=22;
+ length-=MagickMin(22,(ssize_t) length);
break;
}
case 1:
Unexpected subpath knot
*/
blob+=24;
- length-=24;
+ length-=MagickMin(24,(ssize_t) length);
break;
}
/*
xx,
yy;
- yy=ReadPropertyMSBLong(&blob,&length);
- xx=ReadPropertyMSBLong(&blob,&length);
+ yy=(size_t) ((int) ReadPropertyMSBLong(&blob,&length));
+ xx=(size_t) ((int) ReadPropertyMSBLong(&blob,&length));
x=(ssize_t) xx;
if (xx > 2147483647)
x=(ssize_t) xx-4294967295U-1;
default:
{
blob+=24;
- length-=24;
+ length-=MagickMin(24,(ssize_t) length);
break;
}
}
in_subpath=MagickFalse;
while (length != 0)
{
- selector=(ssize_t) ReadPropertyMSBShort(&blob,&length);
+ selector=(ssize_t) ((int) ReadPropertyMSBShort(&blob,&length));
switch (selector)
{
case 0:
if (knot_count != 0)
{
blob+=24;
- length-=24;
+ length-=MagickMin(24,(ssize_t) length);
break;
}
/*
Expected subpath length record.
*/
- knot_count=(ssize_t) ReadPropertyMSBShort(&blob,&length);
+ knot_count=(ssize_t) ((int) ReadPropertyMSBShort(&blob,&length));
blob+=22;
- length-=22;
+ length-=MagickMin(22,(ssize_t) length);
break;
}
case 1:
Unexpected subpath knot.
*/
blob+=24;
- length-=24;
+ length-=MagickMin(24,(ssize_t) length);
break;
}
/*
xx,
yy;
- yy=ReadPropertyMSBLong(&blob,&length);
- xx=ReadPropertyMSBLong(&blob,&length);
+ yy=(size_t) ((int) ReadPropertyMSBLong(&blob,&length));
+ xx=(size_t) ((int) ReadPropertyMSBLong(&blob,&length));
x=(ssize_t) xx;
if (xx > 2147483647)
x=(ssize_t) xx-4294967295U-1;
default:
{
blob+=24;
- length-=24;
+ length-=MagickMin(24,(ssize_t) length);
break;
}
}
}
MagickExport const char *GetImageProperty(const Image *image,
- const char *property)
+ const char *property,ExceptionInfo *exception)
{
- ExceptionInfo
- *exception;
-
FxInfo
*fx_info;
if ((property == (const char *) NULL) ||
(strchr(property,':') == (char *) NULL))
return(p);
- exception=(&((Image *) image)->exception);
switch (*property)
{
case '8':
{
if (LocaleNCompare("8bim:",property,5) == 0)
{
- if ((Get8BIMProperty(image,property) != MagickFalse) &&
+ if ((Get8BIMProperty(image,property,exception) != MagickFalse) &&
(image->properties != (void *) NULL))
{
p=(const char *) GetValueFromSplayTree((SplayTreeInfo *)
{
if (LocaleNCompare("exif:",property,5) == 0)
{
- if ((GetEXIFProperty(image,property) != MagickFalse) &&
+ if ((GetEXIFProperty(image,property,exception) != MagickFalse) &&
(image->properties != (void *) NULL))
{
p=(const char *) GetValueFromSplayTree((SplayTreeInfo *)
(void) FormatLocaleString(value,MaxTextExtent,"%.*g",
GetMagickPrecision(),(double) alpha);
- (void) SetImageProperty((Image *) image,property,value);
+ (void) SetImageProperty((Image *) image,property,value,exception);
}
if (image->properties != (void *) NULL)
{
{
if (LocaleNCompare("iptc:",property,5) == 0)
{
- if ((GetIPTCProperty(image,property) != MagickFalse) &&
+ if ((GetIPTCProperty(image,property,exception) != MagickFalse) &&
(image->properties != (void *) NULL))
{
p=(const char *) GetValueFromSplayTree((SplayTreeInfo *)
char
name[MaxTextExtent];
- (void) QueryMagickColorname(image,&pixel,SVGCompliance,name,
+ (void) QueryColorname(image,&pixel,SVGCompliance,name,
exception);
- (void) SetImageProperty((Image *) image,property,name);
- return(GetImageProperty(image,property));
+ (void) SetImageProperty((Image *) image,property,name,exception);
+ return(GetImageProperty(image,property,exception));
}
}
break;
% The format of the GetMagickProperty method is:
%
% const char *GetMagickProperty(const ImageInfo *image_info,Image *image,
-% const char *key)
+% const char *key,ExceptionInfo *exception)
%
% A description of each parameter follows:
%
%
% o key: the key.
%
+% o exception: return any errors or warnings in this structure.
+%
*/
MagickExport const char *GetMagickProperty(const ImageInfo *image_info,
- Image *image,const char *property)
+ Image *image,const char *property,ExceptionInfo *exception)
{
char
value[MaxTextExtent],
Image storage class and colorspace.
*/
colorspace=image->colorspace;
- if (IsImageGray(image,&image->exception) != MagickFalse)
+ if (IsImageGray(image,exception) != MagickFalse)
colorspace=GRAYColorspace;
(void) FormatLocaleString(value,MaxTextExtent,"%s",
CommandOptionToMnemonic(MagickColorspaceOptions,(ssize_t)
kurtosis,
skewness;
- (void) GetImageKurtosis(image,&kurtosis,&skewness,&image->exception);
+ (void) GetImageKurtosis(image,&kurtosis,&skewness,exception);
(void) FormatLocaleString(value,MaxTextExtent,"%.*g",
GetMagickPrecision(),kurtosis);
break;
maximum,
minimum;
- (void) GetImageRange(image,&minimum,&maximum,&image->exception);
+ (void) GetImageRange(image,&minimum,&maximum,exception);
(void) FormatLocaleString(value,MaxTextExtent,"%.*g",
GetMagickPrecision(),maximum);
break;
standard_deviation;
(void) GetImageMean(image,&mean,&standard_deviation,
- &image->exception);
+ exception);
(void) FormatLocaleString(value,MaxTextExtent,"%.*g",
GetMagickPrecision(),mean);
break;
maximum,
minimum;
- (void) GetImageRange(image,&minimum,&maximum,&image->exception);
+ (void) GetImageRange(image,&minimum,&maximum,exception);
(void) FormatLocaleString(value,MaxTextExtent,"%.*g",
GetMagickPrecision(),minimum);
break;
MagickBooleanType
opaque;
- opaque=IsImageOpaque(image,&image->exception);
+ opaque=IsImageOpaque(image,exception);
(void) CopyMagickString(value,opaque == MagickFalse ? "false" :
"true",MaxTextExtent);
break;
}
+ if (LocaleNCompare("orientation",property,11) == 0)
+ {
+ (void) FormatLocaleString(value,MaxTextExtent,"%s",
+ CommandOptionToMnemonic(MagickOrientationOptions,(ssize_t)
+ image->orientation));
+ break;
+ }
if (LocaleNCompare("output",property,6) == 0)
{
(void) CopyMagickString(value,image_info->filename,MaxTextExtent);
}
break;
}
+ case 'r':
+ {
+ if (LocaleNCompare("resolution.x",property,11) == 0)
+ {
+ (void) FormatLocaleString(value,MaxTextExtent,"%g",
+ image->resolution.x);
+ break;
+ }
+ if (LocaleNCompare("resolution.y",property,11) == 0)
+ {
+ (void) FormatLocaleString(value,MaxTextExtent,"%g",
+ image->resolution.y);
+ break;
+ }
+ break;
+ }
case 's':
{
if (LocaleNCompare("size",property,4) == 0)
}
if (LocaleNCompare("scene",property,5) == 0)
{
+ /* FUTURE: I am not certain this property return makes sense! */
(void) FormatLocaleString(value,MaxTextExtent,"%.20g",(double)
image->scene);
if (image_info->number_scenes != 0)
kurtosis,
skewness;
- (void) GetImageKurtosis(image,&kurtosis,&skewness,&image->exception);
+ (void) GetImageKurtosis(image,&kurtosis,&skewness,exception);
(void) FormatLocaleString(value,MaxTextExtent,"%.*g",
GetMagickPrecision(),skewness);
break;
standard_deviation;
(void) GetImageMean(image,&mean,&standard_deviation,
- &image->exception);
+ exception);
(void) FormatLocaleString(value,MaxTextExtent,"%.*g",
GetMagickPrecision(),standard_deviation);
break;
}
break;
}
- case 'x':
- {
- if (LocaleNCompare("xresolution",property,11) == 0)
- {
- (void) FormatLocaleString(value,MaxTextExtent,"%g",
- image->x_resolution);
- break;
- }
- break;
- }
- case 'y':
- {
- if (LocaleNCompare("yresolution",property,11) == 0)
- {
- (void) FormatLocaleString(value,MaxTextExtent,"%g",
- image->y_resolution);
- break;
- }
- break;
- }
case 'z':
{
if (LocaleNCompare("zero",property,4) == 0)
(void) AddValueToSplayTree((SplayTreeInfo *) image->properties,
ConstantString(property),ConstantString(value));
}
- return(GetImageProperty(image,property));
+ return(GetImageProperty(image,property,exception));
}
\f
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% InterpretImageProperties() replaces any embedded formatting characters with
-% the appropriate image property and returns the interpreted text.
+% the appropriate image property and returns the interpreted text. Free with
+% DestoryString() or RelinquishMagickMemory().
%
% The format of the InterpretImageProperties method is:
%
% char *InterpretImageProperties(const ImageInfo *image_info,Image *image,
-% const char *embed_text)
+% const char *embed_text,ExceptionInfo *exception)
%
% A description of each parameter follows:
%
% o embed_text: the address of a character string containing the embedded
% formatting characters.
%
+% o exception: return any errors or warnings in this structure.
+%
*/
MagickExport char *InterpretImageProperties(const ImageInfo *image_info,
- Image *image,const char *embed_text)
+ Image *image,const char *embed_text,ExceptionInfo *exception)
{
char
filename[MaxTextExtent],
text=(char *) embed_text;
if ((*text == '@') && ((*(text+1) == '-') ||
(IsPathAccessible(text+1) != MagickFalse)))
- return(FileToString(embed_text+1,~0,&image->exception));
+ return(FileToString(embed_text+1,~0,exception));
/*
Translate any embedded format characters.
*/
p++;
switch (*p)
{
- case 'b':
+ case '[': /* multi-character substitution */
{
char
- format[MaxTextExtent];
+ pattern[MaxTextExtent];
+
+ const char
+ *key,
+ *value;
+
+ ssize_t
+ depth;
/*
- File size.
+ Image value.
*/
+ if (strchr(p,']') == (char *) NULL)
+ break;
+ depth=1;
+ p++;
+ for (i=0; (i < (MaxTextExtent-1L)) && (*p != '\0'); i++)
+ {
+ if (*p == '[')
+ depth++;
+ if (*p == ']')
+ depth--;
+ if (depth <= 0)
+ break;
+ pattern[i]=(*p++);
+ }
+ pattern[i]='\0';
+ value=GetImageProperty(image,pattern,exception);
+ if (value != (const char *) NULL)
+ {
+ length=strlen(value);
+ if ((size_t) (q-interpret_text+length+1) >= extent)
+ {
+ extent+=length;
+ interpret_text=(char *) ResizeQuantumMemory(interpret_text,
+ extent+MaxTextExtent,sizeof(*interpret_text));
+ if (interpret_text == (char *) NULL)
+ break;
+ q=interpret_text+strlen(interpret_text);
+ }
+ (void) CopyMagickString(q,value,extent);
+ q+=length;
+ break;
+ }
+ else
+ if (IsGlob(pattern) != MagickFalse)
+ {
+ /*
+ Iterate over image properties.
+ */
+ ResetImagePropertyIterator(image);
+ key=GetNextImageProperty(image);
+ while (key != (const char *) NULL)
+ {
+ if (GlobExpression(key,pattern,MagickTrue) != MagickFalse)
+ {
+ value=GetImageProperty(image,key,exception);
+ if (value != (const char *) NULL)
+ {
+ length=strlen(key)+strlen(value)+2;
+ if ((size_t) (q-interpret_text+length+1) >= extent)
+ {
+ extent+=length;
+ interpret_text=(char *) ResizeQuantumMemory(
+ interpret_text,extent+MaxTextExtent,
+ sizeof(*interpret_text));
+ if (interpret_text == (char *) NULL)
+ break;
+ q=interpret_text+strlen(interpret_text);
+ }
+ q+=FormatLocaleString(q,extent,"%s=%s\n",key,value);
+ }
+ }
+ key=GetNextImageProperty(image);
+ }
+ }
+ value=GetMagickProperty(image_info,image,pattern,exception);
+ if (value != (const char *) NULL)
+ {
+ length=strlen(value);
+ if ((size_t) (q-interpret_text+length+1) >= extent)
+ {
+ extent+=length;
+ interpret_text=(char *) ResizeQuantumMemory(interpret_text,
+ extent+MaxTextExtent,sizeof(*interpret_text));
+ if (interpret_text == (char *) NULL)
+ break;
+ q=interpret_text+strlen(interpret_text);
+ }
+ (void) CopyMagickString(q,value,extent);
+ q+=length;
+ break;
+ }
+ if (image_info == (ImageInfo *) NULL)
+ break;
+ value=GetImageOption(image_info,pattern);
+ if (value != (char *) NULL)
+ {
+ length=strlen(value);
+ if ((size_t) (q-interpret_text+length+1) >= extent)
+ {
+ extent+=length;
+ interpret_text=(char *) ResizeQuantumMemory(interpret_text,
+ extent+MaxTextExtent,sizeof(*interpret_text));
+ if (interpret_text == (char *) NULL)
+ break;
+ q=interpret_text+strlen(interpret_text);
+ }
+ (void) CopyMagickString(q,value,extent);
+ q+=length;
+ break;
+ }
+ break;
+ }
+ case 'b': /* image size as read in */
+ {
+ char
+ format[MaxTextExtent];
+
(void) FormatLocaleString(format,MaxTextExtent,"%.20g",(double)
((MagickOffsetType) image->extent));
if (image->extent != (MagickSizeType) ((size_t) image->extent))
q+=ConcatenateMagickString(q,"B",extent);
break;
}
- case 'c':
+ case 'c': /* image comment properity */
{
- /*
- Image comment.
- */
- value=GetImageProperty(image,"comment");
+ value=GetImageProperty(image,"comment",exception);
if (value == (const char *) NULL)
break;
length=strlen(value);
q+=length;
break;
}
- case 'd':
- case 'e':
- case 'f':
- case 't':
+ case 'd': /* Directory component of filename */
{
- /*
- Label segment is the base of the filename.
- */
- if (*image->magick_filename == '\0')
- break;
- switch (*p)
- {
- case 'd':
- {
- /*
- Directory.
- */
- GetPathComponent(image->magick_filename,HeadPath,filename);
- q+=CopyMagickString(q,filename,extent);
- break;
- }
- case 'e':
- {
- /*
- Filename extension.
- */
- GetPathComponent(image->magick_filename,ExtensionPath,filename);
- q+=CopyMagickString(q,filename,extent);
- break;
- }
- case 'f':
- {
- /*
- Filename.
- */
- GetPathComponent(image->magick_filename,TailPath,filename);
- q+=CopyMagickString(q,filename,extent);
- break;
- }
- case 't':
- {
- /*
- Base filename.
- */
- GetPathComponent(image->magick_filename,BasePath,filename);
- q+=CopyMagickString(q,filename,extent);
- break;
- }
- }
+ GetPathComponent(image->magick_filename,HeadPath,filename);
+ q+=CopyMagickString(q,filename,extent);
break;
}
- case 'g':
+ case 'e': /* Filename extension (suffix) of image file */
+ {
+ GetPathComponent(image->magick_filename,ExtensionPath,filename);
+ q+=CopyMagickString(q,filename,extent);
+ break;
+ }
+ case 'f': /* Filename without directory component */
+ {
+ GetPathComponent(image->magick_filename,TailPath,filename);
+ q+=CopyMagickString(q,filename,extent);
+ break;
+ }
+ case 't': /* Base filename without directory or extention */
+ {
+ GetPathComponent(image->magick_filename,BasePath,filename);
+ q+=CopyMagickString(q,filename,extent);
+ break;
+ }
+ case 'g': /* Image geometry, canvas and offset */
{
- /*
- Image geometry.
- */
q+=FormatLocaleString(q,extent,"%.20gx%.20g%+.20g%+.20g",(double)
image->page.width,(double) image->page.height,(double) image->page.x,
(double) image->page.y);
break;
}
- case 'h':
+ case 'h': /* Image height */
{
- /*
- Image height.
- */
q+=FormatLocaleString(q,extent,"%.20g",(double) (image->rows != 0 ?
image->rows : image->magick_rows));
break;
}
- case 'i':
+ case 'i': /* Images filename - (output filename with "info:" ) */
{
- /*
- Image filename.
- */
q+=CopyMagickString(q,image->filename,extent);
break;
}
- case 'k':
+ case 'k': /* Number of unique colors */
{
- /*
- Number of unique colors.
- */
q+=FormatLocaleString(q,extent,"%.20g",(double) GetNumberColors(image,
- (FILE *) NULL,&image->exception));
+ (FILE *) NULL,exception));
break;
}
- case 'l':
+ case 'l': /* Image label */
{
- /*
- Image label.
- */
- value=GetImageProperty(image,"label");
+ value=GetImageProperty(image,"label",exception);
if (value == (const char *) NULL)
break;
length=strlen(value);
q+=CopyMagickString(q,value,extent);
break;
}
- case 'm':
+ case 'm': /* Image format (file magick) */
{
- /*
- Image format.
- */
q+=CopyMagickString(q,image->magick,extent);
break;
}
- case 'M':
+ case 'M': /* Magick filename - exactly as given incl. read mods */
{
- /*
- Image magick filename.
- */
q+=CopyMagickString(q,image->magick_filename,extent);
break;
}
- case 'n':
+ case 'n': /* Number of images in the list. */
{
- /*
- Number of images in the list.
- */
q+=FormatLocaleString(q,extent,"%.20g",(double)
GetImageListLength(image));
break;
}
- case 'o':
+ case 'o': /* Image output filename */
{
- /*
- Image output filename.
- */
q+=CopyMagickString(q,image_info->filename,extent);
break;
}
- case 'p':
+ case 'p': /* Image index in current image list */
{
- /*
- Image index in list.
- */
q+=FormatLocaleString(q,extent,"%.20g",(double)
- GetImageIndexInList(image));
+ GetImageIndexInList(image));
break;
}
- case 'q':
+ case 'q': /* Quantum depth of image in memory */
{
- /*
- Image depth.
- */
q+=FormatLocaleString(q,extent,"%.20g",(double)
MAGICKCORE_QUANTUM_DEPTH);
break;
}
- case 'r':
+ case 'r': /* Image storage class and colorspace. */
{
ColorspaceType
colorspace;
- /*
- Image storage class and colorspace.
- */
colorspace=image->colorspace;
- if (IsImageGray(image,&image->exception) != MagickFalse)
+ if (IsImageGray(image,exception) != MagickFalse)
colorspace=GRAYColorspace;
q+=FormatLocaleString(q,extent,"%s%s%s",CommandOptionToMnemonic(
MagickClassOptions,(ssize_t) image->storage_class),
image->matte != MagickFalse ? "Matte" : "");
break;
}
- case 's':
+ case 's': /* Image scene number */
{
- /*
- Image scene number.
- */
if (image_info->number_scenes == 0)
q+=FormatLocaleString(q,extent,"%.20g",(double) image->scene);
else
q+=FormatLocaleString(q,extent,"%.20g",(double) image_info->scene);
break;
}
- case 'u':
+ case 'u': /* Unique filename */
{
- /*
- Unique filename.
- */
(void) CopyMagickString(filename,image_info->unique,extent);
q+=CopyMagickString(q,filename,extent);
break;
}
- case 'w':
+ case 'w': /* Image width */
{
- /*
- Image width.
- */
q+=FormatLocaleString(q,extent,"%.20g",(double) (image->columns != 0 ?
image->columns : image->magick_columns));
break;
}
- case 'x':
+ case 'x': /* Image horizontal resolution (density). */
{
- /*
- Image horizontal resolution.
- */
- q+=FormatLocaleString(q,extent,"%g %s",image->x_resolution,
+ q+=FormatLocaleString(q,extent,"%g %s",image->resolution.x,
CommandOptionToMnemonic(MagickResolutionOptions,(ssize_t)
image->units));
break;
}
- case 'y':
+ case 'y': /* Image vertical resolution (density) */
{
- /*
- Image vertical resolution.
- */
- q+=FormatLocaleString(q,extent,"%g %s",image->y_resolution,
+ q+=FormatLocaleString(q,extent,"%g %s",image->resolution.y,
CommandOptionToMnemonic(MagickResolutionOptions,(ssize_t)
image->units));
break;
}
- case 'z':
+ case 'z': /* Image depth as read in */
{
- /*
- Image depth.
- */
q+=FormatLocaleString(q,extent,"%.20g",(double) image->depth);
break;
}
- case 'A':
+ case 'A': /* Image alpha channel */
{
- /*
- Image alpha channel.
- */
q+=FormatLocaleString(q,extent,"%s",CommandOptionToMnemonic(
MagickBooleanOptions,(ssize_t) image->matte));
break;
}
- case 'C':
+ case 'C': /* Image compression method. */
{
- /*
- Image compression method.
- */
q+=FormatLocaleString(q,extent,"%s",CommandOptionToMnemonic(
MagickCompressOptions,(ssize_t) image->compression));
break;
}
- case 'D':
+ case 'D': /* Image dispose method. */
{
- /*
- Image dispose method.
- */
q+=FormatLocaleString(q,extent,"%s",CommandOptionToMnemonic(
MagickDisposeOptions,(ssize_t) image->dispose));
break;
}
- case 'G':
+ case 'G': /* Image size as geometry = "%wx%h" */
{
q+=FormatLocaleString(q,extent,"%.20gx%.20g",(double)
image->magick_columns,(double) image->magick_rows);
break;
}
- case 'H':
+ case 'H': /* layer canvas height */
{
q+=FormatLocaleString(q,extent,"%.20g",(double) image->page.height);
break;
}
- case 'O':
+ case 'O': /* layer canvas offset with sign = "+%X+%Y" */
{
q+=FormatLocaleString(q,extent,"%+ld%+ld",(long) image->page.x,(long)
image->page.y);
break;
}
- case 'P':
+ case 'P': /* layer canvas page size = "%Wx%H" */
{
q+=FormatLocaleString(q,extent,"%.20gx%.20g",(double) image->page.width,
(double) image->page.height);
break;
}
- case 'Q':
+ case 'Q': /* image compression quality */
{
q+=FormatLocaleString(q,extent,"%.20g",(double) image->quality);
break;
}
- case 'S':
+ case 'S': /* Image scenes */
{
- /*
- Image scenes.
- */
if (image_info->number_scenes == 0)
q+=CopyMagickString(q,"2147483647",extent);
else
image_info->number_scenes));
break;
}
- case 'T':
+ case 'T': /* image time delay for animations */
{
q+=FormatLocaleString(q,extent,"%.20g",(double) image->delay);
break;
}
- case 'W':
+ case 'W': /* layer canvas width */
{
q+=FormatLocaleString(q,extent,"%.20g",(double) image->page.width);
break;
}
- case 'X':
+ case 'X': /* layer canvas X offset */
{
q+=FormatLocaleString(q,extent,"%+.20g",(double) image->page.x);
break;
}
- case 'Y':
+ case 'Y': /* layer canvas Y offset */
{
q+=FormatLocaleString(q,extent,"%+.20g",(double) image->page.y);
break;
}
- case 'Z':
+ case 'Z': /* Unique filename. */
{
- /*
- Unique filename.
- */
(void) CopyMagickString(filename,image_info->zero,extent);
q+=CopyMagickString(q,filename,extent);
break;
}
- case '[':
- {
- char
- pattern[MaxTextExtent];
-
- const char
- *key,
- *value;
-
- ssize_t
- depth;
-
- /*
- Image value.
- */
- if (strchr(p,']') == (char *) NULL)
- break;
- depth=1;
- p++;
- for (i=0; (i < (MaxTextExtent-1L)) && (*p != '\0'); i++)
- {
- if (*p == '[')
- depth++;
- if (*p == ']')
- depth--;
- if (depth <= 0)
- break;
- pattern[i]=(*p++);
- }
- pattern[i]='\0';
- value=GetImageProperty(image,pattern);
- if (value != (const char *) NULL)
- {
- length=strlen(value);
- if ((size_t) (q-interpret_text+length+1) >= extent)
- {
- extent+=length;
- interpret_text=(char *) ResizeQuantumMemory(interpret_text,
- extent+MaxTextExtent,sizeof(*interpret_text));
- if (interpret_text == (char *) NULL)
- break;
- q=interpret_text+strlen(interpret_text);
- }
- (void) CopyMagickString(q,value,extent);
- q+=length;
- break;
- }
- else
- if (IsGlob(pattern) != MagickFalse)
- {
- /*
- Iterate over image properties.
- */
- ResetImagePropertyIterator(image);
- key=GetNextImageProperty(image);
- while (key != (const char *) NULL)
- {
- if (GlobExpression(key,pattern,MagickTrue) != MagickFalse)
- {
- value=GetImageProperty(image,key);
- if (value != (const char *) NULL)
- {
- length=strlen(key)+strlen(value)+2;
- if ((size_t) (q-interpret_text+length+1) >= extent)
- {
- extent+=length;
- interpret_text=(char *) ResizeQuantumMemory(
- interpret_text,extent+MaxTextExtent,
- sizeof(*interpret_text));
- if (interpret_text == (char *) NULL)
- break;
- q=interpret_text+strlen(interpret_text);
- }
- q+=FormatLocaleString(q,extent,"%s=%s\n",key,value);
- }
- }
- key=GetNextImageProperty(image);
- }
- }
- value=GetMagickProperty(image_info,image,pattern);
- if (value != (const char *) NULL)
- {
- length=strlen(value);
- if ((size_t) (q-interpret_text+length+1) >= extent)
- {
- extent+=length;
- interpret_text=(char *) ResizeQuantumMemory(interpret_text,
- extent+MaxTextExtent,sizeof(*interpret_text));
- if (interpret_text == (char *) NULL)
- break;
- q=interpret_text+strlen(interpret_text);
- }
- (void) CopyMagickString(q,value,extent);
- q+=length;
- break;
- }
- if (image_info == (ImageInfo *) NULL)
- break;
- value=GetImageOption(image_info,pattern);
- if (value != (char *) NULL)
- {
- length=strlen(value);
- if ((size_t) (q-interpret_text+length+1) >= extent)
- {
- extent+=length;
- interpret_text=(char *) ResizeQuantumMemory(interpret_text,
- extent+MaxTextExtent,sizeof(*interpret_text));
- if (interpret_text == (char *) NULL)
- break;
- q=interpret_text+strlen(interpret_text);
- }
- (void) CopyMagickString(q,value,extent);
- q+=length;
- break;
- }
- break;
- }
- case '@':
+ case '@': /* Image bounding box. */
{
RectangleInfo
page;
- /*
- Image bounding box.
- */
- page=GetImageBoundingBox(image,&image->exception);
+ page=GetImageBoundingBox(image,exception);
q+=FormatLocaleString(q,MaxTextExtent,"%.20gx%.20g%+.20g%+.20g",
(double) page.width,(double) page.height,(double) page.x,(double)
page.y);
break;
}
- case '#':
+ case '#': /* Image signature */
{
- /*
- Image signature.
- */
- (void) SignatureImage(image);
- value=GetImageProperty(image,"signature");
+ (void) SignatureImage(image,exception);
+ value=GetImageProperty(image,"signature",exception);
if (value == (const char *) NULL)
break;
q+=CopyMagickString(q,value,extent);
break;
}
- case '%':
+ case '%': /* percent escaped */
{
*q++=(*p);
break;
}
- default:
+ default: /* percent not expanded */
{
*q++='%';
*q++=(*p);
% The format of the SetImageProperty method is:
%
% MagickBooleanType SetImageProperty(Image *image,const char *property,
-% const char *value)
+% const char *value,ExceptionInfo *exception)
%
% A description of each parameter follows:
%
%
% o values: the image property values.
%
+% o exception: return any errors or warnings in this structure.
+%
*/
MagickExport MagickBooleanType SetImageProperty(Image *image,
- const char *property,const char *value)
+ const char *property,const char *value,ExceptionInfo *exception)
{
- ExceptionInfo
- *exception;
-
MagickBooleanType
status;
if ((value == (const char *) NULL) || (*value == '\0'))
return(DeleteImageProperty(image,property));
status=MagickTrue;
- exception=(&image->exception);
switch (*property)
{
case 'B':
{
if (LocaleCompare(property,"background") == 0)
{
- (void) QueryColorDatabase(value,&image->background_color,exception);
- break;
- }
- if (LocaleCompare(property,"bias") == 0)
- {
- image->bias=SiPrefixToDouble(value,QuantumRange);
+ (void) QueryColorCompliance(value,AllCompliance,
+ &image->background_color,exception);
break;
}
status=AddValueToSplayTree((SplayTreeInfo *) image->properties,
geometry_info;
flags=ParseGeometry(value,&geometry_info);
- image->x_resolution=geometry_info.rho;
- image->y_resolution=geometry_info.sigma;
+ image->resolution.x=geometry_info.rho;
+ image->resolution.y=geometry_info.sigma;
if ((flags & SigmaValue) == 0)
- image->y_resolution=image->x_resolution;
+ image->resolution.y=image->resolution.x;
}
if (LocaleCompare(property,"depth") == 0)
{
value);
if (interpolate < 0)
break;
- image->interpolate=(InterpolatePixelMethod) interpolate;
+ image->interpolate=(PixelInterpolateMethod) interpolate;
break;
}
status=AddValueToSplayTree((SplayTreeInfo *) image->properties,
(void) SetImageInfo(image_info,1,exception);
profile=FileToStringInfo(image_info->filename,~0UL,exception);
if (profile != (StringInfo *) NULL)
- status=SetImageProfile(image,image_info->magick,profile);
+ status=SetImageProfile(image,image_info->magick,profile,exception);
image_info=DestroyImageInfo(image_info);
break;
}