Add SonyMisc3c makernote tags (tag 9400)

Changes:
+ Add tags. Rename Exiftool `SequenceLength` tags to `SequenceLength1`
  and `SequenceLength2`, to prevent a name clash.
+ Update docs and manpage.

Source: [Exiftool](https://exiftool.org)
This commit is contained in:
postscript-dev 2021-07-26 10:40:54 +01:00
parent c474277cc6
commit cc9d780534
No known key found for this signature in database
GPG Key ID: F3EC02A099292862
9 changed files with 346 additions and 22 deletions

View File

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

View File

@ -624,27 +624,28 @@ Exiv2 displays metadata tags and values.
The tag is a triplet of Family.Group.Tagname. The following groups are defined for the family Exif:
.sp 1
.nf
GPSInfo Canon Fujifilm NikonLd1 OlympusFe1 Pentax
Image CanonCf NikonLd2 OlympusFe2 PentaxDng
Image2 CanonCs Nikon1 NikonLd3 OlympusFe3
Image3 CanonFi Nikon2 NikonMe OlympusFe4 Samsung2
Iop CanonPa Nikon3 NikonPc OlympusFe5 SamsungPictureWizard
MakerNote CanonPi NikonAFT NikonPreview OlympusFe6 SamsungPreview
MpfInfo CanonPr NikonAf NikonSi01xx OlympusFe7
Photo CanonSi NikonAf2 NikonSi02xx OlympusFe8 Sony1
SubImage1 CanonTi NikonAf22 NikonSiD300a OlympusFe9 Sony1Cs
SubImage2 NikonCb1 NikonSiD300b OlympusFi Sony1Cs2
SubImage3 Casio NikonCb2 NikonSiD40 OlympusIp Sony1MltCs7D
SubImage4 Casio2 NikonCb2a NikonSiD80 OlympusRd Sony1MltCsA100
SubImage5 NikonCb3 NikonVr OlympusRd2 Sony1MltCsNew
SubImage6 Minolta NikonCb4 NikonWt OlympusRi Sony1MltCsOld
SubImage7 MinoltaCs5D NikonFi Sony2
SubImage8 MinoltaCs7D NikonFl1 Olympus Panasonic Sony2Cs
SubImage9 MinoltaCsNew NikonFl2 Olympus2 PanasonicRaw Sony2Cs2
SubThumb1 MinoltaCsOld NikonFl3 OlympusCs Sony2Fp
Thumbnail NikonIi OlympusEq Sigma SonyMisc1
SonyMisc2b
SonyMinolta
GPSInfo Canon Fujifilm NikonMe OlympusFe7 SonyMisc2b
Image CanonCf NikonPc OlympusFe9 SonyMisc3c
Image2 CanonCs Nikon1 NikonPreview OlympusFi SonyMinolta
Image3 CanonFi Nikon2 NikonSi01xx OlympusIp
Iop CanonPa Nikon3 NikonSi02xx OlympusRd Samsung2
MakerNote CanonPi NikonAFT NikonSiD300a OlympusRd2 SamsungPictureWizard
MpfInfo CanonPr NikonAf NikonSiD300b OlympusRi SamsungPreview
Photo CanonSi NikonAf2 NikonSiD40
SubImage1 CanonTi NikonAf22 NikonSiD80 Sigma
SubImage2 NikonCb1 NikonVr
SubImage3 Casio NikonCb2 NikonWt Sony1
SubImage4 Casio2 NikonCb2a Sony1Cs
SubImage5 NikonCb3 Olympus Sony1Cs2
SubImage6 Minolta NikonCb4 Olympus2 Sony1MltCs7D
SubImage7 MinoltaCs5D NikonFi OlympusCs Sony1MltCsA100
SubImage8 MinoltaCs7D NikonFl1 OlympusEq Sony1MltCsNew
SubImage9 MinoltaCsNew NikonFl2 OlympusFe1 Sony1MltCsOld
SubThumb1 MinoltaCsOld NikonFl3 OlympusFe2 Sony2
Thumbnail NikonIi OlympusFe3 Sony2Cs
Panasonic NikonLd1 OlympusFe4 Sony2Cs2
Pentax PanasonicRaw NikonLd2 OlympusFe5 Sony2Fp
PentaxDng NikonLd3 OlympusFe6 SonyMisc1
.fi
.sp 1
Exiv2 supports Exif 2.2 Standard Tags. Exiv2 also supports reading and writing manufacturer's MakerNote. The information in Exif.Photo.MakerNote is encoded as manufacturer's sub-records. For example, CanonCs are Camera Settings, NikonAf are Nikon Auto Focus records, NikonCb are Nikon Color Balance Records. Every tag is defined by a unique tagId (16 bit integer) which is unique within a Group.

View File

@ -1224,6 +1224,26 @@ namespace Exiv2 {
}
return -1;
}
int sonyMisc3cSelector(uint16_t /*tag*/, const byte* /*pData*/, uint32_t /*size*/, TiffComponent* const pRoot)
{
// From Exiftool (Tag 9400c): https://github.com/exiftool/exiftool/blob/master/lib/Image/ExifTool/Sony.pm
// > first byte decoded: 62, 48, 215, 28, 106 respectively
const auto value = getExifValue(pRoot, 0x9400, Exiv2::Internal::sony1Id);
if (!value || value->count() < 1)
return -1;
switch (value->toLong()) { // Using encrypted values
case 35: // 35 == 62
case 36: // 36 == 48
case 38: // 38 == 215
case 40: // 40 == 28
case 49: // 112 == 106
return 0;
default:
break;
}
return -1;
}
} // namespace Internal
} // namespace Exiv2

View File

@ -729,6 +729,17 @@ namespace Exiv2 {
*/
int sonyMisc2bSelector(uint16_t tag, const byte* pData, uint32_t size, TiffComponent* const pRoot);
/*!
@brief Function to select cfg + def of the SonyMisc3c (tag 9400) 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 sonyMisc3cSelector(uint16_t tag, const byte* pData, uint32_t size, TiffComponent* const pRoot);
/*!
@brief Function to select cfg + def of a Nikon complex binary array.

View File

@ -279,6 +279,33 @@ namespace Exiv2 {
{ 65535, N_("n/a") }
};
//! Lookup table to translate Sony Release Mode 2 values to readable labels
constexpr TagDetails sonyReleaseMode2[] = {
{ 0, N_("Normal") },
{ 1, N_("Continuous") },
{ 2, N_("Continuous - Exposure Bracketing") },
{ 3, N_("DRO or White Balance Bracketing") },
{ 5, N_("Continuous - Burst") },
{ 6, N_("Single Frame - Capture During Movie") },
{ 7, N_("Continuous - Sweep Panorama") },
{ 8, N_("Continuous - Anti-Motion Blur, Hand-held Twilight") },
{ 9, N_("Continuous - HDR") },
{ 10, N_("Continuous - Background defocus") },
{ 13, N_("Continuous - 3D Sweep Panorama") },
{ 15, N_("Continuous - High Resolution Sweep Panorama") },
{ 16, N_("Continuous - 3D Image") },
{ 17, N_("Continuous - Burst 2") },
{ 18, N_("Normal - iAuto+") },
{ 19, N_("Continuous - Speed/Advance Priority") },
{ 20, N_("Continuous - Multi-Frame NR") },
{ 23, N_("Single-frame - Exposure Bracketing") },
{ 26, N_("Continuous Low") },
{ 27, N_("Continuous - High Sensitivity") },
{ 28, N_("Smile Shutter") },
{ 29, N_("Continuous - Tele-zoom Advance Priority") },
{ 146, N_("Single Frame - Movie Capture") }
};
//! Lookup table to translate Sony sequence number values to readable labels
constexpr TagDetails sonySequenceNumber[] = {
{ 0, N_("Single") },
@ -1011,6 +1038,216 @@ namespace Exiv2 {
return os << value;
}
//! Lookup table to translate Sony camera SonyMisc3c sequence length 1 values to readable labels
constexpr TagDetails sonyMisc3cSequenceLength1[] = {
{ 0, N_("Continuous") },
{ 1, N_("1 shot") },
{ 2, N_("2 shots") },
{ 3, N_("3 shots") },
{ 4, N_("4 shots") },
{ 5, N_("5 shots") },
{ 6, N_("6 shots") },
{ 7, N_("7 shots") },
{ 9, N_("9 shots") },
{ 10, N_("10 shots") },
{ 12, N_("12 shots") },
{ 16, N_("16 shots") },
{ 100, N_("Continuous - iSweep Panorama") },
{ 200, N_("Continuous - Sweep Panorama") }
};
//! Lookup table to translate Sony camera SonyMisc3c sequence length 2 values to readable labels
constexpr TagDetails sonyMisc3cSequenceLength2[] = {
{ 0, N_("Continuous") },
{ 1, N_("1 file") },
{ 2, N_("2 files") },
{ 3, N_("3 files") },
{ 5, N_("5 files") },
{ 7, N_("7 files") },
{ 9, N_("9 files") },
{ 10, N_("10 files") }
};
//! Lookup table to translate Sony camera SonyMisc3c, camera orientation values to readable labels
constexpr TagDetails sonyMisc3cCameraOrientation[] = {
{ 1, N_("Horizontal (normal)") },
{ 3, N_("Rotate 180°") },
{ 6, N_("Rotate 90° CW") },
{ 8, N_("Rotate 270° CW") }
};
//! SonyMisc3c tags (Tag 9400c)
constexpr TagInfo SonyMakerNote::tagInfoSonyMisc3c_[] = {
{9, "ReleaseMode2", N_("Release mode 2"),
N_("Release mode 2"),
sonyMisc3cId, makerTags, unsignedByte, -1, EXV_PRINT_TAG(sonyReleaseMode2)},
{10, "ShotNumberSincePowerUp",N_("Shot number since power up"),
N_("Number of photos taken since the camera was powered up"),
sonyMisc3cId, makerTags, unsignedLong, -1, printSonyMisc3cShotNumberSincePowerUp},
{18, "SequenceImageNumber", N_("Sequence image number"),
N_("Number of images captured in burst sequence"),
sonyMisc3cId, makerTags, unsignedLong, -1, printSonyMisc3cSequenceNumber},
// In Exiftool, "SequenceLength1" is called "SequenceLength. Renamed due to clash of names."
{22, "SequenceLength1", N_("Sequence length 1"),
N_("Length of the sequence of photos taken"),
sonyMisc3cId, makerTags, unsignedByte, -1, EXV_PRINT_TAG(sonyMisc3cSequenceLength1)},
{26, "SequenceFileNumber", N_("Sequence file number"),
N_("File number in burst sequence"),
sonyMisc3cId, makerTags, unsignedLong, -1, printSonyMisc3cSequenceNumber},
// In Exiftool, "SequenceLength2" is called "SequenceLength". Renamed due to clash of names."
{30, "SequenceLength2", N_("Sequence length 2"),
N_("Length of the sequence of photos taken"),
sonyMisc3cId, makerTags, unsignedByte, -1, EXV_PRINT_TAG(sonyMisc3cSequenceLength2)},
{41, "CameraOrientation", N_("Camera orientation"),
N_("Orientation of the camera when the photo was taken"),
sonyMisc3cId, makerTags, unsignedByte, -1, EXV_PRINT_TAG(sonyMisc3cCameraOrientation)},
{42, "Quality2", N_("Quality 2"),
N_("Quality 2"),
sonyMisc3cId, makerTags, unsignedByte, -1, printSonyMisc3cQuality2},
{71, "SonyImageHeight", N_("Sony image height"),
N_("Height of the image"),
sonyMisc3cId, makerTags, unsignedShort, -1, printSonyMisc3cSonyImageHeight},
{83, "ModelReleaseYear", N_("Model release year"),
N_("Year that the model of camera was released"),
sonyMisc3cId, makerTags, unsignedByte, -1, printSonyMisc3cModelReleaseYear},
// End of list marker
{0xffff, "(UnknownSonyMisc3c)", "(Unknown SonyMisc3c Tag)",
N_("Unknown SonyMisc23 tag"),
sonyMisc3cId, makerTags, asciiString, -1, printValue},
};
const TagInfo* SonyMakerNote::tagListSonyMisc3c()
{
return tagInfoSonyMisc3c_;
}
std::ostream& SonyMakerNote::printSonyMisc3cShotNumberSincePowerUp(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 support this tag
static constexpr const char* models[] = { "ILCA-68", "ILCA-77M2", "ILCA-99M2",
"ILCE-5000", "ILCE-5100", "ILCE-6000", "ILCE-6300", "ILCE-6500", "ILCE-7",
"ILCE-7M2", "ILCE-7R", "ILCE-7RM2", "ILCE-7S", "ILCE-7SM2", "ILCE-QX1",
"DSC-HX350", "DSC-HX400V", "DSC-HX60V", "DSC-HX80", "DSC-HX90", "DSC-HX90V",
"DSC-QX30", "DSC-RX0", "DSC-RX1RM2", "DSC-RX10", "DSC-RX10M2", "DSC-RX10M3",
"DSC-RX100M3", "DSC-RX100M4", "DSC-RX100M5", "DSC-WX220", "DSC-WX350", "DSC-WX500"
};
std::string model = pos->toString();
for (auto& m : models) {
if (m == model)
return os << value.toLong();
}
return os << N_("n/a");
}
std::ostream& SonyMakerNote::printSonyMisc3cSequenceNumber(std::ostream& os, const Value& value, const ExifData*)
{
return (value.count() != 1) ? os << "(" << value << ")" : os << (value.toLong()+1);
}
std::ostream& SonyMakerNote::printSonyMisc3cQuality2(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 << ")";
long val = value.toLong();
std::string model = pos->toString();
// Value is interpreted differently if model is in list or not
for (auto& m : { "ILCE-1", "ILCE-7SM3", "ILME-FX3" }) {
if (m == model) {
switch (val) {
case 1:
return os << N_("JPEG");
case 2:
return os << N_("Raw");
case 3:
return os << N_("Raw + JPEG");
case 4:
return os << N_("HEIF");
case 6:
return os << N_("Raw + HEIF");
default:
return os << "(" << val << ")";
}
}
}
switch (val) {
case 0:
return os << N_("JPEG");
case 1:
return os << N_("Raw");
case 2:
return os << N_("Raw + JPEG");
case 3:
return os << N_("Raw + MPO");
default:
os << "(" << val << ")";
}
return os;
}
std::ostream& SonyMakerNote::printSonyMisc3cSonyImageHeight(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 << ")";
std::string model = pos->toString();
// Models that do not support this tag
for (auto& m : { "ILCE-1", "ILCE-7SM3", "ILME-FX3" }) {
if (m == model)
return os << N_("n/a");
}
long val = value.toLong();
return val > 0 ? os << (8*val) : os << N_("n/a");
}
std::ostream& SonyMakerNote::printSonyMisc3cModelReleaseYear(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 << ")";
std::string model = pos->toString();
// Models that do not support this tag
for (auto& m : { "ILCE-1", "ILCE-7SM3", "ILME-FX3" }) {
if (m == model)
return os << N_("n/a");
}
long val = value.toLong();
if (val > 99)
return os << "(" << val << ")";
if (val == 0)
return os << "2000";
return os << "20" << val;
}
//! Sony Tag 2010 Sony2010 (Miscellaneous)
constexpr TagInfo SonyMakerNote::tagInfo2010e_[] = {
{0, "SequenceImageNumber", N_("Sequence Image Number"), N_("Sequence Image Number"), sony2010eId, makerTags, unsignedLong, 1, printValue},

View File

@ -53,6 +53,8 @@ namespace Exiv2 {
static const TagInfo* tagListSonyMisc1();
//! Return read-only list of built-in Sony Misc2b tags (Tag 9404)
static const TagInfo* tagListSonyMisc2b();
//! Return read-only list of built-in Sony Misc3c tags (Tag 9400)
static const TagInfo* tagListSonyMisc3c();
static const TagInfo* tagList2010e();
@ -68,6 +70,16 @@ namespace Exiv2 {
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 SonyMisc3c shot number since power up value
static std::ostream& printSonyMisc3cShotNumberSincePowerUp(std::ostream&, const Value&, const ExifData*);
//! Print SonyMisc3c sequence number
static std::ostream& printSonyMisc3cSequenceNumber(std::ostream&, const Value&, const ExifData*);
//! Print SonyMisc3c Sony image height value
static std::ostream& printSonyMisc3cSonyImageHeight(std::ostream&, const Value&, const ExifData* metadata);
//! Print SonyMisc3c model release year value
static std::ostream& printSonyMisc3cModelReleaseYear(std::ostream&, const Value&, const ExifData* metadata);
//! Print SonyMisc3c quality 2 value
static std::ostream& printSonyMisc3cQuality2(std::ostream&, const Value&, const ExifData* metadata);
//! Print Sony Camera Model
static std::ostream& print0xb000(std::ostream&, const Value&, const ExifData*);
//! Print Full and Preview Image size
@ -81,6 +93,7 @@ namespace Exiv2 {
static const TagInfo tagInfoFp_[];
static const TagInfo tagInfoSonyMisc1_[];
static const TagInfo tagInfoSonyMisc2b_[];
static const TagInfo tagInfoSonyMisc3c_[];
static const TagInfo tagInfo2010e_[];
}; // class SonyMakerNote

View File

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

View File

@ -176,6 +176,7 @@ namespace Exiv2 {
sony2FpId,
sonyMisc1Id,
sonyMisc2bId,
sonyMisc3cId,
sony2010eId,
sony1MltCs7DId,
sony1MltCsOldId,

View File

@ -869,6 +869,35 @@ namespace Exiv2 {
{ sonyMisc2bCfg, sonyMisc2bDef, EXV_COUNTOF(sonyMisc2bDef) }
};
constexpr ArrayCfg sonyMisc3cCfg = {
sonyMisc3cId, // 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 sonyMisc3cDef[] = {
{ 0x09, ttUnsignedByte , 1 }, // Exif.SonyMisc3c.ReleaseMode2
{ 0x0a, ttUnsignedLong , 1 }, // Exif.SonyMisc3c.ShotNumberSincePowerUp
{ 0x12, ttUnsignedLong , 1 }, // Exif.SonyMisc3c.SequenceImageNumber
{ 0x16, ttUnsignedByte , 1 }, // Exif.SonyMisc3c.SequenceLength1
{ 0x1a, ttUnsignedLong , 1 }, // Exif.SonyMisc3c.SequenceFileNumber
{ 0x1e, ttUnsignedByte , 1 }, // Exif.SonyMisc3c.SequenceLength2
{ 0x29, ttUnsignedByte , 1 }, // Exif.SonyMisc3c.CameraOrientation
{ 0x2a, ttUnsignedByte , 1 }, // Exif.SonyMisc3c.Quality2
{ 0x47, ttUnsignedShort , 1 }, // Exif.SonyMisc3c.SonyImageHeight
{ 0x53, ttUnsignedByte , 1 }, // Exif.SonyMisc3c.ModelReleaseYear
};
//! SonyMisc3c Settings configurations and definitions
constexpr ArraySet sonyMisc3cSet[] = {
{ sonyMisc3cCfg, sonyMisc3cDef, EXV_COUNTOF(sonyMisc3cDef) }
};
constexpr ArrayCfg sony2010eCfg = {
sony2010eId, // Group for the elements
invalidByteOrder, // inherit from file. Usually littleEndian
@ -1141,6 +1170,7 @@ namespace Exiv2 {
{ Tag::root, sony2FpId, sony1Id, 0x9402 },
{ Tag::root, sonyMisc1Id, sony1Id, 0x9403 },
{ Tag::root, sonyMisc2bId, sony1Id, 0x9404 },
{ Tag::root, sonyMisc3cId, sony1Id, 0x9400 },
{ Tag::root, sony1CsId, sony1Id, 0x0114 },
{ Tag::root, sony1Cs2Id, sony1Id, 0x0114 },
{ Tag::root, sonyMltId, sony1Id, 0xb028 },
@ -1153,6 +1183,7 @@ namespace Exiv2 {
{ Tag::root, sony2FpId, sony2Id, 0x9402 },
{ Tag::root, sonyMisc1Id, sony2Id, 0x9403 },
{ Tag::root, sonyMisc2bId, sony2Id, 0x9404 },
{ Tag::root, sonyMisc3cId, sony2Id, 0x9400 },
{ Tag::root, sony2CsId, sony2Id, 0x0114 },
{ Tag::root, sony2Cs2Id, sony2Id, 0x0114 },
{ Tag::root, minoltaId, exifId, 0x927c },
@ -1595,6 +1626,10 @@ namespace Exiv2 {
{ Tag::all, sonyMisc2bId, newTiffBinaryElement },
{ 0x9404, sony1Id, EXV_COMPLEX_BINARY_ARRAY(sonyMisc2bSet, sonyMisc2bSelector) },
// Tag 0x9400 SonyMisc3c
{ Tag::all, sonyMisc3cId, newTiffBinaryElement },
{ 0x9400, sony1Id, EXV_COMPLEX_BINARY_ARRAY(sonyMisc3cSet, sonyMisc3cSelector) },
// Tag 0x9403 SonyMisc1
{ Tag::all, sonyMisc1Id, newTiffBinaryElement },
{ 0x9403, sony1Id, EXV_BINARY_ARRAY(sonyMisc1Cfg, sonyMisc1Def) },
@ -1624,6 +1659,10 @@ namespace Exiv2 {
{ Tag::all, sonyMisc2bId, newTiffBinaryElement },
{ 0x9404, sony2Id, EXV_COMPLEX_BINARY_ARRAY(sonyMisc2bSet, sonyMisc2bSelector) },
// Tag 0x9400 SonyMisc3c
{ Tag::all, sonyMisc3cId, newTiffBinaryElement },
{ 0x9400, sony2Id, EXV_COMPLEX_BINARY_ARRAY(sonyMisc3cSet, sonyMisc3cSelector) },
// Sony2 makernote
{ 0x0114, sony2Id, EXV_COMPLEX_BINARY_ARRAY(sony2CsSet, sonyCsSelector) },
{ Tag::next, sony2Id, ignoreTiffComponent },