Merge pull request #1792 from postscript-dev/add_SonyMisc2b_tags

Add SonyMisc2b makernote tags (tag 9404)
main
Kevin Backhouse 4 years ago committed by GitHub
commit c474277cc6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -112,7 +112,8 @@ TABLES = Exif \
Sony1MltCsOld \ Sony1MltCsOld \
Sony1MltCsA100 \ Sony1MltCsA100 \
Sony2Fp \ Sony2Fp \
SonyMisc1 SonyMisc1 \
SonyMisc2b
SCHEMA = xmp_dc \ SCHEMA = xmp_dc \
xmp_dwc \ xmp_dwc \

@ -643,6 +643,7 @@ SubImage8 MinoltaCs7D NikonFl1 Olympus Panasonic Son
SubImage9 MinoltaCsNew NikonFl2 Olympus2 PanasonicRaw Sony2Cs2 SubImage9 MinoltaCsNew NikonFl2 Olympus2 PanasonicRaw Sony2Cs2
SubThumb1 MinoltaCsOld NikonFl3 OlympusCs Sony2Fp SubThumb1 MinoltaCsOld NikonFl3 OlympusCs Sony2Fp
Thumbnail NikonIi OlympusEq Sigma SonyMisc1 Thumbnail NikonIi OlympusEq Sigma SonyMisc1
SonyMisc2b
SonyMinolta SonyMinolta
.fi .fi
.sp 1 .sp 1

@ -81,8 +81,11 @@
// ***************************************************************************** // *****************************************************************************
namespace { namespace {
// Todo: Can be generalized further - get any tag as a string/long/... // Todo: Can be generalized further - get any tag as a string/long/...
//! Get the Value for a tag within a particular group
const Exiv2::Value* getExifValue(Exiv2::Internal::TiffComponent* const pRoot, const uint16_t& tag, const Exiv2::Internal::IfdId& group);
//! Get the model name from tag Exif.Image.Model //! Get the model name from tag Exif.Image.Model
std::string getExifModel(Exiv2::Internal::TiffComponent* pRoot); std::string getExifModel(Exiv2::Internal::TiffComponent* pRoot);
//! Nikon en/decryption function //! Nikon en/decryption function
void ncrypt(Exiv2::byte* pData, uint32_t size, uint32_t count, uint32_t serial); void ncrypt(Exiv2::byte* pData, uint32_t size, uint32_t count, uint32_t serial);
} // namespace } // namespace
@ -1201,19 +1204,47 @@ namespace Exiv2 {
} }
return 0; return 0;
} }
int sonyMisc2bSelector(uint16_t /*tag*/, const byte* /*pData*/, uint32_t /*size*/, TiffComponent* const pRoot)
{
// From Exiftool: https://github.com/exiftool/exiftool/blob/master/lib/Image/ExifTool/Sony.pm
// > First byte must be 9 or 12 or 13 or 15 or 16 and 4th byte must be 2 (deciphered)
const auto value = getExifValue(pRoot, 0x9404, Exiv2::Internal::sony1Id);
if (!value || value->count() < 4)
return -1;
switch (value->toLong(0)) { // Using encrypted values
case 231: // 231 == 9
case 234: // 234 == 12
case 205: // 205 == 13
case 138: // 138 == 15
case 112: // 112 == 16
return value->toLong(3) == 8 ? 0 : -1; // 8 == 2
default:
break;
}
return -1;
}
} // namespace Internal } // namespace Internal
} // namespace Exiv2 } // namespace Exiv2
// ***************************************************************************** // *****************************************************************************
// local definitions // local definitions
namespace { namespace {
std::string getExifModel(Exiv2::Internal::TiffComponent* const pRoot) const Exiv2::Value* getExifValue(Exiv2::Internal::TiffComponent* const pRoot, const uint16_t& tag, const Exiv2::Internal::IfdId& group)
{ {
Exiv2::Internal::TiffFinder finder(0x0110, Exiv2::Internal::ifd0Id); // Exif.Image.Model Exiv2::Internal::TiffFinder finder(tag, group);
if (!pRoot)
return nullptr;
pRoot->accept(finder); pRoot->accept(finder);
auto te = dynamic_cast<Exiv2::Internal::TiffEntryBase*>(finder.result()); auto te = dynamic_cast<Exiv2::Internal::TiffEntryBase*>(finder.result());
if (!te || !te->pValue() || te->pValue()->count() == 0) return std::string(); return (!te || !te->pValue()) ? nullptr : te->pValue();
return te->pValue()->toString(); }
std::string getExifModel(Exiv2::Internal::TiffComponent* const pRoot)
{
// Lookup the Exif.Image.Model tag
const auto value = getExifValue(pRoot, 0x0110, Exiv2::Internal::ifd0Id);
return (!value || value->count() == 0) ? std::string("") : std::string(value->toString());
} }
void ncrypt(Exiv2::byte* pData, uint32_t size, uint32_t count, uint32_t serial) void ncrypt(Exiv2::byte* pData, uint32_t size, uint32_t count, uint32_t serial)

@ -718,6 +718,17 @@ namespace Exiv2 {
*/ */
int sony2FpSelector(uint16_t tag, const byte* pData, uint32_t size, TiffComponent* const pRoot); int sony2FpSelector(uint16_t tag, const byte* pData, uint32_t size, TiffComponent* const pRoot);
/*!
@brief Function to select cfg + def of the SonyMisc2b (tag 9404b) complex binary array.
@param tag Tag number of the binary array
@param pData Pointer to the raw array data.
@param size Size of the array data.
@param pRoot Pointer to the root component of the TIFF tree.
@return An index into the array set, -1 if no match was found.
*/
int sonyMisc2bSelector(uint16_t tag, const byte* pData, uint32_t size, TiffComponent* const pRoot);
/*! /*!
@brief Function to select cfg + def of a Nikon complex binary array. @brief Function to select cfg + def of a Nikon complex binary array.

@ -35,6 +35,7 @@
#include <iomanip> #include <iomanip>
#include <cassert> #include <cassert>
#include <cstring> #include <cstring>
#include <cmath>
// ***************************************************************************** // *****************************************************************************
// class member definitions // class member definitions
@ -908,6 +909,107 @@ namespace Exiv2 {
return os; return os;
} }
//! Lookup table to translate Sony Exposure Program 3 values to readable labels
constexpr TagDetails sonyExposureProgram3[] = {
{ 0, N_("Program AE") },
{ 1, N_("Aperture-priority AE") },
{ 2, N_("Shutter speed priority AE") },
{ 3, N_("Manual") },
{ 4, N_("Auto") },
{ 5, N_("iAuto") },
{ 6, N_("Superior Auto") },
{ 7, N_("iAuto+") },
{ 8, N_("Portrait") },
{ 9, N_("Landscape") },
{ 10, N_("Twilight") },
{ 11, N_("Twilight Portrait") },
{ 12, N_("Sunset") },
{ 14, N_("Action (High speed)") },
{ 16, N_("Sports") },
{ 17, N_("Handheld Night Shot") },
{ 18, N_("Anti Motion Blur") },
{ 19, N_("High Sensitivity") },
{ 21, N_("Beach") },
{ 22, N_("Snow") },
{ 23, N_("Fireworks") },
{ 26, N_("Underwater") },
{ 27, N_("Gourmet") },
{ 28, N_("Pet") },
{ 29, N_("Macro") },
{ 30, N_("Backlight Correction HDR") },
{ 33, N_("Sweep Panorama") },
{ 36, N_("Background Defocus") },
{ 37, N_("Soft Skin") },
{ 42, N_("3D Image") },
{ 43, N_("Cont. Priority AE") },
{ 45, N_("Document") },
{ 46, N_("Party") }
};
//! Sony Tag 9404b SonyMisc2b tags
constexpr TagInfo SonyMakerNote::tagInfoSonyMisc2b_[] = {
{12, "ExposureProgram", N_("Exposure program"),
N_("Exposure program"),
sonyMisc2bId, makerTags, unsignedByte, -1, EXV_PRINT_TAG(sonyExposureProgram3)},
{14, "IntelligentAuto", N_("Intelligent auto"),
N_("Whether intelligent auto was used"),
sonyMisc2bId, makerTags, unsignedByte, -1, printMinoltaSonyBoolValue},
{30, "LensZoomPosition", N_("Lens zoom position"),
N_("Lens zoom position (in %)"),
sonyMisc2bId, makerTags, unsignedShort, -1, printSonyMisc2bLensZoomPosition},
{32, "FocusPosition2", N_("Focus position 2"),
N_("Focus position 2"),
sonyMisc2bId, makerTags, unsignedByte, -1, printSonyMisc2bFocusPosition2},
// End of list marker
{0xffff, "(UnknownSonyMisc2bTag)", "(Unknown SonyMisc2b tag)",
"(Unknown SonyMisc2b tag)",
sonyMisc2bId, makerTags, unsignedByte, -1, printValue}
};
const TagInfo* SonyMakerNote::tagListSonyMisc2b()
{
return tagInfoSonyMisc2b_;
}
std::ostream& SonyMakerNote::printSonyMisc2bLensZoomPosition(std::ostream& os, const Value& value, const ExifData* metadata)
{
if (value.count() != 1)
return os << "(" << value << ")";
auto pos = metadata->findKey(ExifKey("Exif.Image.Model"));
if (pos == metadata->end())
return os << "(" << value << ")";
// Models that do not support this tag
std::string model = pos->toString();
for (auto& m : { "SLT-", "HV", "ILCA-"}) {
if (model.find(m) != std::string::npos)
return os << N_("n/a");
}
os << std::round((value.toLong()/10.24)) << "%";
return os;
}
std::ostream& SonyMakerNote::printSonyMisc2bFocusPosition2(std::ostream& os, const Value& value, const ExifData* metadata)
{
if (value.count() != 1)
return os << "(" << value << ")";
auto pos = metadata->findKey(ExifKey("Exif.Image.Model"));
if (pos == metadata->end())
return os << "(" << value << ")";
// Models that do not support this tag
std::string model = pos->toString();
for (auto& m : { "SLT-", "HV", "ILCA-"}) {
if (model.find(m) != std::string::npos)
return os << N_("n/a");
}
return os << value;
}
//! Sony Tag 2010 Sony2010 (Miscellaneous) //! Sony Tag 2010 Sony2010 (Miscellaneous)
constexpr TagInfo SonyMakerNote::tagInfo2010e_[] = { constexpr TagInfo SonyMakerNote::tagInfo2010e_[] = {

@ -51,6 +51,8 @@ namespace Exiv2 {
static const TagInfo* tagListFp(); static const TagInfo* tagListFp();
//! Return read-only list of built-in Sony Misc1 tags (Tag 9403) //! Return read-only list of built-in Sony Misc1 tags (Tag 9403)
static const TagInfo* tagListSonyMisc1(); static const TagInfo* tagListSonyMisc1();
//! Return read-only list of built-in Sony Misc2b tags (Tag 9404)
static const TagInfo* tagListSonyMisc2b();
static const TagInfo* tagList2010e(); static const TagInfo* tagList2010e();
@ -62,6 +64,10 @@ namespace Exiv2 {
static std::ostream& printSony2FpFocusPosition2(std::ostream&, const Value&, const ExifData* metadata); static std::ostream& printSony2FpFocusPosition2(std::ostream&, const Value&, const ExifData* metadata);
//! Print Sony temperature values (in degrees Celsius) //! Print Sony temperature values (in degrees Celsius)
static std::ostream& printTemperatureInDegC(std::ostream&, const Value&, const ExifData*); static std::ostream& printTemperatureInDegC(std::ostream&, const Value&, const ExifData*);
//! Print SonyMisc2b Lens Zoom Position value
static std::ostream& printSonyMisc2bLensZoomPosition(std::ostream&, const Value&, const ExifData* metadata);
//! Print SonyMisc2b Focus Position 2 value
static std::ostream& printSonyMisc2bFocusPosition2(std::ostream&, const Value&, const ExifData* metadata);
//! Print Sony Camera Model //! Print Sony Camera Model
static std::ostream& print0xb000(std::ostream&, const Value&, const ExifData*); static std::ostream& print0xb000(std::ostream&, const Value&, const ExifData*);
//! Print Full and Preview Image size //! Print Full and Preview Image size
@ -74,6 +80,7 @@ namespace Exiv2 {
static const TagInfo tagInfoCs2_[]; static const TagInfo tagInfoCs2_[];
static const TagInfo tagInfoFp_[]; static const TagInfo tagInfoFp_[];
static const TagInfo tagInfoSonyMisc1_[]; static const TagInfo tagInfoSonyMisc1_[];
static const TagInfo tagInfoSonyMisc2b_[];
static const TagInfo tagInfo2010e_[]; static const TagInfo tagInfo2010e_[];
}; // class SonyMakerNote }; // class SonyMakerNote

@ -168,6 +168,7 @@ namespace Exiv2 {
{ sony2Cs2Id, "Makernote", "Sony2Cs2", SonyMakerNote::tagListCs2 }, { sony2Cs2Id, "Makernote", "Sony2Cs2", SonyMakerNote::tagListCs2 },
{ sony2FpId, "Makernote", "Sony2Fp", SonyMakerNote::tagListFp }, { sony2FpId, "Makernote", "Sony2Fp", SonyMakerNote::tagListFp },
{ sonyMisc1Id, "Makernote", "SonyMisc1", SonyMakerNote::tagListSonyMisc1}, { sonyMisc1Id, "Makernote", "SonyMisc1", SonyMakerNote::tagListSonyMisc1},
{ sonyMisc2bId, "Makernote", "SonyMisc2b", SonyMakerNote::tagListSonyMisc2b},
{ sony2010eId, "Makernote", "Sony2010e", SonyMakerNote::tagList2010e }, { sony2010eId, "Makernote", "Sony2010e", SonyMakerNote::tagList2010e },
{ lastId, "(Last IFD info)", "(Last IFD item)", nullptr } { lastId, "(Last IFD info)", "(Last IFD item)", nullptr }
}; };

@ -175,6 +175,7 @@ namespace Exiv2 {
sony2Cs2Id, sony2Cs2Id,
sony2FpId, sony2FpId,
sonyMisc1Id, sonyMisc1Id,
sonyMisc2bId,
sony2010eId, sony2010eId,
sony1MltCs7DId, sony1MltCs7DId,
sony1MltCsOldId, sony1MltCsOldId,

@ -846,6 +846,29 @@ namespace Exiv2 {
{ 0x05, ttSignedByte , 1 }, // Exif.SonyMisc1.CameraTemperature { 0x05, ttSignedByte , 1 }, // Exif.SonyMisc1.CameraTemperature
}; };
constexpr ArrayCfg sonyMisc2bCfg = {
sonyMisc2bId, // Group for the elements
littleEndian, // Little endian
ttUnsignedByte, // Type for array entry and size element
sonyTagDecipher, // (uint16_t, const byte*, uint32_t, TiffComponent* const);
false, // No size element
false, // No fillers
false, // Don't concatenate gaps
{ 0, ttUnsignedByte, 1 }
};
constexpr ArrayDef sonyMisc2bDef[] = {
{ 12, ttUnsignedByte , 1 }, // Exif.SonyMisc2b.ExposureProgram
{ 14, ttUnsignedByte , 1 }, // Exif.SonyMisc2b.IntelligentAuto
{ 30, ttUnsignedShort , 1 }, // Exif.SonyMisc2b.LensZoomPosition
{ 32, ttUnsignedByte , 1 }, // Exif.SonyMisc2b.FocusPosition2
};
//! SonyMisc2b configurations and definitions
constexpr ArraySet sonyMisc2bSet[] = {
{ sonyMisc2bCfg, sonyMisc2bDef, EXV_COUNTOF(sonyMisc2bDef) }
};
constexpr ArrayCfg sony2010eCfg = { constexpr ArrayCfg sony2010eCfg = {
sony2010eId, // Group for the elements sony2010eId, // Group for the elements
invalidByteOrder, // inherit from file. Usually littleEndian invalidByteOrder, // inherit from file. Usually littleEndian
@ -1117,6 +1140,7 @@ namespace Exiv2 {
{ Tag::root, sony2010eId, sony1Id, 0x2010 }, { Tag::root, sony2010eId, sony1Id, 0x2010 },
{ Tag::root, sony2FpId, sony1Id, 0x9402 }, { Tag::root, sony2FpId, sony1Id, 0x9402 },
{ Tag::root, sonyMisc1Id, sony1Id, 0x9403 }, { Tag::root, sonyMisc1Id, sony1Id, 0x9403 },
{ Tag::root, sonyMisc2bId, sony1Id, 0x9404 },
{ Tag::root, sony1CsId, sony1Id, 0x0114 }, { Tag::root, sony1CsId, sony1Id, 0x0114 },
{ Tag::root, sony1Cs2Id, sony1Id, 0x0114 }, { Tag::root, sony1Cs2Id, sony1Id, 0x0114 },
{ Tag::root, sonyMltId, sony1Id, 0xb028 }, { Tag::root, sonyMltId, sony1Id, 0xb028 },
@ -1128,6 +1152,7 @@ namespace Exiv2 {
{ Tag::root, sony2010eId, sony2Id, 0x2010 }, { Tag::root, sony2010eId, sony2Id, 0x2010 },
{ Tag::root, sony2FpId, sony2Id, 0x9402 }, { Tag::root, sony2FpId, sony2Id, 0x9402 },
{ Tag::root, sonyMisc1Id, sony2Id, 0x9403 }, { Tag::root, sonyMisc1Id, sony2Id, 0x9403 },
{ Tag::root, sonyMisc2bId, sony2Id, 0x9404 },
{ Tag::root, sony2CsId, sony2Id, 0x0114 }, { Tag::root, sony2CsId, sony2Id, 0x0114 },
{ Tag::root, sony2Cs2Id, sony2Id, 0x0114 }, { Tag::root, sony2Cs2Id, sony2Id, 0x0114 },
{ Tag::root, minoltaId, exifId, 0x927c }, { Tag::root, minoltaId, exifId, 0x927c },
@ -1566,6 +1591,10 @@ namespace Exiv2 {
{ Tag::all, sony2FpId, newTiffBinaryElement }, { Tag::all, sony2FpId, newTiffBinaryElement },
{ 0x9402, sony1Id, EXV_COMPLEX_BINARY_ARRAY(sony2FpSet, sony2FpSelector) }, { 0x9402, sony1Id, EXV_COMPLEX_BINARY_ARRAY(sony2FpSet, sony2FpSelector) },
// Tag 0x9404 SonyMisc2b
{ Tag::all, sonyMisc2bId, newTiffBinaryElement },
{ 0x9404, sony1Id, EXV_COMPLEX_BINARY_ARRAY(sonyMisc2bSet, sonyMisc2bSelector) },
// Tag 0x9403 SonyMisc1 // Tag 0x9403 SonyMisc1
{ Tag::all, sonyMisc1Id, newTiffBinaryElement }, { Tag::all, sonyMisc1Id, newTiffBinaryElement },
{ 0x9403, sony1Id, EXV_BINARY_ARRAY(sonyMisc1Cfg, sonyMisc1Def) }, { 0x9403, sony1Id, EXV_BINARY_ARRAY(sonyMisc1Cfg, sonyMisc1Def) },
@ -1591,6 +1620,10 @@ namespace Exiv2 {
{ Tag::all, sonyMisc1Id, newTiffBinaryElement }, { Tag::all, sonyMisc1Id, newTiffBinaryElement },
{ 0x9403, sony2Id, EXV_BINARY_ARRAY(sonyMisc1Cfg, sonyMisc1Def) }, { 0x9403, sony2Id, EXV_BINARY_ARRAY(sonyMisc1Cfg, sonyMisc1Def) },
// Tag 0x9404 SonyMisc2b
{ Tag::all, sonyMisc2bId, newTiffBinaryElement },
{ 0x9404, sony2Id, EXV_COMPLEX_BINARY_ARRAY(sonyMisc2bSet, sonyMisc2bSelector) },
// Sony2 makernote // Sony2 makernote
{ 0x0114, sony2Id, EXV_COMPLEX_BINARY_ARRAY(sony2CsSet, sonyCsSelector) }, { 0x0114, sony2Id, EXV_COMPLEX_BINARY_ARRAY(sony2CsSet, sonyCsSelector) },
{ Tag::next, sony2Id, ignoreTiffComponent }, { Tag::next, sony2Id, ignoreTiffComponent },

@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
from system_tests import CaseMeta, path
class SonyMisc2bTestSupported(metaclass=CaseMeta):
filename = path("$data_path/test_issue_1464.exv")
commands = ["$exiv2 -pa --grep SonyMisc2b $filename"]
stdout = ["""Exif.SonyMisc2b.ExposureProgram Byte 1 Shutter speed priority AE
Exif.SonyMisc2b.IntelligentAuto Byte 1 Off
Exif.SonyMisc2b.LensZoomPosition Short 1 100%
Exif.SonyMisc2b.FocusPosition2 Byte 1 0
"""
]
stderr = [""]
retval = [0]
# An example of a Sony camera model that does NOT support SonyMisc2b
class SonyMisc2bTestUnsupported(metaclass=CaseMeta):
filename = path("$data_path/exiv2-pr906.exv")
commands = ["$exiv2 -pa --grep SonyMisc2b $filename"]
stdout = [""""""
]
stderr = [""]
retval = [1]
Loading…
Cancel
Save