From 0da34a9587cf11a4473ea5739613b8626495c42a Mon Sep 17 00:00:00 2001 From: Andreas Huggel Date: Sat, 11 Jun 2005 12:10:40 +0000 Subject: [PATCH] Updated Olympus makernote, added a preliminary "tag translator" --- src/olympusmn.cpp | 230 +++++++++++++++++++++++++--------------------- src/olympusmn.hpp | 21 +++-- src/tags.cpp | 18 ++++ src/tags.hpp | 32 +++++++ 4 files changed, 188 insertions(+), 113 deletions(-) diff --git a/src/olympusmn.cpp b/src/olympusmn.cpp index 0c680f0d..3c4a6575 100644 --- a/src/olympusmn.cpp +++ b/src/olympusmn.cpp @@ -24,9 +24,7 @@ Author(s): Will Stokes (wuz) Andreas Huggel (ahu) History: 10-Mar-05, wuz: created - Credits: Olympus MakerNote implemented according to the specification - in "???" by ???. - + Credits: See header file. */ // ***************************************************************************** @@ -67,49 +65,49 @@ namespace Exiv2 { // Olympus Tag Info const TagInfo OlympusMakerNote::tagInfo_[] = { - TagInfo(0x0200, "SpecialMode", "Picture taking mode (First Value: 0=normal, 2=fast, 3=panorama Second Value: sequence number Third Value: panorma direction (1=left to right, 2=right to left, 3 = bottom to top, 4=top to bottom)", olympusIfdId, makerTags, unsignedLong, printValue), - TagInfo(0x0201, "JpegQual", "JPEG quality 1=SQ 2=HQ 3=SHQ", olympusIfdId, makerTags, unsignedShort, printValue), - TagInfo(0x0202, "Macro", "Macro mode 0=normal, 1=macro", olympusIfdId, makerTags, unsignedShort, printValue), - TagInfo(0x0203, "0x0203", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue), - TagInfo(0x0204, "DigiZoom", "Digital Zoom Ratio 0=normal 2=2x digital zoom", olympusIfdId, makerTags, unsignedRational, printValue), - TagInfo(0x0205, "0x0205", "Unknown", olympusIfdId, makerTags, unsignedRational, printValue), + TagInfo(0x0200, "SpecialMode", "Picture taking mode", olympusIfdId, makerTags, unsignedLong, print0x0200), + TagInfo(0x0201, "Quality", "Jpeg quality", olympusIfdId, makerTags, unsignedShort, print0x0201), + TagInfo(0x0202, "Macro", "Macro mode", olympusIfdId, makerTags, unsignedShort, print0x0202), + TagInfo(0x0203, "BWMode", "Black and White Mode", olympusIfdId, makerTags, unsignedShort, printValue), + TagInfo(0x0204, "DigitalZoom", "Digital Zoom Ratio", olympusIfdId, makerTags, unsignedRational, print0x0204), + TagInfo(0x0205, "FocalPlaneDiagonal", "Focal Plane Diagonal", olympusIfdId, makerTags, unsignedRational, printValue), TagInfo(0x0206, "0x0206", "Unknown", olympusIfdId, makerTags, signedShort, printValue), - TagInfo(0x0207, "SoftwareRelease", "Software firmware version", olympusIfdId, makerTags, asciiString, printValue), - TagInfo(0x0208, "PictInfo", "ASCII format data such as [PictureInfo]", olympusIfdId, makerTags, asciiString, printValue), + TagInfo(0x0207, "FirmwareVersion", "Software firmware version", olympusIfdId, makerTags, asciiString, printValue), + TagInfo(0x0208, "PictureInfo", "ASCII format data such as [PictureInfo]", olympusIfdId, makerTags, asciiString, printValue), TagInfo(0x0209, "CameraID", "CameraID data", olympusIfdId, makerTags, undefined, printValue), - TagInfo(0x0300, "0x0300", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue), + TagInfo(0x0300, "PreCaptureFrames", "Pre-capture Frames", olympusIfdId, makerTags, unsignedShort, printValue), TagInfo(0x0301, "0x0301", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue), - TagInfo(0x0302, "0x0302", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue), + TagInfo(0x0302, "OneTouchWB", "OneTouchWB", olympusIfdId, makerTags, unsignedShort, print0x0302), TagInfo(0x0303, "0x0303", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue), TagInfo(0x0304, "0x0304", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue), - TagInfo(0x0f00, "DataDump", "Various camera settings", olympusIfdId, makerTags, undefined, print0x0f00), + TagInfo(0x0f00, "DataDump", "Various camera settings", olympusIfdId, makerTags, undefined, printValue), TagInfo(0x1000, "0x1000", "Unknown", olympusIfdId, makerTags, signedRational, printValue), TagInfo(0x1001, "0x1001", "Unknown", olympusIfdId, makerTags, signedRational, printValue), TagInfo(0x1002, "0x1002", "Unknown", olympusIfdId, makerTags, signedRational, printValue), TagInfo(0x1003, "0x1003", "Unknown", olympusIfdId, makerTags, signedRational, printValue), - TagInfo(0x1004, "0x1004", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue), - TagInfo(0x1005, "0x1005", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue), - TagInfo(0x1006, "0x1006", "Unknown", olympusIfdId, makerTags, signedRational, printValue), + TagInfo(0x1004, "FlashMode", "Flash Mode", olympusIfdId, makerTags, unsignedShort, printValue), + TagInfo(0x1005, "FlashDevice", "Flash Device", olympusIfdId, makerTags, unsignedShort, print0x1005), + TagInfo(0x1006, "Bracket", "Bracket", olympusIfdId, makerTags, signedRational, printValue), TagInfo(0x1007, "0x1007", "Unknown", olympusIfdId, makerTags, signedShort, printValue), TagInfo(0x1008, "0x1008", "Unknown", olympusIfdId, makerTags, signedShort, printValue), TagInfo(0x1009, "0x1009", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue), TagInfo(0x100a, "0x100a", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue), - TagInfo(0x100b, "0x100b", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue), - TagInfo(0x100c, "0x100c", "Unknown", olympusIfdId, makerTags, unsignedRational, printValue), - TagInfo(0x100d, "0x100d", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue), - TagInfo(0x100e, "0x100e", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue), - TagInfo(0x100f, "0x100f", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue), + TagInfo(0x100b, "FocusMode", "Focus Mode", olympusIfdId, makerTags, unsignedShort, printValue), + TagInfo(0x100c, "FocusDistance", "Focus Distance", olympusIfdId, makerTags, unsignedRational, printValue), + TagInfo(0x100d, "Zoom", "Zoom", olympusIfdId, makerTags, unsignedShort, printValue), + TagInfo(0x100e, "MacroFocus", "MacroFocus", olympusIfdId, makerTags, unsignedShort, printValue), + TagInfo(0x100f, "SharpnessFactor", "Sharpness Factor", olympusIfdId, makerTags, unsignedShort, printValue), TagInfo(0x1010, "0x1010", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue), - TagInfo(0x1011, "0x1011", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue), - TagInfo(0x1012, "0x1012", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue), + TagInfo(0x1011, "ColorMatrix", "Color Matrix", olympusIfdId, makerTags, unsignedShort, printValue), + TagInfo(0x1012, "BlackLevel", "Black Level", olympusIfdId, makerTags, unsignedShort, printValue), TagInfo(0x1013, "0x1013", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue), TagInfo(0x1014, "0x1014", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue), - TagInfo(0x1015, "0x1015", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue), + TagInfo(0x1015, "WhiteBalance", "White Balance", olympusIfdId, makerTags, unsignedShort, printValue), TagInfo(0x1016, "0x1016", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue), - TagInfo(0x1017, "0x1017", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue), - TagInfo(0x1018, "0x1018", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue), + TagInfo(0x1017, "RedBalance", "Red Balance", olympusIfdId, makerTags, unsignedShort, printValue), + TagInfo(0x1018, "BlueBalance", "Blue Balance", olympusIfdId, makerTags, unsignedShort, printValue), TagInfo(0x1019, "0x1019", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue), - TagInfo(0x101a, "0x101a", "Unknown", olympusIfdId, makerTags, asciiString, printValue), + TagInfo(0x101a, "SerialNumber", "Serial Number", olympusIfdId, makerTags, asciiString, printValue), TagInfo(0x101b, "0x101b", "Unknown", olympusIfdId, makerTags, unsignedLong, printValue), TagInfo(0x101c, "0x101c", "Unknown", olympusIfdId, makerTags, unsignedLong, printValue), TagInfo(0x101d, "0x101d", "Unknown", olympusIfdId, makerTags, unsignedLong, printValue), @@ -118,24 +116,23 @@ namespace Exiv2 { TagInfo(0x1020, "0x1020", "Unknown", olympusIfdId, makerTags, unsignedLong, printValue), TagInfo(0x1021, "0x1021", "Unknown", olympusIfdId, makerTags, unsignedLong, printValue), TagInfo(0x1022, "0x1022", "Unknown", olympusIfdId, makerTags, unsignedLong, printValue), - TagInfo(0x1023, "0x1023", "Unknown", olympusIfdId, makerTags, signedRational, printValue), + TagInfo(0x1023, "FlashBias", "Flash Bias", olympusIfdId, makerTags, signedRational, printValue), TagInfo(0x1024, "0x1024", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue), TagInfo(0x1025, "0x1025", "Unknown", olympusIfdId, makerTags, signedRational, printValue), TagInfo(0x1026, "0x1026", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue), TagInfo(0x1027, "0x1027", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue), TagInfo(0x1028, "0x1028", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue), - TagInfo(0x1029, "0x1029", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue), - TagInfo(0x102a, "0x102a", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue), - TagInfo(0x102b, "0x102b", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue), - TagInfo(0x102c, "0x102c", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue), - TagInfo(0x102d, "0x102d", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue), - TagInfo(0x102e, "0x102e", "Unknown", olympusIfdId, makerTags, unsignedLong, printValue), - TagInfo(0x102f, "0x102f", "Unknown", olympusIfdId, makerTags, unsignedLong, printValue), + TagInfo(0x1029, "Contrast", "Contrast", olympusIfdId, makerTags, unsignedShort, printValue), + TagInfo(0x102a, "SharpnessFactor", "Sharpness Factor", olympusIfdId, makerTags, unsignedShort, printValue), + TagInfo(0x102b, "ColorControl", "Color Control", olympusIfdId, makerTags, unsignedShort, printValue), + TagInfo(0x102c, "ValidBits", "Valid Bits", olympusIfdId, makerTags, unsignedShort, printValue), + TagInfo(0x102d, "Coring Filter", "Coring Filter", olympusIfdId, makerTags, unsignedShort, printValue), + TagInfo(0x102e, "ImageWidth", "Image Width", olympusIfdId, makerTags, unsignedLong, printValue), + TagInfo(0x102f, "ImageHeight", "Image Height", olympusIfdId, makerTags, unsignedLong, printValue), TagInfo(0x1030, "0x1030", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue), TagInfo(0x1031, "0x1031", "Unknown", olympusIfdId, makerTags, unsignedLong, printValue), TagInfo(0x1032, "0x1032", "Unknown", olympusIfdId, makerTags, unsignedShort, printValue), TagInfo(0x1033, "0x1033", "Unknown", olympusIfdId, makerTags, unsignedLong, printValue), - TagInfo(0x1034, "0x1034", "Unknown", olympusIfdId, makerTags, unsignedRational, printValue), // End of list marker TagInfo(0xffff, "(UnknownOlympusMakerNoteTag)", "Unknown OlympusMakerNote tag", olympusIfdId, makerTags, invalidTypeId, printValue) }; @@ -204,82 +201,107 @@ namespace Exiv2 { return new OlympusMakerNote(*this); } - std::ostream& OlympusMakerNote::print0x0f00(std::ostream& os, + std::ostream& OlympusMakerNote::print0x0200(std::ostream& os, const Value& value) { - if (value.typeId() != undefined) return os << value; + if (value.count() != 3 || value.typeId() != unsignedLong) { + return os << value; + } + long l0 = value.toLong(0); + switch (l0) { + case 0: os << "Normal"; break; + case 2: os << "Fast"; break; + case 3: os << "Panorama"; break; + default: os << "(" << l0 << ")"; break; + } + if (l0 != 0) { + os << ", "; + long l1 = value.toLong(1); + os << "Sequence number " << l1; + } + if (l0 != 0 && l0 != 2) { + os << ", "; + long l2 = value.toLong(2); + switch (l2) { + case 1: os << "Left to Right"; break; + case 2: os << "Right to Left"; break; + case 3: os << "Bottom to Top"; break; + case 4: os << "Top to Bottom"; break; + default: os << "(" << l2 << ")"; break; + } + } + return os; + } // OlympusMakerNote::print0x0200 - long count = value.count(); - long lA, lB; - - if (count < 11) return os; - lA = value.toLong(11); - os << std::setw(23) << "\n Function "; - print0x0f00_011(os, lA); - - if (count < 138) return os; - lA = value.toLong(138); - os << std::setw(23) << "\n White balance mode "; - print0x0f00_138(os, lA); + //! Quality + const TagDetails Quality[] = { + { 0, "(start)" }, + { 1, "Standard Quality (SQ)" }, + { 2, "High Quality (HQ)" }, + { 3, "Super High Quality (SHQ)" }, + { 6, "Raw" }, + { 0, "(end)" } + }; - if (count < 150) return os; - lA = value.toLong(150); - lB = value.toLong(151); - os << std::setw(23) << "\n Sharpness "; - print0x0f00_150_151(os, lA, lB); - - // Meaning of any further ushorts is unknown - ignore them - return os; + std::ostream& OlympusMakerNote::print0x0201(std::ostream& os, + const Value& value) + { + return TagTranslator(Quality).print(os, value); + } // OlympusMakerNote::print0x0201 - } // OlympusMakerNote::print0x0f00 - - std::ostream& OlympusMakerNote::print0x0f00_011(std::ostream& os, long l) + //! Macro + const TagDetails Macro[] = { + { -1, "(start)" }, + { 0, "Off" }, + { 1, "On" }, + { 2, "Super Macro" }, + { -1, "(end)" } + }; + + std::ostream& OlympusMakerNote::print0x0202(std::ostream& os, + const Value& value) { - switch (l) { - case 0: os << "Off"; break; - case 1: os << "Black and White"; break; - case 2: os << "Sepia"; break; - case 3: os << "White Board"; break; - case 4: os << "Black Board"; break; - default: os << "Unknown (" << l << ")"; - } - return os; - } + return TagTranslator(Macro).print(os, value); + } // OlympusMakerNote::print0x0202 - std::ostream& OlympusMakerNote::print0x0f00_138(std::ostream& os, long l) + std::ostream& OlympusMakerNote::print0x0204(std::ostream& os, + const Value& value) { - switch (l) { - case 0: os << "Auto"; break; - case 16: os << "Daylight"; break; - case 32: os << "Tungsten"; break; - case 48: os << "Fluorescent"; break; - case 64: os << "Shade"; break; - default: os << "Unknown (" << l << ")"; - } - return os; - } - - std::ostream& OlympusMakerNote::print0x0f00_150_151(std::ostream& os, - long l150, long l151) + float f = value.toFloat(); + if (f == 0.0 || f == 1.0) return os << "None"; + return os << std::fixed << std::setprecision(1) << f << "x"; + } // OlympusMakerNote::print0x0204 + + //! OneTouchWB + const TagDetails oneTouchWb[] = { + { -1, "(start)" }, + { 0, "Off" }, + { 1, "On" }, + { 2, "On (Preset)" }, + { -1, "(end)" } + }; + + std::ostream& OlympusMakerNote::print0x0302(std::ostream& os, + const Value& value) { - if( l150 == 24 && l151 == 6 ) { - os << "Soft"; - } - else if ((l150 == 32 && l151 == 12) || - (l150 == 30 && l151 == 11) || - (l150 == 24 && l151 == 8)) { - os << "Normal"; - } - else if ((l150 == 40 && l151 == 16) || - (l150 == 38 && l151 == 15) || - (l150 == 32 && l151 == 12)) { - os << "Hard"; - } - else { - os << "Unknown"; - } - return os; - } + return TagTranslator(oneTouchWb).print(os, value); + } // OlympusMakerNote::print0x0302 + + //! FlashDevice + const TagDetails flashDevice[] = { + { -1, "(start)" }, + { 0, "None" }, + { 1, "Internal" }, + { 4, "External" }, + { 4, "Internal + External" }, + { -1, "(end)" } + }; + + std::ostream& OlympusMakerNote::print0x1005(std::ostream& os, + const Value& value) + { + return TagTranslator(flashDevice).print(os, value); + } // OlympusMakerNote::print0x1005 // ***************************************************************************** // free functions diff --git a/src/olympusmn.hpp b/src/olympusmn.hpp index b7360a39..6bd5cc5b 100644 --- a/src/olympusmn.hpp +++ b/src/olympusmn.hpp @@ -123,15 +123,18 @@ namespace Exiv2 { //! @name Print functions for Olympus %MakerNote tags //@{ - //! Print various camera settings (uses print0x0f00_XXX functions) - static std::ostream& print0x0f00(std::ostream& os, const Value& value); - - //! Function - static std::ostream& print0x0f00_011(std::ostream& os, long l); - //! White Balance - static std::ostream& print0x0f00_138(std::ostream& os, long l); - //! Sharpness - static std::ostream& print0x0f00_150_151(std::ostream& os, long l1, long l2); + //! Print 'Special Mode' + static std::ostream& print0x0200(std::ostream& os, const Value& value); + //! Print Jpeg quality + static std::ostream& print0x0201(std::ostream& os, const Value& value); + //! Print Macro mode + static std::ostream& print0x0202(std::ostream& os, const Value& value); + //! Print Digital Zoom Factor + static std::ostream& print0x0204(std::ostream& os, const Value& value); + //! Print OneTouchWB + static std::ostream& print0x0302(std::ostream& os, const Value& value); + //! Print FlashDevice + static std::ostream& print0x1005(std::ostream& os, const Value& value); //@} //! @cond IGNORE diff --git a/src/tags.cpp b/src/tags.cpp index 62e7120b..7331de24 100644 --- a/src/tags.cpp +++ b/src/tags.cpp @@ -272,6 +272,24 @@ namespace Exiv2 { // Unknown Tag static const TagInfo unknownTag(0xffff, "Unknown tag", "Unknown tag", ifdIdNotSet, sectionIdNotSet, asciiString, printValue); + std::ostream& TagTranslator::print(std::ostream& os, const Value& value) const + { + if (!pTagDetails_) return os << value; + + long l = value.toLong(); + + long e = pTagDetails_[0].val_; + int i = 1; + for (; pTagDetails_[i].val_ != l && pTagDetails_[i].val_ != e; ++i) {} + if (pTagDetails_[i].val_ == l) { + os << pTagDetails_[i].label_; + } + else { + os << "(" << l << ")"; + } + return os; + } // TagTranslator::print + // Tag lookup lists with tag names, desc and where they (preferably) belong to; // this is an array with pointers to one list per IFD. The IfdId is used as the // index into the array. diff --git a/src/tags.hpp b/src/tags.hpp index 0d9313cd..4dfb6afb 100644 --- a/src/tags.hpp +++ b/src/tags.hpp @@ -109,6 +109,38 @@ namespace Exiv2 { PrintFct printFct_; //!< Pointer to tag print function }; // struct TagInfo + /*! + @brief Helper structure for lookup tables for translations of numeric + tag values to human readable labels. + */ + struct TagDetails { + long val_; //!< Tag value + char* label_; //!< Translation of the tag value + }; // struct TagDetails + + /*! + @brief Translation from numeric values from a lookup list to human + readable labels + */ + class TagTranslator { + public: + //! @name Creators + //@{ + //! Default constructor. + explicit TagTranslator(const TagDetails* pTagDetails) + : pTagDetails_(pTagDetails) {} + // No d'tor: Do not delete the list. + //@} + + //! @name Accessors + //@{ + //! Translate the tag value and write it out to the provided stream + std::ostream& print(std::ostream& os, const Value& value) const; + //@} + private: + const TagDetails* pTagDetails_; + }; // class TagTranslator + //! Container for Exif tag information. Implemented as a static class. class ExifTags { //! Prevent construction: not implemented.