Added more tag descriptions and better handling thereof

This commit is contained in:
Andreas Huggel 2004-01-15 07:52:19 +00:00
parent c0810540f3
commit ffa409cb78
6 changed files with 470 additions and 141 deletions

View File

@ -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

View File

@ -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 <iostream>
@ -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; i<n; ++i) {
Metadatum e;
e.ifdId_ = ifdId_;
@ -307,7 +236,7 @@ namespace Exif {
e.count_ = getULong(buf+o+4, byteOrder);
// offset will be converted to a relative offset below
e.offset_ = getULong(buf+o+8, byteOrder);
e.size_ = e.count_ * tagDataFormat[e.type_].size_;
e.size_ = e.count_ * e.typeSize();
// data_ is set later, see below
entries_.push_back(e);
o += 12;
@ -356,7 +285,7 @@ namespace Exif {
int rc = 0;
Metadata::const_iterator pos;
Metadata::const_iterator end = entries_.end();
pos = std::find_if(entries_.begin(), end, matchTag(tag));
pos = std::find_if(entries_.begin(), end, FindMetadatumByTag(tag));
if (pos != end) {
rc = dest.read(buf + pos->offset_, 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()

View File

@ -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 <string>
#include <vector>
#include <iostream>
#include <iosfwd>
// *****************************************************************************
// 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<Metadatum> 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_;

View File

@ -1,5 +1,6 @@
#include "exif.h"
#include <iostream>
#include <iomanip>
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;
}

275
src/tags.cc Normal file
View File

@ -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 {
}

108
src/tags.h Normal file
View File

@ -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_