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.
v0.27.3
Robin Mills 6 years ago committed by D4N
parent 0a47d93ccf
commit ab375fb074

@ -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_);

Binary file not shown.

@ -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…
Cancel
Save