Skip to content

Commit 866d213

Browse files
authored
Merge pull request #1409 from Exiv2/fix_1402_rafimage_0.27
fix_1402_rafimage_0.27
2 parents 54506bd + 2466c78 commit 866d213

File tree

8 files changed

+216
-51
lines changed

8 files changed

+216
-51
lines changed

src/fujimn_int.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,47 @@ namespace Exiv2 {
340340
TagInfo(0x8003, "FrameNumber", N_("Frame Number"),
341341
N_("Frame number"),
342342
fujiId, makerTags, unsignedShort, -1, printValue),
343+
// #1402
344+
TagInfo(0xf000, "FujiIFD", N_("FujiIFD"),
345+
N_("Fujifilm IFD"),
346+
fujiId, makerTags, undefined, -1, printValue),
347+
TagInfo(0xf001, "RawImageFullWidth", N_("Raw Image Full Width"),
348+
N_("Raw Image Full Width"),
349+
fujiId, makerTags, undefined, -1, printValue),
350+
TagInfo(0xf002, "RawImageFullHeight", N_("Raw Image Full Height"),
351+
N_("Raw Image Full Height"),
352+
fujiId, makerTags, undefined, -1, printValue),
353+
TagInfo(0xf003, "BitsPerSample", N_("Bits Per Sample"),
354+
N_("Bits Per Sample"),
355+
fujiId, makerTags, undefined, -1, printValue),
356+
TagInfo(0xf007, "StripOffsets", N_("Strip Offsets"),
357+
N_("Strip Offsets"),
358+
fujiId, makerTags, undefined, -1, printValue),
359+
TagInfo(0xf008, "StripByteCounts", N_("Strip Byte Counts"),
360+
N_("Strip Byte Counts"),
361+
fujiId, makerTags, undefined, -1, printValue),
362+
TagInfo(0xf00a, "BlackLevel", N_("Black Level"),
363+
N_("Black Level"),
364+
fujiId, makerTags, undefined, -1, printValue),
365+
TagInfo(0xf00b, "GeometricDistortionParams", N_("Geometric Distortion Params"),
366+
N_("Geometric Distortion Params"),
367+
fujiId, makerTags, undefined, -1, printValue),
368+
TagInfo(0xf00c, "WB_GRBLevelsStandard", N_("WB GRB Levels Standard"),
369+
N_("WB GRB Levels Standard"),
370+
fujiId, makerTags, undefined, -1, printValue),
371+
TagInfo(0xf00d, "WB_GRBLevelsAuto", N_("WB GRB Levels Auto"),
372+
N_("WB GRB Levels Auto"),
373+
fujiId, makerTags, undefined, -1, printValue),
374+
TagInfo(0xf00e, "WB_GRBLevels", N_("WB GRB Levels"),
375+
N_("WB GRB Levels"),
376+
fujiId, makerTags, undefined, -1, printValue),
377+
TagInfo(0xf00f, "ChromaticAberrationParams", N_("Chromatic Aberration Params"),
378+
N_("Chromatic Aberration Params"),
379+
fujiId, makerTags, undefined, -1, printValue),
380+
TagInfo(0xf010, "VignettingParams", N_("Vignetting Params"),
381+
N_("Vignetting Params"),
382+
fujiId, makerTags, undefined, -1, printValue),
383+
343384
// End of list marker
344385
TagInfo(0xffff, "(UnknownFujiMakerNoteTag)", "(UnknownFujiMakerNoteTag)",
345386
N_("Unknown FujiMakerNote tag"),

src/rafimage.cpp

Lines changed: 86 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
#include "enforce.hpp"
3838
#include "safe_op.hpp"
3939

40-
// + standard includes
40+
// +standard includes
4141
#include <string>
4242
#include <cstring>
4343
#include <iostream>
@@ -92,7 +92,7 @@ namespace Exiv2 {
9292
// not supported
9393
throw(Error(kerInvalidSettingForImage, "Image comment", "RAF"));
9494
}
95-
95+
9696
void RafImage::printStructure(std::ostream& out, PrintStructureOption option, int depth) {
9797
if (io_->open() != 0) {
9898
throw Error(kerDataSourceOpenFailed, io_->path(), strError());
@@ -102,17 +102,21 @@ namespace Exiv2 {
102102
if (io_->error() || io_->eof()) throw Error(kerFailedToReadImageData);
103103
throw Error(kerNotAnImage, "RAF");
104104
}
105+
size_t address = 0 ;
106+
size_t address2 = 0 ;
105107
const bool bPrint = option==kpsBasic || option==kpsRecursive;
106108
if ( bPrint ) {
107109
io_->seek(0,BasicIo::beg); // rewind
110+
address = io_->tell();
111+
const char* format = " %8d | %8d | ";
108112

109113
{
110114
out << Internal::indent(depth)
111115
<< "STRUCTURE OF RAF FILE: "
112116
<< io().path()
113117
<< std::endl;
114118
out << Internal::indent(depth)
115-
<< Internal::stringFormat(" Length | Offset | Payload")
119+
<< Internal::stringFormat(" Address | Length | Payload")
116120
<< std::endl;
117121
}
118122

@@ -121,63 +125,79 @@ namespace Exiv2 {
121125
magicdata[16] = 0;
122126
{
123127
out << Internal::indent(depth)
124-
<< Internal::stringFormat(" %8u | %8u | ", 16, 0)
125-
<< "Magic number : "
126-
<< std::string((char*)&magicdata)
128+
<< Internal::stringFormat(format,address, 16, 0)
129+
<< " magic : "
130+
<< (char*) magicdata
127131
<< std::endl;
128132
}
129133

134+
address = io_->tell();
130135
byte data1 [5];
131136
io_->read(data1, 4);
132137
data1[4] = 0;
133138
{
134139
out << Internal::indent(depth)
135-
<< Internal::stringFormat(" %8u | %8u | ", 4, 16)
136-
<< "data 1 : "
140+
<< Internal::stringFormat(format,address, 4, 16)
141+
<< " data1 : "
137142
<< std::string((char*)&data1)
138143
<< std::endl;
139144
}
140145

146+
address = io_->tell();
141147
byte data2 [9];
142148
io_->read(data2, 8);
143149
data2[8] = 0;
144150
{
145151
out << Internal::indent(depth)
146-
<< Internal::stringFormat(" %8u | %8u | ", 8, 20)
147-
<< "data 2 : "
152+
<< Internal::stringFormat(format,address, 8, 20)
153+
<< " data2 : "
148154
<< std::string((char*)&data2)
149155
<< std::endl;
150156
}
151157

158+
address = io_->tell();
152159
byte camdata [33];
153160
io_->read(camdata, 32);
154161
camdata[32] = 0;
155162
{
156163
out << Internal::indent(depth)
157-
<< Internal::stringFormat(" %8u | %8u | ", 32, 28)
158-
<< "camera : "
164+
<< Internal::stringFormat(format,address, 32, 28)
165+
<< " camera : "
159166
<< std::string((char*)&camdata)
160167
<< std::endl;
161168
}
162169

170+
address = io_->tell();
163171
byte dir_version [5];
164172
io_->read(dir_version, 4);
165173
dir_version[4] = 0;
166174
{
167175
out << Internal::indent(depth)
168-
<< Internal::stringFormat(" %8u | %8u | ", 4, 60)
169-
<< "dir version : "
176+
<< Internal::stringFormat(format,address, 4, 60)
177+
<< " version : "
170178
<< std::string((char*)&dir_version)
171179
<< std::endl;
172180
}
173181

174-
byte unknown [20];
175-
io_->read(unknown, 20);
182+
address = io_->tell();
183+
DataBuf unknown(20);
184+
io_->read(unknown.pData_,unknown.size_);
185+
{
186+
out << Internal::indent(depth)
187+
<< Internal::stringFormat(format,address, 20)
188+
<< " unknown : "
189+
<< Internal::binaryToString(makeSlice(unknown, 0,unknown.size_))
190+
<< std::endl;
191+
}
176192

193+
194+
address = io_->tell();
177195
byte jpg_img_offset [4];
178196
io_->read(jpg_img_offset, 4);
179197
byte jpg_img_length [4];
198+
address2 = io_->tell();
180199
io_->read(jpg_img_length, 4);
200+
181201
long jpg_img_off = Exiv2::getULong((const byte *) jpg_img_offset, bigEndian);
182202
long jpg_img_len = Exiv2::getULong((const byte *) jpg_img_length, bigEndian);
183203
std::stringstream j_off;
@@ -186,20 +206,22 @@ namespace Exiv2 {
186206
j_len << jpg_img_len;
187207
{
188208
out << Internal::indent(depth)
189-
<< Internal::stringFormat(" %8u | %8u | ", 4, 84)
190-
<< "JPEG Image Offset : "
209+
<< Internal::stringFormat(format,address, 4)
210+
<< "JPEG Offset : "
191211
<< j_off.str()
192212
<< std::endl;
193213
out << Internal::indent(depth)
194-
<< Internal::stringFormat(" %8u | %8u | ", 4, 88)
195-
<< "JPEG Image Length : "
214+
<< Internal::stringFormat(format,address2, 4)
215+
<< "JPEG Length : "
196216
<< j_len.str()
197217
<< std::endl;
198218
}
199219

220+
address = io_->tell();
200221
byte cfa_header_offset [4];
201222
io_->read(cfa_header_offset, 4);
202223
byte cfa_header_length [4];
224+
address2 = io_->tell();
203225
io_->read(cfa_header_length, 4);
204226
long cfa_hdr_off = Exiv2::getULong((const byte *) cfa_header_offset, bigEndian);
205227
long cfa_hdr_len = Exiv2::getULong((const byte *) cfa_header_length, bigEndian);
@@ -209,20 +231,22 @@ namespace Exiv2 {
209231
ch_len << cfa_hdr_len;
210232
{
211233
out << Internal::indent(depth)
212-
<< Internal::stringFormat(" %8u | %8u | ", 4, 92)
213-
<< "CFA Header Offset : "
234+
<< Internal::stringFormat(format,address, 4)
235+
<< " CFA Offset : "
214236
<< ch_off.str()
215237
<< std::endl;
216238
out << Internal::indent(depth)
217-
<< Internal::stringFormat(" %8u | %8u | ", 4, 96)
218-
<< "CFA Header Length : "
239+
<< Internal::stringFormat(format,address2, 4)
240+
<< " CFA Length : "
219241
<< ch_len.str()
220242
<< std::endl;
221243
}
222244

223245
byte cfa_offset [4];
246+
address = io_->tell();
224247
io_->read(cfa_offset, 4);
225248
byte cfa_length [4];
249+
address2 = io_->tell();
226250
io_->read(cfa_length, 4);
227251
long cfa_off = Exiv2::getULong((const byte *) cfa_offset, bigEndian);
228252
long cfa_len = Exiv2::getULong((const byte *) cfa_length, bigEndian);
@@ -232,44 +256,47 @@ namespace Exiv2 {
232256
c_len << cfa_len;
233257
{
234258
out << Internal::indent(depth)
235-
<< Internal::stringFormat(" %8u | %8u | ", 4, 100)
236-
<< "CFA Offset : "
259+
<< Internal::stringFormat(format,address,4)
260+
<< "TIFF Offset : "
237261
<< c_off.str()
238262
<< std::endl;
239263
out << Internal::indent(depth)
240-
<< Internal::stringFormat(" %8u | %8u | ", 4, 104)
241-
<< "CFA Length : "
264+
<< Internal::stringFormat(format,address2,4)
265+
<< "TIFF Length : "
242266
<< c_len.str()
243267
<< std::endl;
244268
}
245269

246270
io_->seek(jpg_img_off, BasicIo::beg); // rewind
271+
address = io_->tell();
247272
DataBuf payload(16); // header is different from chunks
248273
io_->read(payload.pData_, payload.size_);
249274
{
250275
out << Internal::indent(depth)
251-
<< Internal::stringFormat(" %8u | %8u | ", jpg_img_len, jpg_img_off)
252-
<< "jpg image / exif : "
276+
<< Internal::stringFormat(format,address, jpg_img_len) // , jpg_img_off)
277+
<< " JPEG : "
253278
<< Internal::binaryToString(makeSlice(payload, 0, payload.size_))
254279
<< std::endl;
255280
}
256281

257282
io_->seek(cfa_hdr_off, BasicIo::beg); // rewind
283+
address = io_->tell();
258284
io_->read(payload.pData_, payload.size_);
259285
{
260286
out << Internal::indent(depth)
261-
<< Internal::stringFormat(" %8u | %8u | ", cfa_hdr_len, cfa_hdr_off)
262-
<< "CFA Header: "
287+
<< Internal::stringFormat(format,address, cfa_hdr_len, cfa_hdr_off)
288+
<< " CFA : "
263289
<< Internal::binaryToString(makeSlice(payload, 0, payload.size_))
264290
<< std::endl;
265291
}
266292

267293
io_->seek(cfa_off, BasicIo::beg); // rewind
294+
address = io_->tell();
268295
io_->read(payload.pData_, payload.size_);
269296
{
270297
out << Internal::indent(depth)
271-
<< Internal::stringFormat(" %8u | %8u | ", cfa_len, cfa_off)
272-
<< "CFA : "
298+
<< Internal::stringFormat(format,address, cfa_len, cfa_off)
299+
<< " TIFF : "
273300
<< Internal::binaryToString(makeSlice(payload, 0, payload.size_))
274301
<< std::endl;
275302
}
@@ -330,6 +357,31 @@ namespace Exiv2 {
330357
exifData_["Exif.Image2.JPEGInterchangeFormatLength"] = getULong(jpg_img_length, bigEndian);
331358

332359
setByteOrder(bo);
360+
361+
// parse the tiff
362+
byte readBuff[4];
363+
if (io_->seek(100, BasicIo::beg) != 0) throw Error(kerFailedToReadImageData);
364+
if (io_->read(readBuff, 4) != 4 ) throw Error(kerFailedToReadImageData);
365+
uint32_t tiffOffset = Exiv2::getULong(readBuff, bigEndian);
366+
367+
if (io_->read(readBuff, 4) != 4) throw Error(kerFailedToReadImageData);
368+
uint32_t tiffLength = Exiv2::getULong(readBuff, bigEndian);
369+
370+
// sanity check. Does tiff lie inside the file?
371+
enforce(Safe::add(tiffOffset, tiffLength) <= io_->size(), kerCorruptedMetadata);
372+
373+
DataBuf tiff(tiffLength);
374+
if (io_->seek(tiffOffset, BasicIo::beg) != 0) throw Error(kerFailedToReadImageData);
375+
io_->read(tiff.pData_, tiff.size_);
376+
377+
if (!io_->error() && !io_->eof())
378+
{
379+
TiffParser::decode(exifData_,
380+
iptcData_,
381+
xmpData_,
382+
tiff.pData_,
383+
tiff.size_);
384+
}
333385
} // RafImage::readMetadata
334386

335387
void RafImage::writeMetadata()

src/tiffcomposite_int.hpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,12 @@ namespace Exiv2 {
7676
Special TIFF tags for the use in TIFF structures only
7777
*/
7878
namespace Tag {
79-
const uint32_t none = 0x10000; //!< Dummy tag
80-
const uint32_t root = 0x20000; //!< Special tag: root IFD
81-
const uint32_t next = 0x30000; //!< Special tag: next IFD
82-
const uint32_t all = 0x40000; //!< Special tag: all tags in a group
83-
const uint32_t pana = 0x80000; //!< Special tag: root IFD of Panasonic RAW images
79+
const uint32_t none = 0x10000; //!< Dummy tag
80+
const uint32_t root = 0x20000; //!< Special tag: root IFD
81+
const uint32_t next = 0x30000; //!< Special tag: next IFD
82+
const uint32_t all = 0x40000; //!< Special tag: all tags in a group
83+
const uint32_t pana = 0x80000; //!< Special tag: root IFD of Panasonic RAW images
84+
const uint32_t fuji = 0x100000; //!< Special tag: root IFD of Fujifilm RAF images
8485
}
8586

8687
/*!
@@ -860,6 +861,7 @@ namespace Exiv2 {
860861
*/
861862
class TiffDirectory : public TiffComponent {
862863
friend class TiffEncoder;
864+
friend class TiffDecoder;
863865
public:
864866
//! @name Creators
865867
//@{

src/tiffimage.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,12 +256,22 @@ namespace Exiv2 {
256256
uint32_t size
257257
)
258258
{
259+
uint32_t root = Tag::root;
260+
261+
// #1402 Fujifilm RAF. Change root when parsing embedded tiff
262+
Exiv2::ExifKey key("Exif.Image.Make");
263+
if (exifData.findKey(key) != exifData.end()) {
264+
if ( exifData.findKey(key)->toString() == "FUJIFILM" ) {
265+
root = Tag::fuji;
266+
}
267+
}
268+
259269
return TiffParserWorker::decode(exifData,
260270
iptcData,
261271
xmpData,
262272
pData,
263273
size,
264-
Tag::root,
274+
root,
265275
TiffMapping::findDecoder);
266276
} // TiffParser::decode
267277

src/tiffimage_int.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,6 +1100,10 @@ namespace Exiv2 {
11001100
// Root directory
11011101
{ Tag::root, ifdIdNotSet, newTiffDirectory<ifd0Id> },
11021102

1103+
// Fujifilm RAF #1402. Use different root when parsing embedded tiff.
1104+
{ Tag::fuji, ifdIdNotSet, newTiffDirectory<fujiId> },
1105+
{ 0xf000, fujiId, newTiffSubIfd<fujiId> },
1106+
11031107
// IFD0
11041108
{ 0x8769, ifd0Id, newTiffSubIfd<exifId> },
11051109
{ 0x8825, ifd0Id, newTiffSubIfd<gpsId> },

0 commit comments

Comments
 (0)