#include "MagickCore/utility.h"
#include "MagickCore/version.h"
#include "MagickCore/module.h"
+
+/*
+ Typedef declarations.
+*/
+typedef struct _IptcValue
+{
+ long
+ dataset,
+ record;
+
+ size_t
+ values_length;
+
+ char
+ tag[32],
+ ***values;
+} IptcValue;
\f
/*
Forward declarations.
return(n);
}
+static void EncodeIptcProfile(FILE *file,const StringInfo *profile)
+{
+ char
+ *attribute,
+ **attribute_list;
+
+ const char
+ *tag;
+
+ IptcValue
+ *value,
+ **values;
+
+ long
+ dataset,
+ record,
+ sentinel;
+
+ register ssize_t
+ i,
+ j,
+ k;
+
+ size_t
+ count,
+ length,
+ profile_length;
+
+ values=(IptcValue **) NULL;
+ count=0;
+ profile_length=GetStringInfoLength(profile);
+ for (i=0; i < (ssize_t) profile_length; i+=(ssize_t) length)
+ {
+ length=1;
+ sentinel=GetStringInfoDatum(profile)[i++];
+ if (sentinel != 0x1c)
+ continue;
+ dataset=GetStringInfoDatum(profile)[i++];
+ record=GetStringInfoDatum(profile)[i++];
+ value=(IptcValue *) NULL;
+ for (j=0; j < count; j++)
+ {
+ if ((values[j]->record == record) && (values[j]->dataset == dataset))
+ value=values[j];
+ }
+ if (value == (IptcValue *) NULL)
+ {
+ values=(IptcValue **) ResizeQuantumMemory(values,count+1,
+ sizeof(*values));
+ if (values == (IptcValue **) NULL)
+ break;
+ value=AcquireMagickMemory(sizeof(*value));
+ if (value == (IptcValue *) NULL)
+ break;
+ /* Check the tag length in IptcValue when a new tag is added */
+ switch (record)
+ {
+ case 5: tag="Image Name"; break;
+ case 7: tag="Edit Status"; break;
+ case 10: tag="Priority"; break;
+ case 15: tag="Category"; break;
+ case 20: tag="Supplemental Category"; break;
+ case 22: tag="Fixture Identifier"; break;
+ case 25: tag="Keyword"; break;
+ case 30: tag="Release Date"; break;
+ case 35: tag="Release Time"; break;
+ case 40: tag="Special Instructions"; break;
+ case 45: tag="Reference Service"; break;
+ case 47: tag="Reference Date"; break;
+ case 50: tag="Reference Number"; break;
+ case 55: tag="Created Date"; break;
+ case 60: tag="Created Time"; break;
+ case 65: tag="Originating Program"; break;
+ case 70: tag="Program Version"; break;
+ case 75: tag="Object Cycle"; break;
+ case 80: tag="Byline"; break;
+ case 85: tag="Byline Title"; break;
+ case 90: tag="City"; break;
+ case 92: tag="Sub-Location"; break;
+ case 95: tag="Province State"; break;
+ case 100: tag="Country Code"; break;
+ case 101: tag="Country"; break;
+ case 103: tag="Original Transmission Reference"; break;
+ case 105: tag="Headline"; break;
+ case 110: tag="Credit"; break;
+ case 115: tag="Src"; break;
+ case 116: tag="Copyright String"; break;
+ case 120: tag="Caption"; break;
+ case 121: tag="Local Caption"; break;
+ case 122: tag="Caption Writer"; break;
+ case 200: tag="Custom Field 1"; break;
+ case 201: tag="Custom Field 2"; break;
+ case 202: tag="Custom Field 3"; break;
+ case 203: tag="Custom Field 4"; break;
+ case 204: tag="Custom Field 5"; break;
+ case 205: tag="Custom Field 6"; break;
+ case 206: tag="Custom Field 7"; break;
+ case 207: tag="Custom Field 8"; break;
+ case 208: tag="Custom Field 9"; break;
+ case 209: tag="Custom Field 10"; break;
+ case 210: tag="Custom Field 11"; break;
+ case 211: tag="Custom Field 12"; break;
+ case 212: tag="Custom Field 13"; break;
+ case 213: tag="Custom Field 14"; break;
+ case 214: tag="Custom Field 15"; break;
+ case 215: tag="Custom Field 16"; break;
+ case 216: tag="Custom Field 17"; break;
+ case 217: tag="Custom Field 18"; break;
+ case 218: tag="Custom Field 19"; break;
+ case 219: tag="Custom Field 20"; break;
+ default: tag="Unknown"; break;
+ }
+ (void) CopyMagickString(value->tag,tag,strlen(tag)+1);
+ value->record=record;
+ value->dataset=dataset;
+ value->values=(char ***) NULL;
+ value->values_length=0;
+ values[count++]=value;
+ }
+ length=(size_t) (GetStringInfoDatum(profile)[i++] << 8);
+ length|=GetStringInfoDatum(profile)[i++];
+ attribute=(char *) NULL;
+ if (~length >= (MagickPathExtent-1))
+ attribute=(char *) AcquireQuantumMemory(length+MagickPathExtent,
+ sizeof(*attribute));
+ if (attribute != (char *) NULL)
+ {
+ (void) CopyMagickString(attribute,(char *)
+ GetStringInfoDatum(profile)+i,length+1);
+ attribute_list=StringToList(attribute);
+ if (attribute_list != (char **) NULL)
+ {
+ value->values=(char ***) ResizeQuantumMemory(value->values,
+ value->values_length+1,
+ sizeof(*value->values));
+ if (value->values == (char ***) NULL)
+ break;
+ value->values[value->values_length++]=attribute_list;
+ }
+ attribute=DestroyString(attribute);
+ }
+ }
+ if (values != (IptcValue **) NULL)
+ {
+ for (i=0; i < count; i++)
+ {
+ value=values[i];
+ (void) FormatLocaleFile(file," \"%s[%.20g,%.20g]\": ",
+ value->tag,(double) value->dataset,(double) value->record);
+ if (value->values_length == 0)
+ (void) FormatLocaleFile(file,"null,");
+ else
+ {
+ (void) FormatLocaleFile(file,"[");
+ for (j=0; j < value->values_length; j++)
+ {
+ for (k=0; value->values[j][k] != (char *) NULL; k++)
+ {
+ if (j > 0 || k > 0)
+ (void) FormatLocaleFile(file,",");
+ JsonFormatLocaleFile(file,"%s",value->values[j][k]);
+ value->values[j][k]=(char *) RelinquishMagickMemory(
+ value->values[j][k]);
+ }
+ value->values[j]=(char **) RelinquishMagickMemory(
+ value->values[j]);
+ }
+ value->values=(char ***) RelinquishMagickMemory(value->values);
+ (void) FormatLocaleFile(file,"],\n");
+ }
+ values[i]=(IptcValue *) RelinquishMagickMemory(values[i]);
+ }
+ values=(IptcValue **) RelinquishMagickMemory(values);
+ }
+}
+
static MagickBooleanType EncodeImageAttributes(Image *image,FILE *file,
ExceptionInfo *exception)
{
(void) FormatLocaleFile(file,",\n");
JsonFormatLocaleFile(file," %s: {\n",name);
if (LocaleCompare(name,"iptc") == 0)
- {
- char
- *attribute,
- **attribute_list;
-
- const char
- *tag;
-
- long
- dataset,
- record,
- sentinel;
-
- register ssize_t
- j;
-
- size_t
- length,
- profile_length;
-
- profile_length=GetStringInfoLength(profile);
- for (i=0; i < (ssize_t) profile_length; i+=(ssize_t) length)
- {
- length=1;
- sentinel=GetStringInfoDatum(profile)[i++];
- if (sentinel != 0x1c)
- continue;
- dataset=GetStringInfoDatum(profile)[i++];
- record=GetStringInfoDatum(profile)[i++];
- switch (record)
- {
- case 5: tag="Image Name"; break;
- case 7: tag="Edit Status"; break;
- case 10: tag="Priority"; break;
- case 15: tag="Category"; break;
- case 20: tag="Supplemental Category"; break;
- case 22: tag="Fixture Identifier"; break;
- case 25: tag="Keyword"; break;
- case 30: tag="Release Date"; break;
- case 35: tag="Release Time"; break;
- case 40: tag="Special Instructions"; break;
- case 45: tag="Reference Service"; break;
- case 47: tag="Reference Date"; break;
- case 50: tag="Reference Number"; break;
- case 55: tag="Created Date"; break;
- case 60: tag="Created Time"; break;
- case 65: tag="Originating Program"; break;
- case 70: tag="Program Version"; break;
- case 75: tag="Object Cycle"; break;
- case 80: tag="Byline"; break;
- case 85: tag="Byline Title"; break;
- case 90: tag="City"; break;
- case 92: tag="Sub-Location"; break;
- case 95: tag="Province State"; break;
- case 100: tag="Country Code"; break;
- case 101: tag="Country"; break;
- case 103: tag="Original Transmission Reference"; break;
- case 105: tag="Headline"; break;
- case 110: tag="Credit"; break;
- case 115: tag="Src"; break;
- case 116: tag="Copyright String"; break;
- case 120: tag="Caption"; break;
- case 121: tag="Local Caption"; break;
- case 122: tag="Caption Writer"; break;
- case 200: tag="Custom Field 1"; break;
- case 201: tag="Custom Field 2"; break;
- case 202: tag="Custom Field 3"; break;
- case 203: tag="Custom Field 4"; break;
- case 204: tag="Custom Field 5"; break;
- case 205: tag="Custom Field 6"; break;
- case 206: tag="Custom Field 7"; break;
- case 207: tag="Custom Field 8"; break;
- case 208: tag="Custom Field 9"; break;
- case 209: tag="Custom Field 10"; break;
- case 210: tag="Custom Field 11"; break;
- case 211: tag="Custom Field 12"; break;
- case 212: tag="Custom Field 13"; break;
- case 213: tag="Custom Field 14"; break;
- case 214: tag="Custom Field 15"; break;
- case 215: tag="Custom Field 16"; break;
- case 216: tag="Custom Field 17"; break;
- case 217: tag="Custom Field 18"; break;
- case 218: tag="Custom Field 19"; break;
- case 219: tag="Custom Field 20"; break;
- default: tag="unknown"; break;
- }
- (void) FormatLocaleFile(file," \"%s[%.20g,%.20g]\": ",tag,
- (double) dataset,(double) record);
- length=(size_t) (GetStringInfoDatum(profile)[i++] << 8);
- length|=GetStringInfoDatum(profile)[i++];
- attribute=(char *) NULL;
- if (~length >= (MagickPathExtent-1))
- attribute=(char *) AcquireQuantumMemory(length+MagickPathExtent,
- sizeof(*attribute));
- if (attribute != (char *) NULL)
- {
- (void) CopyMagickString(attribute,(char *)
- GetStringInfoDatum(profile)+i,length+1);
- attribute_list=StringToList(attribute);
- if (attribute_list != (char **) NULL)
- {
- (void) FormatLocaleFile(file,"[");
- for (j=0; attribute_list[j] != (char *) NULL; j++)
- {
- if (j != 0)
- (void) FormatLocaleFile(file,",");
- JsonFormatLocaleFile(file,"%s",attribute_list[j]);
- attribute_list[j]=(char *) RelinquishMagickMemory(
- attribute_list[j]);
- }
- (void) FormatLocaleFile(file,"],");
- attribute_list=(char **) RelinquishMagickMemory(
- attribute_list);
- }
- else
- (void) FormatLocaleFile(file,"null,");
- attribute=DestroyString(attribute);
- }
- else
- (void) FormatLocaleFile(file,"null,");
- }
- }
+ EncodeIptcProfile(file,profile);
(void) FormatLocaleFile(file," \"length\": \"%.20g\"",(double)
GetStringInfoLength(profile));
(void) FormatLocaleFile(file,"\n }");