134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project// Parse some maker specific onformation. 334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project// (Very limited right now - add maker specific stuff to this module) 434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project#include "jhead.h" 634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project// Process exif format directory, as used by Cannon maker note 934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 1034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectvoid ProcessCanonMakerNoteDir(unsigned char * DirStart, unsigned char * OffsetBase, 1134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project unsigned ExifLength) 1234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project{ 1334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project int de; 1434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project int a; 1534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project int NumDirEntries; 1634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 1734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project NumDirEntries = Get16u(DirStart); 1834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project #define DIR_ENTRY_ADDR(Start, Entry) (Start+2+12*(Entry)) 1934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 2034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project { 2134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project unsigned char * DirEnd; 2234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DirEnd = DIR_ENTRY_ADDR(DirStart, NumDirEntries); 2334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (DirEnd > (OffsetBase+ExifLength)){ 2434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ErrNonfatal("Illegally sized directory",0,0); 2534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project return; 2634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 2734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 2834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (DumpExifMap){ 2934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project printf("Map: %05d-%05d: Directory (makernote)\n",DirStart-OffsetBase, DirEnd-OffsetBase); 3034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 3134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 3234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 3334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (ShowTags){ 3434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project printf("(dir has %d entries)\n",NumDirEntries); 3534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 3634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 3734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project for (de=0;de<NumDirEntries;de++){ 3834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project int Tag, Format, Components; 3934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project unsigned char * ValuePtr; 4034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project int ByteCount; 4134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project unsigned char * DirEntry; 4234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project DirEntry = DIR_ENTRY_ADDR(DirStart, de); 4334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 4434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project Tag = Get16u(DirEntry); 4534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project Format = Get16u(DirEntry+2); 4634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project Components = Get32u(DirEntry+4); 4734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 4834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if ((Format-1) >= NUM_FORMATS) { 4934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // (-1) catches illegal zero case as unsigned underflows to positive large. 5034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ErrNonfatal("Illegal number format %d for tag %04x", Format, Tag); 5134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project continue; 5234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 5334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 5434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if ((unsigned)Components > 0x10000){ 5534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ErrNonfatal("Illegal number of components %d for tag %04x", Components, Tag); 5634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project continue; 5734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 5834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 5934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ByteCount = Components * BytesPerFormat[Format]; 6034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 6134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (ByteCount > 4){ 6234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project unsigned OffsetVal; 6334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project OffsetVal = Get32u(DirEntry+8); 6434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // If its bigger than 4 bytes, the dir entry contains an offset. 6534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (OffsetVal+ByteCount > ExifLength){ 6634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Bogus pointer offset and / or bytecount value 6734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ErrNonfatal("Illegal value pointer for tag %04x", Tag,0); 6834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project continue; 6934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 7034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ValuePtr = OffsetBase+OffsetVal; 7134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 7234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (DumpExifMap){ 7334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project printf("Map: %05d-%05d: Data for makernote tag %04x\n",OffsetVal, OffsetVal+ByteCount, Tag); 7434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 7534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else{ 7634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // 4 bytes or less and value is in the dir entry itself 7734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ValuePtr = DirEntry+8; 7834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 7934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 8034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (ShowTags){ 8134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Show tag name 8234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project printf(" Canon maker tag %04x Value = ", Tag); 8334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 8434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 8534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Show tag value. 8634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project switch(Format){ 8734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 8834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project case FMT_UNDEFINED: 8934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Undefined is typically an ascii string. 9034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 9134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project case FMT_STRING: 9234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // String arrays printed without function call (different from int arrays) 9334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (ShowTags){ 9434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project printf("\""); 9534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project for (a=0;a<ByteCount;a++){ 9634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project int ZeroSkipped = 0; 9734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (ValuePtr[a] >= 32){ 9834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (ZeroSkipped){ 9934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project printf("?"); 10034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ZeroSkipped = 0; 10134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 10234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project putchar(ValuePtr[a]); 10334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else{ 10434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (ValuePtr[a] == 0){ 10534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ZeroSkipped = 1; 10634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 10734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 10834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 10934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project printf("\"\n"); 11034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 11134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project break; 11234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 11334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project default: 11434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (ShowTags){ 11534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project PrintFormatNumber(ValuePtr, Format, ByteCount); 11634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project printf("\n"); 11734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 11834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 11934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (Tag == 1 && Components > 16){ 12034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project int IsoCode = Get16u(ValuePtr + 16*sizeof(unsigned short)); 12134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (IsoCode >= 16 && IsoCode <= 24){ 12234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ImageInfo.ISOequivalent = 50 << (IsoCode-16); 12334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 12434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 12534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 12634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (Tag == 4 && Format == FMT_USHORT){ 12734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (Components > 7){ 12834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project int WhiteBalance = Get16u(ValuePtr + 7*sizeof(unsigned short)); 12934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project switch(WhiteBalance){ 13034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // 0=Auto, 6=Custom 13134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project case 1: ImageInfo.LightSource = 1; break; // Sunny 13234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project case 2: ImageInfo.LightSource = 1; break; // Cloudy 13334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project case 3: ImageInfo.LightSource = 3; break; // Thungsten 13434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project case 4: ImageInfo.LightSource = 2; break; // Fourescent 13534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project case 5: ImageInfo.LightSource = 4; break; // Flash 13634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 13734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 13834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (Components > 19 && ImageInfo.Distance <= 0) { 13934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Inidcates the distance the autofocus camera is focused to. 14034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project // Tends to be less accurate as distance increases. 14134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project int temp_dist = Get16u(ValuePtr + 19*sizeof(unsigned short)); 14234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectprintf("temp dist=%d\n",temp_dist); 14334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (temp_dist != 65535){ 14434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ImageInfo.Distance = (float)temp_dist/100; 14534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else{ 14634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ImageInfo.Distance = -1 /* infinity */; 14734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 14834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 14934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 15034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 15134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project} 15234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 15334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 15434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project// Show generic maker note - just hex bytes. 15534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 15634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectvoid ShowMakerNoteGeneric(unsigned char * ValuePtr, int ByteCount) 15734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project{ 15834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project int a; 15934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project for (a=0;a<ByteCount;a++){ 16034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (a > 10){ 16134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project printf("..."); 16234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project break; 16334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 16434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project printf(" %02x",ValuePtr[a]); 16534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 16634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project printf(" (%d bytes)", ByteCount); 16734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project printf("\n"); 16834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 16934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project} 17034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 17134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 17234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project// Process maker note - to the limited extent that its supported. 17334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project//-------------------------------------------------------------------------- 17434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Projectvoid ProcessMakerNote(unsigned char * ValuePtr, int ByteCount, 17534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project unsigned char * OffsetBase, unsigned ExifLength) 17634a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project{ 17734a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (strstr(ImageInfo.CameraMake, "Canon")){ 17834a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ProcessCanonMakerNoteDir(ValuePtr, OffsetBase, ExifLength); 17934a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project }else{ 18034a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project if (ShowTags){ 18134a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project ShowMakerNoteGeneric(ValuePtr, ByteCount); 18234a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 18334a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project } 18434a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project} 18534a2564d3268a5ca1472c5076675782fbaf724d6The Android Open Source Project 186