From f2b0efecce04af8e987622cfd57d1edf2b40ad5f Mon Sep 17 00:00:00 2001 From: topu Date: Mon, 17 Apr 2017 17:12:06 +0200 Subject: [PATCH] Show lens used on Panasonic cameras --- rtengine/imagedata.cc | 14 +++- rtexif/CMakeLists.txt | 2 +- rtexif/panasonicattribs.cc | 142 +++++++++++++++++++++++++++++++++++++ rtexif/rtexif.cc | 28 +++++++- rtexif/rtexif.h | 4 +- 5 files changed, 185 insertions(+), 5 deletions(-) create mode 100644 rtexif/panasonicattribs.cc diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 0afe612b9..829a0b286 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -157,7 +157,8 @@ void ImageData::extractInfo () "SAMSUNG", "Mamiya", "MOTOROLA", - "Leaf" + "Leaf", + "Panasonic" }) { if (make.find(corp) != std::string::npos) { // Simplify company names make = corp; @@ -482,6 +483,17 @@ void ImageData::extractInfo () lens = eq->getTag ("LensType")->valueToString (); } } + } else if (mnote && !make.compare (0, 9, "Panasonic")) { + if (mnote->getTag ("LensType")) { + std::string panalens = mnote->getTag("LensType")->valueToString(); + + if (panalens.find("LUMIX") != Glib::ustring::npos) { + lens = "Panasonic " + panalens; + } + else { + lens = panalens; + } + } } } else if (exif->getTag ("DNGLensInfo")) { lens = exif->getTag ("DNGLensInfo")->valueToString (); diff --git a/rtexif/CMakeLists.txt b/rtexif/CMakeLists.txt index 0309996f8..312400cf5 100644 --- a/rtexif/CMakeLists.txt +++ b/rtexif/CMakeLists.txt @@ -1,4 +1,4 @@ -add_library(rtexif rtexif.cc stdattribs.cc nikonattribs.cc canonattribs.cc pentaxattribs.cc fujiattribs.cc sonyminoltaattribs.cc olympusattribs.cc kodakattribs.cc) +add_library(rtexif rtexif.cc stdattribs.cc nikonattribs.cc canonattribs.cc pentaxattribs.cc fujiattribs.cc sonyminoltaattribs.cc olympusattribs.cc kodakattribs.cc panasonicattribs.cc) add_dependencies(rtexif UpdateInfo) if(WIN32) diff --git a/rtexif/panasonicattribs.cc b/rtexif/panasonicattribs.cc new file mode 100644 index 000000000..dd6e39302 --- /dev/null +++ b/rtexif/panasonicattribs.cc @@ -0,0 +1,142 @@ +/* + * This file is part of RawTherapee. + */ +#ifndef _PANASONICATTRIBS_ +#define _PANASONICATTRIBS_ + +#include +#include "rtexif.h" + +namespace rtexif +{ + +// TODO: write interpreters + +const TagAttrib panasonicAttribs[] = { + {0, AC_WRITE, 0, nullptr, 0x0001, AUTO, "Quality", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0002, AUTO, "FirmwareVersion", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0003, AUTO, "WhiteBalance", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0007, AUTO, "FocusMode", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x000f, AUTO, "AFMode", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x001a, AUTO, "ImageStabilization", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x001c, AUTO, "Macro", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x001f, AUTO, "ShootingMode", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0020, AUTO, "Audio", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0023, AUTO, "WhiteBalanceBias", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0024, AUTO, "FlashBias", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0025, AUTO, "InternalSerialNumber", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0026, AUTO, "ExifVersion", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0028, AUTO, "ColorEffect", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0029, AUTO, "TimeSincePowerOn", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x002a, AUTO, "BurstMode", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x002b, AUTO, "SequenceNumber", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x002c, AUTO, "Contrast", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x002d, AUTO, "NoiseReduction", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x002e, AUTO, "SelfTimer", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0030, AUTO, "Rotation", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0031, AUTO, "AFAssistLamp", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0032, AUTO, "ColorMode", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0033, AUTO, "BabyAge1", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0034, AUTO, "OpticalZoomMode", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0035, AUTO, "ConversionLens", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0036, AUTO, "TravelDay", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0039, AUTO, "Contrast", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x003a, AUTO, "WorldTimeLocation", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x003b, AUTO, "TextStamp1", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x003c, AUTO, "ProgramISO", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x003d, AUTO, "AdvancedSceneType", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x003e, AUTO, "TextStamp2", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x003f, AUTO, "FacesDetected", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0040, AUTO, "Saturation", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0041, AUTO, "Sharpness", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0042, AUTO, "FilmMode", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0044, AUTO, "ColorTempKelvin", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0045, AUTO, "BracketSettings", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0046, AUTO, "WBAdjustAB", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0047, AUTO, "WBAdjustGM", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0048, AUTO, "FlashCurtain", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0049, AUTO, "LongShutterNoiseReduction", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x004b, AUTO, "ImageWidth", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x004c, AUTO, "ImageHeight", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x004d, AUTO, "AFPointPosition", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x004e, AUTO, "FaceDetInfo", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0051, AUTO, "LensType", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0052, AUTO, "LensSerialNumber", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0053, AUTO, "AccessoryType", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0054, AUTO, "AccessorySerialNumber", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0059, AUTO, "Transform1", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x005d, AUTO, "IntelligentExposure", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0060, AUTO, "LensFirmwareVersion", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0061, AUTO, "FaceRecInfo", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0062, AUTO, "FlashWarning", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0065, AUTO, "Title", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0066, AUTO, "BabyName", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0067, AUTO, "Location", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0069, AUTO, "Country", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x006b, AUTO, "State", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x006d, AUTO, "City", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x006f, AUTO, "Landmark", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0070, AUTO, "IntelligentResolution", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0077, AUTO, "BurstSheed", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0079, AUTO, "IntelligentDRange", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x007c, AUTO, "ClearRetouch", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0080, AUTO, "City2", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0086, AUTO, "ManometerPressure", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0089, AUTO, "PhotoStyle", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x008a, AUTO, "ShadingCompensation", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x008c, AUTO, "AccelerometerZ", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x008d, AUTO, "AccelerometerX", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x008e, AUTO, "AccelerometerY", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x008f, AUTO, "CameraOrientation", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0090, AUTO, "RollAngle", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0091, AUTO, "PitchAngle", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0093, AUTO, "SweepPanoramaDirection", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0094, AUTO, "PanoramaFieldOfView", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0096, AUTO, "TimerRecording", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x009d, AUTO, "InternalNDFilter", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x009e, AUTO, "HDR", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x009f, AUTO, "ShutterType", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x00a3, AUTO, "ClearRetouchValue", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x00ab, AUTO, "TouchAE", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0e00, AUTO, "PrintIM", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x8000, AUTO, "MakerNoteVersion", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x8001, AUTO, "SceneMode", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x8004, AUTO, "WBRedLevel", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x8005, AUTO, "WBGreenLevel", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x8006, AUTO, "WBBlueLevel", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x8007, AUTO, "FlashFired", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x8008, AUTO, "TextStamp3", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x8009, AUTO, "TextStamp4", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x8010, AUTO, "BabyAge2", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x8012, AUTO, "Transform2", &stdInterpreter}, + { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr } +}; + +const TagAttrib panasonicRawAttribs[] = { + {0, AC_WRITE, 0, nullptr, 0x0001, AUTO, "Version", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0002, AUTO, "SensorWidth", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0003, AUTO, "SensorHeight", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0004, AUTO, "SensorTopBorder", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0005, AUTO, "SensorLeftBorder", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0006, AUTO, "ImageHeight", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0007, AUTO, "ImageWidth", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0011, AUTO, "RedBalance", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0012, AUTO, "BlueBalance", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0017, AUTO, "ISOSpeed", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0024, AUTO, "WBRedLevel", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0025, AUTO, "WBGreenLevel", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0026, AUTO, "WBBlueLevel", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x002e, AUTO, "PreviewImage", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x010f, AUTO, "Make", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0110, AUTO, "Model", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0111, AUTO, "StripOffsets", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0112, AUTO, "Orientation", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0116, AUTO, "RowsPerStrip", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0117, AUTO, "StripByteCounts", &stdInterpreter}, + {0, AC_WRITE, 0, nullptr, 0x0118, AUTO, "RawDataOffset", &stdInterpreter}, + { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr } +}; + +} +#endif + diff --git a/rtexif/rtexif.cc b/rtexif/rtexif.cc index 06651bf9e..1cbedc4c3 100644 --- a/rtexif/rtexif.cc +++ b/rtexif/rtexif.cc @@ -847,6 +847,22 @@ Tag::Tag (TagDirectory* p, FILE* f, int base) type = INVALID; } } + + if(tag == 0x002e) { // location of the embedded preview image in raw files of Panasonic cameras + TagDirectory* previewdir = ExifManager::parseJPEG(f, ftell(f)); // try to parse the exif data from the preview image + + if (previewdir) { + if (previewdir->getTag("Exif")) { + if(previewdir->getTag("Make")){ + if(previewdir->getTag("Make")->valueToString() == "Panasonic"){ // "make" is not yet available here, so get it from the preview tags to assure we're doing the right thing + Tag* t = new Tag (parent->getRoot(), lookupAttrib(ifdAttribs, "Exif")); // replace raw exif with preview exif assuming there are the same + t->initSubDir(previewdir->getTag("Exif")->getDirectory()); + parent->getRoot()->addTag(t); + } + } + } + } + } // if this tag is the makernote, it needs special treatment (brand specific parsing) if (tag == 0x927C && attrib && !strcmp (attrib->name, "MakerNote") ) { @@ -1212,6 +1228,14 @@ bool Tag::parseMakerNote(FILE* f, int base, ByteOrder bom ) } else { directory[0] = new TagDirectory (parent, f, base, olympusAttribs, bom); } + } else if ( make.find( "Panasonic" ) != std::string::npos) { + makerNoteKind = HEADERIFD; + valuesize = 12; + value = new unsigned char[12]; + fread (value, 1, 12, f); + directory = new TagDirectory*[2]; + directory[0] = new TagDirectory (parent, f, base, panasonicAttribs, bom); + directory[1] = nullptr; } else { return false; } @@ -2749,10 +2773,10 @@ TagDirectory* ExifManager::parse (FILE* f, int base, bool skipIgnored) return root; } -TagDirectory* ExifManager::parseJPEG (FILE* f) +TagDirectory* ExifManager::parseJPEG (FILE* f, int offset) { - fseek (f, 0, SEEK_SET); + fseek (f, offset, SEEK_SET); unsigned char markerl = 0xff; unsigned char c; fread (&c, 1, 1, f); diff --git a/rtexif/rtexif.h b/rtexif/rtexif.h index e1d8ede6e..555e40fdc 100644 --- a/rtexif/rtexif.h +++ b/rtexif/rtexif.h @@ -312,7 +312,7 @@ class ExifManager static Tag* saveCIFFMNTag (FILE* f, TagDirectory* root, int len, const char* name); public: static TagDirectory* parse (FILE*f, int base, bool skipIgnored = true); - static TagDirectory* parseJPEG (FILE*f); + static TagDirectory* parseJPEG (FILE*f, int offset = 0); // offset: to extract exif data from a embedded preview/thumbnail static TagDirectory* parseTIFF (FILE*f, bool skipIgnored = true); static TagDirectory* parseCIFF (FILE* f, int base, int length); static void parseCIFF (FILE* f, int base, int length, TagDirectory* root); @@ -628,5 +628,7 @@ extern const TagAttrib sonyCameraSettingsAttribs3[]; extern const TagAttrib olympusAttribs[]; extern const TagAttrib kodakIfdAttribs[]; void parseKodakIfdTextualInfo(Tag *textualInfo, Tag* exif); +extern const TagAttrib panasonicAttribs[]; +extern const TagAttrib panasonicRawAttribs[]; } #endif