From e38d3d99764790a1799692e8479e5b07cf71b5ea Mon Sep 17 00:00:00 2001 From: norbertwg Date: Fri, 7 Oct 2022 18:25:25 +0200 Subject: [PATCH] several keys added to easyaccess sample easyaccess-test enhanced with additional optional arguments "category" for easier definition of some tests --- README-SAMPLES.md | 10 +- samples/easyaccess-test.cpp | 127 +-- src/easyaccess.cpp | 148 ++-- test/data/KonicaMinoltaDYNAX5D.exv | Bin 0 -> 26641 bytes test/data/NikonD1.exv | Bin 0 -> 6539 bytes test/data/SonyDSLR-A100.exv | Bin 0 -> 28425 bytes tests/bash_tests/test_easyaccess.py | 1176 ++++++++++++++++++++++++++- 7 files changed, 1342 insertions(+), 119 deletions(-) create mode 100644 test/data/KonicaMinoltaDYNAX5D.exv create mode 100644 test/data/NikonD1.exv create mode 100644 test/data/SonyDSLR-A100.exv diff --git a/README-SAMPLES.md b/README-SAMPLES.md index edd5689f..dcb56b02 100644 --- a/README-SAMPLES.md +++ b/README-SAMPLES.md @@ -352,10 +352,16 @@ Conversion test driver #### easyaccess-test ``` -Usage: easyaccess-test file +Usage: ..\build\bin\easyaccess-test.exe file [category [category ...]] +Categories: Orientation | ISOspeed | DateTimeOriginal | FlashBias | ExposureMode | SceneMode | + MacroMode | ImageQuality | WhiteBalance | LensName | Saturation | Sharpness | + Contrast | SceneCaptureType | MeteringMode | Make | Model | ExposureTime | FNumber | + ShutterSpeed | Aperture | Brightness | ExposureBias | MaxAperture | SubjectDistance | + LightSource | Flash | SerialNumber | FocalLength | SubjectArea | FlashEnergy | + ExposureIndex | SensingMethod | AFpoint ``` -Sample program using high-level metadata access functions +Sample program using high-level metadata access functions. Without specification of a category, metadata for all categories are shown. [Sample](#TOC1) Programs [Test](#TOC2) Programs diff --git a/samples/easyaccess-test.cpp b/samples/easyaccess-test.cpp index ee2fc574..aa602743 100644 --- a/samples/easyaccess-test.cpp +++ b/samples/easyaccess-test.cpp @@ -5,43 +5,57 @@ #include #include +// Type for an Exiv2 Easy access function +using EasyAccessFct = Exiv2::ExifData::const_iterator (*)(const Exiv2::ExifData&); + static constexpr auto easyAccess = std::array{ - std::pair("Orientation", &Exiv2::orientation), - std::pair("ISO speed", &Exiv2::isoSpeed), - std::pair("Date & time original", &Exiv2::dateTimeOriginal), - std::pair("Flash bias", &Exiv2::flashBias), - std::pair("Exposure mode", &Exiv2::exposureMode), - std::pair("Scene mode", &Exiv2::sceneMode), - std::pair("Macro mode", &Exiv2::macroMode), - std::pair("Image quality", &Exiv2::imageQuality), - std::pair("White balance", &Exiv2::whiteBalance), - std::pair("Lens name", &Exiv2::lensName), - std::pair("Saturation", &Exiv2::saturation), - std::pair("Sharpness", &Exiv2::sharpness), - std::pair("Contrast", &Exiv2::contrast), - std::pair("Scene capture type", &Exiv2::sceneCaptureType), - std::pair("Metering mode", &Exiv2::meteringMode), - std::pair("Camera make", &Exiv2::make), - std::pair("Camera model", &Exiv2::model), - std::pair("Exposure time", &Exiv2::exposureTime), - std::pair("FNumber", &Exiv2::fNumber), - std::pair("Shutter speed value", &Exiv2::shutterSpeedValue), - std::pair("Aperture value", &Exiv2::apertureValue), - std::pair("Brightness value", &Exiv2::brightnessValue), - std::pair("Exposure bias", &Exiv2::exposureBiasValue), - std::pair("Max aperture value", &Exiv2::maxApertureValue), - std::pair("Subject distance", &Exiv2::subjectDistance), - std::pair("Light source", &Exiv2::lightSource), - std::pair("Flash", &Exiv2::flash), - std::pair("Camera serial number", &Exiv2::serialNumber), - std::pair("Focal length", &Exiv2::focalLength), - std::pair("Subject location/area", &Exiv2::subjectArea), - std::pair("Flash energy", &Exiv2::flashEnergy), - std::pair("Exposure index", &Exiv2::exposureIndex), - std::pair("Sensing method", &Exiv2::sensingMethod), - std::pair("AF point", &Exiv2::afPoint), + std::make_tuple("Orientation", &Exiv2::orientation, "Orientation"), + std::make_tuple("ISO speed", &Exiv2::isoSpeed, "ISOspeed"), + std::make_tuple("Date & time original", &Exiv2::dateTimeOriginal, "DateTimeOriginal"), + std::make_tuple("Flash bias", &Exiv2::flashBias, "FlashBias"), + std::make_tuple("Exposure mode", &Exiv2::exposureMode, "ExposureMode"), + std::make_tuple("Scene mode", &Exiv2::sceneMode, "SceneMode"), + std::make_tuple("Macro mode", &Exiv2::macroMode, "MacroMode"), + std::make_tuple("Image quality", &Exiv2::imageQuality, "ImageQuality"), + std::make_tuple("White balance", &Exiv2::whiteBalance, "WhiteBalance"), + std::make_tuple("Lens name", &Exiv2::lensName, "LensName"), + std::make_tuple("Saturation", &Exiv2::saturation, "Saturation"), + std::make_tuple("Sharpness", &Exiv2::sharpness, "Sharpness"), + std::make_tuple("Contrast", &Exiv2::contrast, "Contrast"), + std::make_tuple("Scene capture type", &Exiv2::sceneCaptureType, "SceneCaptureType"), + std::make_tuple("Metering mode", &Exiv2::meteringMode, "MeteringMode"), + std::make_tuple("Camera make", &Exiv2::make, "Make"), + std::make_tuple("Camera model", &Exiv2::model, "Model"), + std::make_tuple("Exposure time", &Exiv2::exposureTime, "ExposureTime"), + std::make_tuple("FNumber", &Exiv2::fNumber, "FNumber"), + std::make_tuple("Shutter speed value", &Exiv2::shutterSpeedValue, "ShutterSpeed"), + std::make_tuple("Aperture value", &Exiv2::apertureValue, "Aperture"), + std::make_tuple("Brightness value", &Exiv2::brightnessValue, "Brightness"), + std::make_tuple("Exposure bias", &Exiv2::exposureBiasValue, "ExposureBias"), + std::make_tuple("Max aperture value", &Exiv2::maxApertureValue, "MaxAperture"), + std::make_tuple("Subject distance", &Exiv2::subjectDistance, "SubjectDistance"), + std::make_tuple("Light source", &Exiv2::lightSource, "LightSource"), + std::make_tuple("Flash", &Exiv2::flash, "Flash"), + std::make_tuple("Camera serial number", &Exiv2::serialNumber, "SerialNumber"), + std::make_tuple("Focal length", &Exiv2::focalLength, "FocalLength"), + std::make_tuple("Subject location/area", &Exiv2::subjectArea, "SubjectArea"), + std::make_tuple("Flash energy", &Exiv2::flashEnergy, "FlashEnergy"), + std::make_tuple("Exposure index", &Exiv2::exposureIndex, "ExposureIndex"), + std::make_tuple("Sensing method", &Exiv2::sensingMethod, "SensingMethod"), + std::make_tuple("AF point", &Exiv2::afPoint, "AFpoint"), }; +static const void printFct(EasyAccessFct fct, Exiv2::ExifData ed, const char* label) { + auto pos = fct(ed); + std::cout << std::setw(21) << std::left << label; + if (pos != ed.end()) { + std::cout << " (" << std::setw(35) << pos->key() << ") : " << pos->print(&ed) << "\n"; + } else { + std::cout << " (" << std::setw(35) << " " + << ") : \n"; + } +} + int main(int argc, char** argv) { try { Exiv2::XmpParser::initialize(); @@ -50,8 +64,19 @@ int main(int argc, char** argv) { Exiv2::enableBMFF(); #endif - if (argc != 2) { - std::cout << "Usage: " << argv[0] << " file\n"; + if (argc < 2) { + int count = 0; + std::cout << "Usage: " << argv[0] << " file [category [category ...]]\nCategories: "; + for (auto&& [label, fct, name] : easyAccess) { + if (count > 0) + std::cout << " | "; + if (count == 6 || count == 12 || count == 19 || count == 25 || count == 31) + std::cout << "\n "; + + std::cout << name; + count++; + } + std::cout << "\n"; return EXIT_FAILURE; } @@ -59,18 +84,28 @@ int main(int argc, char** argv) { image->readMetadata(); Exiv2::ExifData& ed = image->exifData(); - for (auto&& [label, fct] : easyAccess) { - auto pos = fct(ed); - std::cout << std::setw(21) << std::left << label; - if (pos != ed.end()) { - std::cout << " (" << std::setw(35) << pos->key() << ") : " << pos->print(&ed) << "\n"; - } else { - std::cout << " (" << std::setw(35) << " " - << ") : \n"; + if (argc > 2) { + for (int i = 2; i < argc; i++) { + bool categoryOk = false; + for (auto&& [label, fct, name] : easyAccess) { + if (strcmp(argv[i], name) == 0) { + printFct(fct, ed, label); + categoryOk = true; + break; + } + } + if (!categoryOk) { + std::cout << "Categoy >" << argv[i] << "< is invalid.\n"; + return EXIT_FAILURE; + } + } + } else { + for (auto&& [label, fct, name] : easyAccess) { + printFct(fct, ed, label); } - } - return EXIT_SUCCESS; + return EXIT_SUCCESS; + } } catch (Exiv2::Error& e) { std::cout << "Caught Exiv2 exception '" << e << "'\n"; return EXIT_FAILURE; diff --git a/src/easyaccess.cpp b/src/easyaccess.cpp index 99840b24..eb07ea5e 100644 --- a/src/easyaccess.cpp +++ b/src/easyaccess.cpp @@ -31,10 +31,10 @@ ExifData::const_iterator findMetadatum(const ExifData& ed, const char* keys[], s namespace Exiv2 { ExifData::const_iterator orientation(const ExifData& ed) { static const char* keys[] = { - "Exif.Image.Orientation", "Exif.Panasonic.Rotation", "Exif.MinoltaCs5D.Rotation", - "Exif.MinoltaCs5D.Rotation2", "Exif.MinoltaCs7D.Rotation", "Exif.Sony1MltCsA100.Rotation", - "Exif.Sony1Cs.Rotation", "Exif.Sony2Cs.Rotation", "Exif.Sony1Cs2.Rotation", - "Exif.Sony2Cs2.Rotation", "Exif.Sony1MltCsA100.Rotation"}; + "Exif.Image.Orientation", "Exif.Panasonic.Rotation", "Exif.PanasonicRaw.Orientation", + "Exif.MinoltaCs5D.Rotation", "Exif.MinoltaCs5D.Rotation2", "Exif.MinoltaCs7D.Rotation", + "Exif.Sony1MltCsA100.Rotation", "Exif.Sony1Cs.Rotation", "Exif.Sony2Cs.Rotation", + "Exif.Sony1Cs2.Rotation", "Exif.Sony2Cs2.Rotation", "Exif.Sony1MltCsA100.Rotation"}; return findMetadatum(ed, keys, std::size(keys)); } @@ -45,9 +45,11 @@ ExifData::const_iterator isoSpeed(const ExifData& ed) { "Exif.CanonCs.ISOSpeed", "Exif.Nikon1.ISOSpeed", "Exif.Nikon2.ISOSpeed", + "Exif.Nikon3.ISOSettings", "Exif.Nikon3.ISOSpeed", "Exif.NikonIi.ISO", "Exif.NikonIi.ISO2", + "Exif.NikonSiD300a.ISO", "Exif.MinoltaCsNew.ISOSetting", "Exif.MinoltaCsOld.ISOSetting", "Exif.MinoltaCs5D.ISOSpeed", @@ -163,10 +165,11 @@ ExifData::const_iterator flashBias(const ExifData& ed) { ExifData::const_iterator exposureMode(const ExifData& ed) { static const char* keys[] = { - "Exif.Photo.ExposureProgram", "Exif.Image.ExposureProgram", "Exif.CanonCs.ExposureProgram", - "Exif.MinoltaCs7D.ExposureMode", "Exif.MinoltaCs5D.ExposureMode", "Exif.MinoltaCsNew.ExposureMode", - "Exif.MinoltaCsOld.ExposureMode", "Exif.Sony1.ExposureMode", "Exif.Sony2.ExposureMode", - "Exif.Sony1Cs.ExposureProgram", "Exif.Sony2Cs.ExposureProgram", "Exif.Sony1MltCsA100.ExposureMode", + "Exif.Photo.ExposureProgram", "Exif.Image.ExposureProgram", "Exif.CanonCs.ExposureProgram", + "Exif.MinoltaCs7D.ExposureMode", "Exif.MinoltaCs5D.ExposureMode", "Exif.MinoltaCsNew.ExposureMode", + "Exif.MinoltaCsOld.ExposureMode", "Exif.OlympusCs.ExposureMode", "Exif.Sony1.ExposureMode", + "Exif.Sony2.ExposureMode", "Exif.Sony1Cs.ExposureProgram", "Exif.Sony1Cs2.ExposureProgram", + "Exif.Sony2Cs.ExposureProgram", "Exif.Sony1MltCsA100.ExposureMode", "Exif.SonyMisc2b.ExposureProgram", "Exif.Sigma.ExposureMode"}; return findMetadatum(ed, keys, std::size(keys)); } @@ -190,58 +193,74 @@ ExifData::const_iterator sceneMode(const ExifData& ed) { } ExifData::const_iterator macroMode(const ExifData& ed) { - static const char* keys[] = {"Exif.CanonCs.Macro", "Exif.Fujifilm.Macro", "Exif.Olympus.Macro", - "Exif.OlympusCs.MacroMode", "Exif.Panasonic.Macro", "Exif.MinoltaCsNew.MacroMode", - "Exif.MinoltaCsOld.MacroMode", "Exif.Sony1.Macro", "Exif.Sony2.Macro"}; + static const char* keys[] = { + "Exif.CanonCs.Macro", "Exif.Fujifilm.Macro", "Exif.Olympus.Macro", "Exif.Olympus2.Macro", + "Exif.OlympusCs.MacroMode", "Exif.Panasonic.Macro", "Exif.MinoltaCsNew.MacroMode", "Exif.MinoltaCsOld.MacroMode", + "Exif.Sony1.Macro", "Exif.Sony2.Macro"}; return findMetadatum(ed, keys, std::size(keys)); } ExifData::const_iterator imageQuality(const ExifData& ed) { - static const char* keys[] = {"Exif.CanonCs.Quality", "Exif.Fujifilm.Quality", "Exif.Sigma.Quality", - "Exif.Nikon1.Quality", "Exif.Nikon2.Quality", "Exif.Nikon3.Quality", - "Exif.Olympus.Quality", "Exif.OlympusCs.Quality", "Exif.Panasonic.Quality", - "Exif.Sony1.JPEGQuality", "Exif.Sony1.Quality", "Exif.Sony1.Quality2", - "Exif.Sony1Cs.Quality", "Exif.Sony2.JPEGQuality", "Exif.Sony2.Quality", - "Exif.Sony2.Quality2", "Exif.Sony2Cs.Quality", "Exif.Minolta.Quality", - "Exif.MinoltaCsNew.Quality", "Exif.MinoltaCsOld.Quality", "Exif.MinoltaCs5D.Quality", - "Exif.MinoltaCs7D.Quality", "Exif.Sony1MltCsA100.Quality", "Exif.Casio.Quality", - "Exif.Casio2.QualityMode", "Exif.Casio2.Quality"}; + static const char* keys[] = {"Exif.CanonCs.Quality", "Exif.Fujifilm.Quality", "Exif.Sigma.Quality", + "Exif.Nikon1.Quality", "Exif.Nikon2.Quality", "Exif.Nikon3.Quality", + "Exif.Olympus.Quality", "Exif.Olympus2.Quality", "Exif.OlympusCs.Quality", + "Exif.Panasonic.Quality", "Exif.Pentax.Quality", "Exif.PentaxDng.Quality", + "Exif.Sony1.JPEGQuality", "Exif.Sony1.Quality", "Exif.Sony1.Quality2", + "Exif.Sony1Cs.Quality", "Exif.Sony2.JPEGQuality", "Exif.Sony2.Quality", + "Exif.Sony2.Quality2", "Exif.Sony2Cs.Quality", "Exif.SonyMinolta.Quality", + "Exif.SonyMisc3c.Quality2", "Exif.Minolta.Quality", "Exif.MinoltaCsNew.Quality", + "Exif.MinoltaCsOld.Quality", "Exif.MinoltaCs5D.Quality", "Exif.MinoltaCs7D.Quality", + "Exif.Sony1MltCsA100.Quality", "Exif.Casio.Quality", "Exif.Casio2.QualityMode", + "Exif.Casio2.Quality"}; return findMetadatum(ed, keys, std::size(keys)); } ExifData::const_iterator whiteBalance(const ExifData& ed) { static const char* keys[] = { - "Exif.CanonSi.WhiteBalance", "Exif.Fujifilm.WhiteBalance", "Exif.Sigma.WhiteBalance", - "Exif.Nikon1.WhiteBalance", "Exif.Nikon2.WhiteBalance", "Exif.Nikon3.WhiteBalance", - "Exif.Olympus.WhiteBalance", "Exif.OlympusCs.WhiteBalance", "Exif.Panasonic.WhiteBalance", - "Exif.MinoltaCs5D.WhiteBalance", "Exif.MinoltaCs7D.WhiteBalance", "Exif.MinoltaCsNew.WhiteBalance", - "Exif.MinoltaCsOld.WhiteBalance", "Exif.Minolta.WhiteBalance", "Exif.Sony1.WhiteBalance", - "Exif.Sony2.WhiteBalance", "Exif.Sony1.WhiteBalance2", "Exif.Sony2.WhiteBalance2", - "Exif.Sony1MltCsA100.WhiteBalance", "Exif.SonyMinolta.WhiteBalance", "Exif.Casio.WhiteBalance", - "Exif.Casio2.WhiteBalance", "Exif.Casio2.WhiteBalance2", "Exif.Photo.WhiteBalance"}; + "Exif.CanonSi.WhiteBalance", "Exif.Fujifilm.WhiteBalance", "Exif.Sigma.WhiteBalance", + "Exif.Nikon1.WhiteBalance", "Exif.Nikon2.WhiteBalance", "Exif.Nikon3.WhiteBalance", + "Exif.Olympus.WhiteBalance", "Exif.OlympusCs.WhiteBalance", "Exif.Panasonic.WhiteBalance", + "Exif.MinoltaCs5D.WhiteBalance", "Exif.MinoltaCs7D.WhiteBalance", "Exif.MinoltaCsNew.WhiteBalance", + "Exif.MinoltaCsOld.WhiteBalance", "Exif.Minolta.WhiteBalance", "Exif.Pentax.WhiteBalance", + "Exif.PentaxDng.WhiteBalance", "Exif.Sony1.WhiteBalance", "Exif.Sony2.WhiteBalance", + "Exif.Sony1.WhiteBalance2", "Exif.Sony2.WhiteBalance2", "Exif.Sony1MltCsA100.WhiteBalance", + "Exif.SonyMinolta.WhiteBalance", "Exif.Casio.WhiteBalance", "Exif.Casio2.WhiteBalance", + "Exif.Casio2.WhiteBalance2", "Exif.Photo.WhiteBalance"}; return findMetadatum(ed, keys, std::size(keys)); } ExifData::const_iterator lensName(const ExifData& ed) { - static const char* keys[] = {// Exif.Canon.LensModel only reports focal length. - // Try Exif.CanonCs.LensType first. - "Exif.CanonCs.LensType", "Exif.Photo.LensModel", "Exif.NikonLd1.LensIDNumber", - "Exif.NikonLd2.LensIDNumber", "Exif.NikonLd3.LensIDNumber", "Exif.Pentax.LensType", - "Exif.PentaxDng.LensType", "Exif.Minolta.LensID", "Exif.SonyMinolta.LensID", - "Exif.Sony1.LensID", "Exif.Sony2.LensID", "Exif.Sony1.LensSpec", - "Exif.Sony2.LensSpec", "Exif.OlympusEq.LensType", "Exif.Panasonic.LensType", - "Exif.Samsung2.LensType"}; - return findMetadatum(ed, keys, std::size(keys)); + static const char* keys[] = { + // Try Exif.CanonCs.LensType first. + "Exif.CanonCs.LensType", "Exif.Photo.LensModel", "Exif.Canon.LensModel", "Exif.NikonLd1.LensIDNumber", + "Exif.NikonLd2.LensIDNumber", "Exif.NikonLd3.LensIDNumber", "Exif.NikonLd4.LensID", "Exif.NikonLd4.LensIDNumber", + "Exif.Pentax.LensType", "Exif.PentaxDng.LensType", "Exif.Minolta.LensID", "Exif.SonyMinolta.LensID", + "Exif.Sony1.LensID", "Exif.Sony2.LensID", "Exif.Sony1.LensSpec", "Exif.Sony2.LensSpec", + "Exif.OlympusEq.LensType", "Exif.Panasonic.LensType", "Exif.Samsung2.LensType"}; + + for (size_t i = 0; i < std::size(keys); ++i) { + Exiv2::ExifData::const_iterator pos = ed.findKey(ExifKey(keys[i])); + if (pos != ed.end()) { + // Exif.NikonLd4.LensID and Exif.NikonLd4.LensIDNumber are usually together included, + // one of them has value 0 (which means undefined), so skip tag with value 0 + if (strncmp(keys[i], "Exif.NikonLd4", 13) == 0) { + if (pos->getValue()->toInt64(0) > 0) + return pos; + } else + return pos; + } + } + return ed.end(); } ExifData::const_iterator saturation(const ExifData& ed) { static const char* keys[] = { "Exif.Photo.Saturation", "Exif.CanonCs.Saturation", "Exif.MinoltaCsNew.Saturation", "Exif.MinoltaCsOld.Saturation", "Exif.MinoltaCs7D.Saturation", "Exif.MinoltaCs5D.Saturation", - "Exif.Fujifilm.Color", "Exif.Nikon3.Saturation", "Exif.Panasonic.Saturation", - "Exif.Pentax.Saturation", "Exif.PentaxDng.Saturation", "Exif.Sigma.Saturation", - "Exif.Sony1.Saturation", "Exif.Sony2.Saturation", "Exif.Casio.Saturation", - "Exif.Casio2.Saturation", "Exif.Casio2.Saturation2"}; + "Exif.Fujifilm.Color", "Exif.Nikon3.Saturation", "Exif.NikonPc.Saturation", + "Exif.Panasonic.Saturation", "Exif.Pentax.Saturation", "Exif.PentaxDng.Saturation", + "Exif.Sigma.Saturation", "Exif.Sony1.Saturation", "Exif.Sony2.Saturation", + "Exif.Casio.Saturation", "Exif.Casio2.Saturation", "Exif.Casio2.Saturation2"}; return findMetadatum(ed, keys, std::size(keys)); } @@ -274,29 +293,41 @@ ExifData::const_iterator sceneCaptureType(const ExifData& ed) { } ExifData::const_iterator meteringMode(const ExifData& ed) { - static const char* keys[] = {"Exif.Photo.MeteringMode", "Exif.Image.MeteringMode", - "Exif.CanonCs.MeteringMode", "Exif.Sony1.MeteringMode2", - "Exif.Sony2.MeteringMode2", "Exif.Sony1MltCsA100.MeteringMode"}; + static const char* keys[] = { + "Exif.Photo.MeteringMode", "Exif.Image.MeteringMode", "Exif.CanonCs.MeteringMode", + "Exif.MinoltaCs5D.MeteringMode", "Exif.MinoltaCsOld.MeteringMode", "Exif.OlympusCs.MeteringMode", + "Exif.Pentax.MeteringMode", "Exif.PentaxDng.MeteringMode", "Exif.Sigma.MeteringMode", + "Exif.Sony1.MeteringMode2", "Exif.Sony1Cs.MeteringMode", "Exif.Sony1Cs2.MeteringMode", + "Exif.Sony2.MeteringMode2", "Exif.Sony2Cs.MeteringMode", "Exif.Sony1MltCsA100.MeteringMode"}; return findMetadatum(ed, keys, std::size(keys)); } ExifData::const_iterator make(const ExifData& ed) { - static const char* keys[] = {"Exif.Image.Make"}; + static const char* keys[] = {"Exif.Image.Make", "Exif.PanasonicRaw.Make"}; return findMetadatum(ed, keys, std::size(keys)); } ExifData::const_iterator model(const ExifData& ed) { - static const char* keys[] = {"Exif.Image.Model", "Exif.Sony1.SonyModelID", "Exif.Sony2.SonyModelID"}; + static const char* keys[] = {"Exif.Image.Model", + "Exif.MinoltaCsOld.MinoltaModel", + "Exif.MinoltaCsNew.MinoltaModel", + "Exif.PanasonicRaw.Model", + "Exif.Pentax.ModelID", + "Exif.PentaxDng.ModelID", + "Exif.Sony1.SonyModelID", + "Exif.Sony2.SonyModelID"}; return findMetadatum(ed, keys, std::size(keys)); } ExifData::const_iterator exposureTime(const ExifData& ed) { - static const char* keys[] = {"Exif.Photo.ExposureTime", "Exif.Image.ExposureTime", "Exif.Samsung2.ExposureTime"}; + static const char* keys[] = {"Exif.Photo.ExposureTime", "Exif.Image.ExposureTime", "Exif.Pentax.ExposureTime", + "Exif.PentaxDng.ExposureTime", "Exif.Samsung2.ExposureTime"}; return findMetadatum(ed, keys, std::size(keys)); } ExifData::const_iterator fNumber(const ExifData& ed) { - static const char* keys[] = {"Exif.Photo.FNumber", "Exif.Image.FNumber", "Exif.Samsung2.FNumber"}; + static const char* keys[] = {"Exif.Photo.FNumber", "Exif.Image.FNumber", "Exif.Pentax.FNumber", + "Exif.PentaxDng.FNumber", "Exif.Samsung2.FNumber"}; return findMetadatum(ed, keys, std::size(keys)); } @@ -306,7 +337,7 @@ ExifData::const_iterator shutterSpeedValue(const ExifData& ed) { } ExifData::const_iterator apertureValue(const ExifData& ed) { - static const char* keys[] = {"Exif.Photo.ApertureValue", "Exif.Image.ApertureValue"}; + static const char* keys[] = {"Exif.Photo.ApertureValue", "Exif.Image.ApertureValue", "Exif.CanonSi.ApertureValue"}; return findMetadatum(ed, keys, std::size(keys)); } @@ -317,12 +348,15 @@ ExifData::const_iterator brightnessValue(const ExifData& ed) { } ExifData::const_iterator exposureBiasValue(const ExifData& ed) { - static const char* keys[] = {"Exif.Photo.ExposureBiasValue", "Exif.Image.ExposureBiasValue"}; + static const char* keys[] = {"Exif.Photo.ExposureBiasValue", "Exif.Image.ExposureBiasValue", + "Exif.MinoltaCs5D.ExposureManualBias", "Exif.OlympusRd.ExposureBiasValue", + "Exif.OlympusRd2.ExposureBiasValue"}; return findMetadatum(ed, keys, std::size(keys)); } ExifData::const_iterator maxApertureValue(const ExifData& ed) { - static const char* keys[] = {"Exif.Photo.MaxApertureValue", "Exif.Image.MaxApertureValue"}; + static const char* keys[] = {"Exif.Photo.MaxApertureValue", "Exif.Image.MaxApertureValue", "Exif.CanonCs.MaxAperture", + "Exif.NikonLd4.MaxAperture"}; return findMetadatum(ed, keys, std::size(keys)); } @@ -342,16 +376,18 @@ ExifData::const_iterator lightSource(const ExifData& ed) { } ExifData::const_iterator flash(const ExifData& ed) { - static const char* keys[] = {"Exif.Photo.Flash", "Exif.Image.Flash", "Exif.Sony1.FlashAction", - "Exif.Sony2.FlashAction"}; + static const char* keys[] = {"Exif.Photo.Flash", "Exif.Image.Flash", "Exif.Pentax.Flash", + "Exif.PentaxDng.Flash", "Exif.Sony1.FlashAction", "Exif.Sony2.FlashAction"}; return findMetadatum(ed, keys, std::size(keys)); } ExifData::const_iterator serialNumber(const ExifData& ed) { static const char* keys[] = { - "Exif.Image.CameraSerialNumber", "Exif.Canon.SerialNumber", "Exif.Nikon3.SerialNumber", - "Exif.Nikon3.SerialNO", "Exif.Fujifilm.SerialNumber", "Exif.Olympus.SerialNumber2", - "Exif.Sigma.SerialNumber", "Exif.Sony1.SerialNumber", "Exif.Sony2.SerialNumber"}; + "Exif.Image.CameraSerialNumber", "Exif.Photo.BodySerialNumber", "Exif.Canon.SerialNumber", + "Exif.Nikon3.SerialNumber", "Exif.Nikon3.SerialNO", "Exif.Fujifilm.SerialNumber", + "Exif.Olympus.SerialNumber2", "Exif.OlympusEq.SerialNumber", "Exif.Pentax.SerialNumber", + "Exif.PentaxDng.SerialNumber", "Exif.Sigma.SerialNumber", "Exif.Sony1.SerialNumber", + "Exif.Sony2.SerialNumber"}; return findMetadatum(ed, keys, std::size(keys)); } diff --git a/test/data/KonicaMinoltaDYNAX5D.exv b/test/data/KonicaMinoltaDYNAX5D.exv new file mode 100644 index 0000000000000000000000000000000000000000..6a593b8da358306697109ed6cfc8afbf5ef83b69 GIT binary patch literal 26641 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 Ml6VIL9M_%y*|fy}82|tP literal 0 HcmV?d00001 diff --git a/test/data/NikonD1.exv b/test/data/NikonD1.exv new file mode 100644 index 0000000000000000000000000000000000000000..63d412cbc0c467d929ad0102cf89cbfb3cbe5751 GIT binary patch literal 6539 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 literal 0 HcmV?d00001 diff --git a/test/data/SonyDSLR-A100.exv b/test/data/SonyDSLR-A100.exv new file mode 100644 index 0000000000000000000000000000000000000000..da0a98a4b4c40e1d263da1684913a19918c3fafa GIT binary patch literal 28425 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 I#bh!4KN|U*RsaA1 literal 0 HcmV?d00001 diff --git a/tests/bash_tests/test_easyaccess.py b/tests/bash_tests/test_easyaccess.py index cd6d1623..4a156a41 100644 --- a/tests/bash_tests/test_easyaccess.py +++ b/tests/bash_tests/test_easyaccess.py @@ -1,24 +1,20 @@ # -*- coding: utf-8 -*- -import system_tests +from system_tests import CaseMeta, CopyTmpFiles, path +########################################################### +# this test cases forces to loop through all keys +# and would identify not existing keys +########################################################### +class Empty(metaclass=CaseMeta): -@system_tests.CopyFiles("$data_path/exiv2-empty.jpg") -class EasyaccessTest(metaclass=system_tests.CaseMeta): - - url = "https://github.com/Exiv2/exiv2/pull/287" - - filename = "$data_path/exiv2-empty_copy.jpg" + filename = path("$data_path/exiv2-empty.jpg") commands = [ - """$exiv2 -u -v -M"set Exif.Image.Make Samsung" $filename""", "$easyaccess_test $filename" ] stdout = [ - """File 1/1: $filename -Set Exif.Image.Make "Samsung" (Ascii) -""", - """Orientation ( ) : + """Orientation ( ) : ISO speed ( ) : Date & time original ( ) : Flash bias ( ) : @@ -33,7 +29,7 @@ Sharpness ( ) : Contrast ( ) : Scene capture type ( ) : Metering mode ( ) : -Camera make (Exif.Image.Make ) : Samsung +Camera make ( ) : Camera model ( ) : Exposure time ( ) : FNumber ( ) : @@ -54,5 +50,1155 @@ Sensing method ( ) : AF point ( ) : """ ] - stderr = [""] * 2 - retval = [0] * 2 + stderr = [""] * 1 + retval = [0] * 1 + +########################################################### +# Canon EOS 300D +########################################################### +@CopyTmpFiles("$data_path/exiv2-canon-eos-300d.jpg") +class Canon1(metaclass=CaseMeta): + + filename = path("$tmp_path/exiv2-canon-eos-300d.jpg") + + commands = [ + "$easyaccess_test $filename", + """$exiv2 -u -v -M"del Exif.Photo.MeteringMode" $filename""", + "$easyaccess_test $filename MeteringMode", + """$exiv2 -u -v -M"del Exif.Photo.ApertureValue" $filename""", + "$easyaccess_test $filename Aperture", + """$exiv2 -u -v -M"del Exif.Photo.FocalLength" $filename""", + "$easyaccess_test $filename FocalLength" + ] + stdout = [ + """Orientation (Exif.Image.Orientation ) : right, top +ISO speed (Exif.Photo.ISOSpeedRatings ) : 100 +Date & time original (Exif.Photo.DateTimeOriginal ) : 2003:09:26 08:19:51 +Flash bias (Exif.CanonSi.FlashBias ) : 0 EV +Exposure mode (Exif.CanonCs.ExposureProgram ) : Program (P) +Scene mode (Exif.CanonCs.EasyMode ) : Manual +Macro mode (Exif.CanonCs.Macro ) : (0) +Image quality (Exif.CanonCs.Quality ) : Fine +White balance (Exif.CanonSi.WhiteBalance ) : Auto +Lens name (Exif.CanonCs.LensType ) : n/a +Saturation (Exif.CanonCs.Saturation ) : High +Sharpness (Exif.CanonCs.Sharpness ) : High +Contrast (Exif.CanonCs.Contrast ) : High +Scene capture type (Exif.Photo.SceneCaptureType ) : Standard +Metering mode (Exif.Photo.MeteringMode ) : Multi-segment +Camera make (Exif.Image.Make ) : Canon +Camera model (Exif.Image.Model ) : Canon EOS 300D DIGITAL +Exposure time (Exif.Photo.ExposureTime ) : 1/80 s +FNumber (Exif.Photo.FNumber ) : F5.6 +Shutter speed value (Exif.Photo.ShutterSpeedValue ) : 1/80 s +Aperture value (Exif.Photo.ApertureValue ) : F5.6 +Brightness value ( ) : +Exposure bias (Exif.Photo.ExposureBiasValue ) : 0 EV +Max aperture value (Exif.Photo.MaxApertureValue ) : F3.5 +Subject distance (Exif.CanonSi.SubjectDistance ) : Infinite +Light source ( ) : +Flash (Exif.Photo.Flash ) : No flash +Camera serial number (Exif.Canon.SerialNumber ) : 21f938089 +Focal length (Exif.Photo.FocalLength ) : 18.0 mm +Subject location/area ( ) : +Flash energy ( ) : +Exposure index ( ) : +Sensing method (Exif.Photo.SensingMethod ) : One-chip color area +AF point (Exif.CanonPi.AFPointsUsed ) : center +""", + """File 1/1: $filename +Del Exif.Photo.MeteringMode +""", + """Metering mode (Exif.CanonCs.MeteringMode ) : Evaluative +""", + """File 1/1: $filename +Del Exif.Photo.ApertureValue +""", + """Aperture value (Exif.CanonSi.ApertureValue ) : F5.4 +""", + """File 1/1: $filename +Del Exif.Photo.FocalLength +""", + """Focal length (Exif.Canon.FocalLength ) : 18.0 mm +""" + ] + stderr = [""] * len(commands) + retval = [0] * len(commands) + +########################################################### +# Canon Canon EOS 6D +########################################################### +@CopyTmpFiles("$data_path/20220610_MG_7238.exv") +class Canon2(metaclass=CaseMeta): + + filename = path("$tmp_path/20220610_MG_7238.exv") + + commands = [ + "$easyaccess_test $filename", + """$exiv2 -u -v -M"del Exif.Photo.ISOSpeedRatings" $filename""", + "$easyaccess_test $filename ISOspeed" + ] + stdout = [ + """Orientation (Exif.Image.Orientation ) : top, left +ISO speed (Exif.Photo.ISOSpeedRatings ) : 800 +Date & time original (Exif.Photo.DateTimeOriginal ) : 2022:06:10 13:03:43 +Flash bias (Exif.CanonSi.FlashBias ) : 0 EV +Exposure mode (Exif.Photo.ExposureProgram ) : Aperture priority +Scene mode (Exif.CanonCs.EasyMode ) : Manual +Macro mode (Exif.CanonCs.Macro ) : Off +Image quality (Exif.CanonCs.Quality ) : RAW +White balance (Exif.CanonSi.WhiteBalance ) : Auto +Lens name (Exif.CanonCs.LensType ) : Canon EF 35-80mm f/4-5.6 +Saturation (Exif.CanonCs.Saturation ) : Normal +Sharpness (Exif.CanonCs.Sharpness ) : (32767) +Contrast (Exif.CanonCs.Contrast ) : Normal +Scene capture type (Exif.Photo.SceneCaptureType ) : Standard +Metering mode (Exif.Photo.MeteringMode ) : Multi-segment +Camera make (Exif.Image.Make ) : Canon +Camera model (Exif.Image.Model ) : Canon EOS 6D +Exposure time (Exif.Photo.ExposureTime ) : 1/100 s +FNumber (Exif.Photo.FNumber ) : F5.6 +Shutter speed value (Exif.Photo.ShutterSpeedValue ) : 1/99 s +Aperture value (Exif.Photo.ApertureValue ) : F5.7 +Brightness value ( ) : +Exposure bias (Exif.Photo.ExposureBiasValue ) : 0 EV +Max aperture value (Exif.CanonCs.MaxAperture ) : F4 +Subject distance (Exif.CanonSi.SubjectDistance ) : 0 m +Light source ( ) : +Flash (Exif.Photo.Flash ) : No, compulsory +Camera serial number (Exif.Photo.BodySerialNumber ) : 113053000536 +Focal length (Exif.Photo.FocalLength ) : 35.0 mm +Subject location/area ( ) : +Flash energy ( ) : +Exposure index ( ) : +Sensing method ( ) : +AF point (Exif.CanonSi.AFPointUsed ) : 0 focus points; none used +""", + """File 1/1: $filename +Del Exif.Photo.ISOSpeedRatings +""", + """ISO speed (Exif.CanonSi.ISOSpeed ) : 800 +""" + ] + stderr = [""] * len(commands) + retval = [0] * len(commands) + +########################################################### +# Nikon D1 +########################################################### +class Nikon1(metaclass=CaseMeta): + + filename = path("$data_path/NikonD1.exv") + + commands = [ + "$easyaccess_test $filename" + ] + stdout = [ + """Orientation ( ) : +ISO speed (Exif.Nikon1.ISOSpeed ) : 400 +Date & time original (Exif.Photo.DateTimeOriginal ) : 2005:12:16 08:25:45 +Flash bias ( ) : +Exposure mode (Exif.Photo.ExposureProgram ) : Auto +Scene mode ( ) : +Macro mode ( ) : +Image quality (Exif.Nikon1.Quality ) : NORMAL +White balance (Exif.Nikon1.WhiteBalance ) : AUTO +Lens name ( ) : +Saturation ( ) : +Sharpness ( ) : +Contrast ( ) : +Scene capture type ( ) : +Metering mode (Exif.Photo.MeteringMode ) : Multi-segment +Camera make (Exif.Image.Make ) : NIKON CORPORATION +Camera model (Exif.Image.Model ) : NIKON D1 +Exposure time (Exif.Photo.ExposureTime ) : 1/125 s +FNumber (Exif.Photo.FNumber ) : F5.3 +Shutter speed value ( ) : +Aperture value ( ) : +Brightness value ( ) : +Exposure bias (Exif.Photo.ExposureBiasValue ) : 0 EV +Max aperture value (Exif.Photo.MaxApertureValue ) : F4.4 +Subject distance ( ) : +Light source ( ) : +Flash ( ) : +Camera serial number ( ) : +Focal length (Exif.Photo.FocalLength ) : 78.0 mm +Subject location/area ( ) : +Flash energy ( ) : +Exposure index ( ) : +Sensing method (Exif.Photo.SensingMethod ) : One-chip color area +AF point (Exif.Nikon1.AFFocusPos ) : Dynamic area; Center +""" + ] + stderr = [""] * len(commands) + retval = [0] * len(commands) + +########################################################### +# Konica Minolta DYNAX 5D +########################################################### +@CopyTmpFiles("$data_path/KonicaMinoltaDYNAX5D.exv") +class KonicaMinolta1(metaclass=CaseMeta): + + filename = path("$tmp_path/KonicaMinoltaDYNAX5D.exv") + + commands = [ + "$easyaccess_test $filename", + """$exiv2 -u -v -M"del Exif.Image.Orientation" $filename""", + "$easyaccess_test $filename Orientation", + """$exiv2 -u -v -M"del Exif.Photo.ISOSpeedRatings" $filename""", + "$easyaccess_test $filename ISOspeed" + ] + stdout = [ + """Orientation (Exif.Image.Orientation ) : top, left +ISO speed (Exif.Photo.ISOSpeedRatings ) : 100 +Date & time original (Exif.Photo.DateTimeOriginal ) : 2005:10:17 14:47:57 +Flash bias (Exif.Minolta.FlashExposureComp ) : 0 EV +Exposure mode (Exif.Photo.ExposureProgram ) : Aperture priority +Scene mode (Exif.Minolta.SceneMode ) : Standard +Macro mode ( ) : +Image quality (Exif.Minolta.Quality ) : Extra Fine +White balance (Exif.MinoltaCs5D.WhiteBalance ) : Auto +Lens name (Exif.Minolta.LensID ) : Minolta/Sony AF DT 18-70mm F3.5-5.6 (D) | Sony AF DT 18-200mm F3.5-6.3 +Saturation (Exif.Photo.Saturation ) : Normal +Sharpness (Exif.Photo.Sharpness ) : Normal +Contrast (Exif.Photo.Contrast ) : Normal +Scene capture type (Exif.Photo.SceneCaptureType ) : Standard +Metering mode (Exif.Photo.MeteringMode ) : Multi-segment +Camera make (Exif.Image.Make ) : KONICA MINOLTA +Camera model (Exif.Image.Model ) : DYNAX 5D +Exposure time (Exif.Photo.ExposureTime ) : 1/125 s +FNumber (Exif.Photo.FNumber ) : F8 +Shutter speed value ( ) : +Aperture value ( ) : +Brightness value (Exif.Photo.BrightnessValue ) : 8 +Exposure bias (Exif.Photo.ExposureBiasValue ) : 0 EV +Max aperture value (Exif.Photo.MaxApertureValue ) : F4.5 +Subject distance ( ) : +Light source (Exif.Photo.LightSource ) : Unknown +Flash (Exif.Photo.Flash ) : No, compulsory +Camera serial number ( ) : +Focal length (Exif.Photo.FocalLength ) : 24.0 mm +Subject location/area (Exif.Photo.SubjectArea ) : 1504 1000 256 304 +Flash energy ( ) : +Exposure index ( ) : +Sensing method ( ) : +AF point ( ) : +""", + """File 1/1: $filename +Del Exif.Image.Orientation +""", + """Orientation (Exif.MinoltaCs5D.Rotation ) : Horizontal (normal) +""", + """File 1/1: $filename +Del Exif.Photo.ISOSpeedRatings +""", + """ISO speed (Exif.MinoltaCs5D.ISOSpeed ) : 100 +""" + ] + stderr = ["""Warning: Directory Minolta, entry 0x0088: Data area exceeds data buffer, ignoring it. +""", + """Warning: Directory Minolta, entry 0x0088: Data area exceeds data buffer, ignoring it. +Warning: Directory Minolta, entry 0x0088: Data area exceeds data buffer, ignoring it. +""", + """Warning: Directory Minolta, entry 0x0088: Data area exceeds data buffer, ignoring it. +""", + """Warning: Directory Minolta, entry 0x0088: Data area exceeds data buffer, ignoring it. +Warning: Directory Minolta, entry 0x0088: Data area exceeds data buffer, ignoring it. +""", + """Warning: Directory Minolta, entry 0x0088: Data area exceeds data buffer, ignoring it. +""" +] + retval = [0] * len(commands) + +########################################################### +# Nikon E950 +########################################################### +@CopyTmpFiles("$data_path/exiv2-nikon-e950.jpg") +class Nikon2(metaclass=CaseMeta): + + filename = path("$tmp_path/exiv2-nikon-e950.jpg") + + commands = [ + "$easyaccess_test $filename", + """$exiv2 -u -v -M"del Exif.Photo.ISOSpeedRatings" $filename""", + "$easyaccess_test $filename ISOspeed" + ] + stdout = [ + """Orientation (Exif.Image.Orientation ) : top, left +ISO speed (Exif.Photo.ISOSpeedRatings ) : 80 +Date & time original (Exif.Photo.DateTimeOriginal ) : 2001:04:06 11:51:40 +Flash bias ( ) : +Exposure mode (Exif.Photo.ExposureProgram ) : Auto +Scene mode ( ) : +Macro mode ( ) : +Image quality (Exif.Nikon2.Quality ) : (12) +White balance (Exif.Nikon2.WhiteBalance ) : Auto +Lens name ( ) : +Saturation ( ) : +Sharpness ( ) : +Contrast ( ) : +Scene capture type ( ) : +Metering mode (Exif.Photo.MeteringMode ) : Multi-segment +Camera make (Exif.Image.Make ) : NIKON +Camera model (Exif.Image.Model ) : E950 +Exposure time (Exif.Photo.ExposureTime ) : 1/77 s +FNumber (Exif.Photo.FNumber ) : F5.5 +Shutter speed value ( ) : +Aperture value ( ) : +Brightness value ( ) : +Exposure bias (Exif.Photo.ExposureBiasValue ) : 0 EV +Max aperture value (Exif.Photo.MaxApertureValue ) : F2.5 +Subject distance ( ) : +Light source (Exif.Photo.LightSource ) : Unknown +Flash (Exif.Photo.Flash ) : No flash +Camera serial number ( ) : +Focal length (Exif.Photo.FocalLength ) : 12.8 mm +Subject location/area ( ) : +Flash energy ( ) : +Exposure index ( ) : +Sensing method ( ) : +AF point ( ) : +""", + """File 1/1: $filename +Del Exif.Photo.ISOSpeedRatings +""", + """ISO speed (Exif.Nikon2.ISOSpeed ) : 80 +""" + ] + stderr = [""] * len(commands) + retval = [0] * len(commands) + +########################################################### +# NIKON Z 6: NikonLd4.LensID and NikonLd4.LensIDNumber +########################################################### +@CopyTmpFiles("$data_path/CH0_0174.exv") +class NikonLd4LensIDx(metaclass=CaseMeta): + + filename = path("$tmp_path/CH0_0174.exv") + + commands = [ + "$easyaccess_test $filename", + """$exiv2 -u -v -M"del Exif.Photo.LensModel" $filename""", + "$easyaccess_test $filename LensName", + """$exiv2 -u -v -M"set Exif.NikonLd4.LensID 13" $filename""", + "$easyaccess_test $filename LensName", + """$exiv2 -u -v -M"del Exif.Photo.ISOSpeedRatings" $filename""", + "$easyaccess_test $filename ISOspeed", + """$exiv2 -u -v -M"del Exif.Photo.DateTimeOriginal" $filename""", + "$easyaccess_test $filename DateTimeOriginal", + """$exiv2 -u -v -M"del Exif.Photo.Saturation" $filename""", + "$easyaccess_test $filename Saturation", + """$exiv2 -u -v -M"del Exif.Photo.BodySerialNumber" $filename""", + "$easyaccess_test $filename SerialNumber" + ] + stdout = [ + """Orientation (Exif.Image.Orientation ) : top, left +ISO speed (Exif.Photo.ISOSpeedRatings ) : 12800 +Date & time original (Exif.Photo.DateTimeOriginal ) : 2020:12:11 19:05:49 +Flash bias ( ) : +Exposure mode (Exif.Photo.ExposureProgram ) : Aperture priority +Scene mode (Exif.Photo.SceneCaptureType ) : Standard +Macro mode ( ) : +Image quality (Exif.Nikon3.Quality ) : RAW +White balance (Exif.Nikon3.WhiteBalance ) : AUTO1 +Lens name (Exif.Photo.LensModel ) : +Saturation (Exif.Photo.Saturation ) : Normal +Sharpness (Exif.Photo.Sharpness ) : Normal +Contrast (Exif.Photo.Contrast ) : Normal +Scene capture type (Exif.Photo.SceneCaptureType ) : Standard +Metering mode (Exif.Photo.MeteringMode ) : Multi-segment +Camera make (Exif.Image.Make ) : NIKON CORPORATION +Camera model (Exif.Image.Model ) : NIKON Z 6 +Exposure time (Exif.Photo.ExposureTime ) : 0.769231 s +FNumber (Exif.Photo.FNumber ) : F4 +Shutter speed value ( ) : +Aperture value ( ) : +Brightness value ( ) : +Exposure bias (Exif.Photo.ExposureBiasValue ) : 0 EV +Max aperture value (Exif.NikonLd4.MaxAperture ) : F0.5 +Subject distance ( ) : +Light source (Exif.Photo.LightSource ) : Unknown +Flash (Exif.Photo.Flash ) : No flash +Camera serial number (Exif.Photo.BodySerialNumber ) : 6078248 +Focal length (Exif.Photo.FocalLength ) : 102.0 mm +Subject location/area ( ) : +Flash energy ( ) : +Exposure index ( ) : +Sensing method (Exif.Photo.SensingMethod ) : One-chip color area +AF point ( ) : +""", + """File 1/1: $filename +Del Exif.Photo.LensModel +""", + """Lens name (Exif.NikonLd4.LensIDNumber ) : Nikon AF-S VR Zoom-Nikkor 70-200mm f/2.8G IF-ED +""", + """File 1/1: $filename +Set Exif.NikonLd4.LensID "13" (Short) +""", + """Lens name (Exif.NikonLd4.LensID ) : Nikon Nikkor Z 24-70mm f/2.8 S +""", + """File 1/1: $filename +Del Exif.Photo.ISOSpeedRatings +""", + """ISO speed (Exif.NikonIi.ISO ) : 12800 +""", + """File 1/1: $filename +Del Exif.Photo.DateTimeOriginal +""", + """Date & time original (Exif.Image.DateTimeOriginal ) : 2020:12:11 19:05:49 +""", + """File 1/1: $filename +Del Exif.Photo.Saturation +""", + """Saturation (Exif.NikonPc.Saturation ) : Normal +""", + """File 1/1: $filename +Del Exif.Photo.BodySerialNumber +""", + """Camera serial number (Exif.Nikon3.SerialNumber ) : 6078248 +""" + ] + stderr = [""] * len(commands) + retval = [0] * len(commands) + +########################################################### +# Pentax K100D +########################################################### +@CopyTmpFiles("$data_path/RAW_PENTAX_K100.exv") +class Pentax1(metaclass=CaseMeta): + + filename = path("$tmp_path/RAW_PENTAX_K100.exv") + + commands = [ + "$easyaccess_test $filename", + """$exiv2 -u -v -M"del Exif.Photo.ISOSpeedRatings" $filename""", + "$easyaccess_test $filename ISOspeed", + """$exiv2 -u -v -M"del Exif.Pentax.WhiteBalance" $filename""", + "$easyaccess_test $filename WhiteBalance", + """$exiv2 -u -v -M"del Exif.Photo.Saturation" $filename""", + "$easyaccess_test $filename Saturation", + """$exiv2 -u -v -M"del Exif.Photo.Sharpness" $filename""", + "$easyaccess_test $filename Sharpness", + """$exiv2 -u -v -M"del Exif.Photo.Contrast" $filename""", + "$easyaccess_test $filename Contrast", + """$exiv2 -u -v -M"del Exif.Photo.MeteringMode" $filename""", + "$easyaccess_test $filename MeteringMode", + """$exiv2 -u -v -M"del Exif.Image.Model" $filename""", + "$easyaccess_test $filename Model", + """$exiv2 -u -v -M"del Exif.Photo.ExposureTime" $filename""", + "$easyaccess_test $filename ExposureTime", + """$exiv2 -u -v -M"del Exif.Photo.FNumber" $filename""", + "$easyaccess_test $filename FNumber", + """$exiv2 -u -v -M"del Exif.Photo.Flash" $filename""", + "$easyaccess_test $filename Flash", + """$exiv2 -u -v -M"del Exif.Photo.FocalLength" $filename""", + "$easyaccess_test $filename FocalLength" + ] + stdout = [ + """Orientation (Exif.Image.Orientation ) : top, left +ISO speed (Exif.Photo.ISOSpeedRatings ) : 400 +Date & time original (Exif.Photo.DateTimeOriginal ) : 2009:12:05 13:26:11 +Flash bias ( ) : +Exposure mode (Exif.Photo.ExposureProgram ) : Aperture priority +Scene mode (Exif.Pentax.PictureMode ) : Aperture Priority +Macro mode ( ) : +Image quality (Exif.Pentax.Quality ) : RAW +White balance (Exif.Pentax.WhiteBalance ) : Auto +Lens name (Exif.Pentax.LensType ) : Tamron AF 18-250mm F3.5-6.3 Di II LD Aspherical [IF] Macro +Saturation (Exif.Photo.Saturation ) : High +Sharpness (Exif.Photo.Sharpness ) : Hard +Contrast (Exif.Photo.Contrast ) : Hard +Scene capture type (Exif.Photo.SceneCaptureType ) : Standard +Metering mode (Exif.Photo.MeteringMode ) : Multi-segment +Camera make (Exif.Image.Make ) : PENTAX Corporation +Camera model (Exif.Image.Model ) : PENTAX K100D +Exposure time (Exif.Photo.ExposureTime ) : 1/750 s +FNumber (Exif.Photo.FNumber ) : F3.5 +Shutter speed value ( ) : +Aperture value ( ) : +Brightness value ( ) : +Exposure bias (Exif.Photo.ExposureBiasValue ) : 0 EV +Max aperture value ( ) : +Subject distance ( ) : +Light source ( ) : +Flash (Exif.Photo.Flash ) : No, compulsory +Camera serial number ( ) : +Focal length (Exif.Photo.FocalLength ) : 18.0 mm +Subject location/area ( ) : +Flash energy ( ) : +Exposure index ( ) : +Sensing method (Exif.Photo.SensingMethod ) : One-chip color area +AF point (Exif.Pentax.AFPoint ) : Fixed Center +""", + """File 1/1: $filename +Del Exif.Photo.ISOSpeedRatings +""", + """ISO speed (Exif.Pentax.ISO ) : 400 +""", + """File 1/1: $filename +Del Exif.Pentax.WhiteBalance +""", + """White balance (Exif.Photo.WhiteBalance ) : Auto +""", + """File 1/1: $filename +Del Exif.Photo.Saturation +""", + """Saturation (Exif.Pentax.Saturation ) : Med High +""", + """File 1/1: $filename +Del Exif.Photo.Sharpness +""", + """Sharpness (Exif.Pentax.Sharpness ) : Med Hard +""", + """File 1/1: $filename +Del Exif.Photo.Contrast +""", + """Contrast (Exif.Pentax.Contrast ) : Med High +""", + """File 1/1: $filename +Del Exif.Photo.MeteringMode +""", + """Metering mode (Exif.Pentax.MeteringMode ) : Multi Segment +""", + """File 1/1: $filename +Del Exif.Image.Model +""", + """Camera model (Exif.Pentax.ModelID ) : K100D +""", + """File 1/1: $filename +Del Exif.Photo.ExposureTime +""", + """Exposure time (Exif.Pentax.ExposureTime ) : 1.33 ms +""", + """File 1/1: $filename +Del Exif.Photo.FNumber +""", + """FNumber (Exif.Pentax.FNumber ) : F3.5 +""", + """File 1/1: $filename +Del Exif.Photo.Flash +""", + """Flash (Exif.Pentax.Flash ) : Off, Did not fire +""", + """File 1/1: $filename +Del Exif.Photo.FocalLength +""", + """Focal length (Exif.Pentax.FocalLength ) : 18.0 mm +""" + ] + stderr = [""] * len(commands) + retval = [0] * len(commands) + +########################################################### +# Pentax K-30 +########################################################### +@CopyTmpFiles("$data_path/RAW_PENTAX_K30.exv") +class Pentax2(metaclass=CaseMeta): + + filename = path("$tmp_path/RAW_PENTAX_K30.exv") + + commands = [ + "$easyaccess_test $filename", + """$exiv2 -u -v -M"del Exif.Photo.ISOSpeedRatings" $filename""", + "$easyaccess_test $filename ISOspeed", + """$exiv2 -u -v -M"del Exif.PentaxDng.WhiteBalance" $filename""", + "$easyaccess_test $filename WhiteBalance", + """$exiv2 -u -v -M"del Exif.Photo.Saturation" $filename""", + "$easyaccess_test $filename Saturation", + """$exiv2 -u -v -M"del Exif.Photo.Sharpness" $filename""", + "$easyaccess_test $filename Sharpness", + """$exiv2 -u -v -M"del Exif.Photo.Contrast" $filename""", + "$easyaccess_test $filename Contrast", + """$exiv2 -u -v -M"del Exif.Photo.MeteringMode" $filename""", + "$easyaccess_test $filename MeteringMode", + """$exiv2 -u -v -M"del Exif.Image.Model" $filename""", + "$easyaccess_test $filename Model", + """$exiv2 -u -v -M"del Exif.Photo.ExposureTime" $filename""", + "$easyaccess_test $filename ExposureTime", + """$exiv2 -u -v -M"del Exif.Photo.FNumber" $filename""", + "$easyaccess_test $filename FNumber", + """$exiv2 -u -v -M"del Exif.Photo.Flash" $filename""", + "$easyaccess_test $filename Flash", + """$exiv2 -u -v -M"del Exif.Photo.FocalLength" $filename""", + "$easyaccess_test $filename FocalLength" + ] + stdout = [ + """Orientation (Exif.Image.Orientation ) : top, left +ISO speed (Exif.Photo.ISOSpeedRatings ) : 100 +Date & time original (Exif.Photo.DateTimeOriginal ) : 2012:07:31 08:56:59 +Flash bias ( ) : +Exposure mode (Exif.Photo.ExposureProgram ) : Landscape mode +Scene mode (Exif.PentaxDng.PictureMode ) : Unknown (0x010601) +Macro mode ( ) : +Image quality (Exif.PentaxDng.Quality ) : RAW +White balance (Exif.PentaxDng.WhiteBalance ) : Auto +Lens name (Exif.PentaxDng.LensType ) : smc PENTAX-DA 18-135mm F3.5-5.6 ED AL [IF] DC WR +Saturation (Exif.Photo.Saturation ) : Normal +Sharpness (Exif.Photo.Sharpness ) : Hard +Contrast (Exif.Photo.Contrast ) : Hard +Scene capture type (Exif.Photo.SceneCaptureType ) : Landscape +Metering mode (Exif.Photo.MeteringMode ) : Multi-segment +Camera make (Exif.Image.Make ) : PENTAX +Camera model (Exif.Image.Model ) : PENTAX K-30 +Exposure time (Exif.Photo.ExposureTime ) : 1/60 s +FNumber (Exif.Photo.FNumber ) : F11 +Shutter speed value ( ) : +Aperture value ( ) : +Brightness value ( ) : +Exposure bias (Exif.Photo.ExposureBiasValue ) : 0 EV +Max aperture value ( ) : +Subject distance ( ) : +Light source ( ) : +Flash (Exif.Photo.Flash ) : No, compulsory +Camera serial number (Exif.PentaxDng.SerialNumber ) : 4364069 +Focal length (Exif.Photo.FocalLength ) : 31.0 mm +Subject location/area ( ) : +Flash energy ( ) : +Exposure index ( ) : +Sensing method (Exif.Photo.SensingMethod ) : One-chip color area +AF point (Exif.PentaxDng.AFPoint ) : Auto +""", + """File 1/1: $filename +Del Exif.Photo.ISOSpeedRatings +""", + """ISO speed (Exif.PentaxDng.ISO ) : 100 +""", + """File 1/1: $filename +Del Exif.PentaxDng.WhiteBalance +""", + """White balance (Exif.Photo.WhiteBalance ) : Auto +""", + """File 1/1: $filename +Del Exif.Photo.Saturation +""", + """Saturation (Exif.PentaxDng.Saturation ) : Normal +""", + """File 1/1: $filename +Del Exif.Photo.Sharpness +""", + """Sharpness (Exif.PentaxDng.Sharpness ) : Med Hard +""", + """File 1/1: $filename +Del Exif.Photo.Contrast +""", + """Contrast (Exif.PentaxDng.Contrast ) : Med High +""", + """File 1/1: $filename +Del Exif.Photo.MeteringMode +""", + """Metering mode (Exif.PentaxDng.MeteringMode ) : Multi Segment +""", + """File 1/1: $filename +Del Exif.Image.Model +""", + """Camera model (Exif.PentaxDng.ModelID ) : K-30 +""", + """File 1/1: $filename +Del Exif.Photo.ExposureTime +""", + """Exposure time (Exif.PentaxDng.ExposureTime ) : 16.66 ms +""", + """File 1/1: $filename +Del Exif.Photo.FNumber +""", + """FNumber (Exif.PentaxDng.FNumber ) : F11 +""", + """File 1/1: $filename +Del Exif.Photo.Flash +""", + """Flash (Exif.PentaxDng.Flash ) : Off, Did not fire +""", + """File 1/1: $filename +Del Exif.Photo.FocalLength +""", + """Focal length (Exif.PentaxDng.FocalLength ) : 31.0 mm +""" + ] + stderr = [""] * len(commands) + retval = [0] * len(commands) + +########################################################### +# Sony DSC-HX60V +########################################################### +@CopyTmpFiles("$data_path/exiv2-SonyDSC-HX60V.exv") +class Sony1(metaclass=CaseMeta): + + filename = path("$tmp_path/exiv2-SonyDSC-HX60V.exv") + + commands = [ + "$easyaccess_test $filename", + """$exiv2 -u -v -M"del Exif.Photo.ISOSpeedRatings" $filename""", + "$easyaccess_test $filename ISOspeed", + """$exiv2 -u -v -M"del Exif.Photo.ExposureProgram" $filename""", + "$easyaccess_test $filename ExposureMode", + """$exiv2 -u -v -M"del Exif.Sony1.ExposureMode" $filename""", + "$easyaccess_test $filename ExposureMode", + """$exiv2 -u -v -M"del Exif.Sony1.JPEGQuality" $filename""", + "$easyaccess_test $filename ImageQuality", + """$exiv2 -u -v -M"del Exif.Sony1.Quality" $filename""", + "$easyaccess_test $filename ImageQuality", + """$exiv2 -u -v -M"del Exif.Sony1.WhiteBalance" $filename""", + "$easyaccess_test $filename WhiteBalance" + ] + stdout = [ + """Orientation (Exif.Image.Orientation ) : top, left +ISO speed (Exif.Photo.ISOSpeedRatings ) : 250 +Date & time original (Exif.Photo.DateTimeOriginal ) : 2014:01:01 00:52:22 +Flash bias (Exif.Sony1.FlashExposureComp ) : 0 EV +Exposure mode (Exif.Photo.ExposureProgram ) : Auto +Scene mode (Exif.Sony1.SceneMode ) : Standard +Macro mode (Exif.Sony1.Macro ) : Off +Image quality (Exif.Sony1.JPEGQuality ) : Fine +White balance (Exif.Sony1.WhiteBalance ) : Auto +Lens name (Exif.Sony1.LensSpec ) : 24-720mm F3.5-6.3 +Saturation (Exif.Photo.Saturation ) : Normal +Sharpness (Exif.Photo.Sharpness ) : Normal +Contrast (Exif.Photo.Contrast ) : Normal +Scene capture type (Exif.Photo.SceneCaptureType ) : Standard +Metering mode (Exif.Photo.MeteringMode ) : Multi-segment +Camera make (Exif.Image.Make ) : SONY +Camera model (Exif.Image.Model ) : DSC-HX60V +Exposure time (Exif.Photo.ExposureTime ) : 1/250 s +FNumber (Exif.Photo.FNumber ) : F6.3 +Shutter speed value ( ) : +Aperture value ( ) : +Brightness value (Exif.Photo.BrightnessValue ) : 7.81016 +Exposure bias (Exif.Photo.ExposureBiasValue ) : 0 EV +Max aperture value (Exif.Photo.MaxApertureValue ) : F6.3 +Subject distance ( ) : +Light source (Exif.Photo.LightSource ) : Unknown +Flash (Exif.Photo.Flash ) : No, compulsory +Camera serial number ( ) : +Focal length (Exif.Photo.FocalLength ) : 129.0 mm +Subject location/area ( ) : +Flash energy ( ) : +Exposure index ( ) : +Sensing method ( ) : +AF point (Exif.Sony1.AFPointSelected ) : n/a +""", + """File 1/1: $filename +Del Exif.Photo.ISOSpeedRatings +""", + """ISO speed (Exif.Photo.RecommendedExposureIndex) : 250 +""", + """File 1/1: $filename +Del Exif.Photo.ExposureProgram +""", + """Exposure mode (Exif.Sony1.ExposureMode ) : Program AE +""", + """File 1/1: $filename +Del Exif.Sony1.ExposureMode +""", + """Exposure mode (Exif.SonyMisc2b.ExposureProgram ) : Program AE +""", + """File 1/1: $filename +Del Exif.Sony1.JPEGQuality +""", + """Image quality (Exif.Sony1.Quality ) : Fine +""", + """File 1/1: $filename +Del Exif.Sony1.Quality +""", + """Image quality (Exif.SonyMisc3c.Quality2 ) : JPEG +""", + """File 1/1: $filename +Del Exif.Sony1.WhiteBalance +""", + """White balance (Exif.Sony1.WhiteBalance2 ) : Auto +""" + ] + stderr = [""] * len(commands) + retval = [0] * len(commands) + +########################################################### +# Sony DSLR-A100 +########################################################### +@CopyTmpFiles("$data_path/SonyDSLR-A100.exv") +class Sony2(metaclass=CaseMeta): + + filename = path("$tmp_path/SonyDSLR-A100.exv") + + commands = [ + "$easyaccess_test $filename", + """$exiv2 -u -v -M"del Exif.SonyMinolta.LensID" $filename""", + "$easyaccess_test $filename LensName" + ] + stdout = [ + """Orientation (Exif.Image.Orientation ) : top, left +ISO speed (Exif.Photo.ISOSpeedRatings ) : 100 +Date & time original (Exif.Photo.DateTimeOriginal ) : 2006:06:09 11:20:37 +Flash bias (Exif.SonyMinolta.FlashExposureComp ) : 0 EV +Exposure mode (Exif.Photo.ExposureProgram ) : Auto +Scene mode (Exif.SonyMinolta.SceneMode ) : Auto +Macro mode (Exif.Sony1.Macro ) : n/a +Image quality (Exif.Sony1.JPEGQuality ) : n/a +White balance (Exif.Sony1MltCsA100.WhiteBalance ) : Auto +Lens name (Exif.SonyMinolta.LensID ) : Minolta/Sony AF DT 18-70mm F3.5-5.6 (D) | Sony AF DT 18-200mm F3.5-6.3 +Saturation (Exif.Photo.Saturation ) : Normal +Sharpness (Exif.Photo.Sharpness ) : Normal +Contrast (Exif.Photo.Contrast ) : Normal +Scene capture type (Exif.Photo.SceneCaptureType ) : Standard +Metering mode (Exif.Photo.MeteringMode ) : Multi-segment +Camera make (Exif.Image.Make ) : SONY +Camera model (Exif.Image.Model ) : DSLR-A100 +Exposure time (Exif.Photo.ExposureTime ) : 1/200 s +FNumber (Exif.Photo.FNumber ) : F10 +Shutter speed value ( ) : +Aperture value ( ) : +Brightness value (Exif.Photo.BrightnessValue ) : 9.37 +Exposure bias (Exif.Photo.ExposureBiasValue ) : 0 EV +Max aperture value (Exif.Photo.MaxApertureValue ) : F3.5 +Subject distance ( ) : +Light source (Exif.Photo.LightSource ) : Unknown +Flash (Exif.Photo.Flash ) : No, compulsory +Camera serial number ( ) : +Focal length (Exif.Photo.FocalLength ) : 18.0 mm +Subject location/area (Exif.Photo.SubjectArea ) : 1448 968 246 294 +Flash energy ( ) : +Exposure index ( ) : +Sensing method ( ) : +AF point (Exif.Sony1MltCsA100.LocalAFAreaPoint) : Center +""", + """File 1/1: $filename +Del Exif.SonyMinolta.LensID +""", + """Lens name (Exif.Sony1.LensID ) : Minolta/Sony AF DT 18-70mm F3.5-5.6 (D) | Sony AF DT 18-200mm F3.5-6.3 +""" + ] + stderr = ["""Warning: Directory SonyMinolta, entry 0x0088: Data area exceeds data buffer, ignoring it. +""", + """Warning: Directory SonyMinolta, entry 0x0088: Data area exceeds data buffer, ignoring it. +Warning: Directory SonyMinolta, entry 0x0088: Data area exceeds data buffer, ignoring it. +""", + """Warning: Directory SonyMinolta, entry 0x0088: Data area exceeds data buffer, ignoring it. +""" + ] + retval = [0] * len(commands) + +########################################################### +# Sony ILCE-7M3 +########################################################### +@CopyTmpFiles("$data_path/exiv2-pr906.exv") +class Sony3(metaclass=CaseMeta): + + filename = path("$tmp_path/exiv2-pr906.exv") + + commands = [ + "$easyaccess_test $filename", + """$exiv2 -u -v -M"del Exif.Photo.ExposureProgram" $filename""", + "$easyaccess_test $filename ExposureMode" + ] + stdout = [ + """Orientation (Exif.Image.Orientation ) : top, left +ISO speed (Exif.Photo.ISOSpeedRatings ) : 100 +Date & time original (Exif.Photo.DateTimeOriginal ) : 2018:10:17 08:55:12 +Flash bias (Exif.Sony2.FlashExposureComp ) : 0 EV +Exposure mode (Exif.Photo.ExposureProgram ) : Manual +Scene mode (Exif.Sony2.SceneMode ) : Standard +Macro mode ( ) : +Image quality (Exif.Sony2.Quality ) : RAW + JPEG/HEIF +White balance (Exif.Sony2.WhiteBalance ) : Custom +Lens name (Exif.Photo.LensModel ) : FE 85mm F1.4 GM +Saturation (Exif.Photo.Saturation ) : Normal +Sharpness (Exif.Photo.Sharpness ) : Normal +Contrast (Exif.Photo.Contrast ) : Normal +Scene capture type (Exif.Photo.SceneCaptureType ) : Standard +Metering mode (Exif.Photo.MeteringMode ) : Multi-segment +Camera make (Exif.Image.Make ) : SONY +Camera model (Exif.Image.Model ) : ILCE-7M3 +Exposure time (Exif.Photo.ExposureTime ) : 1/100 s +FNumber (Exif.Photo.FNumber ) : F8 +Shutter speed value ( ) : +Aperture value ( ) : +Brightness value (Exif.Photo.BrightnessValue ) : 6.59922 +Exposure bias (Exif.Photo.ExposureBiasValue ) : 0 EV +Max aperture value (Exif.Photo.MaxApertureValue ) : F1.4 +Subject distance ( ) : +Light source (Exif.Photo.LightSource ) : Other light source +Flash (Exif.Photo.Flash ) : No, compulsory +Camera serial number ( ) : +Focal length (Exif.Photo.FocalLength ) : 85.0 mm +Subject location/area ( ) : +Flash energy ( ) : +Exposure index ( ) : +Sensing method ( ) : +AF point (Exif.Sony2.AFPointSelected ) : Center Zone +""", + """File 1/1: $filename +Del Exif.Photo.ExposureProgram +""", + """Exposure mode (Exif.Sony2.ExposureMode ) : Manual +""" + ] + stderr = [""] * len(commands) + retval = [0] * len(commands) + +########################################################### +# Sony DSC-RX100M5A +########################################################### +@CopyTmpFiles("$data_path/exiv2-pr2323_coverage3.exv") +class Sony4(metaclass=CaseMeta): + + filename = path("$tmp_path/exiv2-pr2323_coverage3.exv") + + commands = [ + "$easyaccess_test $filename", + """$exiv2 -u -v -M"del Exif.Sony1.Quality" $filename""", + "$easyaccess_test $filename ImageQuality", + """$exiv2 -u -v -M"del Exif.Photo.Saturation" $filename""", + "$easyaccess_test $filename Saturation", + """$exiv2 -u -v -M"del Exif.Photo.Sharpness" $filename""", + "$easyaccess_test $filename Sharpness", + """$exiv2 -u -v -M"del Exif.Photo.Contrast" $filename""", + "$easyaccess_test $filename Contrast", + """$exiv2 -u -v -M"del Exif.Photo.MeteringMode" $filename""", + "$easyaccess_test $filename MeteringMode", + """$exiv2 -u -v -M"del Exif.Image.Model" $filename""", + "$easyaccess_test $filename Model", + """$exiv2 -u -v -M"del Exif.Photo.BrightnessValue" $filename""", + "$easyaccess_test $filename Brightness", + """$exiv2 -u -v -M"del Exif.Photo.Flash" $filename""", + "$easyaccess_test $filename Flash" + ] + stdout = [ + """Orientation (Exif.Image.Orientation ) : top, left +ISO speed (Exif.Photo.ISOSpeedRatings ) : 200 +Date & time original (Exif.Photo.DateTimeOriginal ) : 2018:06:14 11:35:45 +Flash bias (Exif.Sony1.FlashExposureComp ) : 0 EV +Exposure mode (Exif.Photo.ExposureProgram ) : Aperture priority +Scene mode (Exif.Sony1.SceneMode ) : Standard +Macro mode ( ) : +Image quality (Exif.Sony1.Quality ) : RAW + JPEG/HEIF +White balance (Exif.Sony1.WhiteBalance ) : Auto +Lens name (Exif.Sony1.LensSpec ) : 24-70mm F1.8-2.8 +Saturation (Exif.Photo.Saturation ) : Normal +Sharpness (Exif.Photo.Sharpness ) : Normal +Contrast (Exif.Photo.Contrast ) : Normal +Scene capture type (Exif.Photo.SceneCaptureType ) : Standard +Metering mode (Exif.Photo.MeteringMode ) : Multi-segment +Camera make (Exif.Image.Make ) : SONY +Camera model (Exif.Image.Model ) : DSC-RX100M5A +Exposure time (Exif.Photo.ExposureTime ) : 1/125 s +FNumber (Exif.Photo.FNumber ) : F3.2 +Shutter speed value ( ) : +Aperture value ( ) : +Brightness value (Exif.Photo.BrightnessValue ) : 5.22031 +Exposure bias (Exif.Photo.ExposureBiasValue ) : 0 EV +Max aperture value (Exif.Photo.MaxApertureValue ) : F2.8 +Subject distance ( ) : +Light source (Exif.Photo.LightSource ) : Unknown +Flash (Exif.Photo.Flash ) : No, compulsory +Camera serial number ( ) : +Focal length (Exif.Photo.FocalLength ) : 18.5 mm +Subject location/area ( ) : +Flash energy ( ) : +Exposure index ( ) : +Sensing method ( ) : +AF point (Exif.Sony1.AFPointSelected ) : n/a +""", + """File 1/1: $filename +Del Exif.Sony1.Quality +""", + """Image quality (Exif.Sony1.Quality2 ) : RAW + extra fine +""", + """File 1/1: $filename +Del Exif.Photo.Saturation +""", + """Saturation (Exif.Sony1.Saturation ) : 0 +""", + """File 1/1: $filename +Del Exif.Photo.Sharpness +""", + """Sharpness (Exif.Sony1.Sharpness ) : 0 +""", + """File 1/1: $filename +Del Exif.Photo.Contrast +""", + """Contrast (Exif.Sony1.Contrast ) : 0 +""", + """File 1/1: $filename +Del Exif.Photo.MeteringMode +""", + """Metering mode (Exif.Sony1.MeteringMode2 ) : Multi-segment +""", + """File 1/1: $filename +Del Exif.Image.Model +""", + """Camera model (Exif.Sony1.SonyModelID ) : DSC-RX100M5A +""", + """File 1/1: $filename +Del Exif.Photo.BrightnessValue +""", + """Brightness value (Exif.Sony1.Brightness ) : 0 +""", + """File 1/1: $filename +Del Exif.Photo.Flash +""", + """Flash (Exif.Sony1.FlashAction ) : Did not fire +""" + ] + stderr = [""] * len(commands) + retval = [0] * len(commands) + +########################################################### +# Sony DSC-RX100M5A +########################################################### +@CopyTmpFiles("$data_path/exiv2-pr906.exv") +class Sony5(metaclass=CaseMeta): + + filename = path("$tmp_path/exiv2-pr906.exv") + + commands = [ + "$easyaccess_test $filename", + """$exiv2 -u -v -M"del Exif.Sony2.Quality" $filename""", + "$easyaccess_test $filename ImageQuality", + """$exiv2 -u -v -M"del Exif.Sony2.WhiteBalance" $filename""", + "$easyaccess_test $filename WhiteBalance", + """$exiv2 -u -v -M"del Exif.Photo.LensModel" $filename""", + "$easyaccess_test $filename LensName", + """$exiv2 -u -v -M"del Exif.Sony2.LensID" $filename""", + "$easyaccess_test $filename LensName", + """$exiv2 -u -v -M"del Exif.Photo.Saturation" $filename""", + "$easyaccess_test $filename Saturation", + """$exiv2 -u -v -M"del Exif.Photo.Sharpness" $filename""", + "$easyaccess_test $filename Sharpness", + """$exiv2 -u -v -M"del Exif.Photo.Contrast" $filename""", + "$easyaccess_test $filename Contrast", + """$exiv2 -u -v -M"del Exif.Photo.MeteringMode" $filename""", + "$easyaccess_test $filename MeteringMode", + """$exiv2 -u -v -M"del Exif.Image.Model" $filename""", + "$easyaccess_test $filename Model", + """$exiv2 -u -v -M"del Exif.Photo.BrightnessValue" $filename""", + "$easyaccess_test $filename Brightness", + """$exiv2 -u -v -M"del Exif.Photo.Flash" $filename""", + "$easyaccess_test $filename Flash" + ] + stdout = [ + """Orientation (Exif.Image.Orientation ) : top, left +ISO speed (Exif.Photo.ISOSpeedRatings ) : 100 +Date & time original (Exif.Photo.DateTimeOriginal ) : 2018:10:17 08:55:12 +Flash bias (Exif.Sony2.FlashExposureComp ) : 0 EV +Exposure mode (Exif.Photo.ExposureProgram ) : Manual +Scene mode (Exif.Sony2.SceneMode ) : Standard +Macro mode ( ) : +Image quality (Exif.Sony2.Quality ) : RAW + JPEG/HEIF +White balance (Exif.Sony2.WhiteBalance ) : Custom +Lens name (Exif.Photo.LensModel ) : FE 85mm F1.4 GM +Saturation (Exif.Photo.Saturation ) : Normal +Sharpness (Exif.Photo.Sharpness ) : Normal +Contrast (Exif.Photo.Contrast ) : Normal +Scene capture type (Exif.Photo.SceneCaptureType ) : Standard +Metering mode (Exif.Photo.MeteringMode ) : Multi-segment +Camera make (Exif.Image.Make ) : SONY +Camera model (Exif.Image.Model ) : ILCE-7M3 +Exposure time (Exif.Photo.ExposureTime ) : 1/100 s +FNumber (Exif.Photo.FNumber ) : F8 +Shutter speed value ( ) : +Aperture value ( ) : +Brightness value (Exif.Photo.BrightnessValue ) : 6.59922 +Exposure bias (Exif.Photo.ExposureBiasValue ) : 0 EV +Max aperture value (Exif.Photo.MaxApertureValue ) : F1.4 +Subject distance ( ) : +Light source (Exif.Photo.LightSource ) : Other light source +Flash (Exif.Photo.Flash ) : No, compulsory +Camera serial number ( ) : +Focal length (Exif.Photo.FocalLength ) : 85.0 mm +Subject location/area ( ) : +Flash energy ( ) : +Exposure index ( ) : +Sensing method ( ) : +AF point (Exif.Sony2.AFPointSelected ) : Center Zone +""", + """File 1/1: $filename +Del Exif.Sony2.Quality +""", + """Image quality (Exif.Sony2.Quality2 ) : RAW + extra fine +""", + """File 1/1: $filename +Del Exif.Sony2.WhiteBalance +""", + """White balance (Exif.Sony2.WhiteBalance2 ) : Manual +""", + """File 1/1: $filename +Del Exif.Photo.LensModel +""", + """Lens name (Exif.Sony2.LensID ) : Manual lens +""", + """File 1/1: $filename +Del Exif.Sony2.LensID +""", + """Lens name (Exif.Sony2.LensSpec ) : FE 85mm F1.4 +""", + """File 1/1: $filename +Del Exif.Photo.Saturation +""", + """Saturation (Exif.Sony2.Saturation ) : 0 +""", + """File 1/1: $filename +Del Exif.Photo.Sharpness +""", + """Sharpness (Exif.Sony2.Sharpness ) : 0 +""", + """File 1/1: $filename +Del Exif.Photo.Contrast +""", + """Contrast (Exif.Sony2.Contrast ) : 0 +""", + """File 1/1: $filename +Del Exif.Photo.MeteringMode +""", + """Metering mode (Exif.Sony2.MeteringMode2 ) : Multi-segment +""", + """File 1/1: $filename +Del Exif.Image.Model +""", + """Camera model (Exif.Sony2.SonyModelID ) : ILCE-7M3 +""", + """File 1/1: $filename +Del Exif.Photo.BrightnessValue +""", + """Brightness value (Exif.Sony2.Brightness ) : 0 +""", + """File 1/1: $filename +Del Exif.Photo.Flash +""", + """Flash (Exif.Sony2.FlashAction ) : Did not fire +""" + ] + stderr = [""] * len(commands) + retval = [0] * len(commands) + +########################################################### +# test cases for a single specific tag +########################################################### +#Exif.Image.ISOSpeedRatings +class ImageISOSpeedRatings(metaclass=CaseMeta): + + filename = path("$data_path/exiv2-bug479.jpg") + + commands = [ + "$easyaccess_test $filename ISOspeed" + ] + stdout = [ + """ISO speed (Exif.Image.ISOSpeedRatings ) : 250 +""" + ] + stderr = ["""Error: Directory Image: Next pointer is out of bounds; ignored. +"""] * 1 + retval = [0] * 1 + +#Exif.Sony2.SerialNumber +class Sony2SerialNumber(metaclass=CaseMeta): + + filename = path("$data_path/exiv2-pr2323_coverage1.exv") + + commands = [ + "$easyaccess_test $filename SerialNumber" + ] + stdout = [ + """Camera serial number (Exif.Sony1.SerialNumber ) : 12345678 +""" + ] + stderr = [""] * 1 + retval = [0] * 1 +