Skip to content

Commit

Permalink
Add support for FocusPosition in Sony RAW files (#906)
Browse files Browse the repository at this point in the history
* 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.

(cherry picked from commit ab375fb)
  • Loading branch information
clanmills authored and D4N committed Jun 27, 2019
1 parent 2d3b4f8 commit a803ce3
Show file tree
Hide file tree
Showing 9 changed files with 110 additions and 4 deletions.
5 changes: 3 additions & 2 deletions doc/templates/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ TABLES = Exif \
OlympusFi \
OlympusFe1 \
OlympusRi \
Panasonic \
Panasonic \
PanasonicRaw \
Pentax \
Samsung2 \
Expand All @@ -110,7 +110,8 @@ TABLES = Exif \
Sony1Cs2 \
Sony1MltCs7D \
Sony1MltCsOld \
Sony1MltCsA100
Sony1MltCsA100 \
Sony2Fp

SCHEMA = xmp_dc \
xmp_dwc \
Expand Down
51 changes: 51 additions & 0 deletions src/sonymn_int.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down Expand Up @@ -796,4 +797,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
7 changes: 7 additions & 0 deletions src/sonymn_int.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,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>
Expand All @@ -57,6 +58,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
//@{
Expand All @@ -70,7 +73,11 @@ 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
3 changes: 2 additions & 1 deletion src/tags_int.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
};

Expand Down
1 change: 1 addition & 0 deletions src/tags_int.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ namespace Exiv2 {
sony1Cs2Id,
sony2CsId,
sony2Cs2Id,
sony2FpId,
sony1MltCs7DId,
sony1MltCsOldId,
sony1MltCsNewId,
Expand Down
24 changes: 24 additions & 0 deletions src/tiffimage_int.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "error.hpp"
#include "makernote_int.hpp"
#include "sonymn_int.hpp"
#include "tiffvisitor_int.hpp"
#include "i18n.h" // NLS support.

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 },
Expand Down Expand Up @@ -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 },
Expand Down
6 changes: 5 additions & 1 deletion src/tiffvisitor_int.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "value.hpp"
#include "image.hpp"
#include "jpgimage.hpp"
#include "sonymn_int.hpp"
#include "i18n.h" // NLS support.

// + standard includes
Expand Down Expand Up @@ -782,7 +783,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_);
Expand Down
Binary file added test/data/exiv2-pr906.exv
Binary file not shown.
17 changes: 17 additions & 0 deletions tests/bugfixes/github/test_pr_906.py
Original file line number Diff line number Diff line change
@@ -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]

0 comments on commit a803ce3

Please sign in to comment.