diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 19:30:03 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 19:30:03 -0800 |
commit | 34a2564d3268a5ca1472c5076675782fbaf724d6 (patch) | |
tree | 4ef54cbea93bf6aa7c37ca25add416d126166fa3 /iptc.c | |
parent | e0fbb24f6ea00ce3d61b73ef05faa893abf33151 (diff) | |
download | jhead-34a2564d3268a5ca1472c5076675782fbaf724d6.tar.gz |
auto import from //depot/cupcake/@135843
Diffstat (limited to 'iptc.c')
-rw-r--r-- | iptc.c | 156 |
1 files changed, 156 insertions, 0 deletions
@@ -0,0 +1,156 @@ +//-------------------------------------------------------------------------- +// Process IPTC data. +//-------------------------------------------------------------------------- +#include "jhead.h" + +// Supported IPTC entry types +#define IPTC_SUPLEMENTAL_CATEGORIES 0x14 +#define IPTC_KEYWORDS 0x19 +#define IPTC_CAPTION 0x78 +#define IPTC_AUTHOR 0x7A +#define IPTC_HEADLINE 0x69 +#define IPTC_SPECIAL_INSTRUCTIONS 0x28 +#define IPTC_CATEGORY 0x0F +#define IPTC_BYLINE 0x50 +#define IPTC_BYLINE_TITLE 0x55 +#define IPTC_CREDIT 0x6E +#define IPTC_SOURCE 0x73 +#define IPTC_COPYRIGHT_NOTICE 0x74 +#define IPTC_OBJECT_NAME 0x05 +#define IPTC_CITY 0x5A +#define IPTC_STATE 0x5F +#define IPTC_COUNTRY 0x65 +#define IPTC_TRANSMISSION_REFERENCE 0x67 +#define IPTC_DATE 0x37 +#define IPTC_COPYRIGHT 0x0A +#define IPTC_COUNTRY_CODE 0x64 +#define IPTC_REFERENCE_SERVICE 0x2D + +//-------------------------------------------------------------------------- +// Process and display IPTC marker. +// +// IPTC block consists of: +// - Marker: 1 byte (0xED) +// - Block length: 2 bytes +// - IPTC Signature: 14 bytes ("Photoshop 3.0\0") +// - 8BIM Signature 4 bytes ("8BIM") +// - IPTC Block start 2 bytes (0x04, 0x04) +// - IPTC Header length 1 byte +// - IPTC header Header is padded to even length, counting the length byte +// - Length 4 bytes +// - IPTC Data which consists of a number of entries, each of which has the following format: +// - Signature 2 bytes (0x1C02) +// - Entry type 1 byte (for defined entry types, see #defines above) +// - entry length 2 bytes +// - entry data 'entry length' bytes +// +//-------------------------------------------------------------------------- +void show_IPTC (unsigned char* Data, unsigned int itemlen) +{ + const char IptcSig1[] = "Photoshop 3.0"; + const char IptcSig2[] = "8BIM"; + const char IptcSig3[] = {0x04, 0x04}; + + unsigned char * pos = Data + sizeof(short); // position data pointer after length field + unsigned char * maxpos = Data+itemlen; + char headerLen = 0; + + if (itemlen < 25) goto corrupt; + + // Check IPTC signatures + if (memcmp(pos, IptcSig1, sizeof(IptcSig1)-1) != 0) goto badsig; + pos += sizeof(IptcSig1); // move data pointer to the next field + + if (memcmp(pos, IptcSig2, sizeof(IptcSig2)-1) != 0) goto badsig; + pos += sizeof(IptcSig2)-1; // move data pointer to the next field + + if (memcmp(pos, IptcSig3, sizeof(IptcSig3)) != 0){ +badsig: + if (ShowTags){ + ErrNonfatal("IPTC type signature mismatch\n",0,0); + } + return; + } + pos += sizeof(IptcSig3); // move data pointer to the next field + + if (pos >= maxpos) goto corrupt; + + // IPTC section found + + // Skip header + headerLen = *pos++; // get header length and move data pointer to the next field + pos += headerLen + 1 - (headerLen % 2); // move data pointer to the next field (Header is padded to even length, counting the length byte) + + if (pos+4 >= maxpos) goto corrupt; + + // Get length (from motorola format) + //length = (*pos << 24) | (*(pos+1) << 16) | (*(pos+2) << 8) | *(pos+3); + + pos += sizeof(long); // move data pointer to the next field + + printf("======= IPTC data: =======\n"); + + // Now read IPTC data + while (pos < (Data + itemlen-5)) { + short signature; + char type = 0; + short length = 0; + char * description = NULL; + + if (pos+5 > maxpos) goto corrupt; + + signature = (*pos << 8) + (*(pos+1)); + pos += sizeof(short); + + if (signature != 0x1C02){ + break; + } + + type = *pos++; + length = (*pos << 8) + (*(pos+1)); + pos += sizeof(short); // Skip tag length + + if (pos+length > maxpos) goto corrupt; + // Process tag here + switch (type) { + case IPTC_SUPLEMENTAL_CATEGORIES: description = "SuplementalCategories"; break; + case IPTC_KEYWORDS: description = "Keywords"; break; + case IPTC_CAPTION: description = "Caption"; break; + case IPTC_AUTHOR: description = "Author"; break; + case IPTC_HEADLINE: description = "Headline"; break; + case IPTC_SPECIAL_INSTRUCTIONS: description = "Spec.Instr."; break; + case IPTC_CATEGORY: description = "Category"; break; + case IPTC_BYLINE: description = "Byline"; break; + case IPTC_BYLINE_TITLE: description = "BylineTitle"; break; + case IPTC_CREDIT: description = "Credit"; break; + case IPTC_SOURCE: description = "Source"; break; + case IPTC_COPYRIGHT_NOTICE: description = "(C)Notice"; break; + case IPTC_OBJECT_NAME: description = "ObjectName"; break; + case IPTC_CITY: description = "City"; break; + case IPTC_STATE: description = "State"; break; + case IPTC_COUNTRY: description = "Country"; break; + case IPTC_TRANSMISSION_REFERENCE: description = "OriginalTransmissionReference"; break; + case IPTC_DATE: description = "DateCreated"; break; + case IPTC_COPYRIGHT: description = "(C)Flag"; break; + case IPTC_REFERENCE_SERVICE: description = "CountryCode"; break; + case IPTC_COUNTRY_CODE: description = "Ref.Service"; break; + default: + if (ShowTags){ + printf("Unrecognised IPTC tag: 0x%02x \n", type); + } + break; + } + if (description != NULL) { + char TempBuf[32]; + memset(TempBuf, 0, sizeof(TempBuf)); + memset(TempBuf, ' ', 13); + memcpy(TempBuf, description, strlen(description)); + strcat(TempBuf, ":"); + printf("%s %*.*s\n", TempBuf, length, length, pos); + } + pos += length; + } + return; +corrupt: + ErrNonfatal("Pointer corruption in IPTC\n",0,0); +} |