Add support for FocusPosition in Sony RAW files (#906)
* Fix 582 Add support for FocusPosition in Sony RAW files * Thanks to @boardhead sonyFpCrypt() works correctly. Removed debug code. Fixed typos. * Update doc/templates/Makefile to process Sony2Fp * Following review by @boardhead. Renamed sonyFpCrypt() as sonyTagDecipher(). * Fixed writing the tag thanks to @boardhead explaining encipher/decipher. Sadly, ArrayCfg/crpyt does not know if he's encrypting/decrypting. I've added a sniff in TiffEncoder::visitBinaryArrayEnd to avoid changing the API. * Added URL to discussion concerning sonyTagCipher() * make sonyTagCipher() a static function with no external visibility.
This commit is contained in:
parent
0a47d93ccf
commit
ab375fb074
5
doc/templates/Makefile
vendored
5
doc/templates/Makefile
vendored
@ -98,7 +98,7 @@ TABLES = Exif \
|
|||||||
OlympusFi \
|
OlympusFi \
|
||||||
OlympusFe1 \
|
OlympusFe1 \
|
||||||
OlympusRi \
|
OlympusRi \
|
||||||
Panasonic \
|
Panasonic \
|
||||||
PanasonicRaw \
|
PanasonicRaw \
|
||||||
Pentax \
|
Pentax \
|
||||||
Samsung2 \
|
Samsung2 \
|
||||||
@ -110,7 +110,8 @@ TABLES = Exif \
|
|||||||
Sony1Cs2 \
|
Sony1Cs2 \
|
||||||
Sony1MltCs7D \
|
Sony1MltCs7D \
|
||||||
Sony1MltCsOld \
|
Sony1MltCsOld \
|
||||||
Sony1MltCsA100
|
Sony1MltCsA100 \
|
||||||
|
Sony2Fp
|
||||||
|
|
||||||
SCHEMA = xmp_dc \
|
SCHEMA = xmp_dc \
|
||||||
xmp_dwc \
|
xmp_dwc \
|
||||||
|
|||||||
@ -28,6 +28,7 @@
|
|||||||
#include "minoltamn_int.hpp"
|
#include "minoltamn_int.hpp"
|
||||||
#include "sonymn_int.hpp"
|
#include "sonymn_int.hpp"
|
||||||
#include "tags_int.hpp"
|
#include "tags_int.hpp"
|
||||||
|
#include "tiffcomposite_int.hpp"
|
||||||
#include "value.hpp"
|
#include "value.hpp"
|
||||||
#include "i18n.h" // NLS support.
|
#include "i18n.h" // NLS support.
|
||||||
|
|
||||||
@ -795,4 +796,54 @@ namespace Exiv2 {
|
|||||||
return tagInfoCs2_;
|
return tagInfoCs2_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Sony Tag 9402 Sony2Fp (FocusPosition)
|
||||||
|
const TagInfo SonyMakerNote::tagInfoFp_[] = {
|
||||||
|
TagInfo( 0x04, "AmbientTemperature", N_("Ambient Temperature"), N_("Ambient Temperature"), sony2FpId, makerTags, signedByte, 1, printValue),
|
||||||
|
TagInfo( 0x16, "FocusMode" , N_("Focus Mode") , N_("Focus Mode") , sony2FpId, makerTags, unsignedByte, 1, printValue),
|
||||||
|
TagInfo( 0x17, "AFAreaMode" , N_("AF Area Mode") , N_("AF Area Mode") , sony2FpId, makerTags, unsignedByte, 1, printValue),
|
||||||
|
TagInfo( 0x2d, "FocusPosition2" , N_("Focus Position 2") , N_("Focus Position 2") , sony2FpId, makerTags, unsignedByte, 1, printValue),
|
||||||
|
// End of list marker
|
||||||
|
TagInfo(0xffff, "(Unknownsony2FpTag)", "(Unknownsony2FpTag)" , "(Unknownsony2FpTag)" , sony2FpId, makerTags, unsignedByte, 1, printValue)
|
||||||
|
};
|
||||||
|
|
||||||
|
const TagInfo* SonyMakerNote::tagListFp()
|
||||||
|
{
|
||||||
|
return tagInfoFp_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://github.com/Exiv2/exiv2/pull/906#issuecomment-504338797
|
||||||
|
static DataBuf sonyTagCipher(uint16_t /* tag */, const byte* bytes, uint32_t size, TiffComponent* const /*object*/, bool bDecipher)
|
||||||
|
{
|
||||||
|
DataBuf b(bytes,size); // copy the data
|
||||||
|
|
||||||
|
// initialize the code table
|
||||||
|
byte code[256];
|
||||||
|
for ( uint32_t i = 0 ; i < 249 ; i++ ) {
|
||||||
|
if ( bDecipher ) {
|
||||||
|
code[(i * i * i) % 249] = i ;
|
||||||
|
} else {
|
||||||
|
code[i] = (i * i * i) % 249 ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for ( uint32_t i = 249 ; i < 256 ; i++ ) {
|
||||||
|
code[i] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// code byte-by-byte
|
||||||
|
for ( uint32_t i = 0 ; i < size ; i++ ) {
|
||||||
|
b.pData_[i] = code[bytes[i]];
|
||||||
|
}
|
||||||
|
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
DataBuf sonyTagDecipher(uint16_t tag, const byte* bytes, uint32_t size, TiffComponent* const object)
|
||||||
|
{
|
||||||
|
return sonyTagCipher(tag,bytes,size,object,true);
|
||||||
|
}
|
||||||
|
DataBuf sonyTagEncipher(uint16_t tag, const byte* bytes, uint32_t size, TiffComponent* const object)
|
||||||
|
{
|
||||||
|
return sonyTagCipher(tag,bytes,size,object,false);
|
||||||
|
}
|
||||||
|
|
||||||
}} // namespace Internal, Exiv2
|
}} // namespace Internal, Exiv2
|
||||||
|
|||||||
@ -36,6 +36,7 @@ Email communication with <a href="mailto:caulier dot gilles at gmail dot com">ca
|
|||||||
// included header files
|
// included header files
|
||||||
#include "tags.hpp"
|
#include "tags.hpp"
|
||||||
#include "types.hpp"
|
#include "types.hpp"
|
||||||
|
#include "tiffcomposite_int.hpp"
|
||||||
|
|
||||||
// + standard includes
|
// + standard includes
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -58,6 +59,8 @@ namespace Exiv2 {
|
|||||||
static const TagInfo* tagListCs();
|
static const TagInfo* tagListCs();
|
||||||
//! Return read-only list of built-in Sony Standard Camera Settings version 2 tags
|
//! Return read-only list of built-in Sony Standard Camera Settings version 2 tags
|
||||||
static const TagInfo* tagListCs2();
|
static const TagInfo* tagListCs2();
|
||||||
|
//! Return read-only list of built-in Sony FocusPosition tags
|
||||||
|
static const TagInfo* tagListFp();
|
||||||
|
|
||||||
//! @name Print functions for Sony %MakerNote tags
|
//! @name Print functions for Sony %MakerNote tags
|
||||||
//@{
|
//@{
|
||||||
@ -71,9 +74,13 @@ namespace Exiv2 {
|
|||||||
static const TagInfo tagInfo_[];
|
static const TagInfo tagInfo_[];
|
||||||
static const TagInfo tagInfoCs_[];
|
static const TagInfo tagInfoCs_[];
|
||||||
static const TagInfo tagInfoCs2_[];
|
static const TagInfo tagInfoCs2_[];
|
||||||
|
static const TagInfo tagInfoFp_[];
|
||||||
|
|
||||||
}; // class SonyMakerNote
|
}; // class SonyMakerNote
|
||||||
|
|
||||||
|
DataBuf sonyTagDecipher(uint16_t, const byte*, uint32_t, TiffComponent* const);
|
||||||
|
DataBuf sonyTagEncipher(uint16_t, const byte*, uint32_t, TiffComponent* const);
|
||||||
|
|
||||||
}} // namespace Internal, Exiv2
|
}} // namespace Internal, Exiv2
|
||||||
|
|
||||||
#endif // #ifndef SONYMN_INT_HPP_
|
#endif // #ifndef SONYMN_INT_HPP_
|
||||||
|
|||||||
@ -162,9 +162,10 @@ namespace Exiv2 {
|
|||||||
{ sony1MltCs7DId, "Makernote", "Sony1MltCs7D", MinoltaMakerNote::tagListCs7D },
|
{ sony1MltCs7DId, "Makernote", "Sony1MltCs7D", MinoltaMakerNote::tagListCs7D },
|
||||||
{ sony1MltCsOldId, "Makernote", "Sony1MltCsOld",MinoltaMakerNote::tagListCsStd },
|
{ sony1MltCsOldId, "Makernote", "Sony1MltCsOld",MinoltaMakerNote::tagListCsStd },
|
||||||
{ sony1MltCsNewId, "Makernote", "Sony1MltCsNew",MinoltaMakerNote::tagListCsStd },
|
{ sony1MltCsNewId, "Makernote", "Sony1MltCsNew",MinoltaMakerNote::tagListCsStd },
|
||||||
{ sony1MltCsA100Id,"Makernote","Sony1MltCsA100",MinoltaMakerNote::tagListCsA100},
|
{ sony1MltCsA100Id,"Makernote", "Sony1MltCsA100",MinoltaMakerNote::tagListCsA100},
|
||||||
{ sony2CsId, "Makernote", "Sony2Cs", SonyMakerNote::tagListCs },
|
{ sony2CsId, "Makernote", "Sony2Cs", SonyMakerNote::tagListCs },
|
||||||
{ sony2Cs2Id, "Makernote", "Sony2Cs2", SonyMakerNote::tagListCs2 },
|
{ sony2Cs2Id, "Makernote", "Sony2Cs2", SonyMakerNote::tagListCs2 },
|
||||||
|
{ sony2FpId, "Makernote", "Sony2Fp", SonyMakerNote::tagListFp },
|
||||||
{ lastId, "(Last IFD info)", "(Last IFD item)", 0 }
|
{ lastId, "(Last IFD info)", "(Last IFD item)", 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -154,6 +154,7 @@ namespace Exiv2 {
|
|||||||
sony1Cs2Id,
|
sony1Cs2Id,
|
||||||
sony2CsId,
|
sony2CsId,
|
||||||
sony2Cs2Id,
|
sony2Cs2Id,
|
||||||
|
sony2FpId,
|
||||||
sony1MltCs7DId,
|
sony1MltCs7DId,
|
||||||
sony1MltCsOldId,
|
sony1MltCsOldId,
|
||||||
sony1MltCsNewId,
|
sony1MltCsNewId,
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "error.hpp"
|
#include "error.hpp"
|
||||||
#include "makernote_int.hpp"
|
#include "makernote_int.hpp"
|
||||||
|
#include "sonymn_int.hpp"
|
||||||
#include "tiffvisitor_int.hpp"
|
#include "tiffvisitor_int.hpp"
|
||||||
#include "i18n.h" // NLS support.
|
#include "i18n.h" // NLS support.
|
||||||
|
|
||||||
@ -767,6 +768,24 @@ namespace Exiv2 {
|
|||||||
false, // Don't concatenate gaps
|
false, // Don't concatenate gaps
|
||||||
{ 0, ttUnsignedShort, 1 }
|
{ 0, ttUnsignedShort, 1 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern const ArrayCfg sony2FpCfg = {
|
||||||
|
sony2FpId, // Group for the elements
|
||||||
|
bigEndian, // Big 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 }
|
||||||
|
};
|
||||||
|
extern const ArrayDef sony2FpDef[] = {
|
||||||
|
{ 0x4, ttSignedByte , 1 }, // Exif.Sony2Fp.AmbientTemperature
|
||||||
|
{ 0x16, ttUnsignedByte, 1 }, // Exif.Sony2Fp.FocusMode
|
||||||
|
{ 0x17, ttUnsignedByte, 1 }, // Exif.Sony2Fp.AFAreaMode
|
||||||
|
{ 0x2d, ttUnsignedByte, 1 } // Exif.Sony2Fp.FocusPosition2
|
||||||
|
};
|
||||||
|
|
||||||
//! Sony[12] Camera Settings binary array - definition
|
//! Sony[12] Camera Settings binary array - definition
|
||||||
extern const ArrayDef sonyCsDef[] = {
|
extern const ArrayDef sonyCsDef[] = {
|
||||||
{ 12, ttSignedShort, 1 } // Exif.Sony[12]Cs.WhiteBalanceFineTune
|
{ 12, ttSignedShort, 1 } // Exif.Sony[12]Cs.WhiteBalanceFineTune
|
||||||
@ -988,6 +1007,7 @@ namespace Exiv2 {
|
|||||||
{ Tag::root, sony1MltCs7DId, sonyMltId, 0x0004 },
|
{ Tag::root, sony1MltCs7DId, sonyMltId, 0x0004 },
|
||||||
{ Tag::root, sony1MltCsA100Id, sonyMltId, 0x0114 },
|
{ Tag::root, sony1MltCsA100Id, sonyMltId, 0x0114 },
|
||||||
{ Tag::root, sony2Id, exifId, 0x927c },
|
{ Tag::root, sony2Id, exifId, 0x927c },
|
||||||
|
{ Tag::root, sony2FpId, sony2Id, 0x9402 },
|
||||||
{ 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 },
|
||||||
@ -1418,6 +1438,10 @@ namespace Exiv2 {
|
|||||||
{ Tag::all, sony1CsId, newTiffBinaryElement },
|
{ Tag::all, sony1CsId, newTiffBinaryElement },
|
||||||
{ Tag::all, sony1Cs2Id, newTiffBinaryElement },
|
{ Tag::all, sony1Cs2Id, newTiffBinaryElement },
|
||||||
|
|
||||||
|
// Tag 0x9402 Sony2Fp Focus Position
|
||||||
|
{ Tag::all, sony2FpId, newTiffBinaryElement },
|
||||||
|
{ 0x9402, sony2Id, EXV_BINARY_ARRAY(sony2FpCfg, sony2FpDef) },
|
||||||
|
|
||||||
// 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 },
|
||||||
|
|||||||
@ -36,6 +36,7 @@
|
|||||||
#include "value.hpp"
|
#include "value.hpp"
|
||||||
#include "image.hpp"
|
#include "image.hpp"
|
||||||
#include "jpgimage.hpp"
|
#include "jpgimage.hpp"
|
||||||
|
#include "sonymn_int.hpp"
|
||||||
#include "i18n.h" // NLS support.
|
#include "i18n.h" // NLS support.
|
||||||
|
|
||||||
// + standard includes
|
// + standard includes
|
||||||
@ -780,7 +781,10 @@ namespace Exiv2 {
|
|||||||
if (!object->initialize(pRoot_)) return;
|
if (!object->initialize(pRoot_)) return;
|
||||||
|
|
||||||
// Re-encrypt buffer if necessary
|
// Re-encrypt buffer if necessary
|
||||||
const CryptFct cryptFct = object->cfg()->cryptFct_;
|
CryptFct cryptFct = object->cfg()->cryptFct_;
|
||||||
|
if ( cryptFct == sonyTagDecipher ) {
|
||||||
|
cryptFct = sonyTagEncipher;
|
||||||
|
}
|
||||||
if (cryptFct != 0) {
|
if (cryptFct != 0) {
|
||||||
const byte* pData = object->pData();
|
const byte* pData = object->pData();
|
||||||
DataBuf buf = cryptFct(object->tag(), pData, size, pRoot_);
|
DataBuf buf = cryptFct(object->tag(), pData, size, pRoot_);
|
||||||
|
|||||||
BIN
test/data/exiv2-pr906.exv
Normal file
BIN
test/data/exiv2-pr906.exv
Normal file
Binary file not shown.
17
tests/bugfixes/github/test_pr_906.py
Normal file
17
tests/bugfixes/github/test_pr_906.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from system_tests import CaseMeta, path
|
||||||
|
|
||||||
|
class Sony2FpTest(metaclass=CaseMeta):
|
||||||
|
|
||||||
|
filename = path("$data_path/exiv2-pr906.exv")
|
||||||
|
commands = ["$exiv2 -pa --grep Sony2Fp $filename"]
|
||||||
|
|
||||||
|
stdout = ["""Exif.Sony2Fp.AmbientTemperature SByte 1 19
|
||||||
|
Exif.Sony2Fp.FocusMode Byte 1 6
|
||||||
|
Exif.Sony2Fp.AFAreaMode Byte 1 12
|
||||||
|
Exif.Sony2Fp.FocusPosition2 Byte 1 140
|
||||||
|
"""
|
||||||
|
]
|
||||||
|
stderr = [""]
|
||||||
|
retval = [0]
|
||||||
Loading…
Reference in New Issue
Block a user