#define cmsOpenProfileFromMemTHR(context,profile,length) \
cmsOpenProfileFromMem(profile,length)
#endif
+
+/*
+ Forward declarations
+*/
+static MagickBooleanType
+ SetImageProfileInternal(Image *,const char *,const StringInfo *,
+ const MagickBooleanType,ExceptionInfo *);
+
+static void
+ WriteTo8BimProfile(Image *,const char*,const StringInfo *);
\f
/*
Typedef declarations
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
if (image->profiles == (SplayTreeInfo *) NULL)
return(MagickFalse);
+ WriteTo8BimProfile(image,name,(StringInfo *) NULL);
return(DeleteNodeFromSplayTree((SplayTreeInfo *) image->profiles,name));
}
\f
(void) ResetMagickMemory(transform,0,number_threads*sizeof(*transform));
for (i=0; i < (ssize_t) number_threads; i++)
{
- transform[i]=cmsCreateTransformTHR(image,source_profile,source_type,
- target_profile,target_type,intent,flags);
+ transform[i]=cmsCreateTransformTHR((cmsContext) image,source_profile,
+ source_type,target_profile,target_type,intent,flags);
if (transform[i] == (cmsHTRANSFORM) NULL)
return(DestroyTransformThreadSet(transform));
}
cms_exception.image=image;
cms_exception.exception=exception;
(void) cms_exception;
- source_profile=cmsOpenProfileFromMemTHR(&cms_exception,
+ source_profile=cmsOpenProfileFromMemTHR((cmsContext) &cms_exception,
GetStringInfoDatum(profile),(cmsUInt32Number)
GetStringInfoLength(profile));
if (source_profile == (cmsHPROFILE) NULL)
if (icc_profile != (StringInfo *) NULL)
{
target_profile=source_profile;
- source_profile=cmsOpenProfileFromMemTHR(&cms_exception,
- GetStringInfoDatum(icc_profile),(cmsUInt32Number)
- GetStringInfoLength(icc_profile));
+ source_profile=cmsOpenProfileFromMemTHR((cmsContext)
+ &cms_exception,GetStringInfoDatum(icc_profile),
+ (cmsUInt32Number) GetStringInfoLength(icc_profile));
if (source_profile == (cmsHPROFILE) NULL)
ThrowProfileException(ResourceLimitError,
"ColorspaceColorProfileMismatch",name);
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
if (image->profiles == (SplayTreeInfo *) NULL)
return((StringInfo *) NULL);
+ WriteTo8BimProfile(image,name,(StringInfo *) NULL);
profile=(StringInfo *) RemoveNodeFromSplayTree((SplayTreeInfo *)
image->profiles,name);
return(profile);
}
static inline const unsigned char *ReadResourceLong(const unsigned char *p,
- size_t *quantum)
+ unsigned int *quantum)
{
*quantum=(size_t) (*p++ << 24);
*quantum|=(size_t) (*p++ << 16);
*quantum=(unsigned short) (*p++ << 8);
*quantum|=(unsigned short) (*p++ << 0);
return(p);
+}static inline void WriteResourceLong(unsigned char *p,
+ const unsigned int quantum)
+{
+ unsigned char
+ buffer[4];
+
+ buffer[0]=(unsigned char) (quantum >> 24);
+ buffer[1]=(unsigned char) (quantum >> 16);
+ buffer[2]=(unsigned char) (quantum >> 8);
+ buffer[3]=(unsigned char) quantum;
+ (void) CopyMagickMemory(p,buffer,4);
+}
+
+static void WriteTo8BimProfile(Image *image,const char *name,
+ const StringInfo *profile)
+{
+
+ const unsigned char
+ *datum,
+ *s;
+
+ register const unsigned char
+ *p;
+
+ size_t
+ length;
+
+ StringInfo
+ *profile_8bim;
+
+ ssize_t
+ count;
+
+ unsigned char
+ length_byte;
+
+ unsigned int
+ value;
+
+ unsigned short
+ id,
+ profile_id;
+
+ if (LocaleCompare(name,"icc") == 0)
+ profile_id=0x040f;
+ else if (LocaleCompare(name,"iptc") == 0)
+ profile_id=0x0404;
+ else if (LocaleCompare(name,"xmp") == 0)
+ profile_id=0x0424;
+ else
+ return;
+ profile_8bim=(StringInfo *)GetValueFromSplayTree((SplayTreeInfo *)
+ image->profiles,"8bim");
+ if (profile_8bim == (StringInfo *) NULL)
+ return;
+ datum=GetStringInfoDatum(profile_8bim);
+ length=GetStringInfoLength(profile_8bim);
+ for (p=datum; p < (datum+length-16); )
+ {
+ s=p;
+ if (LocaleNCompare((char *) p,"8BIM",4) != 0)
+ break;
+ p+=4;
+ p=ReadResourceShort(p,&id);
+ p=ReadResourceByte(p,&length_byte);
+ p+=length_byte;
+ if (((length_byte+1) & 0x01) != 0)
+ p++;
+ if (p > (datum+length-4))
+ break;
+ p=ReadResourceLong(p,&value);
+ count=(ssize_t) value;
+ if ((p > (datum+length-count)) || (count > length))
+ break;
+ if ((count & 0x01) != 0)
+ count++;
+ if (id == profile_id)
+ {
+ size_t
+ offset,
+ rest;
+
+ ssize_t
+ new_count;
+
+ StringInfo
+ *new_profile;
+
+ new_count=0;
+ rest=(datum+length)-(p+count);
+ if (profile == (StringInfo *) NULL)
+ {
+ offset=(s-datum);
+ new_profile=AcquireStringInfo(offset+rest);
+ (void) CopyMagickMemory(new_profile->datum,datum,offset);
+ }
+ else
+ {
+ offset=(p-datum);
+ new_count=profile->length;
+ if ((new_count & 0x01) != 0)
+ new_count++;
+ new_profile=AcquireStringInfo(offset+new_count+rest);
+ (void) CopyMagickMemory(new_profile->datum,datum,offset-4);
+ WriteResourceLong(new_profile->datum+offset-4,profile->length);
+ (void) CopyMagickMemory(new_profile->datum+offset,profile->datum,
+ profile->length);
+ }
+ (void) CopyMagickMemory(new_profile->datum+offset+new_count,p+count,
+ rest);
+ (void) AddValueToSplayTree((SplayTreeInfo *) image->profiles,
+ ConstantString("8bim"),CloneStringInfo(new_profile));
+ new_profile=DestroyStringInfo(new_profile);
+ break;
+ }
+ else
+ p+=count;
+ }
}
-static MagickBooleanType GetProfilesFromResourceBlock(Image *image,
+static void GetProfilesFromResourceBlock(Image *image,
const StringInfo *resource_block,ExceptionInfo *exception)
{
const unsigned char
size_t
length;
+ ssize_t
+ count;
+
StringInfo
*profile;
unsigned char
length_byte;
- size_t
- count;
+ unsigned int
+ value;
unsigned short
id;
p++;
if (p > (datum+length-4))
break;
- p=ReadResourceLong(p,&count);
+ p=ReadResourceLong(p,&value);
+ count=(ssize_t) value;
if ((p > (datum+length-count)) || (count > length))
break;
switch (id)
{
case 0x03ed:
{
- unsigned short
+ unsigned int
resolution;
+ unsigned short
+ units;
+
/*
Resolution.
*/
- p=ReadResourceShort(p,&resolution)+6;
- image->resolution.x=(double) resolution;
- p=ReadResourceShort(p,&resolution)+6;
- image->resolution.y=(double) resolution;
+ p=ReadResourceLong(p,&resolution);
+ image->resolution.x=((double) resolution)/65536.0;
+ p=ReadResourceShort(p,&units)+2;
+ p=ReadResourceLong(p,&resolution)+4;
+ image->resolution.y=((double) resolution)/65536.0;
+ /*
+ Values are always stored as pixels per inch.
+ */
+ if ((ResolutionType) units != PixelsPerCentimeterResolution)
+ image->units=PixelsPerInchResolution;
+ else
+ {
+ image->units=PixelsPerCentimeterResolution;
+ image->resolution.x/=2.54;
+ image->resolution.y/=2.54;
+ }
break;
}
case 0x0404:
*/
profile=AcquireStringInfo(count);
SetStringInfoDatum(profile,p);
- (void) SetImageProfile(image,"iptc",profile,exception);
+ (void) SetImageProfileInternal(image,"iptc",profile,MagickTrue,
+ exception);
profile=DestroyStringInfo(profile);
p+=count;
break;
*/
profile=AcquireStringInfo(count);
SetStringInfoDatum(profile,p);
- (void) SetImageProfile(image,"icc",profile,exception);
+ (void) SetImageProfileInternal(image,"icc",profile,MagickTrue,
+ exception);
profile=DestroyStringInfo(profile);
p+=count;
break;
*/
profile=AcquireStringInfo(count);
SetStringInfoDatum(profile,p);
- (void) SetImageProfile(image,"exif",profile,exception);
+ (void) SetImageProfileInternal(image,"exif",profile,MagickTrue,
+ exception);
profile=DestroyStringInfo(profile);
p+=count;
break;
*/
profile=AcquireStringInfo(count);
SetStringInfoDatum(profile,p);
- (void) SetImageProfile(image,"xmp",profile,exception);
+ (void) SetImageProfileInternal(image,"xmp",profile,MagickTrue,
+ exception);
profile=DestroyStringInfo(profile);
p+=count;
break;
if ((count & 0x01) != 0)
p++;
}
- return(MagickTrue);
}
-MagickExport MagickBooleanType SetImageProfile(Image *image,const char *name,
- const StringInfo *profile,ExceptionInfo *exception)
+static MagickBooleanType SetImageProfileInternal(Image *image,const char *name,
+ const StringInfo *profile,const MagickBooleanType recursive,
+ ExceptionInfo *exception)
{
char
key[MaxTextExtent],
image->profiles=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory,
DestroyProfile);
(void) CopyMagickString(key,name,MaxTextExtent);
+ LocaleLower(key);
status=AddValueToSplayTree((SplayTreeInfo *) image->profiles,
ConstantString(key),CloneStringInfo(profile));
- if ((status != MagickFalse) &&
- ((LocaleCompare(name,"iptc") == 0) || (LocaleCompare(name,"8bim") == 0)))
- (void) GetProfilesFromResourceBlock(image,profile,exception);
+ if (status != MagickFalse)
+ {
+ if (LocaleCompare(name,"8bim") == 0)
+ GetProfilesFromResourceBlock(image,profile,exception);
+ else if (recursive == MagickFalse)
+ WriteTo8BimProfile(image,name,profile);
+ }
/*
Inject profile into image properties.
*/
(void) GetImageProperty(image,property,exception);
return(status);
}
+
+MagickExport MagickBooleanType SetImageProfile(Image *image,const char *name,
+ const StringInfo *profile,ExceptionInfo *exception)
+{
+ return(SetImageProfileInternal(image,name,profile,MagickFalse,exception));
+}
\f
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
return(MagickFalse);
if (id == 0x3ED && count == 16)
{
- WriteProfileShort(MSBEndian, (unsigned short) (image->resolution.x+
- 0.5),p);
- WriteProfileShort(MSBEndian, (unsigned short) (image->resolution.y+
- 0.5),p+8);
+ if (image->units == PixelsPerCentimeterResolution)
+ WriteProfileLong(MSBEndian, (unsigned int) (image->resolution.x*2.54*
+ 65536.0),p);
+ else
+ WriteProfileLong(MSBEndian, (unsigned int) (image->resolution.x*
+ 65536.0),p);
+ WriteProfileShort(MSBEndian,(unsigned short) image->units,p+4);
+ if (image->units == PixelsPerCentimeterResolution)
+ WriteProfileLong(MSBEndian, (unsigned int) (image->resolution.y*2.54*
+ 65536.0),p+8);
+ else
+ WriteProfileLong(MSBEndian, (unsigned int) (image->resolution.y*
+ 65536.0),p+8);
+ WriteProfileShort(MSBEndian,(unsigned short) image->units,p+12);
}
p+=count;
length-=count;
return(MagickTrue);
}
-MagickExport MagickBooleanType SyncImageProfiles(Image *image)
+MagickPrivate MagickBooleanType SyncImageProfiles(Image *image)
{
MagickBooleanType
status;
if (SyncExifProfile(image,profile) == MagickFalse)
status=MagickFalse;
return(status);
-}
\ No newline at end of file
+}