From 8f4668a6e9be9f1b6435b5f3f64eee522db84ae4 Mon Sep 17 00:00:00 2001 From: Andreas Huggel Date: Tue, 10 Feb 2004 09:25:09 +0000 Subject: [PATCH] Added printing of the interpreted metadatum value --- src/exif.cpp | 19 +- src/exif.hpp | 8 +- src/exifprint.cpp | 8 +- src/exiftest.cpp | 7 +- src/tags.cpp | 591 +++++++++++++++++++++++++++++++++++----------- src/tags.hpp | 70 +++++- 6 files changed, 555 insertions(+), 148 deletions(-) diff --git a/src/exif.cpp b/src/exif.cpp index c1abc3e7..c5f55788 100644 --- a/src/exif.cpp +++ b/src/exif.cpp @@ -20,13 +20,13 @@ */ /* File: exif.cpp - Version: $Name: $ $Revision: 1.18 $ + Version: $Name: $ $Revision: 1.19 $ Author(s): Andreas Huggel (ahu) History: 26-Jan-04, ahu: created */ // ***************************************************************************** #include "rcsid.hpp" -EXIV2_RCSID("@(#) $Name: $ $Revision: 1.18 $ $RCSfile: exif.cpp,v $") +EXIV2_RCSID("@(#) $Name: $ $Revision: 1.19 $ $RCSfile: exif.cpp,v $") // ***************************************************************************** // included header files @@ -359,7 +359,14 @@ namespace Exif { std::ostream& AsciiValue::write(std::ostream& os) const { - return os << value_; + // Strip trailing '\0', if any + if (value_.size() > 0 && value_[value_.size() - 1] == '\0') { + os << value_.substr(0, value_.size() - 1); + } + else { + os << value_; + } + return os; } Metadatum::Metadatum(const Entry& e, ByteOrder byteOrder) @@ -1685,4 +1692,10 @@ std::cout << "->>>>>> writing from metadata <<<<<<-\n"; return lhs.key() < rhs.key(); } + std::ostream& operator<<(std::ostream& os, const Metadatum& md) + { + PrintFct fct = ExifTags::printFct(md.tag(), md.ifdId()); + return fct(os, md.value()); + } + } // namespace Exif diff --git a/src/exif.hpp b/src/exif.hpp index 0536fb4f..694b3cea 100644 --- a/src/exif.hpp +++ b/src/exif.hpp @@ -21,7 +21,7 @@ /*! @file exif.hpp @brief Encoding and decoding of %Exif data - @version $Name: $ $Revision: 1.18 $ + @version $Name: $ $Revision: 1.19 $ @author Andreas Huggel (ahu) ahuggel@gmx.net @date 09-Jan-04, ahu: created @@ -595,6 +595,12 @@ namespace Exif { }; // class Metadatum + /*! + @brief Output operator for Metadatum types, printing the interpreted + tag value. + */ + std::ostream& operator<<(std::ostream& os, const Metadatum& md); + //! Container type to hold all metadata typedef std::vector Metadata; diff --git a/src/exifprint.cpp b/src/exifprint.cpp index a98b14d4..45490160 100644 --- a/src/exifprint.cpp +++ b/src/exifprint.cpp @@ -23,12 +23,12 @@ File: exifprint.cpp Author(s): Andreas Huggel (ahu) - Version : $Name: $ $Revision: 1.6 $ + Version : $Name: $ $Revision: 1.7 $ History : 26-Jan-04, ahu: created */ // ***************************************************************************** #include "rcsid.hpp" -EXIV2_RCSID("@(#) $Name: $ $Revision: 1.6 $ $RCSfile: exifprint.cpp,v $") +EXIV2_RCSID("@(#) $Name: $ $Revision: 1.7 $ $RCSfile: exifprint.cpp,v $") // ***************************************************************************** // included header files @@ -73,7 +73,9 @@ try { << i->ifdItem() << " " << std::setw(27) << std::setfill(' ') << std::left << i->tagName() << " " - << std::dec << i->value() << "\n"; +// << std::dec << i->value() + << std::dec << *i + << "\n"; } return rc; diff --git a/src/exiftest.cpp b/src/exiftest.cpp index a972bc33..cf4035d7 100644 --- a/src/exiftest.cpp +++ b/src/exiftest.cpp @@ -3,11 +3,11 @@ Abstract : This is playground code, do what you want with it. Author(s): Andreas Huggel (ahu) - Version : $Name: $ $Revision: 1.14 $ + Version : $Name: $ $Revision: 1.15 $ */ // ***************************************************************************** #include "rcsid.hpp" -EXIV2_RCSID("@(#) $Name: $ $Revision: 1.14 $ $RCSfile: exiftest.cpp,v $") +EXIV2_RCSID("@(#) $Name: $ $Revision: 1.15 $ $RCSfile: exiftest.cpp,v $") // ***************************************************************************** // included header files @@ -97,7 +97,8 @@ void exifPrint(const ExifData& exifData) << std::dec << std::setw(3) << std::setfill(' ') << std::right << i->count() << " " - << std::dec << i->value() + << std::dec << *i +// << std::dec << i->value() // << " | " << i->key() << " | " << i->ifdName() diff --git a/src/tags.cpp b/src/tags.cpp index 01930a98..bea8980b 100644 --- a/src/tags.cpp +++ b/src/tags.cpp @@ -20,20 +20,22 @@ */ /* File: tags.cpp - Version: $Name: $ $Revision: 1.10 $ + Version: $Name: $ $Revision: 1.11 $ Author(s): Andreas Huggel (ahu) History: 15-Jan-04, ahu: created */ // ***************************************************************************** #include "rcsid.hpp" -EXIV2_RCSID("@(#) $Name: $ $Revision: 1.10 $ $RCSfile: tags.cpp,v $") +EXIV2_RCSID("@(#) $Name: $ $Revision: 1.11 $ $RCSfile: tags.cpp,v $") // ***************************************************************************** // included header files #include "tags.hpp" +#include "exif.hpp" // Todo: resolve this unwanted dependency #include #include +#include // ***************************************************************************** // class member definitions @@ -111,160 +113,161 @@ namespace Exif { const char* name, const char* desc, IfdId ifdId, - SectionId sectionId + SectionId sectionId, + PrintFct printFct ) - : tag_(tag), name_(name), desc_(desc), - ifdId_(ifdId), sectionId_(sectionId) + : tag_(tag), name_(name), desc_(desc), ifdId_(ifdId), + sectionId_(sectionId), printFct_(printFct) { } // Base IFD Tags (IFD0 and IFD1) static const TagInfo ifdTagInfo[] = { - TagInfo(0x0100, "ImageWidth", "Image width", ifd0, imgStruct), - TagInfo(0x0101, "ImageLength", "Image height", ifd0, imgStruct), - TagInfo(0x0102, "BitsPerSample", "Number of bits per component", ifd0, imgStruct), - TagInfo(0x0103, "Compression", "Compression scheme", ifd0, imgStruct), - TagInfo(0x0106, "PhotometricInterpretation", "Pixel composition", ifd0, imgStruct), - TagInfo(0x010e, "ImageDescription", "Image title", ifd0, otherTags), - TagInfo(0x010f, "Make", "Manufacturer of image input equipment", ifd0, otherTags), - TagInfo(0x0110, "Model", "Model of image input equipment", ifd0, otherTags), - TagInfo(0x0111, "StripOffsets", "Image data location", ifd0, recOffset), - TagInfo(0x0112, "Orientation", "Orientation of image", ifd0, imgStruct), - TagInfo(0x0115, "SamplesPerPixel", "Number of components", ifd0, imgStruct), - TagInfo(0x0116, "RowsPerStrip", "Number of rows per strip", ifd0, recOffset), - TagInfo(0x0117, "StripByteCounts", "Bytes per compressed strip", ifd0, recOffset), - TagInfo(0x011a, "XResolution", "Image resolution in width direction", ifd0, imgStruct), - TagInfo(0x011b, "YResolution", "Image resolution in height direction", ifd0, imgStruct), - TagInfo(0x011c, "PlanarConfiguration", "Image data arrangement", ifd0, imgStruct), - TagInfo(0x0128, "ResolutionUnit", "Unit of X and Y resolution", ifd0, imgStruct), - TagInfo(0x012d, "TransferFunction", "Transfer function", ifd0, imgCharacter), - TagInfo(0x0131, "Software", "Software used", ifd0, otherTags), - TagInfo(0x0132, "DateTime", "File change date and time", ifd0, otherTags), - TagInfo(0x013b, "Artist", "Person who created the image", ifd0, otherTags), - TagInfo(0x013e, "WhitePoint", "White point chromaticity", ifd0, imgCharacter), - TagInfo(0x013f, "PrimaryChromaticities", "Chromaticities of primaries", ifd0, imgCharacter), - TagInfo(0x0201, "JPEGInterchangeFormat", "Offset to JPEG SOI", ifd0, recOffset), - TagInfo(0x0202, "JPEGInterchangeFormatLength", "Bytes of JPEG data", ifd0, recOffset), - TagInfo(0x0211, "YCbCrCoefficients", "Color space transformation matrix coefficients", ifd0, imgCharacter), - TagInfo(0x0212, "YCbCrSubSampling", "Subsampling ratio of Y to C", ifd0, imgStruct), - TagInfo(0x0213, "YCbCrPositioning", "Y and C positioning", ifd0, imgStruct), - TagInfo(0x0214, "ReferenceBlackWhite", "Pair of black and white reference values", ifd0, imgCharacter), - TagInfo(0x8298, "Copyright", "Copyright holder", ifd0, otherTags), - TagInfo(0x8769, "ExifTag", "Exif IFD Pointer", ifd0, exifFormat), - TagInfo(0x8825, "GPSTag", "GPSInfo IFD Pointer", ifd0, exifFormat), + TagInfo(0x0100, "ImageWidth", "Image width", ifd0, imgStruct, printValue), + TagInfo(0x0101, "ImageLength", "Image height", ifd0, imgStruct, printValue), + TagInfo(0x0102, "BitsPerSample", "Number of bits per component", ifd0, imgStruct, printValue), + TagInfo(0x0103, "Compression", "Compression scheme", ifd0, imgStruct, print0x0103), + TagInfo(0x0106, "PhotometricInterpretation", "Pixel composition", ifd0, imgStruct, print0x0106), + TagInfo(0x010e, "ImageDescription", "Image title", ifd0, otherTags, printValue), + TagInfo(0x010f, "Make", "Manufacturer of image input equipment", ifd0, otherTags, printValue), + TagInfo(0x0110, "Model", "Model of image input equipment", ifd0, otherTags, printValue), + TagInfo(0x0111, "StripOffsets", "Image data location", ifd0, recOffset, printValue), + TagInfo(0x0112, "Orientation", "Orientation of image", ifd0, imgStruct, printValue), + TagInfo(0x0115, "SamplesPerPixel", "Number of components", ifd0, imgStruct, printValue), + TagInfo(0x0116, "RowsPerStrip", "Number of rows per strip", ifd0, recOffset, printValue), + TagInfo(0x0117, "StripByteCounts", "Bytes per compressed strip", ifd0, recOffset, printValue), + TagInfo(0x011a, "XResolution", "Image resolution in width direction", ifd0, imgStruct, printLong), + TagInfo(0x011b, "YResolution", "Image resolution in height direction", ifd0, imgStruct, printLong), + TagInfo(0x011c, "PlanarConfiguration", "Image data arrangement", ifd0, imgStruct, printValue), + TagInfo(0x0128, "ResolutionUnit", "Unit of X and Y resolution", ifd0, imgStruct, printUnit), + TagInfo(0x012d, "TransferFunction", "Transfer function", ifd0, imgCharacter, printValue), + TagInfo(0x0131, "Software", "Software used", ifd0, otherTags, printValue), + TagInfo(0x0132, "DateTime", "File change date and time", ifd0, otherTags, printValue), + TagInfo(0x013b, "Artist", "Person who created the image", ifd0, otherTags, printValue), + TagInfo(0x013e, "WhitePoint", "White point chromaticity", ifd0, imgCharacter, printValue), + TagInfo(0x013f, "PrimaryChromaticities", "Chromaticities of primaries", ifd0, imgCharacter, printValue), + TagInfo(0x0201, "JPEGInterchangeFormat", "Offset to JPEG SOI", ifd0, recOffset, printValue), + TagInfo(0x0202, "JPEGInterchangeFormatLength", "Bytes of JPEG data", ifd0, recOffset, printValue), + TagInfo(0x0211, "YCbCrCoefficients", "Color space transformation matrix coefficients", ifd0, imgCharacter, printValue), + TagInfo(0x0212, "YCbCrSubSampling", "Subsampling ratio of Y to C", ifd0, imgStruct, printValue), + TagInfo(0x0213, "YCbCrPositioning", "Y and C positioning", ifd0, imgStruct, print0x0213), + TagInfo(0x0214, "ReferenceBlackWhite", "Pair of black and white reference values", ifd0, imgCharacter, printValue), + TagInfo(0x8298, "Copyright", "Copyright holder", ifd0, otherTags, printValue), + TagInfo(0x8769, "ExifTag", "Exif IFD Pointer", ifd0, exifFormat, printValue), + TagInfo(0x8825, "GPSTag", "GPSInfo IFD Pointer", ifd0, exifFormat, printValue), // End of list marker - TagInfo(0xffff, "(UnknownIfdTag)", "Unknown IFD tag", ifdIdNotSet, sectionIdNotSet) + TagInfo(0xffff, "(UnknownIfdTag)", "Unknown IFD tag", ifdIdNotSet, sectionIdNotSet, printNull) }; // Exif IFD Tags static const TagInfo exifTagInfo[] = { - TagInfo(0x829a, "ExposureTime", "Exposure time", exifIfd, captureCond), - TagInfo(0x829d, "FNumber", "F number", exifIfd, captureCond), - TagInfo(0x8822, "ExposureProgram", "Exposure program", exifIfd, captureCond), - TagInfo(0x8824, "SpectralSensitivity", "Spectral sensitivity", exifIfd, captureCond), - TagInfo(0x8827, "ISOSpeedRatings", "ISO speed ratings", exifIfd, captureCond), - TagInfo(0x8828, "OECF", "Optoelectric coefficient", exifIfd, captureCond), - TagInfo(0x9000, "ExifVersion", "Exif Version", exifIfd, exifVersion), - TagInfo(0x9003, "DateTimeOriginal", "Date and time original image was generated", exifIfd, dateTime), - TagInfo(0x9004, "DateTimeDigitized", "Date and time image was made digital data", exifIfd, dateTime), - TagInfo(0x9101, "ComponentsConfiguration", "Meaning of each component", exifIfd, imgConfig), - TagInfo(0x9102, "CompressedBitsPerPixel", "Image compression mode", exifIfd, imgConfig), - TagInfo(0x9201, "ShutterSpeedValue", "Shutter speed", exifIfd, captureCond), - TagInfo(0x9202, "ApertureValue", "Aperture", exifIfd, captureCond), - TagInfo(0x9203, "BrightnessValue", "Brightness", exifIfd, captureCond), - TagInfo(0x9204, "ExposureBiasValue", "Exposure bias", exifIfd, captureCond), - TagInfo(0x9205, "MaxApertureValue", "Maximum lens aperture", exifIfd, captureCond), - TagInfo(0x9206, "SubjectDistance", "Subject distance", exifIfd, captureCond), - TagInfo(0x9207, "MeteringMode", "Metering mode", exifIfd, captureCond), - TagInfo(0x9208, "LightSource", "Light source", exifIfd, captureCond), - TagInfo(0x9209, "Flash", "Flash", exifIfd, captureCond), - TagInfo(0x920a, "FocalLength", "Lens focal length", exifIfd, captureCond), - TagInfo(0x9214, "SubjectArea", "Subject area", exifIfd, captureCond), - TagInfo(0x927c, "MakerNote", "Manufacturer notes", exifIfd, userInfo), - TagInfo(0x9286, "UserComment", "User comments", exifIfd, userInfo), - TagInfo(0x9290, "SubSecTime", "DateTime subseconds", exifIfd, dateTime), - TagInfo(0x9291, "SubSecTimeOriginal", "DateTimeOriginal subseconds", exifIfd, dateTime), - TagInfo(0x9292, "SubSecTimeDigitized", "DateTimeDigitized subseconds", exifIfd, dateTime), - TagInfo(0xa000, "FlashpixVersion", "Supported Flashpix version", exifIfd, exifVersion), - TagInfo(0xa001, "ColorSpace", "Color space information", exifIfd, imgCharacter), - TagInfo(0xa002, "PixelXDimension", "Valid image width", exifIfd, imgConfig), - TagInfo(0xa003, "PixelYDimension", "Valid image height", exifIfd, imgConfig), - TagInfo(0xa004, "RelatedSoundFile", "Related audio file", exifIfd, relatedFile), - TagInfo(0xa005, "InteroperabilityTag", "Interoperability IFD Pointer", exifIfd, exifFormat), - TagInfo(0xa20b, "FlashEnergy", "Flash energy", exifIfd, captureCond), - TagInfo(0xa20c, "SpatialFrequencyResponse", "Spatial frequency response", exifIfd, captureCond), - TagInfo(0xa20e, "FocalPlaneXResolution", "Focal plane X resolution", exifIfd, captureCond), - TagInfo(0xa20f, "FocalPlaneYResolution", "Focal plane Y resolution", exifIfd, captureCond), - TagInfo(0xa210, "FocalPlaneResolutionUnit", "Focal plane resolution unit", exifIfd, captureCond), - TagInfo(0xa214, "SubjectLocation", "Subject location", exifIfd, captureCond), - TagInfo(0xa215, "ExposureIndex", "Exposure index", exifIfd, captureCond), - TagInfo(0xa217, "SensingMethod", "Sensing method", exifIfd, captureCond), - TagInfo(0xa300, "FileSource", "File source", exifIfd, captureCond), - TagInfo(0xa301, "SceneType", "Scene type", exifIfd, captureCond), - TagInfo(0xa302, "CFAPattern", "CFA pattern", exifIfd, captureCond), - TagInfo(0xa401, "CustomRendered", "Custom image processing", exifIfd, captureCond), - TagInfo(0xa402, "ExposureMode", "Exposure mode", exifIfd, captureCond), - TagInfo(0xa403, "WhiteBalance", "White balance", exifIfd, captureCond), - TagInfo(0xa404, "DigitalZoomRatio", "Digital zoom ratio", exifIfd, captureCond), - TagInfo(0xa405, "FocalLengthIn35mmFilm", "Focal length in 35 mm film", exifIfd, captureCond), - TagInfo(0xa406, "SceneCaptureType", "Scene capture type", exifIfd, captureCond), - TagInfo(0xa407, "GainControl", "Gain control", exifIfd, captureCond), - TagInfo(0xa408, "Contrast", "Contrast", exifIfd, captureCond), - TagInfo(0xa409, "Saturation", "Saturation", exifIfd, captureCond), - TagInfo(0xa40a, "Sharpness", "Sharpness", exifIfd, captureCond), - TagInfo(0xa40b, "DeviceSettingDescription", "Device settings description", exifIfd, captureCond), - TagInfo(0xa40c, "SubjectDistanceRange", "Subject distance range", exifIfd, captureCond), - TagInfo(0xa420, "ImageUniqueID", "Unique image ID", exifIfd, otherTags), + TagInfo(0x829a, "ExposureTime", "Exposure time", exifIfd, captureCond, print0x829a), + TagInfo(0x829d, "FNumber", "F number", exifIfd, captureCond, print0x829d), + TagInfo(0x8822, "ExposureProgram", "Exposure program", exifIfd, captureCond, print0x8822), + TagInfo(0x8824, "SpectralSensitivity", "Spectral sensitivity", exifIfd, captureCond, printValue), + TagInfo(0x8827, "ISOSpeedRatings", "ISO speed ratings", exifIfd, captureCond, printValue), + TagInfo(0x8828, "OECF", "Optoelectric coefficient", exifIfd, captureCond, printValue), + TagInfo(0x9000, "ExifVersion", "Exif Version", exifIfd, exifVersion, printValue), + TagInfo(0x9003, "DateTimeOriginal", "Date and time original image was generated", exifIfd, dateTime, printValue), + TagInfo(0x9004, "DateTimeDigitized", "Date and time image was made digital data", exifIfd, dateTime, printValue), + TagInfo(0x9101, "ComponentsConfiguration", "Meaning of each component", exifIfd, imgConfig, print0x9101), + TagInfo(0x9102, "CompressedBitsPerPixel", "Image compression mode", exifIfd, imgConfig, printFloat), + TagInfo(0x9201, "ShutterSpeedValue", "Shutter speed", exifIfd, captureCond, printFloat), + TagInfo(0x9202, "ApertureValue", "Aperture", exifIfd, captureCond, printFloat), + TagInfo(0x9203, "BrightnessValue", "Brightness", exifIfd, captureCond, printFloat), + TagInfo(0x9204, "ExposureBiasValue", "Exposure bias", exifIfd, captureCond, printFloat), + TagInfo(0x9205, "MaxApertureValue", "Maximum lens aperture", exifIfd, captureCond, printFloat), + TagInfo(0x9206, "SubjectDistance", "Subject distance", exifIfd, captureCond, print0x9206), + TagInfo(0x9207, "MeteringMode", "Metering mode", exifIfd, captureCond, print0x9207), + TagInfo(0x9208, "LightSource", "Light source", exifIfd, captureCond, printValue), + TagInfo(0x9209, "Flash", "Flash", exifIfd, captureCond, print0x9209), + TagInfo(0x920a, "FocalLength", "Lens focal length", exifIfd, captureCond, print0x920a), + TagInfo(0x9214, "SubjectArea", "Subject area", exifIfd, captureCond, printValue), + TagInfo(0x927c, "MakerNote", "Manufacturer notes", exifIfd, userInfo, printValue), + TagInfo(0x9286, "UserComment", "User comments", exifIfd, userInfo, printValue), + TagInfo(0x9290, "SubSecTime", "DateTime subseconds", exifIfd, dateTime, printValue), + TagInfo(0x9291, "SubSecTimeOriginal", "DateTimeOriginal subseconds", exifIfd, dateTime, printValue), + TagInfo(0x9292, "SubSecTimeDigitized", "DateTimeDigitized subseconds", exifIfd, dateTime, printValue), + TagInfo(0xa000, "FlashpixVersion", "Supported Flashpix version", exifIfd, exifVersion, printValue), + TagInfo(0xa001, "ColorSpace", "Color space information", exifIfd, imgCharacter, print0xa001), + TagInfo(0xa002, "PixelXDimension", "Valid image width", exifIfd, imgConfig, printValue), + TagInfo(0xa003, "PixelYDimension", "Valid image height", exifIfd, imgConfig, printValue), + TagInfo(0xa004, "RelatedSoundFile", "Related audio file", exifIfd, relatedFile, printValue), + TagInfo(0xa005, "InteroperabilityTag", "Interoperability IFD Pointer", exifIfd, exifFormat, printValue), + TagInfo(0xa20b, "FlashEnergy", "Flash energy", exifIfd, captureCond, printValue), + TagInfo(0xa20c, "SpatialFrequencyResponse", "Spatial frequency response", exifIfd, captureCond, printValue), + TagInfo(0xa20e, "FocalPlaneXResolution", "Focal plane X resolution", exifIfd, captureCond, printFloat), + TagInfo(0xa20f, "FocalPlaneYResolution", "Focal plane Y resolution", exifIfd, captureCond, printFloat), + TagInfo(0xa210, "FocalPlaneResolutionUnit", "Focal plane resolution unit", exifIfd, captureCond, printUnit), + TagInfo(0xa214, "SubjectLocation", "Subject location", exifIfd, captureCond, printValue), + TagInfo(0xa215, "ExposureIndex", "Exposure index", exifIfd, captureCond, printValue), + TagInfo(0xa217, "SensingMethod", "Sensing method", exifIfd, captureCond, print0xa217), + TagInfo(0xa300, "FileSource", "File source", exifIfd, captureCond, printValue), + TagInfo(0xa301, "SceneType", "Scene type", exifIfd, captureCond, printValue), + TagInfo(0xa302, "CFAPattern", "CFA pattern", exifIfd, captureCond, printValue), + TagInfo(0xa401, "CustomRendered", "Custom image processing", exifIfd, captureCond, printValue), + TagInfo(0xa402, "ExposureMode", "Exposure mode", exifIfd, captureCond, print0xa402), + TagInfo(0xa403, "WhiteBalance", "White balance", exifIfd, captureCond, print0xa403), + TagInfo(0xa404, "DigitalZoomRatio", "Digital zoom ratio", exifIfd, captureCond, print0xa404), + TagInfo(0xa405, "FocalLengthIn35mmFilm", "Focal length in 35 mm film", exifIfd, captureCond, printValue), + TagInfo(0xa406, "SceneCaptureType", "Scene capture type", exifIfd, captureCond, print0xa406), + TagInfo(0xa407, "GainControl", "Gain control", exifIfd, captureCond, printValue), + TagInfo(0xa408, "Contrast", "Contrast", exifIfd, captureCond, printValue), + TagInfo(0xa409, "Saturation", "Saturation", exifIfd, captureCond, printValue), + TagInfo(0xa40a, "Sharpness", "Sharpness", exifIfd, captureCond, printValue), + TagInfo(0xa40b, "DeviceSettingDescription", "Device settings description", exifIfd, captureCond, printValue), + TagInfo(0xa40c, "SubjectDistanceRange", "Subject distance range", exifIfd, captureCond, printValue), + TagInfo(0xa420, "ImageUniqueID", "Unique image ID", exifIfd, otherTags, printValue), // End of list marker - TagInfo(0xffff, "(UnknownExifTag)", "Unknown Exif tag", ifdIdNotSet, sectionIdNotSet) + TagInfo(0xffff, "(UnknownExifTag)", "Unknown Exif tag", ifdIdNotSet, sectionIdNotSet, printNull) }; // GPS Info Tags static const TagInfo gpsTagInfo[] = { - TagInfo(0x0000, "GPSVersionID", "GPS tag version", gpsIfd, gpsTags), - TagInfo(0x0001, "GPSLatitudeRef", "North or South Latitude", gpsIfd, gpsTags), - TagInfo(0x0002, "GPSLatitude", "Latitude", gpsIfd, gpsTags), - TagInfo(0x0003, "GPSLongitudeRef", "East or West Longitude", gpsIfd, gpsTags), - TagInfo(0x0004, "GPSLongitude", "Longitude", gpsIfd, gpsTags), - TagInfo(0x0005, "GPSAltitudeRef", "Altitude reference", gpsIfd, gpsTags), - TagInfo(0x0006, "GPSAltitude", "Altitude", gpsIfd, gpsTags), - TagInfo(0x0007, "GPSTimeStamp", "GPS time (atomic clock)", gpsIfd, gpsTags), - TagInfo(0x0008, "GPSSatellites", "GPS satellites used for measurement", gpsIfd, gpsTags), - TagInfo(0x0009, "GPSStatus", "GPS receiver status", gpsIfd, gpsTags), - TagInfo(0x000a, "GPSMeasureMode", "GPS measurement mode", gpsIfd, gpsTags), - TagInfo(0x000b, "GPSDOP", "Measurement precision", gpsIfd, gpsTags), - TagInfo(0x000c, "GPSSpeedRef", "Speed unit", gpsIfd, gpsTags), - TagInfo(0x000d, "GPSSpeed", "Speed of GPS receiver", gpsIfd, gpsTags), - TagInfo(0x000e, "GPSTrackRef", "Reference for direction of movement", gpsIfd, gpsTags), - TagInfo(0x000f, "GPSTrack", "Direction of movement", gpsIfd, gpsTags), - TagInfo(0x0010, "GPSImgDirectionRef", "Reference for direction of image", gpsIfd, gpsTags), - TagInfo(0x0011, "GPSImgDirection", "Direction of image", gpsIfd, gpsTags), - TagInfo(0x0012, "GPSMapDatum", "Geodetic survey data used", gpsIfd, gpsTags), - TagInfo(0x0013, "GPSDestLatitudeRef", "Reference for latitude of destination", gpsIfd, gpsTags), - TagInfo(0x0014, "GPSDestLatitude", "Latitude of destination", gpsIfd, gpsTags), - TagInfo(0x0015, "GPSDestLongitudeRef", "Reference for longitude of destination", gpsIfd, gpsTags), - TagInfo(0x0016, "GPSDestLongitude", "Longitude of destination", gpsIfd, gpsTags), - TagInfo(0x0017, "GPSDestBearingRef", "Reference for bearing of destination", gpsIfd, gpsTags), - TagInfo(0x0018, "GPSDestBearing", "Bearing of destination", gpsIfd, gpsTags), - TagInfo(0x0019, "GPSDestDistanceRef", "Reference for distance to destination", gpsIfd, gpsTags), - TagInfo(0x001a, "GPSDestDistance", "Distance to destination", gpsIfd, gpsTags), - TagInfo(0x001b, "GPSProcessingMethod", "Name of GPS processing method", gpsIfd, gpsTags), - TagInfo(0x001c, "GPSAreaInformation", "Name of GPS area", gpsIfd, gpsTags), - TagInfo(0x001d, "GPSDateStamp", "GPS date", gpsIfd, gpsTags), - TagInfo(0x001e, "GPSDifferential", "GPS differential correction", gpsIfd, gpsTags), + TagInfo(0x0000, "GPSVersionID", "GPS tag version", gpsIfd, gpsTags, printValue), + TagInfo(0x0001, "GPSLatitudeRef", "North or South Latitude", gpsIfd, gpsTags, printValue), + TagInfo(0x0002, "GPSLatitude", "Latitude", gpsIfd, gpsTags, printValue), + TagInfo(0x0003, "GPSLongitudeRef", "East or West Longitude", gpsIfd, gpsTags, printValue), + TagInfo(0x0004, "GPSLongitude", "Longitude", gpsIfd, gpsTags, printValue), + TagInfo(0x0005, "GPSAltitudeRef", "Altitude reference", gpsIfd, gpsTags, printValue), + TagInfo(0x0006, "GPSAltitude", "Altitude", gpsIfd, gpsTags, printValue), + TagInfo(0x0007, "GPSTimeStamp", "GPS time (atomic clock)", gpsIfd, gpsTags, printValue), + TagInfo(0x0008, "GPSSatellites", "GPS satellites used for measurement", gpsIfd, gpsTags, printValue), + TagInfo(0x0009, "GPSStatus", "GPS receiver status", gpsIfd, gpsTags, printValue), + TagInfo(0x000a, "GPSMeasureMode", "GPS measurement mode", gpsIfd, gpsTags, printValue), + TagInfo(0x000b, "GPSDOP", "Measurement precision", gpsIfd, gpsTags, printValue), + TagInfo(0x000c, "GPSSpeedRef", "Speed unit", gpsIfd, gpsTags, printValue), + TagInfo(0x000d, "GPSSpeed", "Speed of GPS receiver", gpsIfd, gpsTags, printValue), + TagInfo(0x000e, "GPSTrackRef", "Reference for direction of movement", gpsIfd, gpsTags, printValue), + TagInfo(0x000f, "GPSTrack", "Direction of movement", gpsIfd, gpsTags, printValue), + TagInfo(0x0010, "GPSImgDirectionRef", "Reference for direction of image", gpsIfd, gpsTags, printValue), + TagInfo(0x0011, "GPSImgDirection", "Direction of image", gpsIfd, gpsTags, printValue), + TagInfo(0x0012, "GPSMapDatum", "Geodetic survey data used", gpsIfd, gpsTags, printValue), + TagInfo(0x0013, "GPSDestLatitudeRef", "Reference for latitude of destination", gpsIfd, gpsTags, printValue), + TagInfo(0x0014, "GPSDestLatitude", "Latitude of destination", gpsIfd, gpsTags, printValue), + TagInfo(0x0015, "GPSDestLongitudeRef", "Reference for longitude of destination", gpsIfd, gpsTags, printValue), + TagInfo(0x0016, "GPSDestLongitude", "Longitude of destination", gpsIfd, gpsTags, printValue), + TagInfo(0x0017, "GPSDestBearingRef", "Reference for bearing of destination", gpsIfd, gpsTags, printValue), + TagInfo(0x0018, "GPSDestBearing", "Bearing of destination", gpsIfd, gpsTags, printValue), + TagInfo(0x0019, "GPSDestDistanceRef", "Reference for distance to destination", gpsIfd, gpsTags, printValue), + TagInfo(0x001a, "GPSDestDistance", "Distance to destination", gpsIfd, gpsTags, printValue), + TagInfo(0x001b, "GPSProcessingMethod", "Name of GPS processing method", gpsIfd, gpsTags, printValue), + TagInfo(0x001c, "GPSAreaInformation", "Name of GPS area", gpsIfd, gpsTags, printValue), + TagInfo(0x001d, "GPSDateStamp", "GPS date", gpsIfd, gpsTags, printValue), + TagInfo(0x001e, "GPSDifferential", "GPS differential correction", gpsIfd, gpsTags, printValue), // End of list marker - TagInfo(0xffff, "(UnknownGpsTag)", "Unknown GPSInfo tag", ifdIdNotSet, sectionIdNotSet) + TagInfo(0xffff, "(UnknownGpsTag)", "Unknown GPSInfo tag", ifdIdNotSet, sectionIdNotSet, printNull) }; // Exif Interoperability IFD Tags static const TagInfo iopTagInfo[] = { - TagInfo(0x0001, "InteroperabilityIndex", "Interoperability Identification", iopIfd, iopTags), - TagInfo(0x0002, "InteroperabilityVersion", "Interoperability version", iopIfd, iopTags), - TagInfo(0x1000, "RelatedImageFileFormat", "File format of image file", iopIfd, iopTags), - TagInfo(0x1001, "RelatedImageWidth", "Image width", iopIfd, iopTags), - TagInfo(0x1002, "RelatedImageLength", "Image height", iopIfd, iopTags), + TagInfo(0x0001, "InteroperabilityIndex", "Interoperability Identification", iopIfd, iopTags, printValue), + TagInfo(0x0002, "InteroperabilityVersion", "Interoperability version", iopIfd, iopTags, printValue), + TagInfo(0x1000, "RelatedImageFileFormat", "File format of image file", iopIfd, iopTags, printValue), + TagInfo(0x1001, "RelatedImageWidth", "Image width", iopIfd, iopTags, printValue), + TagInfo(0x1002, "RelatedImageLength", "Image height", iopIfd, iopTags, printValue), // End of list marker - TagInfo(0xffff, "(UnknownIopTag)", "Unknown Exif Interoperability tag", ifdIdNotSet, sectionIdNotSet) + TagInfo(0xffff, "(UnknownIopTag)", "Unknown Exif Interoperability tag", ifdIdNotSet, sectionIdNotSet, printNull) }; // Tag lookup lists with tag names, desc and where they (preferably) belong to; @@ -406,6 +409,13 @@ namespace Exif { return std::make_pair(tag, ifdId); } // ExifTags::decomposeKey + PrintFct ExifTags::printFct(uint16 tag, IfdId ifdId) + { + int idx = tagInfoIdx(tag, ifdId); + if (idx == -1) throw Error("No taginfo for IFD"); + return tagInfos_[ifdId][idx].printFct_; + } + void ExifTags::taglist() { for (int i=0; ifdTagInfo[i].tag_ != 0xffff; ++i) { @@ -467,4 +477,317 @@ namespace Exif { return is; } + std::ostream& printNull(std::ostream& os, const Value& value) + { + return os << "(NULL print function)"; + } + + std::ostream& printValue(std::ostream& os, const Value& value) + { + return os << value; + } + + std::ostream& printLong(std::ostream& os, const Value& value) + { + return os << value.toLong(); + } + + // Todo: Cleanup needed + std::ostream& printFloat(std::ostream& os, const Value& value) + { + const URationalValue* ur = dynamic_cast(&value); + if (ur) { + if (ur->value_[0].second != 0) { + return os << (float)ur->value_[0].first / ur->value_[0].second; + } + else { + return os << value; + } + } + + const RationalValue* sr = dynamic_cast(&value); + if (sr) { + if (sr->value_[0].second != 0) { + return os << (float)sr->value_[0].first / sr->value_[0].second; + } + else { + return os << value; + } + } + + return os << value; + } + + std::ostream& print0x0103(std::ostream& os, const Value& value) + { + long compression = value.toLong(); + switch (compression) { + case 1: os << "Uncompressed"; break; + case 6: os << "JPEG compression"; break; + default: os << compression; break; + } + return os; + } + + std::ostream& print0x0106(std::ostream& os, const Value& value) + { + long photo = value.toLong(); + switch (photo) { + case 2: os << "RGB"; break; + case 6: os << "YCbCr"; break; + default: os << photo; break; + } + return os; + } + + std::ostream& print0x0213(std::ostream& os, const Value& value) + { + long position = value.toLong(); + switch (position) { + case 1: os << "Centered"; break; + case 2: os << "Co-sited"; break; + default: os << position; break; + } + return os; + } + + std::ostream& printUnit(std::ostream& os, const Value& value) + { + long unit = value.toLong(); + switch (unit) { + case 2: os << "Inch"; break; + case 3: os << "Centimeter"; break; + default: os << unit; break; + } + return os; + } + + std::ostream& print0x829a(std::ostream& os, const Value& value) + { + return os << value << " s"; + } + + std::ostream& print0x829d(std::ostream& os, const Value& value) + { + const URationalValue* fnumber = dynamic_cast(&value); + if (fnumber) { + os << "f/" + << (float)fnumber->value_[0].first / fnumber->value_[0].second; + } + else { + os << value; + } + return os; + } + + std::ostream& print0x8822(std::ostream& os, const Value& value) + { + long program = value.toLong(); + switch (program) { + case 0: os << "Not defined"; break; + case 1: os << "Manual"; break; + case 2: os << "Normal program"; break; + case 3: os << "Aperture priority"; break; + case 4: os << "Shutter priority"; break; + case 5: os << "Creative program"; break; + case 6: os << "Action program"; break; + case 7: os << "Portrait mode"; break; + case 8: os << "Landscape mode"; break; + default: os << program; break; + } + return os; + } + + std::ostream& print0x9101(std::ostream& os, const Value& value) + { + for (long i = 0; i < value.count(); ++i) { + long l = value.toLong(i); + switch (l) { + case 0: break; + case 1: os << "Y"; break; + case 2: os << "Cb"; break; + case 3: os << "Cr"; break; + case 4: os << "R"; break; + case 5: os << "G"; break; + case 6: os << "B"; break; + default: os << l; break; + } + } + return os; + } + + std::ostream& print0x9206(std::ostream& os, const Value& value) + { + const URationalValue* distance = dynamic_cast(&value); + if (distance) { + if (distance->value_[0].first == 0) { + os << "Unknown"; + } + else if (distance->value_[0].first == 0xffffffff) { + os << "Infinity"; + } + else { + std::ostringstream oss; + oss.copyfmt(os); + os << std::fixed << std::setprecision(2) + << (float)distance->value_[0].first / distance->value_[0].second + << " m"; + os.copyfmt(oss); + } + } + else { + os << value; + } + return os; + } + + std::ostream& print0x9207(std::ostream& os, const Value& value) + { + long mode = value.toLong(); + switch (mode) { + case 0: os << "Unknown"; break; + case 1: os << "Average"; break; + case 2: os << "Center weighted average"; break; + case 3: os << "Spot"; break; + case 4: os << "Multispot"; break; + case 5: os << "Pattern"; break; + case 6: os << "Partial"; break; + default: os << mode; break; + } + return os; + } + + std::ostream& print0x9209(std::ostream& os, const Value& value) + { + long flash = value.toLong(); + switch (flash) { + case 0x00: os << "No"; break; + case 0x01: os << "Yes"; break; + case 0x05: os << "Strobe return light not detected"; break; + case 0x07: os << "Strobe return light detected"; break; + case 0x09: os << "Yes, compulsory"; break; + case 0x0d: os << "Yes, compulsory, return light not detected"; break; + case 0x0f: os << "Yes, compulsory, return light detected"; break; + case 0x10: os << "No, compulsory"; break; + case 0x18: os << "No, auto"; break; + case 0x19: os << "Yes, auto"; break; + case 0x1d: os << "Yes, auto, return light not detected"; break; + case 0x1f: os << "Yes, auto, return light detected"; break; + case 0x20: os << "No flash function"; break; + case 0x41: os << "Yes, red-eye reduction"; break; + case 0x45: os << "Yes, red-eye reduction, return light not detected"; break; + case 0x47: os << "Yes, red-eye reduction, return light detected"; break; + case 0x49: os << "Yes, compulsory, red-eye reduction"; break; + case 0x4d: os << "Yes, compulsory, red-eye reduction, return light not detected"; break; + case 0x4f: os << "Yes, compulsory, red-eye reduction, return light detected"; break; + case 0x59: os << "Yes, auto, red-eye reduction"; break; + case 0x5d: os << "Yes, auto, red-eye reduction, return light not detected"; break; + case 0x5f: os << "Yes, auto, red-eye reduction, return light detected"; break; + default: os << flash; break; + } + return os; + } + + std::ostream& print0x920a(std::ostream& os, const Value& value) + { + const URationalValue* length = dynamic_cast(&value); + if (length) { + std::ostringstream oss; + oss.copyfmt(os); + os << std::fixed << std::setprecision(1) + << (float)length->value_[0].first / length->value_[0].second + << " mm"; + os.copyfmt(oss); + } + else { + os << value; + } + return os; + } + + std::ostream& print0xa001(std::ostream& os, const Value& value) + { + long space = value.toLong(); + switch (space) { + case 1: os << "sRGB"; break; + case 0xffff: os << "Uncalibrated"; break; + default: os << space; break; + } + return os; + } + + std::ostream& print0xa217(std::ostream& os, const Value& value) + { + long method = value.toLong(); + switch (method) { + case 1: os << "Not defined"; break; + case 2: os << "One-chip color area"; break; + case 3: os << "Two-chip color area"; break; + case 4: os << "Three-chip color area"; break; + case 5: os << "Color sequential area"; break; + case 7: os << "Trilinear sensor"; break; + case 8: os << "Color sequential linear"; break; + default: os << method; break; + } + return os; + } + + std::ostream& print0xa402(std::ostream& os, const Value& value) + { + long mode = value.toLong(); + switch (mode) { + case 0: os << "Auto"; break; + case 1: os << "Manual"; break; + case 2: os << "Auto bracket"; break; + default: os << mode; break; + } + return os; + } + + std::ostream& print0xa403(std::ostream& os, const Value& value) + { + long wb = value.toLong(); + switch (wb) { + case 0: os << "Auto"; break; + case 1: os << "Manual"; break; + default: os << wb; break; + } + return os; + } + + std::ostream& print0xa404(std::ostream& os, const Value& value) + { + const URationalValue* zoom = dynamic_cast(&value); + if (zoom) { + if (zoom->value_[0].second == 0) { + os << "Digital zoom not used"; + } + else { + std::ostringstream oss; + oss.copyfmt(os); + os << std::fixed << std::setprecision(1) + << (float)zoom->value_[0].first / zoom->value_[0].second; + os.copyfmt(oss); + } + } + else { + os << value; + } + return os; + + } + + std::ostream& print0xa406(std::ostream& os, const Value& value) + { + long scene = value.toLong(); + switch (scene) { + case 0: os << "Standard"; break; + case 1: os << "Landscape"; break; + case 2: os << "Portrait"; break; + case 3: os << "Night scene"; break; + default: os << scene; break; + } + return os; + } + } // namespace Exif diff --git a/src/tags.hpp b/src/tags.hpp index a3a04959..a9859a41 100644 --- a/src/tags.hpp +++ b/src/tags.hpp @@ -21,7 +21,7 @@ /*! @file tags.hpp @brief %Exif tag and type information - @version $Name: $ $Revision: 1.10 $ + @version $Name: $ $Revision: 1.11 $ @author Andreas Huggel (ahu) ahuggel@gmx.net @date 15-Jan-04, ahu: created @@ -41,6 +41,10 @@ // namespace extensions namespace Exif { +// ***************************************************************************** +// class declarations + class Value; + // ***************************************************************************** // type definitions @@ -58,6 +62,9 @@ namespace Exif { //! 8 byte signed rational type. typedef std::pair Rational; + //! Type for a function pointer for functions interpreting the tag value + typedef std::ostream& (*PrintFct)(std::ostream&, const Value&); + //! Type identifiers for IFD format types enum TypeId { invalid, unsignedByte, asciiString, unsignedShort, unsignedLong, unsignedRational, invalid6, undefined, @@ -141,13 +148,15 @@ namespace Exif { const char* name, const char* desc, IfdId ifdId, - SectionId sectionId + SectionId sectionId, + PrintFct printFct ); uint16 tag_; //!< Tag const char* name_; //!< One word tag label const char* desc_; //!< Short tag description IfdId ifdId_; //!< Link to the (prefered) IFD SectionId sectionId_; //!< Section id + PrintFct printFct_; //!< Pointer to tag print function }; // struct TagInfo //! Container for %Exif tag information. Implemented as a static class. @@ -228,10 +237,11 @@ namespace Exif { item item, section name and tag name parts. */ static std::pair decomposeKey(const std::string& key); - + //! Return the print function for the tag, IFD id combination + static PrintFct printFct(uint16 tag, IfdId ifdId); //! Print a list of all tags to standart output static void taglist(); - + private: static int tagInfoIdx(uint16 tag, IfdId ifdId); static int tagInfoIdx(const std::string& tagName, IfdId ifdId); @@ -287,6 +297,58 @@ namespace Exif { return os.str(); } + //! @name Functions printing interpreted tag values + //@{ + //! NULL print function, prints a constant error message + std::ostream& printNull(std::ostream& os, const Value& value); + //! Default print function, using the Value output operator + std::ostream& printValue(std::ostream& os, const Value& value); + //! Print the value converted to a long + std::ostream& printLong(std::ostream& os, const Value& value); + //! Print a Rational or URational value in floating point format + std::ostream& printFloat(std::ostream& os, const Value& value); + //! Print the unit for measuring X and Y resolution + std::ostream& printUnit(std::ostream& os, const Value& value); + + //! Print the compression scheme used for the image data + std::ostream& print0x0103(std::ostream& os, const Value& value); + //! Print the pixel composition + std::ostream& print0x0106(std::ostream& os, const Value& value); + //! Print the YCbCrPositioning + std::ostream& print0x0213(std::ostream& os, const Value& value); + //! Print the Exposure time + std::ostream& print0x829a(std::ostream& os, const Value& value); + //! Print the F number + std::ostream& print0x829d(std::ostream& os, const Value& value); + //! Print the Exposure mode + std::ostream& print0x8822(std::ostream& os, const Value& value); + //! Print components configuration specific to compressed data + std::ostream& print0x9101(std::ostream& os, const Value& value); + //! Print the subject distance + std::ostream& print0x9206(std::ostream& os, const Value& value); + //! Print the metering mode + std::ostream& print0x9207(std::ostream& os, const Value& value); + //! Print the flash status + std::ostream& print0x9209(std::ostream& os, const Value& value); + //! Print the actual focal length of the lens + std::ostream& print0x920a(std::ostream& os, const Value& value); + //! Print color space information + std::ostream& print0xa001(std::ostream& os, const Value& value); + //! Print info on image sensor type on the camera or input device + std::ostream& print0xa217(std::ostream& os, const Value& value); + //! Print the exposure mode + std::ostream& print0xa402(std::ostream& os, const Value& value); + //! Print white balance information + std::ostream& print0xa403(std::ostream& os, const Value& value); + //! Print digital zoom ratio + std::ostream& print0xa404(std::ostream& os, const Value& value); + //! Print scene capture type + std::ostream& print0xa406(std::ostream& os, const Value& value); + + // Todo: Copyright (0x8298) + // Todo: UserComment (0x9286) + + //@} } // namespace Exif #endif // #ifndef TAGS_HPP_