From ffa409cb781e1cd07568704662a81f021892ca54 Mon Sep 17 00:00:00 2001 From: Andreas Huggel Date: Thu, 15 Jan 2004 07:52:19 +0000 Subject: [PATCH] Added more tag descriptions and better handling thereof --- src/Makefile | 4 +- src/exif.cc | 99 +++-------------- src/exif.h | 97 ++++++++--------- src/exiftest.cc | 28 ++++- src/tags.cc | 275 ++++++++++++++++++++++++++++++++++++++++++++++++ src/tags.h | 108 +++++++++++++++++++ 6 files changed, 470 insertions(+), 141 deletions(-) create mode 100644 src/tags.cc create mode 100644 src/tags.h diff --git a/src/Makefile b/src/Makefile index dfa0268d..1ac98293 100644 --- a/src/Makefile +++ b/src/Makefile @@ -8,7 +8,7 @@ # # RCS information # $Name: $ -# $Revision: 1.1 $ +# $Revision: 1.2 $ # # Description: # Do NOT change this file! All system specific settings and configs @@ -40,7 +40,7 @@ include $(top_srcdir)/config.mk CCHDR = # Add library C++ source files to this list -CCSRC = exif.cc utils.cc +CCSRC = exif.cc tags.cc utils.cc # Add source files of applications to this list BINSRC = exiftest.cc diff --git a/src/exif.cc b/src/exif.cc index b76b1112..425b8f5d 100644 --- a/src/exif.cc +++ b/src/exif.cc @@ -1,10 +1,9 @@ // ***************************************************************** -*- C++ -*- /* * Copyright (c) 2004 Andreas Huggel - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.ibm.com/developerworks/oss/CPLv1.0.htm + * + * Todo: Insert license blabla here + * */ /* Author(s): Andreas Huggel (ahu) @@ -13,13 +12,12 @@ RCS information $Name: $ - $Revision: 1.1 $ + $Revision: 1.2 $ */ // ***************************************************************************** // included header files #include "exif.h" - -// + PMT includes +#include "tags.h" // + standard includes #include @@ -167,79 +165,9 @@ namespace Exif { ul2Data(buf+4, offset_, byteOrder_); } - Format::Format(uint16 type, const std::string& name, long size) - : type_(type), name_(name), size_(size) - { - } - - //! Lookup list of IFD tag data formats and their properties - static const Format tagDataFormat[] = { - Format( 0, "invalid", 0), - Format( 1, "unsigned byte", 1), - Format( 2, "ascii strings", 1), - Format( 3, "unsigned short", 2), - Format( 4, "unsigned long", 4), - Format( 5, "unsigned rational", 8), - Format( 6, "signed byte", 1), - Format( 7, "undefined", 1), - Format( 8, "signed short", 2), - Format( 9, "signed long", 4), - Format(10, "signed rational", 8), - Format(11, "single float", 4), - Format(12, "double float", 8) - }; - - TagInfo::TagInfo( - uint16 tag, - const std::string& fieldName, - const std::string& tagName, - IfdId ifdId, - TagSection tagSection - ) - : tag_(tag), fieldName_(fieldName), tagName_(tagName), - ifdId_(ifdId), tagSection_(tagSection) - { - } - - //! Lookup list with tags, their names and where they belong to - static const TagInfo tagInfo[] = { - TagInfo(0x0100, "ImageWidth", "Image width", ifd0, ifd0Tiff), - TagInfo(0x0101, "ImageLength", "Image height", ifd0, ifd0Tiff), - TagInfo(0x0102, "BitsPerSample", "Number of bits per component", ifd0, ifd0Tiff), - TagInfo(0x0103, "Compression", "Compression scheme", ifd0, ifd0Tiff), - TagInfo(0x0106, "PhotometricInterpretation", "Pixel composition", ifd0, ifd0Tiff), - TagInfo(0x010e, "ImageDescription", "Image title", ifd0, ifd0Tiff), - TagInfo(0x010f, "Make", "Manufacturer of image input equipment", ifd0, ifd0Tiff), - TagInfo(0x0110, "Model", "Model of image input equipment", ifd0, ifd0Tiff), - TagInfo(0x0111, "StripOffsets", "Image data location", ifd0, ifd0Tiff), - TagInfo(0x0112, "Orientation", "Orientation of image", ifd0, ifd0Tiff), - TagInfo(0x0115, "SamplesPerPixel", "Number of components", ifd0, ifd0Tiff), - TagInfo(0x0116, "RowsPerStrip", "Number of rows per strip", ifd0, ifd0Tiff), - TagInfo(0x0117, "StripByteCounts", "Bytes per compressed strip", ifd0, ifd0Tiff), - TagInfo(0x011a, "XResolution", "Image resolution in width direction", ifd0, ifd0Tiff), - TagInfo(0x011b, "YResolution", "Image resolution in height direction", ifd0, ifd0Tiff), - TagInfo(0x011c, "PlanarConfiguration", "Image data arrangement", ifd0, ifd0Tiff), - TagInfo(0x0128, "ResolutionUnit", "Unit of X and Y resolution", ifd0, ifd0Tiff), - TagInfo(0x012d, "TransferFunction", "Transfer function", ifd0, ifd0Tiff), - TagInfo(0x0131, "Software", "Software used", ifd0, ifd0Tiff), - TagInfo(0x0132, "DateTime", "File change date and time", ifd0, ifd0Tiff), - TagInfo(0x013b, "Artist", "Person who created the image", ifd0, ifd0Tiff), - TagInfo(0x013e, "WhitePoint", "White point chromaticity", ifd0, ifd0Tiff), - TagInfo(0x013f, "PrimaryChromaticities", "Chromaticities of primaries", ifd0, ifd0Tiff), - TagInfo(0x0201, "JPEGInterchangeFormat", "Offset to JPEG SOI", ifd0, ifd0Tiff), - TagInfo(0x0202, "JPEGInterchangeFormatLength", "Bytes of JPEG data", ifd0, ifd0Tiff), - TagInfo(0x0211, "YCbCrCoefficients", "Color space transformation matrix coefficients", ifd0, ifd0Tiff), - TagInfo(0x0212, "YCbCrSubSampling", "Subsampling ratio of Y to C", ifd0, ifd0Tiff), - TagInfo(0x0213, "YCbCrPositioning", "Y and C positioning", ifd0, ifd0Tiff), - TagInfo(0x0214, "ReferenceBlackWhite", "Pair of black and white reference values", ifd0, ifd0Tiff), - TagInfo(0x8298, "Copyright", "Copyright holder", ifd0, ifd0Tiff), - TagInfo(0x8769, "ExifTag", "Exif IFD Pointer", ifd0, ifd0Tiff), - TagInfo(0x8825, "GPSTag", "GPSInfo IFD Pointer", ifd0, ifd0Tiff) - }; - Metadatum::Metadatum() : tag_(0), type_(0), count_(0), offset_(0), size_(0), - ifdId_(unknown), ifdIdx_(-1), data_(0) + ifdId_(IfdIdNotSet), ifdIdx_(-1), data_(0) { } @@ -285,8 +213,8 @@ namespace Exif { } return *this; - } - + } // Metadatum::operator= + Ifd::Ifd(IfdId ifdId) : ifdId_(ifdId), offset_(0), next_(0), size_(0) { @@ -298,6 +226,7 @@ namespace Exif { int n = getUShort(buf, byteOrder); long o = 2; + entries_.clear(); for (int i=0; ioffset_, byteOrder, pos->offset_); } @@ -429,7 +358,7 @@ namespace Exif { Metadata::const_iterator i = b; for (; i != e; ++i) { std::ostringstream offset; - if (tagDataFormat[i->type_].size_ * i->count_ <= 4) { + if (i->typeSize() * i->count_ <= 4) { // Minor cheat here: we use data_ instead of offset_ to avoid // having to invoke ul2Data() which would require byte order. offset << std::setw(2) << std::setfill('0') << std::hex @@ -451,8 +380,8 @@ namespace Exif { << " 0x" << std::setw(4) << std::setfill('0') << std::hex << std::right << i->tag_ << " " << std::setw(17) << std::setfill(' ') - << std::left << tagDataFormat[i->type_].name_ - << " (" << std::dec << tagDataFormat[i->type_].size_ << ")" + << std::left << i->typeName() + << " (" << std::dec << i->typeSize() << ")" << " " << std::setw(6) << std::setfill(' ') << std::dec << std::right << i->count_ << " " << offset.str() diff --git a/src/exif.h b/src/exif.h index ecc67d32..a631bb6e 100644 --- a/src/exif.h +++ b/src/exif.h @@ -2,18 +2,13 @@ /* * Copyright (c) 2004 Andreas Huggel. All rights reserved. * - * This file may be distributed and/or modified under the terms of the - * GNU General Public License version 2 as published by the Free Software - * Foundation and appearing in the file license-gpl.txt included in the - * packaging of this file. + * Todo: Insert license blabla here * - * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ /*! @file exif.h @brief Encoding and decoding of %Exif data - @version $Name: $ $Revision: 1.1 $ + @version $Name: $ $Revision: 1.2 $ @author Andreas Huggel (ahu) @date 09-Jan-03, ahu: created */ @@ -22,10 +17,12 @@ // ***************************************************************************** // included header files +#include "tags.h" + // + standard includes #include #include -#include +#include // ***************************************************************************** // namespace extensions @@ -35,15 +32,6 @@ namespace Exif { // ***************************************************************************** // type definitions - //! 2 byte unsigned integer type. - typedef unsigned short uint16; - //! 4 byte unsigned integer type. - typedef unsigned long uint32; - //! 2 byte signed integer type. - typedef short int16; - //! 4 byte signed integer type. - typedef long int32; - // ***************************************************************************** // class definitions @@ -102,11 +90,11 @@ namespace Exif { //! @name Accessors //@{ //! Returns the size of the %Exif data buffer - long sizeExifData() { return sizeExifData_; } + long sizeExifData() const { return sizeExifData_; } //! Returns the offset of the %Exif data buffer from SOI - long offsetExifData() { return offsetExifData_; } + long offsetExifData() const { return offsetExifData_; } //! Returns a read-only pointer to the %Exif data buffer - const char* exifData() { return exifData_; } + const char* exifData() const { return exifData_; } //@} private: @@ -154,46 +142,25 @@ namespace Exif { uint32 offset_; }; // class TiffHeader - //! Description of a format for a metadatum - struct Format { - //! Constructor - Format(uint16 type, const std::string& name, long size); - uint16 type_; //!< Format type id - std::string name_; //!< Name of the format - long size_; //!< Bytes per data entry - }; // struct Format - - //! Type to specify the IFD to which a metadata belongs - enum IfdId { unknown, ifd0, ifd1, exifIfd, gpsIfd, makerNoteIfd, exifIopIfd, ifd1IopIfd }; - - enum TagSection { ifd0Tiff }; - - struct TagInfo { - //! Constructor - TagInfo( - uint16 tag, - const std::string& fieldName, - const std::string& tagName, - IfdId ifdId, - TagSection tagSection - ); - uint16 tag_; - std::string fieldName_; - std::string tagName_; - IfdId ifdId_; - TagSection tagSection_; - }; - /*! @brief Information related to one %Exif tag. */ - struct Metadatum { + class Metadatum { + public: Metadatum(); //!< Constructor ~Metadatum(); //!< Destructor Metadatum(const Metadatum& rhs); //!< Copy constructor Metadatum& operator=(const Metadatum& rhs); //!< Assignment operator + //! Returns the name of the type + const char* tagName() const { return ExifTags::tagName(tag_, ifdId_); } + //! Returns the name of the type + const char* typeName() const { return ExifTags::typeName(type_); } + //! Returns the size in bytes of one element of this type + long typeSize() const { return ExifTags::typeSize(type_); } + + public: uint16 tag_; //!< Tag value uint16 type_; //!< Type of the data uint32 count_; //!< Number of components @@ -204,11 +171,28 @@ namespace Exif { int ifdIdx_; //!< Position in the IFD (-1: not set) char* data_; //!< Pointer to the data + }; // struct Metadatum //! Container type to hold all metadata typedef std::vector Metadata; + //! Unary predicate that matches a Metadatum with a given tag + class FindMetadatumByTag { + public: + //! Constructor, initializes the object with the tag to look for + FindMetadatumByTag(uint16 tag) : tag_(tag) {} + /*! + @brief Returns true if the tag of the argument metadatum is equal + to that of the object. + */ + bool operator()(const Metadatum& metadatum) const + { return tag_ == metadatum.tag_; } + + private: + uint16 tag_; + }; + /*! @brief Models an IFD (Image File Directory) @@ -219,7 +203,7 @@ namespace Exif { class Ifd { public: //! Constructor. Allows to set the IFD identifier. - Ifd(IfdId ifdId =unknown); + Ifd(IfdId ifdId =IfdIdNotSet); /*! @brief Read a complete IFD and its data from a data buffer @@ -269,7 +253,7 @@ namespace Exif { @brief Print the IFD in human readable format to the given stream; begin each line with prefix. */ - void print(std::ostream& os =std::cout, const std::string& prefix ="") const; + void print(std::ostream& os, const std::string& prefix ="") const; //! @name Accessors //@{ //! Offset of the IFD from SOI @@ -336,6 +320,13 @@ namespace Exif { //! Add Metadatum src to the Exif metadata void add(const Metadatum& src); + //! Metadata iterator type (const) + typedef Metadata::const_iterator const_iterator; + //! Begin of the metadata + const_iterator begin() const { return metadata_.begin(); } + //! End of the metadata + const_iterator end() const { return metadata_.end(); } + private: long offset_; // Original abs offset of the Exif data TiffHeader tiffHeader_; diff --git a/src/exiftest.cc b/src/exiftest.cc index 0a476e82..9ddc04bf 100644 --- a/src/exiftest.cc +++ b/src/exiftest.cc @@ -1,5 +1,6 @@ #include "exif.h" #include +#include int main(int argc, char* const argv[]) { @@ -9,5 +10,30 @@ int main(int argc, char* const argv[]) } Exif::ExifData exifData; - return exifData.read(argv[1]); + int rc = exifData.read(argv[1]); + + if (rc == 0) { + + Exif::ExifData::const_iterator beg = exifData.begin(); + Exif::ExifData::const_iterator end = exifData.end(); + Exif::ExifData::const_iterator i = beg; + for (; i != end; ++i) { + + std::cout << "0x" + << std::hex << std::setw(4) << std::setfill('0') << std::right + << i->tag_ << " " + << std::setw(27) << std::setfill(' ') << std::left + << i->tagName() << " " + << std::setw(17) << std::setfill(' ') << std::left + << i->typeName() << " " + << std::dec << std::setw(3) << std::setfill(' ') << std::right + << i->count_ << " " + << std::dec << std::setw(3) << std::setfill(' ') << std::right + << i->typeSize() * i->count_ << "\n"; + + } + } + + return rc; + } diff --git a/src/tags.cc b/src/tags.cc new file mode 100644 index 00000000..843793b4 --- /dev/null +++ b/src/tags.cc @@ -0,0 +1,275 @@ +// ***************************************************************** -*- C++ -*- +/* + * Copyright (c) 2004 Andreas Huggel + * + * Todo: Insert license blabla here + * + */ +/* + Author(s): Andreas Huggel (ahu) + History: + 15-Jan-04, ahu: created + + RCS information + $Name: $ + $Revision: 1.1 $ + */ +// ***************************************************************************** +// included header files +#include "tags.h" + +// + standard includes + +// ***************************************************************************** +// local declarations +namespace { + +} + +// ***************************************************************************** +// class member definitions +namespace Exif { + + TagFormat::TagFormat(uint16 type, const char* name, long size) + : type_(type), name_(name), size_(size) + { + } + + //! Lookup list of IFD tag data formats and their properties + const TagFormat ExifTags::tagFormat_[] = { + TagFormat( 0, "invalid", 0), + TagFormat( 1, "unsigned byte", 1), + TagFormat( 2, "ascii strings", 1), + TagFormat( 3, "unsigned short", 2), + TagFormat( 4, "unsigned long", 4), + TagFormat( 5, "unsigned rational", 8), + TagFormat( 6, "signed byte", 1), + TagFormat( 7, "undefined", 1), + TagFormat( 8, "signed short", 2), + TagFormat( 9, "signed long", 4), + TagFormat(10, "signed rational", 8), + TagFormat(11, "single float", 4), + TagFormat(12, "double float", 8) + }; + + TagInfo::TagInfo( + uint16 tag, + const char* name, + const char* desc, + IfdId ifdId, + TagSection section + ) + : tag_(tag), name_(name), desc_(desc), + ifdId_(ifdId), section_(section) + { + } + + //! Lookup list with tags, their names and where they belong to + const TagInfo ExifTags::tagInfo_[] = { + // Exif Interoperability IFD Tags + TagInfo(0x0001, "InteroperabilityIndex", "Interoperability Identification", exifIopIfd, exifIopIfdSection), + TagInfo(0x0002, "InteroperabilityVersion", "Interoperability version", exifIopIfd, exifIopIfdSection), + TagInfo(0x1000, "RelatedImageFileFormat", "File format of image file", exifIopIfd, exifIopIfdSection), + TagInfo(0x1001, "RelatedImageWidth", "Image width", exifIopIfd, exifIopIfdSection), + TagInfo(0x1002, "RelatedImageLength", "Image height", exifIopIfd, exifIopIfdSection), + + // GPS Info Tags + TagInfo(0x0000, "GPSVersionID", "GPS tag version", gpsIfd, gpsIfdSection), + TagInfo(0x0001, "GPSLatitudeRef", "North or South Latitude", gpsIfd, gpsIfdSection), + TagInfo(0x0002, "GPSLatitude", "Latitude", gpsIfd, gpsIfdSection), + TagInfo(0x0003, "GPSLongitudeRef", "East or West Longitude", gpsIfd, gpsIfdSection), + TagInfo(0x0004, "GPSLongitude", "Longitude", gpsIfd, gpsIfdSection), + TagInfo(0x0005, "GPSAltitudeRef", "Altitude reference", gpsIfd, gpsIfdSection), + TagInfo(0x0006, "GPSAltitude", "Altitude", gpsIfd, gpsIfdSection), + TagInfo(0x0007, "GPSTimeStamp", "GPS time (atomic clock)", gpsIfd, gpsIfdSection), + TagInfo(0x0008, "GPSSatellites", "GPS satellites used for measurement", gpsIfd, gpsIfdSection), + TagInfo(0x0009, "GPSStatus", "GPS receiver status", gpsIfd, gpsIfdSection), + TagInfo(0x000a, "GPSMeasureMode", "GPS measurement mode", gpsIfd, gpsIfdSection), + TagInfo(0x000b, "GPSDOP", "Measurement precision", gpsIfd, gpsIfdSection), + TagInfo(0x000c, "GPSSpeedRef", "Speed unit", gpsIfd, gpsIfdSection), + TagInfo(0x000d, "GPSSpeed", "Speed of GPS receiver", gpsIfd, gpsIfdSection), + TagInfo(0x000e, "GPSTrackRef", "Reference for direction of movement", gpsIfd, gpsIfdSection), + TagInfo(0x000f, "GPSTrack", "Direction of movement", gpsIfd, gpsIfdSection), + TagInfo(0x0010, "GPSImgDirectionRef", "Reference for direction of image", gpsIfd, gpsIfdSection), + TagInfo(0x0011, "GPSImgDirection", "Direction of image", gpsIfd, gpsIfdSection), + TagInfo(0x0012, "GPSMapDatum", "Geodetic survey data used", gpsIfd, gpsIfdSection), + TagInfo(0x0013, "GPSDestLatitudeRef", "Reference for latitude of destination", gpsIfd, gpsIfdSection), + TagInfo(0x0014, "GPSDestLatitude", "Latitude of destination", gpsIfd, gpsIfdSection), + TagInfo(0x0015, "GPSDestLongitudeRef", "Reference for longitude of destination", gpsIfd, gpsIfdSection), + TagInfo(0x0016, "GPSDestLongitude", "Longitude of destination", gpsIfd, gpsIfdSection), + TagInfo(0x0017, "GPSDestBearingRef", "Reference for bearing of destination", gpsIfd, gpsIfdSection), + TagInfo(0x0018, "GPSDestBearing", "Bearing of destination", gpsIfd, gpsIfdSection), + TagInfo(0x0019, "GPSDestDistanceRef", "Reference for distance to destination", gpsIfd, gpsIfdSection), + TagInfo(0x001a, "GPSDestDistance", "Distance to destination", gpsIfd, gpsIfdSection), + TagInfo(0x001b, "GPSProcessingMethod", "Name of GPS processing method", gpsIfd, gpsIfdSection), + TagInfo(0x001c, "GPSAreaInformation", "Name of GPS area", gpsIfd, gpsIfdSection), + TagInfo(0x001d, "GPSDateStamp", "GPS date", gpsIfd, gpsIfdSection), + TagInfo(0x001e, "GPSDifferential", "GPS differential correction", gpsIfd, gpsIfdSection), + + // IFD0 Tags + TagInfo(0x0100, "ImageWidth", "Image width", ifd0, ifd0Tiff), + TagInfo(0x0101, "ImageLength", "Image height", ifd0, ifd0Tiff), + TagInfo(0x0102, "BitsPerSample", "Number of bits per component", ifd0, ifd0Tiff), + TagInfo(0x0103, "Compression", "Compression scheme", ifd0, ifd0Tiff), + TagInfo(0x0106, "PhotometricInterpretation", "Pixel composition", ifd0, ifd0Tiff), + TagInfo(0x010e, "ImageDescription", "Image title", ifd0, ifd0Tiff), + TagInfo(0x010f, "Make", "Manufacturer of image input equipment", ifd0, ifd0Tiff), + TagInfo(0x0110, "Model", "Model of image input equipment", ifd0, ifd0Tiff), + TagInfo(0x0111, "StripOffsets", "Image data location", ifd0, ifd0Tiff), + TagInfo(0x0112, "Orientation", "Orientation of image", ifd0, ifd0Tiff), + TagInfo(0x0115, "SamplesPerPixel", "Number of components", ifd0, ifd0Tiff), + TagInfo(0x0116, "RowsPerStrip", "Number of rows per strip", ifd0, ifd0Tiff), + TagInfo(0x0117, "StripByteCounts", "Bytes per compressed strip", ifd0, ifd0Tiff), + TagInfo(0x011a, "XResolution", "Image resolution in width direction", ifd0, ifd0Tiff), + TagInfo(0x011b, "YResolution", "Image resolution in height direction", ifd0, ifd0Tiff), + TagInfo(0x011c, "PlanarConfiguration", "Image data arrangement", ifd0, ifd0Tiff), + TagInfo(0x0128, "ResolutionUnit", "Unit of X and Y resolution", ifd0, ifd0Tiff), + TagInfo(0x012d, "TransferFunction", "Transfer function", ifd0, ifd0Tiff), + TagInfo(0x0131, "Software", "Software used", ifd0, ifd0Tiff), + TagInfo(0x0132, "DateTime", "File change date and time", ifd0, ifd0Tiff), + TagInfo(0x013b, "Artist", "Person who created the image", ifd0, ifd0Tiff), + TagInfo(0x013e, "WhitePoint", "White point chromaticity", ifd0, ifd0Tiff), + TagInfo(0x013f, "PrimaryChromaticities", "Chromaticities of primaries", ifd0, ifd0Tiff), + TagInfo(0x0201, "JPEGInterchangeFormat", "Offset to JPEG SOI", ifd0, ifd0Tiff), + TagInfo(0x0202, "JPEGInterchangeFormatLength", "Bytes of JPEG data", ifd0, ifd0Tiff), + TagInfo(0x0211, "YCbCrCoefficients", "Color space transformation matrix coefficients", ifd0, ifd0Tiff), + TagInfo(0x0212, "YCbCrSubSampling", "Subsampling ratio of Y to C", ifd0, ifd0Tiff), + TagInfo(0x0213, "YCbCrPositioning", "Y and C positioning", ifd0, ifd0Tiff), + TagInfo(0x0214, "ReferenceBlackWhite", "Pair of black and white reference values", ifd0, ifd0Tiff), + TagInfo(0x8298, "Copyright", "Copyright holder", ifd0, ifd0Tiff), + TagInfo(0x8769, "ExifTag", "Exif IFD Pointer", ifd0, ifd0Tiff), + TagInfo(0x8825, "GPSTag", "GPSInfo IFD Pointer", ifd0, ifd0Tiff), + + // IFD1 Tags + TagInfo(0x0100, "ImageWidth", "Image width", ifd1, ifd1Section), + TagInfo(0x0101, "ImageLength", "Image height", ifd1, ifd1Section), + TagInfo(0x0102, "BitsPerSample", "Number of bits per component", ifd1, ifd1Section), + TagInfo(0x0103, "Compression", "Compression scheme", ifd1, ifd1Section), + TagInfo(0x0106, "PhotometricInterpretation", "Pixel composition", ifd1, ifd1Section), + TagInfo(0x010e, "ImageDescription", "Image title", ifd1, ifd1Section), + TagInfo(0x010f, "Make", "Manufacturer of image input equipment", ifd1, ifd1Section), + TagInfo(0x0110, "Model", "Model of image input equipment", ifd1, ifd1Section), + TagInfo(0x0111, "StripOffsets", "Image data location", ifd1, ifd1Section), + TagInfo(0x0112, "Orientation", "Orientation of image", ifd1, ifd1Section), + TagInfo(0x0115, "SamplesPerPixel", "Number of components", ifd1, ifd1Section), + TagInfo(0x0116, "RowsPerStrip", "Number of rows per strip", ifd1, ifd1Section), + TagInfo(0x0117, "StripByteCounts", "Bytes per compressed strip", ifd1, ifd1Section), + TagInfo(0x011a, "XResolution", "Image resolution in width direction", ifd1, ifd1Section), + TagInfo(0x011b, "YResolution", "Image resolution in height direction", ifd1, ifd1Section), + TagInfo(0x011c, "PlanarConfiguration", "Image data arrangement", ifd1, ifd1Section), + TagInfo(0x0128, "ResolutionUnit", "Unit of X and Y resolution", ifd1, ifd1Section), + TagInfo(0x012d, "TransferFunction", "Transfer function", ifd1, ifd1Section), + TagInfo(0x0131, "Software", "Software used", ifd1, ifd1Section), + TagInfo(0x0132, "DateTime", "File change date and time", ifd1, ifd1Section), + TagInfo(0x013b, "Artist", "Person who created the image", ifd1, ifd1Section), + TagInfo(0x013e, "WhitePoint", "White point chromaticity", ifd1, ifd1Section), + TagInfo(0x013f, "PrimaryChromaticities", "Chromaticities of primaries", ifd1, ifd1Section), + TagInfo(0x0201, "JPEGInterchangeFormat", "Offset to JPEG SOI", ifd1, ifd1Section), + TagInfo(0x0202, "JPEGInterchangeFormatLength", "Bytes of JPEG data", ifd1, ifd1Section), + TagInfo(0x0211, "YCbCrCoefficients", "Color space transformation matrix coefficients", ifd1, ifd1Section), + TagInfo(0x0212, "YCbCrSubSampling", "Subsampling ratio of Y to C", ifd1, ifd1Section), + TagInfo(0x0213, "YCbCrPositioning", "Y and C positioning", ifd1, ifd1Section), + TagInfo(0x0214, "ReferenceBlackWhite", "Pair of black and white reference values", ifd1, ifd1Section), + TagInfo(0x8298, "Copyright", "Copyright holder", ifd1, ifd1Section), + TagInfo(0x8769, "ExifTag", "Exif IFD Pointer", ifd1, ifd1Section), + TagInfo(0x8825, "GPSTag", "GPSInfo IFD Pointer", ifd1, ifd1Section), + + // Exif IFD Tags + TagInfo(0x829a, "ExposureTime", "Exposure time", exifIfd, exifIfdSection), + TagInfo(0x829d, "FNumber", "F number", exifIfd, exifIfdSection), + TagInfo(0x8822, "ExposureProgram", "Exposure program", exifIfd, exifIfdSection), + TagInfo(0x8824, "SpectralSensitivity", "Spectral sensitivity", exifIfd, exifIfdSection), + TagInfo(0x8827, "ISOSpeedRatings", "ISO speed ratings", exifIfd, exifIfdSection), + TagInfo(0x8828, "OECF", "Optoelectric coefficient", exifIfd, exifIfdSection), + TagInfo(0x9000, "ExifVersion", "Exif Version", exifIfd, exifIfdSection), + TagInfo(0x9003, "DateTimeOriginal", "Date and time original image was generated", exifIfd, exifIfdSection), + TagInfo(0x9004, "DateTimeDigitized", "Date and time image was made digital data", exifIfd, exifIfdSection), + TagInfo(0x9101, "ComponentsConfiguration", "Meaning of each component", exifIfd, exifIfdSection), + TagInfo(0x9102, "CompressedBitsPerPixel", "Image compression mode", exifIfd, exifIfdSection), + TagInfo(0x9201, "ShutterSpeedValue", "Shutter speed", exifIfd, exifIfdSection), + TagInfo(0x9202, "ApertureValue", "Aperture", exifIfd, exifIfdSection), + TagInfo(0x9203, "BrightnessValue", "Brightness", exifIfd, exifIfdSection), + TagInfo(0x9204, "ExposureBiasValue", "Exposure bias", exifIfd, exifIfdSection), + TagInfo(0x9205, "MaxApertureValue", "Maximum lens aperture", exifIfd, exifIfdSection), + TagInfo(0x9206, "SubjectDistance", "Subject distance", exifIfd, exifIfdSection), + TagInfo(0x9207, "MeteringMode", "Metering mode", exifIfd, exifIfdSection), + TagInfo(0x9208, "LightSource", "Light source", exifIfd, exifIfdSection), + TagInfo(0x9209, "Flash", "Flash", exifIfd, exifIfdSection), + TagInfo(0x920a, "FocalLength", "Lens focal length", exifIfd, exifIfdSection), + TagInfo(0x9214, "SubjectArea", "Subject area", exifIfd, exifIfdSection), + TagInfo(0x927c, "MakerNote", "Manufacturer notes", exifIfd, exifIfdSection), + TagInfo(0x9286, "UserComment", "User comments", exifIfd, exifIfdSection), + TagInfo(0x9290, "SubSecTime", "DateTime subseconds", exifIfd, exifIfdSection), + TagInfo(0x9291, "SubSecTimeOriginal", "DateTimeOriginal subseconds", exifIfd, exifIfdSection), + TagInfo(0x9292, "SubSecTimeDigitized", "DateTimeDigitized subseconds", exifIfd, exifIfdSection), + TagInfo(0xa000, "FlashpixVersion", "Supported Flashpix version", exifIfd, exifIfdSection), + TagInfo(0xa001, "ColorSpace", "Color space information", exifIfd, exifIfdSection), + TagInfo(0xa002, "PixelXDimension", "Valid image width", exifIfd, exifIfdSection), + TagInfo(0xa003, "PixelYDimension", "Valid image height", exifIfd, exifIfdSection), + TagInfo(0xa004, "RelatedSoundFile", "Related audio file", exifIfd, exifIfdSection), + TagInfo(0xa005, "InteroperabilityTag", "Interoperability IFD Pointer", exifIfd, exifIfdSection), + TagInfo(0xa20b, "FlashEnergy", "Flash energy", exifIfd, exifIfdSection), + TagInfo(0xa20c, "SpatialFrequencyResponse", "Spatial frequency response", exifIfd, exifIfdSection), + TagInfo(0xa20e, "FocalPlaneXResolution", "Focal plane X resolution", exifIfd, exifIfdSection), + TagInfo(0xa20f, "FocalPlaneYResolution", "Focal plane Y resolution", exifIfd, exifIfdSection), + TagInfo(0xa210, "FocalPlaneResolutionUnit", "Focal plane resolution unit", exifIfd, exifIfdSection), + TagInfo(0xa214, "SubjectLocation", "Subject location", exifIfd, exifIfdSection), + TagInfo(0xa215, "ExposureIndex", "Exposure index", exifIfd, exifIfdSection), + TagInfo(0xa217, "SensingMethod", "Sensing method", exifIfd, exifIfdSection), + TagInfo(0xa300, "FileSource", "File source", exifIfd, exifIfdSection), + TagInfo(0xa301, "SceneType", "Scene type", exifIfd, exifIfdSection), + TagInfo(0xa302, "CFAPattern", "CFA pattern", exifIfd, exifIfdSection), + TagInfo(0xa401, "CustomRendered", "Custom image processing", exifIfd, exifIfdSection), + TagInfo(0xa402, "ExposureMode", "Exposure mode", exifIfd, exifIfdSection), + TagInfo(0xa403, "WhiteBalance", "White balance", exifIfd, exifIfdSection), + TagInfo(0xa404, "DigitalZoomRatio", "Digital zoom ratio", exifIfd, exifIfdSection), + TagInfo(0xa405, "FocalLengthIn35mmFilm", "Focal length in 35 mm film", exifIfd, exifIfdSection), + TagInfo(0xa406, "SceneCaptureType", "Scene capture type", exifIfd, exifIfdSection), + TagInfo(0xa407, "GainControl", "Gain control", exifIfd, exifIfdSection), + TagInfo(0xa408, "Contrast", "Contrast", exifIfd, exifIfdSection), + TagInfo(0xa409, "Saturation", "Saturation", exifIfd, exifIfdSection), + TagInfo(0xa40a, "Sharpness", "Sharpness", exifIfd, exifIfdSection), + TagInfo(0xa40b, "DeviceSettingDescription", "Device settings description", exifIfd, exifIfdSection), + TagInfo(0xa40c, "SubjectDistanceRange", "Subject distance range", exifIfd, exifIfdSection), + TagInfo(0xa420, "ImageUniqueID", "Unique image ID", exifIfd, exifIfdSection), + + // End of list marker + TagInfo(0xffff, "(Unknown)", "Unknown tag", IfdIdNotSet, TagSectionNotSet) + }; + + int ExifTags::tagInfoIdx(uint16 tag, IfdId ifdId) + { + // Todo: implement a better algorithm + int idx; + for (idx = 0; tagInfo_[idx].tag_ != 0xffff; ++idx) { + if ( tagInfo_[idx].tag_ == tag + && tagInfo_[idx].ifdId_ == ifdId) break; + } + return idx; + } + + const char* ExifTags::tagName(uint16 tag, IfdId ifdId) + { + return tagInfo_[tagInfoIdx(tag, ifdId)].name_; + } + + const char* ExifTags::typeName(uint16 type) + { + return tagFormat_[type].name_; + } + + long ExifTags::typeSize(uint16 type) + { + return tagFormat_[type].size_; + } + + // ************************************************************************* + // free functions + +} // namespace Exif + +// ***************************************************************************** +// local definitions +namespace { + +} diff --git a/src/tags.h b/src/tags.h new file mode 100644 index 00000000..0d687505 --- /dev/null +++ b/src/tags.h @@ -0,0 +1,108 @@ +// ***************************************************************** -*- C++ -*- +/* + * Copyright (c) 2004 Andreas Huggel. All rights reserved. + * + * Todo: Insert license blabla here + * + */ +/*! + @file tags.h + @brief %Exif tag and type information + @version $Name: $ $Revision: 1.1 $ + @author Andreas Huggel (ahu) + @date 15-Jan-03, ahu: created + */ +#ifndef _TAGS_H_ +#define _TAGS_H_ + +// ***************************************************************************** +// included header files + +// + standard includes + +// ***************************************************************************** +// namespace extensions +namespace Exif { + +// ***************************************************************************** +// type definitions + + //! 2 byte unsigned integer type. + typedef unsigned short uint16; + //! 4 byte unsigned integer type. + typedef unsigned long uint32; + //! 2 byte signed integer type. + typedef short int16; + //! 4 byte signed integer type. + typedef long int32; + + //! Type to specify the IFD to which a metadata belongs + enum IfdId { IfdIdNotSet, + ifd0, ifd1, exifIfd, gpsIfd, + makerNoteIfd, exifIopIfd, ifd1IopIfd }; + + //! Section identifiers to logically group tags + enum TagSection { TagSectionNotSet, + ifd0Tiff, ifd1Section, exifIfdSection, gpsIfdSection, + exifIopIfdSection }; + +// ***************************************************************************** +// class definitions + + //! Description of the format of a metadatum + struct TagFormat { + //! Constructor + TagFormat(uint16 type, const char* name, long size); + uint16 type_; //!< Format type id + const char* name_; //!< Name of the format + long size_; //!< Bytes per data entry + }; // struct TagFormat + + //! Tag information + struct TagInfo { + //! Constructor + TagInfo( + uint16 tag, + const char* name, + const char* desc, + IfdId ifdId, + TagSection section + ); + uint16 tag_; //!< Tag + const char* name_; //!< One word tag label + const char* desc_; //!< Short tag description + IfdId ifdId_; //!< Link to the IFD + TagSection section_; //!< Section id + }; // struct TagInfo + + //! Container for Exif tag information. Implemented as a static class. + class ExifTags { + //! Prevent construction: not implemented. + ExifTags() {} + //! Prevent copy-construction: not implemented. + ExifTags(const ExifTags& rhs); + //! Prevent assignment: not implemented. + ExifTags& operator=(const ExifTags& rhs); + + public: + //! Returns the name of the tag + static const char* tagName(uint16 tag, IfdId ifdId); + //! Returns the name of the type + static const char* typeName(uint16 type); + //! Returns the size in bytes of one element of this type + static long typeSize(uint16 type); + + private: + static int tagInfoIdx(uint16 tag, IfdId ifdId); + + static const TagFormat tagFormat_[]; + static const TagInfo tagInfo_[]; + + }; + +// ***************************************************************************** +// free functions + +} // namespace Exif + +#endif // #ifndef _TAGS_H_