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 \
|
||||
OlympusFe1 \
|
||||
OlympusRi \
|
||||
Panasonic \
|
||||
Panasonic \
|
||||
PanasonicRaw \
|
||||
Pentax \
|
||||
Samsung2 \
|
||||
@ -110,7 +110,8 @@ TABLES = Exif \
|
||||
Sony1Cs2 \
|
||||
Sony1MltCs7D \
|
||||
Sony1MltCsOld \
|
||||
Sony1MltCsA100
|
||||
Sony1MltCsA100 \
|
||||
Sony2Fp
|
||||
|
||||
SCHEMA = xmp_dc \
|
||||
xmp_dwc \
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
#include "minoltamn_int.hpp"
|
||||
#include "sonymn_int.hpp"
|
||||
#include "tags_int.hpp"
|
||||
#include "tiffcomposite_int.hpp"
|
||||
#include "value.hpp"
|
||||
#include "i18n.h" // NLS support.
|
||||
|
||||
@ -795,4 +796,54 @@ namespace Exiv2 {
|
||||
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
|
||||
|
||||
@ -36,6 +36,7 @@ Email communication with <a href="mailto:caulier dot gilles at gmail dot com">ca
|
||||
// included header files
|
||||
#include "tags.hpp"
|
||||
#include "types.hpp"
|
||||
#include "tiffcomposite_int.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <string>
|
||||
@ -58,6 +59,8 @@ namespace Exiv2 {
|
||||
static const TagInfo* tagListCs();
|
||||
//! Return read-only list of built-in Sony Standard Camera Settings version 2 tags
|
||||
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
|
||||
//@{
|
||||
@ -71,9 +74,13 @@ namespace Exiv2 {
|
||||
static const TagInfo tagInfo_[];
|
||||
static const TagInfo tagInfoCs_[];
|
||||
static const TagInfo tagInfoCs2_[];
|
||||
static const TagInfo tagInfoFp_[];
|
||||
|
||||
}; // 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
|
||||
|
||||
#endif // #ifndef SONYMN_INT_HPP_
|
||||
|
||||
@ -162,9 +162,10 @@ namespace Exiv2 {
|
||||
{ sony1MltCs7DId, "Makernote", "Sony1MltCs7D", MinoltaMakerNote::tagListCs7D },
|
||||
{ sony1MltCsOldId, "Makernote", "Sony1MltCsOld",MinoltaMakerNote::tagListCsStd },
|
||||
{ sony1MltCsNewId, "Makernote", "Sony1MltCsNew",MinoltaMakerNote::tagListCsStd },
|
||||
{ sony1MltCsA100Id,"Makernote","Sony1MltCsA100",MinoltaMakerNote::tagListCsA100},
|
||||
{ sony1MltCsA100Id,"Makernote", "Sony1MltCsA100",MinoltaMakerNote::tagListCsA100},
|
||||
{ sony2CsId, "Makernote", "Sony2Cs", SonyMakerNote::tagListCs },
|
||||
{ sony2Cs2Id, "Makernote", "Sony2Cs2", SonyMakerNote::tagListCs2 },
|
||||
{ sony2FpId, "Makernote", "Sony2Fp", SonyMakerNote::tagListFp },
|
||||
{ lastId, "(Last IFD info)", "(Last IFD item)", 0 }
|
||||
};
|
||||
|
||||
|
||||
@ -154,6 +154,7 @@ namespace Exiv2 {
|
||||
sony1Cs2Id,
|
||||
sony2CsId,
|
||||
sony2Cs2Id,
|
||||
sony2FpId,
|
||||
sony1MltCs7DId,
|
||||
sony1MltCsOldId,
|
||||
sony1MltCsNewId,
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
#include "error.hpp"
|
||||
#include "makernote_int.hpp"
|
||||
#include "sonymn_int.hpp"
|
||||
#include "tiffvisitor_int.hpp"
|
||||
#include "i18n.h" // NLS support.
|
||||
|
||||
@ -767,6 +768,24 @@ namespace Exiv2 {
|
||||
false, // Don't concatenate gaps
|
||||
{ 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
|
||||
extern const ArrayDef sonyCsDef[] = {
|
||||
{ 12, ttSignedShort, 1 } // Exif.Sony[12]Cs.WhiteBalanceFineTune
|
||||
@ -988,6 +1007,7 @@ namespace Exiv2 {
|
||||
{ Tag::root, sony1MltCs7DId, sonyMltId, 0x0004 },
|
||||
{ Tag::root, sony1MltCsA100Id, sonyMltId, 0x0114 },
|
||||
{ Tag::root, sony2Id, exifId, 0x927c },
|
||||
{ Tag::root, sony2FpId, sony2Id, 0x9402 },
|
||||
{ Tag::root, sony2CsId, sony2Id, 0x0114 },
|
||||
{ Tag::root, sony2Cs2Id, sony2Id, 0x0114 },
|
||||
{ Tag::root, minoltaId, exifId, 0x927c },
|
||||
@ -1418,6 +1438,10 @@ namespace Exiv2 {
|
||||
{ Tag::all, sony1CsId, newTiffBinaryElement },
|
||||
{ Tag::all, sony1Cs2Id, newTiffBinaryElement },
|
||||
|
||||
// Tag 0x9402 Sony2Fp Focus Position
|
||||
{ Tag::all, sony2FpId, newTiffBinaryElement },
|
||||
{ 0x9402, sony2Id, EXV_BINARY_ARRAY(sony2FpCfg, sony2FpDef) },
|
||||
|
||||
// Sony2 makernote
|
||||
{ 0x0114, sony2Id, EXV_COMPLEX_BINARY_ARRAY(sony2CsSet, sonyCsSelector) },
|
||||
{ Tag::next, sony2Id, ignoreTiffComponent },
|
||||
|
||||
@ -36,6 +36,7 @@
|
||||
#include "value.hpp"
|
||||
#include "image.hpp"
|
||||
#include "jpgimage.hpp"
|
||||
#include "sonymn_int.hpp"
|
||||
#include "i18n.h" // NLS support.
|
||||
|
||||
// + standard includes
|
||||
@ -780,7 +781,10 @@ namespace Exiv2 {
|
||||
if (!object->initialize(pRoot_)) return;
|
||||
|
||||
// Re-encrypt buffer if necessary
|
||||
const CryptFct cryptFct = object->cfg()->cryptFct_;
|
||||
CryptFct cryptFct = object->cfg()->cryptFct_;
|
||||
if ( cryptFct == sonyTagDecipher ) {
|
||||
cryptFct = sonyTagEncipher;
|
||||
}
|
||||
if (cryptFct != 0) {
|
||||
const byte* pData = object->pData();
|
||||
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