Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix 582 Add support for FocusPosition in Sony RAW files #906

Merged
merged 9 commits into from
Jun 26, 2019
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 @@ -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
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
8 changes: 8 additions & 0 deletions src/sonymn_int.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -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
//@{
Expand All @@ -71,9 +74,14 @@ namespace Exiv2 {
static const TagInfo tagInfo_[];
static const TagInfo tagInfoCs_[];
static const TagInfo tagInfoCs2_[];
static const TagInfo tagInfoFp_[];

}; // class SonyMakerNote

DataBuf sonyTagCipher (uint16_t, const byte*, uint32_t, TiffComponent* const, bool bCipher);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function can very well be static in the .cpp, couldn't it?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you're right, it could be static. It started of life as a single decipher function and grown. sonyTagCipher does not need to be visible outside of sonymn_int.cpp.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm going to update the PR to be sure sonyTagCipher() doesn't end up in visible symbols. I think you'll have to approve that change. I understand what "squashing commits" does, however I've never done it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2335 rmills@rmillsmbp:~/gnu/github/exiv2/0.27-maintenance/build $ nm -g --demangle lib/libexiv2.0.27.2.1.dylib | grep sonyTag
00000000001c75a0 T Exiv2::Internal::sonyTagCipher(unsigned short, unsigned char const*, unsigned int, Exiv2::Internal::TiffComponent*, bool)
00000000001c77b0 T Exiv2::Internal::sonyTagDecipher(unsigned short, unsigned char const*, unsigned int, Exiv2::Internal::TiffComponent*)
00000000001c7890 T Exiv2::Internal::sonyTagEncipher(unsigned short, unsigned char const*, unsigned int, Exiv2::Internal::TiffComponent*)
2336 rmills@rmillsmbp:~/gnu/github/exiv2/0.27-maintenance/build $ ce ../src/sonymn_int.cpp 
bbedit "../src/sonymn_int.cpp"

2337 rmills@rmillsmbp:~/gnu/github/exiv2/0.27-maintenance/build $ make
[ 10%] Built target exiv2-xmp
...
2338 rmills@rmillsmbp:~/gnu/github/exiv2/0.27-maintenance/build $ nm -g --demangle lib/libexiv2.0.27.2.1.dylib | grep sonyTag
00000000001c75a0 T Exiv2::Internal::sonyTagDecipher(unsigned short, unsigned char const*, unsigned int, Exiv2::Internal::TiffComponent*)
00000000001c7890 T Exiv2::Internal::sonyTagEncipher(unsigned short, unsigned char const*, unsigned int, Exiv2::Internal::TiffComponent*)

Copy link
Collaborator

@piponazo piponazo Jun 26, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Robin, you did not push that change yet, right?

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_
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 @@ -154,6 +154,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 @@ -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_);
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]