--- exif.c- Sun Aug 20 18:38:32 2000 +++ exif.c Sun Aug 20 18:33:32 2000 @@ -0,0 +1,3234 @@ +/* $Id$ */ + +/************************************************************************* + * * + * exif.c * + * EXIF specific code of RenamePics * + * * + *************************************************************************/ + +/* + * exif.c and exif.h are taken from + * renamepics . + * Originally by Denise Hallmark, it is currently + * maintained by Rolf Lochbuehler + * and Brian Morrison . + * Their exif code was dropped into rdjpgcom by + * John Heidemann . + */ + + +/* + +EXIF and TIFF documentation: + +Adobe: TIFF 6.0 +http://partners.adobe.com/asn/developer/technotes.html + +Thierry Bousch : exifdump.py +Public domain EXIF reader written in Python + +ISO/DIS 12234-2: Photography - Electronic still picture +cameras - Removable Memory Part 2: Image data format - TIFF/EP + +Karl Logan : Re: Display image thumbnail +Posted 1999-01-15 in comp.lang.java.programmer + +Tsuro Zoh Tachibanaya: Description of EXIF File Format +http://www.butaman.ne.jp:8000/~tsuruzoh/Computer/Digicams/exif-e.html + +Tawbaware: EXIFRead.exe +Freeware EXIF reader for Windows, written in Visual Basic +http://members.tripod.com/~tawba + +James D Murray: Graphics File Formats FAQs +http://168.229.3.2/AAST/ComputerAnimation/Help_FAQs_File1.html + +JPEG FAQs +http://www.cis.ohio-state.edu/hypertext/faq/usenet/jpeg-faq/part1/faq.html +http://www.cis.ohio-state.edu/hypertext/faq/usenet/jpeg-faq/part2/faq.html + +The Unofficial TIFF Home Page +http://fax.st.carnet.hr/tiff_unoficial.html + +*/ + + +#include +#include +#include +#include +#include +#include +#include +/* #include */ + +/* + * #include "renamepics.h" + * #include "denise.h" + */ +#include "exif.h" + +/* _itoa seems to be an os2-ism */ +#define _itoa(n, s, slen) snprintf(s, slen, "%d", n) +#define _ultoa(n, s, slen) snprintf(s, slen, "%uld", n) +#define _ltoa(n, s, slen) snprintf(s, slen, "%ld", n) + + +/************************************************************************* + * * + * isExif() * + * Input is start of file header (at least 12 byte long) * + * * + *************************************************************************/ +int isExif ( Tbyte* start ) + { + + if( + 'E' == *(start + EXIF_IdOffset) && + 'x' == *(start + EXIF_IdOffset + 1) && + 'i' == *(start + EXIF_IdOffset + 2) && + 'f' == *(start + EXIF_IdOffset + 3) && + '\0' == *(start + EXIF_IdOffset + 4) && + '\0' == *(start + EXIF_IdOffset + 5) + ) + return YES; + else + return NO; + + } + + +/************************************************************************* + * * + * getOrder() * + * Determine if EXIF/TIFF file in Intel or Motorola byte order. * + * Input is start of TIFF within EXIF * + * * + *************************************************************************/ +int getOrder ( Tbyte* start ) + { + + if( TIFF_II == *((Tshort*)start) ) + return TIFF_Intel; + + else if( TIFF_MM == *((Tshort*)start) ) + return TIFF_Motorola; + + else + return TIFF_UnkownByteOrder; + + } + + +/************************************************************************* + * * + * getShort() * + * Read Tshort starting at p in specified byte order * + * * + *************************************************************************/ +Tshort getShort ( Tbyte* p, int byteOrder ) + { + + switch( byteOrder ) + { + + /* Intel byte order: 3210 stored as 1032 */ + case TIFF_Intel: + return *( (Tshort*)p ); + + /* Motorola byte order: 3210 stored as 3210 */ + case TIFF_Motorola: + return (*p << 8) | *(p + 1); + + otherwise: + printf( "*Error* Unknown byteOrder %d in getShort()\n", byteOrder ); + exit( RET_ERROR ); + + } /* end switch */ + + } + + +/************************************************************************* + * * + * tiffShort() * + * Read TtiffShort starting at p in specified byte order * + * * + *************************************************************************/ +TtiffShort tiffShort ( Tbyte* p, int byteOrder ) + { + + switch( byteOrder ) + { + + /* Intel byte order: 3210 stored as 1032 */ + case TIFF_Intel: + return *( (TtiffShort*)p ); + + /* Motorola byte order: 3210 stored as 3210 */ + case TIFF_Motorola: + return (*p << 8) | *(p + 1); + + otherwise: + printf( "*Error* Unknown byteOrder %d in tiffShort()\n", byteOrder ); + exit( RET_ERROR ); + + } /* end switch */ + + } + + +/************************************************************************* + * * + * tiffSShort() * + * Read TtiffSShort starting at p in specified byte order * + * * + *************************************************************************/ +TtiffSShort tiffSShort ( Tbyte* p, int byteOrder ) + { + + switch( byteOrder ) + { + + /* Intel byte order: 3210 stored as 1032 */ + case TIFF_Intel: + return *( (TtiffSShort*)p ); + + /* Motorola byte order: 3210 stored as 3210 */ + case TIFF_Motorola: + return (*p << 8) | *(p + 1); + + otherwise: + printf( "*Error* Unknown byteOrder %d in tiffSShort()\n", byteOrder ); + exit( RET_ERROR ); + + } /* end switch */ + + } + + +/************************************************************************* + * * + * getLong() * + * Read Tlong starting at p in specified byte order * + * * + *************************************************************************/ +Tlong getLong ( Tbyte* p, int byteOrder ) + { + + register Tlong x; + + switch( byteOrder ) + { + + /* Intel byte order: 76543210 stored as 10325476 */ + case TIFF_Intel: + return *( (Tlong*)p ); + + /* Motorola byte order: 76543210 stored as 76543210 */ + case TIFF_Motorola: + x = *p; + x = (x << 8) | *(p+1); + x = (x << 8) | *(p+2); + x = (x << 8) | *(p+3); + return x; + + otherwise: + printf( "*Error* Unknown byteOrder %d in getLong()\n", byteOrder ); + exit( RET_ERROR ); + + } /* end switch */ + + } + + +/************************************************************************* + * * + * tifflong() * + * Read TtiffLong starting at p in specified byte order * + * * + *************************************************************************/ +TtiffLong tifflong ( Tbyte* p, int byteOrder ) + { + + register TtiffLong x; + + switch( byteOrder ) + { + + /* Intel byte order: 76543210 stored as 10325476 */ + case TIFF_Intel: + return *( (TtiffLong*)p ); + + /* Motorola byte order: 76543210 stored as 76543210 */ + case TIFF_Motorola: + x = *p; + x = (x << 8) | *(p+1); + x = (x << 8) | *(p+2); + x = (x << 8) | *(p+3); + return x; + + otherwise: + printf( "*Error* Unknown byteOrder %d in tifflong()\n", byteOrder ); + exit( RET_ERROR ); + + } /* end switch */ + + } + + +/************************************************************************* + * * + * tiffSLong() * + * Read TtiffSLong starting at p in specified byte order * + * * + *************************************************************************/ +TtiffSLong tiffSLong ( Tbyte* p, int byteOrder ) + { + + register TtiffSLong x; + + switch( byteOrder ) + { + + /* Intel byte order: 76543210 stored as 10325476 */ + case TIFF_Intel: + return *( (TtiffSLong*)p ); + + /* Motorola byte order: 76543210 stored as 76543210 */ + case TIFF_Motorola: + x = *p; + x = (x << 8) | *(p+1); + x = (x << 8) | *(p+2); + x = (x << 8) | *(p+3); + return x; + + otherwise: + printf( "*Error* Unknown byteOrder %d in tiffSLong()\n", byteOrder ); + exit( RET_ERROR ); + + } /* end switch */ + + } + + +#ifdef OS2 +/************************************************************************* + * * + * exifPhoto() * + * Rename EXIF photo file, store exposure info as extended attributes * + * * + *************************************************************************/ +int exifPhoto ( FILE* file, char* oldName, Tbyte* start, Tbyte* end ) + { + + Tphoto photo; + Tbyte* p; + Tlong i; + Texif exif; + Tifd ifd; + char comment [TOTAL_LENGTH] = ""; + char dummy [TOTAL_LENGTH] = ""; + char newName [FILENAME_MAX+1] = ""; + char longName [FILENAME_MAX+1] = ""; + char extension [10]; + char dateTime [ENTRY_LENGTH+1]; + int rc; + int keepOldName; + + exif.tiffOffset = EXIF_TiffOffset; + exif.byteOrder = getOrder( start + exif.tiffOffset ); + exif.numIfd = EXIF_NumIfd; + + strcpy( photo.type, "Type: photo" ); + + p = start + exif.tiffOffset + (2 * SHORT_SIZE); + exif.ifdOffset[1] = getLong( p, exif.byteOrder ); + + + /* Read IFD 1 */ + + p = start + exif.tiffOffset + exif.ifdOffset[1]; + ifd.numEntries = getShort( p, exif.byteOrder ); + + p += SHORT_SIZE; + + *(photo.dateTime) = '\0'; + *(photo.imageDescription) = '\0'; + *(photo.make) = '\0'; + *(photo.model) = '\0'; + *(photo.resolutionUnit) = '\0'; + *(photo.software) = '\0'; + *(photo.xResolution) = '\0'; + *(photo.yResolution) = '\0'; + + for( i = 1; i <= ifd.numEntries; i += 1 ) + switch( getShort(p,exif.byteOrder) ) + { + case TIFF_ExifSubIfdOffset: + p += (2 * SHORT_SIZE) + LONG_SIZE; + exif.subIfdOffset = getLong( p, exif.byteOrder ); + p += LONG_SIZE; + break; + case TIFF_ImageDescription: + strcpy( photo.imageDescription, getImageDescription(exif.byteOrder,start+exif.tiffOffset,p,dummy) ); + p += IFD_ENTRY_SIZE; + break; + case TIFF_Make: + strcpy( photo.make, getMake(exif.byteOrder,start+exif.tiffOffset,p,dummy) ); + p += IFD_ENTRY_SIZE; + break; + case TIFF_Model: + strcpy( photo.model, getModel(exif.byteOrder,start+exif.tiffOffset,p,dummy) ); + p += IFD_ENTRY_SIZE; + break; + case TIFF_ResolutionUnit: + strcpy( photo.resolutionUnit, getResolutionUnit(exif.byteOrder,start+exif.tiffOffset,p,dummy) ); + p += IFD_ENTRY_SIZE; + break; + case TIFF_Software: + strcpy( photo.software, getSoftware(exif.byteOrder,start+exif.tiffOffset,p,dummy) ); + p += IFD_ENTRY_SIZE; + break; + case TIFF_XResolution: + strcpy( photo.xResolution, getXResolution(exif.byteOrder,start+exif.tiffOffset,p,dummy) ); + p += IFD_ENTRY_SIZE; + break; + case TIFF_YResolution: + strcpy( photo.yResolution, getYResolution(exif.byteOrder,start+exif.tiffOffset,p,dummy) ); + p += IFD_ENTRY_SIZE; + break; + default: + p += IFD_ENTRY_SIZE; + } + + + /* Read SubIFD */ + + p = start + exif.tiffOffset + exif.subIfdOffset; + ifd.numEntries = getShort( p, exif.byteOrder ); + + p += SHORT_SIZE; + + *(photo.dateTimeDigitized) = '\0'; + *(photo.dateTimeOriginal) = '\0'; + *(photo.exifImageHeight) = '\0'; + *(photo.exifImageWidth) = '\0'; + *(photo.exifVersion) = '\0'; + *(photo.exposureBiasValue) = '\0'; + *(photo.exposureTime) = '\0'; + *(photo.fNumber) = '\0'; + *(photo.flash) = '\0'; + *(photo.flashPixVersion) = '\0'; + *(photo.focalLength) = '\0'; + *(photo.isoSpeedRatings) = '\0'; + *(photo.lightSource) = '\0'; + *(photo.maxApertureValue) = '\0'; + *(photo.meteringMode) = '\0'; + + for( i = 1; i <= ifd.numEntries; i += 1 ) + switch( getShort(p,exif.byteOrder) ) + { + case TIFF_DateTimeDigitized: + strcpy( photo.dateTimeDigitized, getDateTimeDigitized(exif.byteOrder,start+exif.tiffOffset,p,dummy) ); + p += IFD_ENTRY_SIZE; + break; + case TIFF_DateTimeOriginal: + strcpy( photo.dateTimeOriginal, getDateTimeOriginal(exif.byteOrder,start+exif.tiffOffset,p,dummy) ); + p += IFD_ENTRY_SIZE; + break; + case TIFF_ExifImageHeight: + strcpy( photo.exifImageHeight, getExifImageHeight(exif.byteOrder,start+exif.tiffOffset,p,dummy) ); + p += IFD_ENTRY_SIZE; + break; + case TIFF_ExifImageWidth: + strcpy( photo.exifImageWidth, getExifImageWidth(exif.byteOrder,start+exif.tiffOffset,p,dummy) ); + p += IFD_ENTRY_SIZE; + break; + case TIFF_ExifVersion: + strcpy( photo.exifVersion, getExifVersion(exif.byteOrder,start+exif.tiffOffset,p,dummy) ); + p += IFD_ENTRY_SIZE; + break; + case TIFF_ExposureBiasValue: + strcpy( photo.exposureBiasValue, getExposureBiasValue(exif.byteOrder,start+exif.tiffOffset,p,dummy) ); + p += IFD_ENTRY_SIZE; + break; + case TIFF_ExposureTime: + strcpy( photo.exposureTime, getExposureTime(exif.byteOrder,start+exif.tiffOffset,p,dummy) ); + p += IFD_ENTRY_SIZE; + break; + case TIFF_FNumber: + strcpy( photo.fNumber, getFNumber(exif.byteOrder,start+exif.tiffOffset,p,dummy) ); + p += IFD_ENTRY_SIZE; + break; + case TIFF_Flash: + strcpy( photo.flash, getFlash(exif.byteOrder,start+exif.tiffOffset,p,dummy) ); + p += IFD_ENTRY_SIZE; + break; + case TIFF_FlashPixVersion: + strcpy( photo.flashPixVersion, getFlashPixVersion(exif.byteOrder,start+exif.tiffOffset,p,dummy) ); + p += IFD_ENTRY_SIZE; + break; + case TIFF_FocalLength: + strcpy( photo.focalLength, getFocalLength(exif.byteOrder,start+exif.tiffOffset,p,dummy) ); + p += IFD_ENTRY_SIZE; + break; + case TIFF_IsoSpeedRatings: + strcpy( photo.isoSpeedRatings, getIsoSpeedRatings(exif.byteOrder,start+exif.tiffOffset,p,dummy) ); + p += IFD_ENTRY_SIZE; + break; + case TIFF_LightSource: + strcpy( photo.lightSource, getLightSource(exif.byteOrder,start+exif.tiffOffset,p,dummy) ); + p += IFD_ENTRY_SIZE; + break; + case TIFF_MaxApertureValue: + strcpy( photo.maxApertureValue, getMaxApertureValue(exif.byteOrder,start+exif.tiffOffset,p,dummy) ); + p += IFD_ENTRY_SIZE; + break; + case TIFF_MeteringMode: + strcpy( photo.meteringMode, getMeteringMode(exif.byteOrder,start+exif.tiffOffset,p,dummy) ); + p += IFD_ENTRY_SIZE; + break; + default: + p += IFD_ENTRY_SIZE; + } + + /* Rename file, assumming 12345678.123 format of old name */ + + strcpy( extension, oldName + strlen(oldName) - 4 ); + + if( 0 < strlen(photo.dateTimeDigitized) ) + { + strcpy( dateTime, photo.dateTimeDigitized ); + keepOldName = NO; + } + else if( 0 < strlen(photo.dateTimeOriginal) ) + { + strcpy( dateTime, photo.dateTimeOriginal ); + keepOldName = NO; + } + else if( 0 < strlen(photo.dateTime) ) + { + strcpy( dateTime, photo.dateTime ); + keepOldName = NO; + } + else + keepOldName = YES; + + if( YES == keepOldName ) + strcpy( newName, oldName ); + else + { + + p = strchr( dateTime, ':' ); + + /* Year yyyy */ + strncpy( newName, p + 2, 4 ); + newName[4] = '\0'; + + strcat( newName, "-" ); + + /* Month mm */ + strncat( newName, p + 7, 2 ); + newName[7] = '\0'; + + strcat( newName, "-" ); + + /* Day dd */ + strncat( newName, p + 10, 2 ); + newName[10] = '\0'; + + strcat( newName, "_" ); + + /* Hour hh */ + strncat( newName, p + 13, 2 ); + newName[13] = '\0'; + + strcat( newName, "-" ); + + /* Minute mm */ + strncat( newName, p + 16, 2 ); + newName[16] = '\0'; + + strcat( newName, "-" ); + + /* Second ss */ + strncat( newName, p + 19, 2 ); + newName[19] = '\0'; + + strcat( newName, extension ); + + rc = rename( oldName, newName ); + if( 0 != rc ) + { + printf( "*Error* Failed to rename %s to %s: %s\n", oldName, newName, strerror(errno) ); + return RET_ERROR; + } + + strcpy( longName, newName ); + writeLongnameEa( newName, longName ); + + } /* end else */ + + + /* Store EAs */ + + strcpy( dummy, "ORIGINAL PHOTO" ); + strcat( dummy, "\n" ); + if( 0 < strlen(photo.dateTimeDigitized) ) + { + strcat( dummy, photo.dateTimeDigitized ); + strcat( dummy, "\n" ); + } + else if( 0 < strlen(photo.dateTimeOriginal) ) + { + strcat( dummy, photo.dateTimeOriginal ); + strcat( dummy, "\n" ); + } + strcat( dummy, photo.exposureBiasValue ); + strcat( dummy, "\n" ); + strcat( dummy, photo.exposureTime ); + strcat( dummy, "\n" ); + strcat( dummy, photo.fNumber ); + strcat( dummy, "\n" ); + strcat( dummy, photo.maxApertureValue ); + strcat( dummy, "\n" ); + strcat( dummy, photo.focalLength ); + strcat( dummy, "\n" ); + strcat( dummy, photo.flash ); + strcat( dummy, "\n" ); + strcat( dummy, photo.isoSpeedRatings ); + strcat( dummy, "\n" ); + strcat( dummy, photo.lightSource ); + strcat( dummy, "\n" ); + strcat( dummy, photo.meteringMode ); + strcat( dummy, "\n" ); + strcat( dummy, "Width x height: " ); + strcat( dummy, photo.exifImageWidth ); + strcat( dummy, " x " ); + strcat( dummy, photo.exifImageHeight ); + strcat( dummy, "\n" ); + strcat( dummy, photo.xResolution ); + strcat( dummy, " " ); + strcat( dummy, photo.resolutionUnit ); + strcat( dummy, "\n" ); + strcat( dummy, photo.yResolution ); + strcat( dummy, " " ); + strcat( dummy, photo.resolutionUnit ); + strcat( dummy, "\n" ); + strcat( dummy, photo.make ); + strcat( dummy, "\n" ); + strcat( dummy, photo.model ); + strcat( dummy, "\n" ); + strcat( dummy, photo.software ); + strcat( dummy, "\n" ); + strcat( dummy, photo.exifVersion ); + strcat( dummy, "\n" ); + strcat( dummy, photo.flashPixVersion ); + strcat( dummy, "\n" ); + + writeCommentEA( newName, dummy ); + + + return RET_OK; + + } +#endif /* OS2 */ + + +/************************************************************************* + * * + * dumpExif() * + * Rename EXIF file and store exposure info as extended attributes * + * * + *************************************************************************/ +int dumpExif ( char* oldName, Tbyte* start, Tbyte* end ) + { + + Texif exif; + Tapp1 app1; + Tifd ifd; + Tentry entry; + Tlong count; + Tlong i, k; + Tbyte* p; + Tlong offset; + + int headersize; + char dummy [1000] = ""; + + /* Read TIFF data */ + + exif.tiffOffset = EXIF_TiffOffset; + exif.byteOrder = getOrder( start + exif.tiffOffset ); + + /* Read EXIF data */ + + app1.size = getShort( start + LONG_SIZE, TIFF_Motorola ); + + puts( "--" ); + puts( "(Note that all offsets are relative to start of file)" ); + printf( "File name: %s\n", oldName ); + + switch( exif.byteOrder ) + { + case TIFF_Intel: puts( " Byte order: Intel" ); break; + case TIFF_Motorola: puts( " Byte order: Motorola" ); break; + otherwise: puts( " Byte order: *Unknown Entry*" ); + }; + + printf( " Size of APP1: %d byte\n", app1.size, app1.size ); + + /* Read regular IFDs */ + + p = start + exif.tiffOffset + (2 * SHORT_SIZE); + exif.numIfd = 0; + while( (offset = getLong(p,exif.byteOrder)) > 0 ) + { + exif.numIfd += 1; + exif.ifdOffset[exif.numIfd] = offset; + p = start + exif.tiffOffset + exif.ifdOffset[exif.numIfd]; + ifd.numEntries = getShort( p, exif.byteOrder ); + printf( "IFD %d at offset %Xh = %d has %d entries\n", exif.numIfd, exif.tiffOffset + exif.ifdOffset[exif.numIfd], exif.tiffOffset + exif.ifdOffset[exif.numIfd], ifd.numEntries ); + p += SHORT_SIZE; + dumpEntries( start, p, ifd.numEntries, &exif ); + p += ifd.numEntries * ((2 * SHORT_SIZE) + (2 * LONG_SIZE)); + } /* end while */ + + /* Read Sub IFD */ + + p = start + exif.tiffOffset + exif.subIfdOffset; + ifd.numEntries = getShort( p, exif.byteOrder ); + printf( "SubIFD at offset %Xh = %d has %d entries\n", exif.tiffOffset + exif.subIfdOffset, exif.tiffOffset + exif.subIfdOffset, ifd.numEntries ); + p += SHORT_SIZE; + dumpEntries( start, p, ifd.numEntries, &exif ); + + /* Read EXIF Interoperability IFD */ + + p = start + exif.tiffOffset + exif.interoperabilityOffset; + ifd.numEntries = getShort( p, exif.byteOrder ); + printf( "Interoperability IFD at offset %Xh = %d has %d entries\n", exif.tiffOffset + exif.interoperabilityOffset, exif.tiffOffset + exif.interoperabilityOffset, ifd.numEntries ); + p += SHORT_SIZE; + dumpEntries( start, p, ifd.numEntries, &exif ); + + /* Read MakerNote IFD */ + + p = start + exif.tiffOffset + exif.makerNoteOffset; + printf( "MakerNote IFD at offset %Xh = %d has unknown data structure:\n", exif.tiffOffset + exif.makerNoteOffset, exif.tiffOffset + exif.makerNoteOffset ); + printf( " " ); + for( i = 0, k = 0; i < exif.makerNoteLength; i += 1, k += 3, p += 1 ) + printf( "%02X ", *p ); + printf( "(hex, unknown meaning)\n" ); + + return RET_OK; + + } /* end dumpExif() */ + + +/**************************************************************** + * * + * getNewSubFileType() * + * * + ****************************************************************/ +char* getNewSubfileType ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getSubfileType ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getImageWidth ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getImageLength ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getBitsPerSample ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * getCompression() * + * * + ****************************************************************/ +char* getCompression ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* compression ) + { + + Tlong count; + Tshort c; + char dummy [20]; + + getTiffShort( byteOrder, tiff, entry, &count, &c ); + + strcpy( compression, "Compression: " ); + + switch( c ) + { + case 1: + strcat( compression, "(uncompressed)" ); + break; + case 2: + strcat( compression, "ITU-T Group-3 1-D modified Huffman RLE" ); + break; + case 6: + strcat( compression, "JPEG" ); + break; + case 32773: + strcat( compression, "PackBits" ); + break; + default: + _itoa( c, dummy, 10 ); + strcat( compression, dummy ); + strcat( compression, " *Unknown Entry*" ); + } + + return compression; + + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getPhotometricInterpretation ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getThresholding ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getCellWidth ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getCellLength ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getFillOrder ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getDocumentName ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * getImageDescription() * + * * + ****************************************************************/ +char* getImageDescription ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* description ) + { + + char dummy [100]; + + getTiffAscii( byteOrder, tiff, entry, dummy ); + + strcpy( description, "Created with (ImageDescription): " ); + + if( 0 == strlen(dummy) ) + strcat( description, "(unspecified camera)" ); + else + strcat( description, dummy ); + + return description; + + } + +/**************************************************************** + * * + * getInteroperabilityTag1() * + * * + ****************************************************************/ +char* getInteroperabilityTag1 ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* value ) + { + + char dummy [50]; + + getTiffAscii( byteOrder, tiff, entry, dummy ); + + strcpy( value, "Interoperability tag 1: " ); + + if( 0 == strlen(dummy) ) + strcat( value, "(no value)" ); + else + strcat( value, dummy ); + + return value; + + } + +/**************************************************************** + * * + * getInteroperabilityTag2() * + * * + ****************************************************************/ +char* getInteroperabilityTag2 ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* value ) + { + + char dummy [50]; + Tlong count; + + getTiffUndefined( byteOrder, tiff, entry, &count, dummy ); + + strcpy( value, "Interoperability tag 2: " ); + strcat( value, dummy ); + + return value; + + } + +/**************************************************************** + * * + * getMake() * + * * + ****************************************************************/ +char* getMake ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* make ) + { + + char dummy [200]; + + getTiffAscii( byteOrder, tiff, entry, dummy ); + + strcpy( make, "Camera manufacturer (Make): " ); + + if( 0 == strlen(dummy) ) + strcat( make, "(unspecified)" ); + else + strcat( make, dummy ); + + return make; + + } + +/**************************************************************** + * * + * getModel() * + * * + ****************************************************************/ +char* getModel ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* model ) + { + + char dummy [100]; + + getTiffAscii( byteOrder, tiff, entry, dummy ); + + strcpy( model, "Camera model: " ); + + if( 0 == strlen(dummy) ) + strcat( model, "(unspecified)" ); + else + strcat( model, dummy ); + + return model; + + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getStripOffset ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * getOrientation() * + * * + ****************************************************************/ +char* getOrientation ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* orientation ) + { + + Tlong count; + Tshort orient; + char dummy [20]; + + getTiffShort( byteOrder, tiff, entry, &count, &orient ); + + strcpy( orientation, "Orientation: " ); + + switch( orient ) + { + case 1: + strcat( orientation, "(0,0) = top left" ); + break; + case 2: + strcat( orientation, "(0,0) = top right" ); + break; + case 3: + strcat( orientation, "(0,0) = bottom right" ); + break; + case 4: + strcat( orientation, "(0,0) = bottom left" ); + break; + case 5: + strcat( orientation, "(0,0) = left top" ); + break; + case 6: + strcat( orientation, "(0,0) = right top" ); + break; + case 7: + strcat( orientation, "(0,0) = right bottom" ); + break; + case 8: + strcat( orientation, "(0,0) = left bottom" ); + break; + default: + _itoa( orient, dummy, 10 ); + strcat( orientation, dummy ); + strcat( orientation, " *Unknown Entry*" ); + } + + return orientation; + + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getSamplesPerPixel ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getRowsPerStrip ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getStripByteCounts ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getMinSampleValue ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getMaxSampleValue ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * getXResolution() * + * * + ****************************************************************/ +char* getXResolution ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* resolution ) + { + + char dummy [80]; + + strcpy( resolution, "X resolution: " ); + + getTiffRational( byteOrder, tiff, entry, dummy ); + + strcat( resolution, dummy ); + + return resolution; + + } + +/**************************************************************** + * * + * getYResolution() * + * * + ****************************************************************/ +char* getYResolution ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* resolution ) + { + + char dummy [80]; + + strcpy( resolution, "Y resolution: " ); + + getTiffRational( byteOrder, tiff, entry, dummy ); + + strcat( resolution, dummy ); + + return resolution; + + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getPlanarConfiguration ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getPageName ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getXPosition ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getYPosition ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getFreeOffsets ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getFreeByteCounts ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * getGrayResponseUnit() * + * Note that this function returns just the unit, without any * + * preceding text! * + * * + ****************************************************************/ +char* getGrayResponseUnit ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getGrayResponseCurve ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getT4Options ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getT6Options ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * getResolutionUnit() * + * Note that this function returns just the unit, without any * + * preceding text! * + * * + ****************************************************************/ +char* getResolutionUnit ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* unit ) + { + + Tlong count; + Tshort u; + char dummy [20]; + + strcpy( unit, "" ); + + getTiffShort( byteOrder, tiff, entry, &count, &u ); + + switch( u ) + { + case 1: + strcat( unit, "pixel" ); + break; + case 2: + strcat( unit, "pixel/in" ); + break; + case 3: + strcat( unit, "pixel/cm" ); + break; + default: + _itoa( u, dummy, 10 ); + strcat( unit, "*unknown unit: " ); + strcat( unit, dummy ); + strcat( unit, "*" ); + } + + return unit; + + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getPageNumber ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getTransferFunction ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * getSoftware() * + * * + ****************************************************************/ +char* getSoftware ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* software ) + { + + char dummy [50]; + + getTiffAscii( byteOrder, tiff, entry, dummy ); + + strcpy( software, "Software version: " ); + strcat( software, dummy ); + + return software; + + } + +/**************************************************************** + * * + * getDateTime() * + * * + ****************************************************************/ +char* getDateTime ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* dateTime ) + { + + char dummy [ENTRY_LENGTH+1]; + + getTiffAscii( byteOrder, tiff, entry, dummy ); + + dummy[4] = '-'; + dummy[7] = '-'; + + strcpy( dateTime, "Date/time: " ); + strcat( dateTime, dummy ); + + return dateTime; + + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getArtist ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getHostComputer ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getPredictor ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getWhitePoint ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getPrimaryChromaticities ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getColorMap ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getHalftoneHints ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getTileWidth ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getTileLength ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getTileOffsets ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getTileByteCounts ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getInkSet ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getInkNames ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getNumberOfInks ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getDotRange ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getTargetPrinter ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getExtraSamples ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getSampleFormat ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getSMinSampleValue ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getSMaxSampleValue ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getTransferRange ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getJpegTables ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getJpegProc ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getJpegRestartInterval ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getJpegLosslessPredictors ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getJpegPointTransforms ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getJpegQTables ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getJpegDcTables ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getJpegAcTables ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getYCbCrCoefficients ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getYCbCrSubSampling ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * getYCbCrPositioning() * + * * + ****************************************************************/ +char* getYCbCrPositioning ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* position ) + { + + Tlong count; + TtiffShort pos; + char dummy [20]; + + getTiffShort( byteOrder, tiff, entry, &count, &pos ); + + strcpy( position, "Y Cb Cr positioning: " ); + + switch( pos ) + { + case 1: + strcat( position, "centered" ); + break; + case 2: + strcat( position, "cosited" ); + break; + default: + _itoa( pos, dummy, 10 ); + strcat( position, dummy ); + strcat( position, " *Unknown Entry*" ); + } + + return position; + + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getReferenceBlackWhite ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getCfaRepeatPatternDim ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getCfaPattern ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getBatteryLevel ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getCopyright ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * getExposureTime() * + * * + ****************************************************************/ +char* getExposureTime ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* time ) + { + + char dummy [50]; + + getTiffRational2( byteOrder, tiff, entry, dummy ); + + strcpy( time, "Exposure time (shutter speed): " ); + strcat( time, dummy ); + strcat( time, " s" ); + + return time; + + } + +/**************************************************************** + * * + * getFNumber() * + * * + ****************************************************************/ +char* getFNumber ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* fstop ) + { + + char dummy [20]; + + getTiffRational( byteOrder, tiff, entry, dummy ); + + strcpy( fstop, "Aperture (FNumber): F" ); + strcat( fstop, dummy ); + if( NULL == strchr(fstop,'.') ) + strcat( fstop, ".0" ); + + return fstop; + + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getIptcNaa ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getInterColorProfile ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * getExposureProgram() * + * * + ****************************************************************/ +char* getExposureProgram ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* prog ) + { + + TtiffShort prognum; + Tlong count; + char dummy [20]; + + getTiffShort( byteOrder, tiff, entry, &count, &prognum ); + + strcpy( prog, "Exposure program: " ); + + switch( prognum ) + { + case 1: + strcat( prog, "manual" ); + break; + case 2: + strcat( prog, "normal, auto" ); + break; + case 3: + strcat( prog, "aperture priority" ); + break; + case 4: + strcat( prog, "shutter priority" ); + break; + case 5: + strcat( prog, "creative, slow)" ); + break; + case 6: + strcat( prog, "action, high-speed" ); + break; + case 7: + strcat( prog, "portrait" ); + break; + case 8: + strcat( prog, "landscape" ); + break; + default: + _itoa( prognum, dummy, 10 ); + strcat( prog, dummy ); + strcat( prog, " *Unknown Entry*" ); + } + + return prog; + + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getSpectralSensitivity ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getGpsInfo ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * getIsoSpeedRatings() * + * * + ****************************************************************/ +char* getIsoSpeedRatings ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* iso ) + { + + TtiffShort n; + char dummy [10]; + Tlong count; + + getTiffShort( byteOrder, tiff, entry, &count, &n ); + + strcpy( iso, "ISO speed rating: " ); + + _ltoa( (long)(n), dummy, 10 ); + + strcat( iso, dummy ); + + return iso; + + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getOecf ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getInterlace ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getTimeZoneOffset ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getSelfTimerMode ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * getExifVersion() * + * * + ****************************************************************/ +char* getExifVersion ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* version ) + { + + Tlong count; /* strlen(dummy) */ + char dummy [10]; + Tlong i; + + getTiffUndefined( byteOrder, tiff, entry, &count, dummy ); + + strcpy( version, "EXIF version: " ); + + if( 4 == count ) + { + i = strlen( version ); + if( '0' != dummy[0] ) + version[i++] = dummy[0]; + version[i++] = dummy[1]; + version[i++] = '.'; + version[i++] = dummy[2]; + if( '0' != dummy[3] ) + version[i++] = dummy[3]; + version[i] = '\0'; + } + else + strcat( version, dummy ); + + return version; + + } + +/**************************************************************** + * * + * getDateTimeOriginal() * + * * + ****************************************************************/ +char* getDateTimeOriginal ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* dateTime ) + { + + char dummy [ENTRY_LENGTH+1]; + + getTiffAscii( byteOrder, tiff, entry, dummy ); + + dummy[4] = '-'; + dummy[7] = '-'; + + strcpy( dateTime, "Date/time original: " ); + strcat( dateTime, dummy ); + + return dateTime; + + } + +/**************************************************************** + * * + * getDateTimeDigitized() * + * * + ****************************************************************/ +char* getDateTimeDigitized ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* dateTime ) + { + + char dummy [ENTRY_LENGTH+1]; + + getTiffAscii( byteOrder, tiff, entry, dummy ); + + dummy[4] = '-'; + dummy[7] = '-'; + + strcpy( dateTime, "Date/time digitized: " ); + strcat( dateTime, dummy ); + + return dateTime; + + } + +/**************************************************************** + * * + * getComponentConfiguration() * + * * + ****************************************************************/ +char* getComponentConfiguration ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* config ) + { + + Tlong count; + char dummy [ENTRY_LENGTH+1]; + + getTiffUnknownFormat( byteOrder, tiff, entry, &count, dummy ); + + strcpy( config, "Component configuration: " ); + strcat( config, dummy ); + + return config; + + } + +/**************************************************************** + * * + * getCompressedBitsPerLevel() * + * * + ****************************************************************/ +char* getCompressedBitsPerLevel ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* compressed ) + { + + char dummy [ENTRY_LENGTH+1]; + + getTiffRational( byteOrder, tiff, entry, dummy ); + + strcpy( compressed, "Compressed bits/level: " ); + strcat( compressed, dummy ); + + return compressed; + + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getShutterSpeedValue ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getApertureValue ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getBrightnessValue ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * getExposureBiasValue() * + * * + ****************************************************************/ +char* getExposureBiasValue ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* bias ) + { + + char dummy [50]; + + getTiffSRational( byteOrder, tiff, entry, dummy ); + + strcpy( bias, "Exposure bias: " ); + strcat( bias, dummy ); + strcat( bias, " EV" ); + + return bias; + + } + +/**************************************************************** + * * + * getMaxApertureValue() * + * * + ****************************************************************/ +char* getMaxApertureValue ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* aperture ) + { + + char dummy [50]; + + getTiffRational( byteOrder, tiff, entry, dummy ); + + strcpy( aperture, "Max aperture: F" ); + strcat( aperture, dummy ); + if( NULL == strchr(aperture,'.') ) + strcat( aperture, ".0" ); + + return aperture; + + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getSubjectDistance ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * getMeteringMode() * + * * + ****************************************************************/ +char* getMeteringMode ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* mode ) + { + + Tlong count; + Tshort m; + char dummy [20]; + + getTiffShort( byteOrder, tiff, entry, &count, &m ); + + strcpy( mode, "Metering mode: " ); + + switch( m ) + { + case 1: + strcat( mode, "average" ); + break; + case 2: + strcat( mode, "center weighted average" ); + break; + case 3: + strcat( mode, "spot" ); + break; + case 4: + strcat( mode, "multi-spot" ); + break; + case 5: + strcat( mode, "multi-segment" ); + break; + default: + _itoa( m, dummy, 10 ); + strcat( mode, dummy ); + strcat( mode, " *Unknown Entry*" ); + } + + return mode; + + } + +/**************************************************************** + * * + * getLightSource() * + * * + ****************************************************************/ +char* getLightSource ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* balance ) + { + + TtiffShort n; + Tlong count; + char dummy [20]; + + getTiffShort( byteOrder, tiff, entry, &count, &n ); + + strcpy( balance, "White balance (LightSource): " ); + + switch( n ) + { + case 0: + strcat( balance, "auto" ); + break; + case 1: + strcat( balance, "daylight" ); + break; + case 2: + strcat( balance, "fluorescent" ); + break; + case 3: + strcat( balance, "tungsten" ); + break; + case 10: + strcat( balance, "flash" ); + break; + default: + _itoa( n, dummy, 10 ); + strcat( balance, dummy ); + strcat( balance, " *Unknown Entry*" ); + } + + return balance; + + } + +/**************************************************************** + * * + * getFlash() * + * * + ****************************************************************/ +char* getFlash ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* flash ) + { + + TtiffShort n; + Tlong count; + char dummy [20]; + + getTiffShort( byteOrder, tiff, entry, &count, &n ); + + strcpy( flash, "Flash: " ); + + switch( n ) + { + case 0: + strcat( flash, "none" ); + break; + case 1: + strcat( flash, "yes" ); + break; + default: + _itoa( n, dummy, 10 ); + strcat( flash, dummy ); + strcat( flash, " *Unknown Entry*" ); + } + + return flash; + + } + +/**************************************************************** + * * + * getFocalLength() * + * * + ****************************************************************/ +char* getFocalLength ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* length ) + { + + char dummy [20]; + + getTiffRational( byteOrder, tiff, entry, dummy ); + + strcpy( length, "Focal length: " ); + strcat( length, dummy ); + strcat( length, " mm" ); + + return length; + + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getFlashEnergy ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getSpatialFrequencyResponse ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getNoise ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getImageNumber ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getSecurityClassification ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getImageHistory ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getSubjectLocation ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getExposureIndex ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getTiffEpStandardId ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * getUserComment() * + * * + ****************************************************************/ +char* getUserComment ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* comment ) + { + + Tlong count; + Tlong i; + char dummy [TOTAL_LENGTH]; + + getTiffUndefined( byteOrder, tiff, entry, &count, dummy ); + + strcpy( comment, "User comment: " ); + + if( 0 == strlen(dummy) ) + strcat( comment, "(none)" ); + else + strcat( comment, dummy ); + + return comment; + + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getSubSecTime ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getSubSecTimeOriginal ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getSubSecTimeDigitized ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * getFlashPixVersion() * + * * + ****************************************************************/ +char* getFlashPixVersion ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* version ) + { + + Tlong count; + Tlong i; + char dummy [50]; + + getTiffUndefined( byteOrder, tiff, entry, &count, dummy ); + + strcpy( version, "FlashPix version: " ); + + if( 4 == count ) + { + i = strlen( version ); + if( '0' != dummy[0] ) + version[i++] = dummy[0]; + version[i++] = dummy[1]; + version[i++] = '.'; + version[i++] = dummy[2]; + if( '0' != dummy[3] ) + version[i++] = dummy[3]; + version[i] = '\0'; + } + else + strcat( version, dummy ); + + return version; + + } + +/**************************************************************** + * * + * getColorSpace() * + * * + ****************************************************************/ +char* getColorSpace ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* color ) + { + + TtiffShort c; + Tlong count; + char dummy [20]; + + getTiffShort( byteOrder, tiff, entry, &count, &c ); + + strcpy( color, "Color space: " ); + + switch( c ) + { + case 1: + strcat( color, "1" ); + break; + default: + _itoa( c, dummy, 10 ); + strcat( color, dummy ); + strcat( color, " *Unknown Entry*" ); + } + + return color; + + } + +/**************************************************************** + * * + * getExifImageWidth() * + * Note that this function returns just a value, without any * + * text prefixed * + * * + ****************************************************************/ +char* getExifImageWidth ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* width ) + { + + Tlong count; + TtiffLong w; + char dummy [20]; + + getTiffLong( byteOrder, tiff, entry, &count, &w ); + + _ultoa( w, dummy, 10 ); + + strcpy( width, "" ); + strcat( width, dummy ); + strcat( width, " pixel" ); + + return width; + + } + +/**************************************************************** + * * + * getExifImageHeight() * + * Note that this function returns just a value, without any * + * text prefixed * + * * + ****************************************************************/ +char* getExifImageHeight ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* height ) + { + + Tlong count; + TtiffLong h; + char dummy [20]; + + getTiffLong( byteOrder, tiff, entry, &count, &h ); + + _ultoa( h, dummy, 10 ); + + strcpy( height, "" ); + strcat( height, dummy ); + strcat( height, " pixel" ); + + return height; + + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getRelatedSoundFile ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + + return "?"; + + } + +/**************************************************************** + * * + * getFocalPlaneXResolution() * + * * + ****************************************************************/ +char* getFocalPlaneXResolution ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* resolution ) + { + + char dummy [20]; + + getTiffRational( byteOrder, tiff, entry, dummy ); + + strcpy( resolution, "Focal plane X resolution: " ); + strcat( resolution, dummy ); + + return resolution; + + } + +/**************************************************************** + * * + * getFocalPlaneYResolution() * + * * + ****************************************************************/ +char* getFocalPlaneYResolution ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* resolution ) + { + + char dummy [20]; + + getTiffRational( byteOrder, tiff, entry, dummy ); + + strcpy( resolution, "Focal plane Y resolution: " ); + strcat( resolution, dummy ); + + return resolution; + + } + +/**************************************************************** + * * + * getFocalPlaneResolutionUnit() * + * Note that this function returns just the unit, without any * + * preceding text! * + * * + ****************************************************************/ +char* getFocalPlaneResolutionUnit ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* unit ) + { + + Tlong count; + Tshort u; + char dummy [20]; + + getTiffShort( byteOrder, tiff, entry, &count, &u ); + + strcpy( unit, "" ); + + switch( u ) + { + case 1: + strcat( unit, "pixel/in" ); + break; + case 2: + strcat( unit, "pixel/m" ); + break; + case 3: + strcat( unit, "pixel/cm" ); + break; + case 4: + strcat( unit, "pixel/mm" ); + break; + case 5: + strcat( unit, "pixel/æm" ); + break; + default: + _itoa( u, dummy, 10 ); + strcat( unit, "*unknown unit: " ); + strcat( unit, dummy ); + strcat( unit, "*" ); + } + + return unit; + + } + +/**************************************************************** + * * + * * + * * + ****************************************************************/ +char* getSensingMethod ( int byteOrder, Tbyte* tiff, Tbyte* entry ) + { + return "?"; + } + +/**************************************************************** + * * + * getFileSource() * + * * + ****************************************************************/ +char* getFileSource ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* source ) + { + + Tlong count; + Tlong i; + char dummy [ENTRY_LENGTH+1]; + + getTiffUnknownFormat( byteOrder, tiff, entry, &count, dummy ); + + strcpy( source, "File source: " ); + strcat( source, dummy ); + + return source; + + } + +/**************************************************************** + * * + * getSceneType() * + * * + ****************************************************************/ +char* getSceneType ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* type ) + { + + Tlong count; + Tlong i; + char dummy [ENTRY_LENGTH+1]; + + getTiffUnknownFormat( byteOrder, tiff, entry, &count, dummy ); + + strcpy( type, "Scene type: " ); + strcat( type, dummy ); + + return type; + + } + + +/**************************************************************** + * * + * getTiffRational() * + * Read RATIONAL number and return as float x/y * + * * + ****************************************************************/ +char* getTiffRational ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* string ) + { + + Tbyte* p; + char dummy [30]; + Tlong x, y; + + p = entry + (2 * SHORT_SIZE) + LONG_SIZE; + p = tiff + getLong( p, byteOrder ); + + x = tifflong( p, byteOrder ); + + p += LONG_SIZE; + + y = tifflong( p, byteOrder ); + + sprintf( string, "%g", ((float)x)/((float)y) ); + + return string; + + } + + +/**************************************************************** + * * + * getTiffRational2() * + * Read RATIONAL number and return as string "x/y" * + * * + ****************************************************************/ +char* getTiffRational2 ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* string ) + { + + Tbyte* p; + char dummy [30]; + Tlong x, y; + + p = entry + (2 * SHORT_SIZE) + LONG_SIZE; + p = tiff + getLong( p, byteOrder ); + x = tifflong( p, byteOrder ); + p += LONG_SIZE; + y = tifflong( p, byteOrder ); + + if( 0 == x ) + { + strcpy( string, "0" ); + return string; + } + else if( 0 == y % x ) + { + strcpy( string, "1/" ); + _ultoa( y / x, dummy, 10 ); + strcat( string, dummy ); + return string; + } + else + { + _ultoa( x, dummy, 10 ); + strcpy( string, dummy ); + strcat( string, "/" ); + _ultoa( y, dummy, 10 ); + strcat( string, dummy ); + return string; + } + + } + + +/**************************************************************** + * * + * getTiffSRational() * + * Read SRATIONAL number and return as string "x/y" * + * * + ****************************************************************/ +char* getTiffSRational ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* string ) + { + + Tbyte* p; + char dummy [30]; + Tlong x, y; + + p = entry + (2 * SHORT_SIZE) + LONG_SIZE; + + p = tiff + getLong( p, byteOrder ); + +#if 1 + + x = tiffSLong( p, byteOrder ); + + p += LONG_SIZE; + + y = tiffSLong( p, byteOrder ); + + sprintf( string, "%g", ((float)x)/((float)y) ); + +#else + + _ltoa( tiffSLong(p,byteOrder), dummy, 10 ); + strcpy( string, dummy ); + + strcat( string, "/" ); + + p += LONG_SIZE; + + _ltoa( tiffSLong(p,byteOrder), dummy, 10 ); + strcat( string, dummy ); + +#endif + + return string; + + } + + +/**************************************************************** + * * + * getTiffShort() * + * Read SHORT number * + * * + ****************************************************************/ +TtiffShort* getTiffShort ( int byteOrder, Tbyte* tiff, Tbyte* entry, Tlong* count, TtiffShort* val ) + { + + Tbyte* p; + Tlong i; + + p = entry + (2 * SHORT_SIZE); + *count = getLong( p, byteOrder ); + + p += LONG_SIZE; + if( *count > (LONG_SIZE / TIFF_SHORT_SIZE) ) + p = tiff + getLong( p, byteOrder ); + + for( i = 0; i < *count; i += 1 ) + { + val[i] = tiffShort( p, byteOrder ); + p += TIFF_SHORT_SIZE; + } + + return val; + + } + + +/**************************************************************** + * * + * getTiffAscii() * + * Read ASCII string * + * * + ****************************************************************/ +char* getTiffAscii ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* string ) + { + + Tbyte* p; + Tlong i; + Tlong count; + + p = entry + (2 * SHORT_SIZE); + count = getShort( p, byteOrder ); + + p += LONG_SIZE; + if( count > LONG_SIZE ) + p = tiff + getLong( p, byteOrder ); + + strncpy( string, p, count ); + string[count] = '\0'; + + return string; + + } + + +/**************************************************************** + * * + * getTiffUndefined() * + * Read byte string of undefined format * + * * + ****************************************************************/ +char* getTiffUndefined ( int byteOrder, Tbyte* tiff, Tbyte* entry, Tlong* count, char* string ) + { + + Tbyte* p; + Tlong i; + + p = entry + (2 * SHORT_SIZE); + *count = getShort( p, byteOrder ); + + p += LONG_SIZE; + if( *count > LONG_SIZE ) + p = tiff + getLong( p, byteOrder ); + + /* Cannot use strncpy() here since it stops at the first '\0' */ + for( i = 0; i < *count; i += 1 ) + string[i] = p[i]; + + /* Last byte may not be '\0' */ + string[*count] = '\0'; + + return string; + + } + + +/**************************************************************** + * * + * getTiffUnknownFormat() * + * Read byte string of unknown format * + * * + ****************************************************************/ +char* getTiffUnknownFormat ( int byteOrder, Tbyte* tiff, Tbyte* entry, Tlong* count, char* string ) + { + + Tbyte* p; + Tlong i, k; + + p = entry + (2 * SHORT_SIZE); + *count = getShort( p, byteOrder ); + + p += LONG_SIZE; + if( *count > LONG_SIZE ) + p = tiff + getLong( p, byteOrder ); + + for( i = 0, k = 0; i < *count; i += 1, k += 3, p += 1 ) + sprintf( string + k, "%02X ", *p ); + + strcat( string, "(hex, unknown meaning)" ); + + return string; + + } + + +/**************************************************************** + * * + * getTiffLong() * + * Read LONG number * + * * + ****************************************************************/ +TtiffLong* getTiffLong ( int byteOrder, Tbyte* tiff, Tbyte* entry, Tlong* count, TtiffLong* val ) + { + + Tbyte* p; + Tlong i; + + p = entry + (2 * SHORT_SIZE); + *count = getLong( p, byteOrder ); + + p += LONG_SIZE; + if( *count > (LONG_SIZE / TIFF_SHORT_SIZE) ) + p = tiff + getLong( p, byteOrder ); + + for( i = 0; i < *count; i += 1 ) + { + val[i] = tifflong( p, byteOrder ); + p += TIFF_LONG_SIZE; + } + + return val; + + } + + +/**************************************************************** + * * + * dumpEntries() * + * Read entries in IFD * + * * + ****************************************************************/ +void dumpEntries ( Tbyte* start, Tbyte* firstentry, Tlong entries, Texif* exif ) + { + + Tentry entry; + + Tlong i; + Tbyte* p; + + char dummy [1000] = ""; + + p = firstentry; + + for( i = 1; i <= entries; i += 1 ) + { + + entry.tag = getShort( p, exif->byteOrder ); + + switch( entry.tag ) + { + + case TIFF_ColorSpace: + printf( " %s\n", getColorSpace(exif->byteOrder,start+(exif->tiffOffset),p,dummy) ); + p += (2 * SHORT_SIZE) + (2 * LONG_SIZE); + break; + + case TIFF_ComponentConfiguration: + printf( " %s\n", getComponentConfiguration(exif->byteOrder,start+(exif->tiffOffset),p,dummy) ); + p += (2 * SHORT_SIZE) + (2 * LONG_SIZE); + break; + + case TIFF_CompressedBitsPerLevel: + printf( " %s\n", getCompressedBitsPerLevel(exif->byteOrder,start+(exif->tiffOffset),p,dummy) ); + p += (2 * SHORT_SIZE) + (2 * LONG_SIZE); + break; + + case TIFF_Compression: + printf( " %s\n", getCompression(exif->byteOrder,start+(exif->tiffOffset),p,dummy) ); + p += (2 * SHORT_SIZE) + (2 * LONG_SIZE); + break; + + case TIFF_DateTime: + printf( " %s\n", getDateTime(exif->byteOrder,start+(exif->tiffOffset),p,dummy) ); + p += (2 * SHORT_SIZE) + (2 * LONG_SIZE); + break; + + case TIFF_DateTimeDigitized: + printf( " %s\n", getDateTimeDigitized(exif->byteOrder,start+(exif->tiffOffset),p,dummy) ); + p += (2 * SHORT_SIZE) + (2 * LONG_SIZE); + break; + + case TIFF_DateTimeOriginal: + printf( " %s\n", getDateTimeOriginal(exif->byteOrder,start+(exif->tiffOffset),p,dummy) ); + p += (2 * SHORT_SIZE) + (2 * LONG_SIZE); + break; + + case TIFF_ExifImageHeight: + printf( " EXIF image height: %s\n", getExifImageHeight(exif->byteOrder,start+(exif->tiffOffset),p,dummy) ); + p += (2 * SHORT_SIZE) + (2 * LONG_SIZE); + break; + + case TIFF_ExifImageWidth: + printf( " EXIF image width: %s\n", getExifImageWidth(exif->byteOrder,start+(exif->tiffOffset),p,dummy) ); + p += (2 * SHORT_SIZE) + (2 * LONG_SIZE); + break; + + case TIFF_ExifInteroperabilityOffset: + p += (2 * SHORT_SIZE) + LONG_SIZE; + exif->interoperabilityOffset = getLong( p, exif->byteOrder ); + printf( " EXIF interoperability IFD offset: %Xh = %d (see separate listing)\n", (exif->tiffOffset) + (exif->interoperabilityOffset), (exif->tiffOffset) + (exif->interoperabilityOffset) ); + p += LONG_SIZE; + break; + + case TIFF_ExifSubIfdOffset: + p += (2 * SHORT_SIZE) + LONG_SIZE; + exif->subIfdOffset = getLong( p, exif->byteOrder ); + printf( " EXIF SubIFD offset: %Xh = %d (see separate listing)\n", (exif->tiffOffset) + (exif->subIfdOffset), (exif->tiffOffset) + (exif->subIfdOffset) ); + p += LONG_SIZE; + break; + + case TIFF_ExifVersion: + printf( " %s\n", getExifVersion(exif->byteOrder,start+(exif->tiffOffset),p,dummy) ); + p += (2 * SHORT_SIZE) + (2 * LONG_SIZE); + break; + + case TIFF_ExposureBiasValue: + printf( " %s\n", getExposureBiasValue(exif->byteOrder,start+(exif->tiffOffset),p,dummy) ); + p += (2 * SHORT_SIZE) + (2 * LONG_SIZE); + break; + + case TIFF_ExposureTime: + printf( " %s\n", getExposureTime(exif->byteOrder,start+(exif->tiffOffset),p,dummy) ); + p += (2 * SHORT_SIZE) + (2 * LONG_SIZE); + break; + + case TIFF_ExposureProgram: + printf( " %s\n", getExposureProgram(exif->byteOrder,start+(exif->tiffOffset),p,dummy) ); + p += (2 * SHORT_SIZE) + (2 * LONG_SIZE); + break; + + case TIFF_FileSource: + printf( " %s\n", getFileSource(exif->byteOrder,start+(exif->tiffOffset),p,dummy) ); + p += (2 * SHORT_SIZE) + (2 * LONG_SIZE); + break; + + case TIFF_Flash: + printf( " %s\n", getFlash(exif->byteOrder,start+(exif->tiffOffset),p,dummy) ); + p += (2 * SHORT_SIZE) + (2 * LONG_SIZE); + break; + + case TIFF_FlashPixVersion: + printf( " %s\n", getFlashPixVersion(exif->byteOrder,start+(exif->tiffOffset),p,dummy) ); + p += (2 * SHORT_SIZE) + (2 * LONG_SIZE); + break; + + case TIFF_FNumber: + printf( " %s\n", getFNumber(exif->byteOrder,start+(exif->tiffOffset),p,dummy) ); + p += (2 * SHORT_SIZE) + (2 * LONG_SIZE); + break; + + case TIFF_FocalLength: + printf( " %s\n", getFocalLength(exif->byteOrder,start+(exif->tiffOffset),p,dummy) ); + p += (2 * SHORT_SIZE) + (2 * LONG_SIZE); + break; + + case TIFF_FocalPlaneResolutionUnit: + printf( " Focal plane resolution unit: %s\n", getFocalPlaneResolutionUnit(exif->byteOrder,start+(exif->tiffOffset),p,dummy) ); + p += (2 * SHORT_SIZE) + (2 * LONG_SIZE); + break; + + case TIFF_FocalPlaneXResolution: + printf( " %s\n", getFocalPlaneXResolution(exif->byteOrder,start+(exif->tiffOffset),p,dummy) ); + p += (2 * SHORT_SIZE) + (2 * LONG_SIZE); + break; + + case TIFF_FocalPlaneYResolution: + printf( " %s\n", getFocalPlaneYResolution(exif->byteOrder,start+(exif->tiffOffset),p,dummy) ); + p += (2 * SHORT_SIZE) + (2 * LONG_SIZE); + break; + + case TIFF_ImageDescription: + printf( " %s\n", getImageDescription(exif->byteOrder,start+(exif->tiffOffset),p,dummy) ); + p += (2 * SHORT_SIZE) + (2 * LONG_SIZE); + break; + + case TIFF_InteroperabilityTag1: + printf( " %s\n", getInteroperabilityTag1(exif->byteOrder,start+(exif->tiffOffset),p,dummy) ); + p += (2 * SHORT_SIZE) + (2 * LONG_SIZE); + break; + + case TIFF_InteroperabilityTag2: + printf( " %s\n", getInteroperabilityTag2(exif->byteOrder,start+(exif->tiffOffset),p,dummy) ); + p += (2 * SHORT_SIZE) + (2 * LONG_SIZE); + break; + + case TIFF_IsoSpeedRatings: + printf( " %s\n", getIsoSpeedRatings(exif->byteOrder,start+(exif->tiffOffset),p,dummy) ); + p += (2 * SHORT_SIZE) + (2 * LONG_SIZE); + break; + + case TIFF_JpegInterchangeFormat: + p += (2 * SHORT_SIZE) + LONG_SIZE; + exif->jpegOffset = getLong( p, exif->byteOrder ); + printf( " JPEG data offset (JpegInterchangeFormat): %Xh = %d\n", (exif->tiffOffset) + (exif->jpegOffset), (exif->tiffOffset) + (exif->jpegOffset) ); + p += LONG_SIZE; + break; + + case TIFF_JpegInterchangeFormatLength: + p += (2 * SHORT_SIZE) + LONG_SIZE; + exif->jpegLength = getLong( p, exif->byteOrder ); + printf( " JPEG data size (JpegInterchangeFormatLength): %d byte\n", exif->jpegLength ); + p += LONG_SIZE; + break; + + case TIFF_LightSource: + printf( " %s\n", getLightSource(exif->byteOrder,start+(exif->tiffOffset),p,dummy) ); + p += (2 * SHORT_SIZE) + (2 * LONG_SIZE); + break; + + case TIFF_Make: + printf( " %s\n", getMake(exif->byteOrder,start+(exif->tiffOffset),p,dummy) ); + p += (2 * SHORT_SIZE) + (2 * LONG_SIZE); + break; + + case TIFF_MakerNote: + p += (2 * SHORT_SIZE); + exif->makerNoteLength = getLong( p, exif->byteOrder ); + p += LONG_SIZE; + exif->makerNoteOffset = getLong( p, exif->byteOrder ); + printf( " Maker note offset (MakerNote): %Xh = %d (see separate listing)\n", (exif->tiffOffset) + (exif->makerNoteOffset), (exif->tiffOffset) + (exif->makerNoteOffset) ); + p += LONG_SIZE; + break; + + case TIFF_MaxApertureValue: + printf( " %s\n", getMaxApertureValue(exif->byteOrder,start+(exif->tiffOffset),p,dummy) ); + p += (2 * SHORT_SIZE) + (2 * LONG_SIZE); + break; + + case TIFF_MeteringMode: + printf( " %s\n", getMeteringMode(exif->byteOrder,start+(exif->tiffOffset),p,dummy) ); + p += (2 * SHORT_SIZE) + (2 * LONG_SIZE); + break; + + case TIFF_Model: + printf( " %s\n", getModel(exif->byteOrder,start+(exif->tiffOffset),p,dummy) ); + p += (2 * SHORT_SIZE) + (2 * LONG_SIZE); + break; + + case TIFF_Orientation: + printf( " %s\n", getOrientation(exif->byteOrder,start+(exif->tiffOffset),p,dummy) ); + p += (2 * SHORT_SIZE) + (2 * LONG_SIZE); + break; + + case TIFF_SceneType: + printf( " %s\n", getSceneType(exif->byteOrder,start+(exif->tiffOffset),p,dummy) ); + p += (2 * SHORT_SIZE) + (2 * LONG_SIZE); + break; + + case TIFF_Software: + printf( " %s\n", getSoftware(exif->byteOrder,start+(exif->tiffOffset),p,dummy) ); + p += (2 * SHORT_SIZE) + (2 * LONG_SIZE); + break; + + case TIFF_ResolutionUnit: + printf( " Resolution unit: %s\n", getResolutionUnit(exif->byteOrder,start+(exif->tiffOffset),p,dummy) ); + p += (2 * SHORT_SIZE) + (2 * LONG_SIZE); + break; + + case TIFF_XResolution: + printf( " %s\n", getXResolution(exif->byteOrder,start+(exif->tiffOffset),p,dummy) ); + p += (2 * SHORT_SIZE) + (2 * LONG_SIZE); + break; + + case TIFF_YResolution: + printf( " %s\n", getYResolution(exif->byteOrder,start+(exif->tiffOffset),p,dummy) ); + p += (2 * SHORT_SIZE) + (2 * LONG_SIZE); + break; + + case TIFF_YCbCrPositioning: + printf( " %s\n", getYCbCrPositioning(exif->byteOrder,start+(exif->tiffOffset),p,dummy) ); + p += (2 * SHORT_SIZE) + (2 * LONG_SIZE); + break; + + case TIFF_UserComment: + printf( " %s\n", getUserComment(exif->byteOrder,start+(exif->tiffOffset),p,dummy) ); + p += (2 * SHORT_SIZE) + (2 * LONG_SIZE); + break; + + default: + + p += SHORT_SIZE; + entry.type = getShort( p, exif->byteOrder ); + + p += SHORT_SIZE; + entry.count = getLong( p, exif->byteOrder ); + + p += LONG_SIZE; + entry.offset = getLong( p, exif->byteOrder ); + + printf( + " Entry: %d Tag: %x Type: %x Count: %d Value or offset (- %d) of value: %Xh = %d\n", + i, entry.tag, entry.type, entry.count, exif->tiffOffset, entry.offset, entry.offset + ); + + p += LONG_SIZE; + + } /* end switch */ + + } /* end for */ + + return; + + } + --- exif.h- Sun Aug 20 18:38:32 2000 +++ exif.h Sun Aug 20 18:28:22 2000 @@ -0,0 +1,504 @@ +#ifndef INCL_EXIF_H +#define INCL_EXIF_H + + +/* $Id$ */ + + +/************************************************************************* + * * + * exif.h * + * Header file for EXIF specific code or RenamePics * + * * + *************************************************************************/ + +/* Return values */ + +#define RET_OK 0 +#define RET_ERROR 1 +#define RET_HELP 2 +#define RET_INVALID_ARG 3 + +#define NO 0 +#define YES 1 +#define EQUAL 0 +#define SUCCESS 0 + + +/* TIFF specifics */ + +#define ENTRY_LENGTH 101 +#define TOTAL_LENGTH 10001 + + +/* Data types */ + +typedef unsigned char Tbyte; +typedef unsigned short Tshort; +typedef unsigned long Tlong; + +typedef struct _Texif + { + Tshort byteOrder; + Tshort numIfd; + Tlong ifdOffset[10]; + Tlong subIfdOffset; + Tlong makerNoteOffset; + Tlong makerNoteLength; + Tlong interoperabilityOffset; + Tlong jpegOffset; + Tlong jpegLength; + Tlong tiffOffset; + char version [ENTRY_LENGTH+1]; + } Texif; + + +typedef struct _Tphoto + { + char colorSpace [ENTRY_LENGTH+1]; + char dateTime [ENTRY_LENGTH+1]; + char dateTimeDigitized [ENTRY_LENGTH+1]; + char dateTimeOriginal [ENTRY_LENGTH+1]; + char exifImageHeight [ENTRY_LENGTH+1]; + char exifImageWidth [ENTRY_LENGTH+1]; + char exposureBiasValue [ENTRY_LENGTH+1]; + char exposureTime [ENTRY_LENGTH+1]; + char exifVersion [ENTRY_LENGTH+1]; + char fNumber [ENTRY_LENGTH+1]; + char flash [ENTRY_LENGTH+1]; + char flashPixVersion [ENTRY_LENGTH+1]; + char focalLength [ENTRY_LENGTH+1]; + char imageDescription [ENTRY_LENGTH+1]; + char isoSpeedRatings [ENTRY_LENGTH+1]; + char lightSource [ENTRY_LENGTH+1]; + char make [ENTRY_LENGTH+1]; + char maxApertureValue [ENTRY_LENGTH+1]; + char meteringMode [ENTRY_LENGTH+1]; + char model [ENTRY_LENGTH+1]; + char resolutionUnit [ENTRY_LENGTH+1]; + char software [ENTRY_LENGTH+1]; + char type [ENTRY_LENGTH+1]; + char xResolution [ENTRY_LENGTH+1]; + char yResolution [ENTRY_LENGTH+1]; + } Tphoto; + + +/* Tiff internal data types */ + +typedef unsigned char TtiffByte; +typedef char TtiffAscii; +typedef unsigned short TtiffShort; +typedef unsigned int TtiffLong; +typedef signed char TtiffSByte; +typedef char TtiffUndefined; +typedef signed short TtiffSShort; +typedef signed int TtiffSLong; +typedef float TtiffFloat; +typedef double TtiffDouble; + +typedef struct _TtiffRational + { + TtiffLong numerator; + TtiffLong denominator; + } TtiffRational; + +typedef struct _TtiffSRational + { + TtiffSLong numerator; + TtiffSLong denominator; + } TtiffSRational; + +typedef struct _Tapp1 + { + TtiffShort size; + } Tapp1; + +typedef struct _Tifd + { + TtiffShort numEntries; + } Tifd; + +typedef struct _Tentry + { + TtiffShort tag; + TtiffShort type; + TtiffLong count; + TtiffLong offset; + } Tentry; + + +/* EXIF specifics */ + +/* originally, renamepics had EXIF_JpegBufferStart == 0 + * in rdjpgcom we make it -6 because we already handle + * the marker and length + */ +#define EXIF_JpegBufferStart -6 +#define EXIF_IdOffset (6+EXIF_JpegBufferStart) /* Offset of 'Exif\0\0' */ +#define EXIF_TiffOffset (12+EXIF_JpegBufferStart) /* Start of TIFF within EXIF file */ +#define EXIF_NumIfd 2 /* EXIF file has IFD 1 and 2 */ + +#define EXIF_EndOfImage ((Tshort)0xffd9) +#define EXIF_StartOfImage ((Tshort)0xffd8) +#define EXIF_StartOfStream ((Tshort)0xffda) + + +/* TIFF file specifics */ + +#define LONG_SIZE sizeof(Tlong) +#define SHORT_SIZE sizeof(Tshort) +#define IFD_ENTRY_SIZE ((2 * SHORT_SIZE) + (2 * LONG_SIZE)) + + +/* TIFF specifics */ + +#define TIFF_LONG_SIZE sizeof(TtiffLong) +#define TIFF_SHORT_SIZE sizeof(TtiffShort) +#define TIFF_SLONG_SIZE sizeof(TtiffSLong) +#define TIFF_SSHORT_SIZE sizeof(TtiffSShort) + +#define TIFF_UnkownByteOrder 0 +#define TIFF_Intel 1 +#define TIFF_Motorola 2 + +#define TIFF_Byte ((Tshort)1) +#define TIFF_Ascii ((Tshort)2) +#define TIFF_Short ((Tshort)3) +#define TIFF_Long ((Tshort)4) +#define TIFF_Rational ((Tshort)5) +#define TIFF_SByte ((Tshort)6) +#define TIFF_Undefined ((Tshort)7) +#define TIFF_SShort ((Tshort)8) +#define TIFF_SLong ((Tshort)9) +#define TIFF_SRational ((Tshort)10) +#define TIFF_Float ((Tshort)11) +#define TIFF_Double ((Tshort)12) + +#define TIFF_UNDEFINED ((Tshort)0x0) /* Not any tag, type, or other TIFF structure */ + +#define TIFF_42 ((Tshort)0x002a) /* TIFF file identifier */ +#define TIFF_II ((Tshort)0x4949) /* Intel byte order: 76543210 stored as 10325476 */ +#define TIFF_MM ((Tshort)0x4d4d) /* Motorola byte order: 76543210 stored as 76543210 */ + +#define TIFF_App0 ((Tshort)0xffe0) +#define TIFF_App1 ((Tshort)0xffe1) +#define TIFF_App2 ((Tshort)0xffe2) +#define TIFF_App3 ((Tshort)0xffe3) +#define TIFF_App4 ((Tshort)0xffe4) +#define TIFF_App5 ((Tshort)0xffe5) +#define TIFF_App6 ((Tshort)0xffe6) +#define TIFF_App7 ((Tshort)0xffe7) +#define TIFF_App8 ((Tshort)0xffe8) +#define TIFF_App9 ((Tshort)0xffe9) +#define TIFF_App10 ((Tshort)0xffea) +#define TIFF_App11 ((Tshort)0xffeb) +#define TIFF_App12 ((Tshort)0xffec) +#define TIFF_App13 ((Tshort)0xffed) +#define TIFF_App14 ((Tshort)0xffee) +#define TIFF_App15 ((Tshort)0xffef) + +#define TIFF_InteroperabilityTag1 ((Tshort)0x1) +#define TIFF_InteroperabilityTag2 ((Tshort)0x2) +#define TIFF_NewSubfileType ((Tshort)0xfe) +#define TIFF_SubfileType ((Tshort)0xff) +#define TIFF_ImageWidth ((Tshort)0x100) +#define TIFF_ImageLength ((Tshort)0x101) +#define TIFF_BitsPerSample ((Tshort)0x102) +#define TIFF_Compression ((Tshort)0x103) +#define TIFF_PhotometricInterpretation ((Tshort)0x106) +#define TIFF_Thresholding ((Tshort)0x107) +#define TIFF_CellWidth ((Tshort)0x108) +#define TIFF_CellLength ((Tshort)0x109) +#define TIFF_FillOrder ((Tshort)0x10a) +#define TIFF_DocumentName ((Tshort)0x10d) +#define TIFF_ImageDescription ((Tshort)0x10e) +#define TIFF_Make ((Tshort)0x10f) +#define TIFF_Model ((Tshort)0x110) +#define TIFF_StripOffset ((Tshort)0x111) +#define TIFF_Orientation ((Tshort)0x112) +#define TIFF_SamplesPerPixel ((Tshort)0x115) +#define TIFF_RowsPerStrip ((Tshort)0x116) +#define TIFF_StripByteCounts ((Tshort)0x117) +#define TIFF_MinSampleValue ((Tshort)0x118) +#define TIFF_MaxSampleValue ((Tshort)0x119) +#define TIFF_XResolution ((Tshort)0x11a) +#define TIFF_YResolution ((Tshort)0x11b) +#define TIFF_PlanarConfiguration ((Tshort)0x11c) +#define TIFF_PageName ((Tshort)0x11d) +#define TIFF_XPosition ((Tshort)0x11e) +#define TIFF_YPosition ((Tshort)0x11f) +#define TIFF_FreeOffsets ((Tshort)0x120) +#define TIFF_FreeByteCounts ((Tshort)0x121) +#define TIFF_GrayResponseUnit ((Tshort)0x122) +#define TIFF_GrayResponseCurve ((Tshort)0x123) +#define TIFF_T4Options ((Tshort)0x124) +#define TIFF_T6Options ((Tshort)0x125) +#define TIFF_ResolutionUnit ((Tshort)0x128) +#define TIFF_PageNumber ((Tshort)0x129) +#define TIFF_TransferFunction ((Tshort)0x12d) +#define TIFF_Software ((Tshort)0x131) +#define TIFF_DateTime ((Tshort)0x132) +#define TIFF_Artist ((Tshort)0x13b) +#define TIFF_HostComputer ((Tshort)0x13c) +#define TIFF_Predictor ((Tshort)0x13d) +#define TIFF_WhitePoint ((Tshort)0x13e) +#define TIFF_PrimaryChromaticities ((Tshort)0x13f) +#define TIFF_ColorMap ((Tshort)0x140) +#define TIFF_HalftoneHints ((Tshort)0x141) +#define TIFF_TileWidth ((Tshort)0x142) +#define TIFF_TileLength ((Tshort)0x143) +#define TIFF_TileOffsets ((Tshort)0x144) +#define TIFF_TileByteCounts ((Tshort)0x145) +#define TIFF_InkSet ((Tshort)0x14c) +#define TIFF_InkNames ((Tshort)0x14d) +#define TIFF_NumberOfInks ((Tshort)0x14e) +#define TIFF_DotRange ((Tshort)0x150) +#define TIFF_TargetPrinter ((Tshort)0x151) +#define TIFF_ExtraSamples ((Tshort)0x152) +#define TIFF_SampleFormat ((Tshort)0x153) +#define TIFF_SMinSampleValue ((Tshort)0x154) +#define TIFF_SMaxSampleValue ((Tshort)0x155) +#define TIFF_TransferRange ((Tshort)0x156) +#define TIFF_JpegTables ((Tshort)0x15b) +#define TIFF_JpegProc ((Tshort)0x200) +#define TIFF_JpegInterchangeFormat ((Tshort)0x201) +#define TIFF_JpegInterchangeFormatLength ((Tshort)0x202) +#define TIFF_JpegRestartInterval ((Tshort)0x203) +#define TIFF_JpegLosslessPredictors ((Tshort)0x205) +#define TIFF_JpegPointTransforms ((Tshort)0x206) +#define TIFF_JpegQTables ((Tshort)0x207) +#define TIFF_JpegDcTables ((Tshort)0x208) +#define TIFF_JpegAcTables ((Tshort)0x209) +#define TIFF_YCbCrCoefficients ((Tshort)0x211) +#define TIFF_YCbCrSubSampling ((Tshort)0x212) +#define TIFF_YCbCrPositioning ((Tshort)0x213) +#define TIFF_ReferenceBlackWhite ((Tshort)0x214) +#define TIFF_CfaRepeatPatternDim ((Tshort)0x828d) +#define TIFF_CfaPattern ((Tshort)0x828e) +#define TIFF_BatteryLevel ((Tshort)0x828f) +#define TIFF_Copyright ((Tshort)0x8298) +#define TIFF_ExposureTime ((Tshort)0x829a) +#define TIFF_FNumber ((Tshort)0x829d) +#define TIFF_IptcNaa ((Tshort)0x83bb) +#define TIFF_ExifSubIfdOffset ((Tshort)0x8769) /* Offset to EXIF SubIFD */ +#define TIFF_InterColorProfile ((Tshort)0x8773) +#define TIFF_ExposureProgram ((Tshort)0x8822) +#define TIFF_SpectralSensitivity ((Tshort)0x8824) +#define TIFF_GpsInfo ((Tshort)0x8825) +#define TIFF_IsoSpeedRatings ((Tshort)0x8827) +#define TIFF_Oecf ((Tshort)0x8828) +#define TIFF_Interlace ((Tshort)0x8829) +#define TIFF_TimeZoneOffset ((Tshort)0x882a) +#define TIFF_SelfTimerMode ((Tshort)0x882b) +#define TIFF_ExifVersion ((Tshort)0x9000) +#define TIFF_DateTimeOriginal ((Tshort)0x9003) +#define TIFF_DateTimeDigitized ((Tshort)0x9004) +#define TIFF_ComponentConfiguration ((Tshort)0x9101) +#define TIFF_CompressedBitsPerLevel ((Tshort)0x9102) /* CompressedBitsPerPixel */ +#define TIFF_ShutterSpeedValue ((Tshort)0x9201) +#define TIFF_ApertureValue ((Tshort)0x9202) +#define TIFF_BrightnessValue ((Tshort)0x9203) +#define TIFF_ExposureBiasValue ((Tshort)0x9204) +#define TIFF_MaxApertureValue ((Tshort)0x9205) +#define TIFF_SubjectDistance ((Tshort)0x9206) +#define TIFF_MeteringMode ((Tshort)0x9207) +#define TIFF_LightSource ((Tshort)0x9208) +#define TIFF_Flash ((Tshort)0x9209) +#define TIFF_FocalLength ((Tshort)0x920a) +#define TIFF_FlashEnergy ((Tshort)0x920b) +#define TIFF_SpatialFrequencyResponse ((Tshort)0x920c) +#define TIFF_Noise ((Tshort)0x920d) +#define TIFF_ImageNumber ((Tshort)0x9211) +#define TIFF_SecurityClassification ((Tshort)0x9212) +#define TIFF_ImageHistory ((Tshort)0x9213) +#define TIFF_SubjectLocation ((Tshort)0x9214) +#define TIFF_ExposureIndex ((Tshort)0x9215) +#define TIFF_TiffEpStandardId ((Tshort)0x9216) +#define TIFF_MakerNote ((Tshort)0x927c) +#define TIFF_UserComment ((Tshort)0x9286) +#define TIFF_SubSecTime ((Tshort)0x9290) +#define TIFF_SubSecTimeOriginal ((Tshort)0x9291) +#define TIFF_SubSecTimeDigitized ((Tshort)0x9292) +#define TIFF_FlashPixVersion ((Tshort)0xa000) +#define TIFF_ColorSpace ((Tshort)0xa001) +#define TIFF_ExifImageWidth ((Tshort)0xa002) +#define TIFF_ExifImageHeight ((Tshort)0xa003) +#define TIFF_RelatedSoundFile ((Tshort)0xa004) +#define TIFF_ExifInteroperabilityOffset ((Tshort)0xa005) +/* +#define TIFF_FlashEnergy ((Tshort)0xa20b) +#define TIFF_SpatialFrequencyResponse ((Tshort)0xa20c) +*/ +#define TIFF_FocalPlaneXResolution ((Tshort)0xa20e) +#define TIFF_FocalPlaneYResolution ((Tshort)0xa20f) +#define TIFF_FocalPlaneResolutionUnit ((Tshort)0xa210) +/* +#define TIFF_SubjectLocation ((Tshort)0xa214) +#define TIFF_ExposureIndex ((Tshort)0xa215) +*/ +#define TIFF_SensingMethod ((Tshort)0xa217) +#define TIFF_FileSource ((Tshort)0xa300) +#define TIFF_SceneType ((Tshort)0xa301) +/* +#define TIFF_CfaPattern ((Tshort)0xa302) +*/ + + +/* Functions */ + +void dumpEntries ( Tbyte* start, Tbyte* firstentry, Tlong entries, Texif* exif ); +int getOrder ( Tbyte* start ); +int isExif ( Tbyte* start ); + +int dumpExif ( char* oldName, Tbyte* start, Tbyte* end ); +int exifPhoto ( FILE* file, char* oldName, Tbyte* start, Tbyte* end ); + +char* getTiffAscii ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* string ); +TtiffLong* getTiffLong ( int byteOrder, Tbyte* tiff, Tbyte* entry, Tlong* count, TtiffLong* val ); +char* getTiffRational ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* string ); +char* getTiffRational2 ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* string ); +TtiffShort* getTiffShort ( int byteOrder, Tbyte* tiff, Tbyte* entry, Tlong* count, TtiffShort* val ); +char* getTiffSRational ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* string ); +char* getTiffUndefined ( int byteOrder, Tbyte* tiff, Tbyte* entry, Tlong* count, char* string ); +char* getTiffUnknownFormat ( int byteOrder, Tbyte* tiff, Tbyte* entry, Tlong* count, char* string ); + +Tlong getLong ( Tbyte* p, int byteOrder ); +Tshort getShort ( Tbyte* p, int byteOrder ); +TtiffLong tifflong ( Tbyte* p, int byteOrder ); +TtiffShort tiffShort ( Tbyte* p, int byteOrder ); +TtiffSLong tiffSLong ( Tbyte* p, int byteOrder ); +TtiffSShort tiffSShort ( Tbyte* p, int byteOrder ); + +char* getApertureValue ( int byteOrder, Tbyte* tiff, Tbyte* entry ); +char* getArtist ( int byteOrder, Tbyte* tiff, Tbyte* entry ); +char* getBatteryLevel ( int byteOrder, Tbyte* tiff, Tbyte* entry ); +char* getBitsPerSample ( int byteOrder, Tbyte* tiff, Tbyte* entry ); +char* getBrightnessValue ( int byteOrder, Tbyte* tiff, Tbyte* entry ); +char* getCellLength ( int byteOrder, Tbyte* tiff, Tbyte* entry ); +char* getCellWidth ( int byteOrder, Tbyte* tiff, Tbyte* entry ); +char* getCfaPattern ( int byteOrder, Tbyte* tiff, Tbyte* entry ); +char* getCfaRepeatPatternDim ( int byteOrder, Tbyte* tiff, Tbyte* entry ); +char* getColorMap ( int byteOrder, Tbyte* tiff, Tbyte* entry ); +char* getColorSpace ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* color ); +char* getComponentConfiguration ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* config ); +char* getCompressedBitsPerLevel ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* compressed ); +char* getCompression ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* compression ); +char* getCopyright ( int byteOrder, Tbyte* tiff, Tbyte* entry ); +char* getDateTime ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* dateTime ); +char* getDateTimeDigitized ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* dateTime ); +char* getDateTimeOriginal ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* dateTime ); +char* getDocumentName ( int byteOrder, Tbyte* tiff, Tbyte* entry ); +char* getDotRange ( int byteOrder, Tbyte* tiff, Tbyte* entry ); +char* getExifImageHeight ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* height ); +char* getExifImageWidth ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* width ); +char* getExifVersion ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* version ); +char* getExposureBiasValue ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* bias ); +char* getExposureIndex ( int byteOrder, Tbyte* tiff, Tbyte* entry ); +char* getExposureProgram ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* prog ); +char* getExposureTime ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* time ); +char* getExtraSamples ( int byteOrder, Tbyte* tiff, Tbyte* entry ); +char* getFNumber ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* fstop ); +char* getFileSource ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* source ); +char* getFillOrder ( int byteOrder, Tbyte* tiff, Tbyte* entry ); +char* getFlash ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* flash ); +char* getFlashEnergy ( int byteOrder, Tbyte* tiff, Tbyte* entry ); +char* getFlashPixVersion ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* version ); +char* getFocalLength ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* length ); +char* getFocalPlaneResolutionUnit ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* unit ); +char* getFocalPlaneXResolution ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* resolution ); +char* getFocalPlaneYResolution ( int byteOrder, Tbyte* tiff, Tbyte* entry, char* resolution ); +char* getFreeByteCounts ( int byteOrder, Tbyte* tiff, Tbyte* entry ); +char* getFreeOffsets ( int