Coverage Report

Created: 2026-08-11 07:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/exiv2/src/tiffimage_int.cpp
Line
Count
Source
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
3
#include "tiffimage_int.hpp"
4
#include "basicio.hpp"
5
#include "config.h"
6
#include "error.hpp"
7
#include "i18n.h"  // NLS support.
8
#include "image_int.hpp"
9
#include "makernote_int.hpp"
10
#include "sonymn_int.hpp"
11
#include "tags.hpp"
12
#include "tiffcomposite_int.hpp"
13
#include "tiffvisitor_int.hpp"
14
#include "value.hpp"
15
16
#ifdef EXIV2_DEBUG_MESSAGES
17
#include "tags_int.hpp"
18
#endif
19
20
#include <array>
21
#include <iostream>
22
23
// Shortcuts for the newTiffBinaryArray templates.
24
#define EXV_BINARY_ARRAY(arrayCfg, arrayDef) &newTiffBinaryArray0<arrayCfg, std::size(arrayDef), arrayDef>
25
#define EXV_SIMPLE_BINARY_ARRAY(arrayCfg) &newTiffBinaryArray1<arrayCfg>
26
#define EXV_COMPLEX_BINARY_ARRAY(arraySet, cfgSelFct) &newTiffBinaryArray2<std::size(arraySet), arraySet, cfgSelFct>
27
28
namespace Exiv2::Internal {
29
0
bool FindExifdatum::operator()(const Exiv2::Exifdatum& md) const {
30
0
  return ifdId_ == md.ifdId();
31
0
}
32
//! Constant for non-encrypted binary arrays
33
constexpr CryptFct notEncrypted = nullptr;
34
35
//! Canon Camera Settings binary array - configuration
36
constexpr ArrayCfg canonCsCfg = {
37
    IfdId::canonCsId,  // Group for the elements
38
    invalidByteOrder,  // Use byte order from parent
39
    ttUnsignedShort,   // Type for array entry and size element
40
    notEncrypted,      // Not encrypted
41
    true,              // With size element
42
    false,             // No fillers
43
    false,             // Don't concatenate gaps
44
    {0, ttUnsignedShort, 1},
45
};
46
47
//! Canon Camera Settings binary array - definition
48
constexpr ArrayDef canonCsDef[] = {
49
    {46, ttUnsignedShort, 3}  // Exif.CanonCs.Lens
50
};
51
52
//! Canon Shot Info binary array - configuration
53
constexpr ArrayCfg canonSiCfg = {
54
    IfdId::canonSiId,  // Group for the elements
55
    invalidByteOrder,  // Use byte order from parent
56
    ttUnsignedShort,   // Type for array entry and size element
57
    notEncrypted,      // Not encrypted
58
    true,              // With size element
59
    false,             // No fillers
60
    false,             // Don't concatenate gaps
61
    {0, ttUnsignedShort, 1},
62
};
63
64
//! Canon Panorama binary array - configuration
65
constexpr ArrayCfg canonPaCfg = {
66
    IfdId::canonPaId,  // Group for the elements
67
    invalidByteOrder,  // Use byte order from parent
68
    ttUnsignedShort,   // Type for array entry and size element
69
    notEncrypted,      // Not encrypted
70
    false,             // No size element
71
    false,             // No fillers
72
    false,             // Don't concatenate gaps
73
    {0, ttUnsignedShort, 1},
74
};
75
76
//! Canon Custom Function binary array - configuration
77
constexpr ArrayCfg canonCfCfg = {
78
    IfdId::canonCfId,  // Group for the elements
79
    invalidByteOrder,  // Use byte order from parent
80
    ttUnsignedShort,   // Type for array entry and size element
81
    notEncrypted,      // Not encrypted
82
    true,              // With size element
83
    false,             // No fillers
84
    false,             // Don't concatenate gaps
85
    {0, ttUnsignedShort, 1},
86
};
87
88
//! Canon Picture Info binary array - configuration
89
constexpr ArrayCfg canonPiCfg = {
90
    IfdId::canonPiId,  // Group for the elements
91
    invalidByteOrder,  // Use byte order from parent
92
    ttUnsignedShort,   // Type for array entry and size element
93
    notEncrypted,      // Not encrypted
94
    false,             // No size element
95
    false,             // No fillers
96
    false,             // Don't concatenate gaps
97
    {0, ttUnsignedShort, 1},
98
};
99
100
//! Canon Time Info binary array - configuration
101
constexpr ArrayCfg canonTiCfg = {
102
    IfdId::canonTiId,  // Group for the elements
103
    invalidByteOrder,  // Use byte order from parent
104
    ttSignedLong,      // Type for array entry and size element
105
    notEncrypted,      // Not encrypted
106
    true,              // With size element
107
    false,             // No fillers
108
    false,             // Don't concatenate gaps
109
    {0, ttSignedLong, 1},
110
};
111
112
//! Canon File Info binary array - configuration
113
constexpr ArrayCfg canonFiCfg = {
114
    IfdId::canonFiId,  // Group for the elements
115
    invalidByteOrder,  // Use byte order from parent
116
    ttUnsignedShort,   // Type for array entry and size element
117
    notEncrypted,      // Not encrypted
118
    true,              // Has a size element
119
    false,             // No fillers
120
    false,             // Don't concatenate gaps
121
    {0, ttSignedShort, 1},
122
};
123
//! Canon File Info binary array - definition
124
constexpr ArrayDef canonFiDef[] = {
125
    {2, ttUnsignedLong, 1},
126
};
127
128
//! Canon Processing Info binary array - configuration
129
constexpr ArrayCfg canonPrCfg = {
130
    IfdId::canonPrId,  // Group for the elements
131
    invalidByteOrder,  // Use byte order from parent
132
    ttUnsignedShort,   // Type for array entry and size element
133
    notEncrypted,      // Not encrypted
134
    true,              // Has a size element
135
    false,             // No fillers
136
    false,             // Don't concatenate gaps
137
    {0, ttSignedShort, 1},
138
};
139
140
//! Canon canonAfMiAdj Info binary array - configuration
141
constexpr ArrayCfg canonAfMiAdjCfg = {
142
    IfdId::canonAfMiAdjId,  // Group for the elements
143
    invalidByteOrder,       // Use byte order from parent
144
    ttSignedLong,           // Type for array entry and size element
145
    notEncrypted,           // Not encrypted
146
    true,                   // Has a size element
147
    false,                  // No fillers
148
    false,                  // Don't concatenate gaps
149
    {0, ttSignedLong, 1},
150
};
151
152
//! Canon Vignetting Correction 2 Info binary array - configuration
153
constexpr ArrayCfg canonVigCor2Cfg = {
154
    IfdId::canonVigCor2Id,  // Group for the elements
155
    invalidByteOrder,       // Use byte order from parent
156
    ttSignedLong,           // Type for array entry and size element
157
    notEncrypted,           // Not encrypted
158
    true,                   // Has a size element
159
    false,                  // No fillers
160
    false,                  // Don't concatenate gaps
161
    {0, ttSignedLong, 1},
162
};
163
164
//! Canon Lighting Optimization Info binary array - configuration
165
constexpr ArrayCfg canonLiOpCfg = {
166
    IfdId::canonLiOpId,  // Group for the elements
167
    invalidByteOrder,    // Use byte order from parent
168
    ttSignedLong,        // Type for array entry and size element
169
    notEncrypted,        // Not encrypted
170
    true,                // Has a size element
171
    false,               // No fillers
172
    false,               // Don't concatenate gaps
173
    {0, ttSignedLong, 1},
174
};
175
176
//! Canon LensInfo binary array - configuration
177
constexpr ArrayCfg canonLeCfg = {
178
    IfdId::canonLeId,  // Group for the elements
179
    invalidByteOrder,  // Use byte order from parent
180
    ttUndefined,       // Type for array entry and size element
181
    notEncrypted,      // Not encrypted
182
    false,             // No size element
183
    false,             // No fillers
184
    false,             // Don't concatenate gaps
185
    {0, ttUnsignedByte, 1},
186
};
187
//! Canon LensInfo binary array - definition
188
constexpr ArrayDef canonLeDef[] = {
189
    {0, ttUnsignedByte, 5},  // Serial number
190
    {5, ttUndefined, 25},    // The array contains 30 bytes
191
};
192
193
//! Canon Ambience Selection Info binary array - configuration
194
constexpr ArrayCfg canonAmCfg = {
195
    IfdId::canonAmId,  // Group for the elements
196
    invalidByteOrder,  // Use byte order from parent
197
    ttSignedLong,      // Type for array entry and size element
198
    notEncrypted,      // Not encrypted
199
    true,              // Has a size element
200
    false,             // No fillers
201
    false,             // Don't concatenate gaps
202
    {0, ttSignedLong, 1},
203
};
204
205
//! Canon MultiExposure Selection Info binary array - configuration
206
constexpr ArrayCfg canonMeCfg = {
207
    IfdId::canonMeId,  // Group for the elements
208
    invalidByteOrder,  // Use byte order from parent
209
    ttSignedLong,      // Type for array entry and size element
210
    notEncrypted,      // Not encrypted
211
    true,              // Has a size element
212
    false,             // No fillers
213
    false,             // Don't concatenate gaps
214
    {0, ttSignedLong, 1},
215
};
216
217
//! Canon Filter Info binary array - configuration
218
constexpr ArrayCfg canonFilCfg = {
219
    IfdId::canonFilId,  // Group for the elements
220
    invalidByteOrder,   // Use byte order from parent
221
    ttSignedLong,       // Type for array entry and size element
222
    notEncrypted,       // Not encrypted
223
    true,               // Has a size element
224
    false,              // No fillers
225
    false,              // Don't concatenate gaps
226
    {0, ttSignedLong, 1},
227
};
228
229
//! Canon Hdr Info binary array - configuration
230
constexpr ArrayCfg canonHdrCfg = {
231
    IfdId::canonHdrId,  // Group for the elements
232
    invalidByteOrder,   // Use byte order from parent
233
    ttSignedLong,       // Type for array entry and size element
234
    notEncrypted,       // Not encrypted
235
    true,               // Has a size element
236
    false,              // No fillers
237
    false,              // Don't concatenate gaps
238
    {0, ttSignedLong, 1},
239
};
240
241
//! Canon AF Config Info binary array - configuration
242
constexpr ArrayCfg canonAfCCfg = {
243
    IfdId::canonAfCId,  // Group for the elements
244
    invalidByteOrder,   // Use byte order from parent
245
    ttSignedLong,       // Type for array entry and size element
246
    notEncrypted,       // Not encrypted
247
    true,               // Has a size element
248
    false,              // No fillers
249
    false,              // Don't concatenate gaps
250
    {0, ttSignedLong, 1},
251
};
252
253
//! Canon RawBurst Info binary array - configuration
254
constexpr ArrayCfg canonRawBCfg = {
255
    IfdId::canonRawBId,  // Group for the elements
256
    invalidByteOrder,    // Use byte order from parent
257
    ttSignedLong,        // Type for array entry and size element
258
    notEncrypted,        // Not encrypted
259
    true,                // Has a size element
260
    false,               // No fillers
261
    false,               // Don't concatenate gaps
262
    {0, ttUnsignedLong, 1},
263
};
264
265
//! Nikon Vibration Reduction binary array - configuration
266
constexpr ArrayCfg nikonVrCfg = {
267
    IfdId::nikonVrId,  // Group for the elements
268
    invalidByteOrder,  // Use byte order from parent
269
    ttUndefined,       // Type for array entry
270
    notEncrypted,      // Not encrypted
271
    false,             // No size element
272
    true,              // Write all tags
273
    true,              // Concatenate gaps
274
    {0, ttUnsignedByte, 1},
275
};
276
//! Nikon Vibration Reduction binary array - definition
277
constexpr ArrayDef nikonVrDef[] = {
278
    {0, ttUndefined, 4},     // Version
279
    {7, ttUnsignedByte, 1},  // The array contains 8 bytes
280
};
281
282
//! Nikon Picture Control binary array - configuration
283
constexpr ArrayCfg nikonPcCfg = {
284
    IfdId::nikonPcId,  // Group for the elements
285
    invalidByteOrder,  // Use byte order from parent
286
    ttUndefined,       // Type for array entry
287
    notEncrypted,      // Not encrypted
288
    false,             // No size element
289
    true,              // Write all tags
290
    true,              // Concatenate gaps
291
    {0, ttUnsignedByte, 1},
292
};
293
//! Nikon Picture Control binary array - definition
294
constexpr ArrayDef nikonPcDef[] = {
295
    {0, ttUndefined, 4},  // Version
296
    {4, ttAsciiString, 20},  {24, ttAsciiString, 20}, {48, ttUnsignedByte, 1},
297
    {49, ttUnsignedByte, 1}, {50, ttUnsignedByte, 1}, {51, ttUnsignedByte, 1},
298
    {52, ttUnsignedByte, 1}, {53, ttUnsignedByte, 1}, {54, ttUnsignedByte, 1},
299
    {55, ttUnsignedByte, 1}, {56, ttUnsignedByte, 1}, {57, ttUnsignedByte, 1},  // The array contains 58 bytes
300
};
301
302
//! Nikon World Time binary array - configuration
303
constexpr ArrayCfg nikonWtCfg = {
304
    IfdId::nikonWtId,  // Group for the elements
305
    invalidByteOrder,  // Use byte order from parent
306
    ttUndefined,       // Type for array entry
307
    notEncrypted,      // Not encrypted
308
    false,             // No size element
309
    true,              // Write all tags
310
    true,              // Concatenate gaps
311
    {0, ttUnsignedByte, 1},
312
};
313
//! Nikon World Time binary array - definition
314
constexpr ArrayDef nikonWtDef[] = {
315
    {0, ttSignedShort, 1},
316
    {2, ttUnsignedByte, 1},
317
    {3, ttUnsignedByte, 1},
318
};
319
320
//! Nikon ISO info binary array - configuration
321
constexpr ArrayCfg nikonIiCfg = {
322
    IfdId::nikonIiId,  // Group for the elements
323
    bigEndian,         // Byte order
324
    ttUndefined,       // Type for array entry
325
    notEncrypted,      // Not encrypted
326
    false,             // No size element
327
    true,              // Write all tags
328
    true,              // Concatenate gaps
329
    {0, ttUnsignedByte, 1},
330
};
331
//! Nikon ISO info binary array - definition
332
constexpr ArrayDef nikonIiDef[] = {
333
    {0, ttUnsignedByte, 1},   {4, ttUnsignedShort, 1}, {6, ttUnsignedByte, 1},
334
    {10, ttUnsignedShort, 1}, {13, ttUnsignedByte, 1},  // The array contains 14 bytes
335
};
336
337
//! Nikon Auto Focus binary array - configuration
338
constexpr ArrayCfg nikonAfCfg = {
339
    IfdId::nikonAfId,  // Group for the elements
340
    invalidByteOrder,  // Use byte order from parent
341
    ttUndefined,       // Type for array entry
342
    notEncrypted,      // Not encrypted
343
    false,             // No size element
344
    true,              // Write all tags
345
    true,              // Concatenate gaps
346
    {0, ttUnsignedByte, 1},
347
};
348
//! Nikon Auto Focus binary array - definition
349
constexpr ArrayDef nikonAfDef[] = {
350
    {0, ttUnsignedByte, 1}, {1, ttUnsignedByte, 1}, {2, ttUnsignedShort, 1},  // The array contains 4 bytes
351
};
352
353
//! Nikon Auto Focus 21 binary array - configuration
354
constexpr ArrayCfg nikonAf21Cfg = {
355
    IfdId::nikonAf21Id,  // Group for the elements
356
    invalidByteOrder,    // Use byte order from parent
357
    ttUndefined,         // Type for array entry
358
    notEncrypted,        // Not encrypted
359
    false,               // No size element
360
    true,                // Write all tags
361
    true,                // Concatenate gaps
362
    {0, ttUnsignedByte, 1},
363
};
364
//! Nikon Auto Focus 21 binary array - definition
365
constexpr ArrayDef nikonAf21Def[] = {
366
    {0, ttUndefined, 4},       // Version
367
    {4, ttUnsignedByte, 1},    // ContrastDetectAF
368
    {5, ttUnsignedByte, 1},    // AFAreaMode
369
    {6, ttUnsignedByte, 1},    // PhaseDetectAF
370
    {7, ttUnsignedByte, 1},    // PrimaryAFPoint
371
    {8, ttUnsignedByte, 7},    // AFPointsUsed
372
    {16, ttUnsignedShort, 1},  // AFImageWidth
373
    {18, ttUnsignedShort, 1},  // AFImageHeight
374
    {20, ttUnsignedShort, 1},  // AFAreaXPosition
375
    {22, ttUnsignedShort, 1},  // AFAreaYPosition
376
    {24, ttUnsignedShort, 1},  // AFAreaWidth
377
    {26, ttUnsignedShort, 1},  // AFAreaHeight
378
    {28, ttUnsignedByte, 1},   // ContrastDetectAFInFocus
379
};
380
//! Nikon Auto Focus 22 binary array - configuration
381
constexpr ArrayCfg nikonAf22Cfg = {
382
    IfdId::nikonAf22Id,  // Group for the elements
383
    invalidByteOrder,    // Byte order
384
    ttUndefined,         // Type for array entry
385
    notEncrypted,        // Not encrypted
386
    false,               // No size element
387
    true,                // Write all tags
388
    true,                // Concatenate gaps
389
    {0, ttUnsignedByte, 1},
390
};
391
//! Nikon Auto Focus 22 binary array - definition
392
constexpr ArrayDef nikonAf22Def[] = {
393
    {0, ttUndefined, 4},       // Version
394
    {4, ttUnsignedByte, 1},    // ContrastDetectAF
395
    {5, ttUnsignedByte, 1},    // AFAreaMode
396
    {6, ttUnsignedByte, 1},    // PhaseDetectAF
397
    {7, ttUnsignedByte, 1},    // PrimaryAFPoint
398
    {8, ttUnsignedByte, 7},    // AFPointsUsed
399
    {70, ttUnsignedShort, 1},  // AFImageWidth
400
    {72, ttUnsignedShort, 1},  // AFImageHeight
401
    {74, ttUnsignedShort, 1},  // AFAreaXPosition
402
    {76, ttUnsignedShort, 1},  // AFAreaYPosition
403
    {78, ttUnsignedShort, 1},  // AFAreaWidth
404
    {80, ttUnsignedShort, 1},  // AFAreaHeight
405
    {82, ttUnsignedByte, 1},   // ContrastDetectAFInFocus
406
};
407
408
//! Nikon AF2 configuration and definitions
409
//  https://github.com/Exiv2/exiv2/issues/646
410
constexpr ArraySet nikonAf2Set[] = {
411
    {nikonAf21Cfg, nikonAf21Def, std::size(nikonAf21Def)},
412
    {nikonAf22Cfg, nikonAf22Def, std::size(nikonAf22Def)},
413
};
414
415
//! Nikon AF Fine Tune binary array - configuration
416
constexpr ArrayCfg nikonAFTCfg = {
417
    IfdId::nikonAFTId,  // Group for the elements
418
    invalidByteOrder,   // Use byte order from parent
419
    ttUndefined,        // Type for array entry
420
    notEncrypted,       // Not encrypted
421
    false,              // No size element
422
    true,               // Write all tags
423
    true,               // Concatenate gaps
424
    {0, ttUnsignedByte, 1},
425
};
426
//! Nikon AF Fine Tune binary array - definition
427
constexpr ArrayDef nikonAFTDef[] = {
428
    {0, ttUnsignedByte, 1},  // AF Fine Tune on/off
429
    {1, ttUnsignedByte, 1},  // AF Fine Tune index
430
    {2, ttUnsignedByte, 1},  // AF Fine Tune value
431
};
432
433
//! Nikon File Info binary array - configuration
434
constexpr ArrayCfg nikonFiCfg = {
435
    IfdId::nikonFiId,  // Group for the elements
436
    invalidByteOrder,  // Use byte order from parent
437
    ttUndefined,       // Type for array entry
438
    notEncrypted,      // Not encrypted
439
    false,             // No size element
440
    true,              // Write all tags
441
    true,              // Concatenate gaps
442
    {0, ttUnsignedByte, 1},
443
};
444
//! Nikon File Info binary array - definition
445
constexpr ArrayDef nikonFiDef[] = {
446
    {0, ttUndefined, 4},      // Version
447
    {6, ttUnsignedShort, 1},  // Directory Number
448
    {8, ttUnsignedShort, 1},  // File Number
449
};
450
451
//! Nikon Multi Exposure binary array - configuration
452
constexpr ArrayCfg nikonMeCfg = {
453
    IfdId::nikonMeId,  // Group for the elements
454
    invalidByteOrder,  // Use byte order from parent
455
    ttUndefined,       // Type for array entry
456
    notEncrypted,      // Not encrypted
457
    false,             // No size element
458
    true,              // Write all tags
459
    true,              // Concatenate gaps
460
    {0, ttUnsignedByte, 1},
461
};
462
//! Nikon Multi Exposure binary array - definition
463
constexpr ArrayDef nikonMeDef[] = {
464
    {0, ttUndefined, 4},      // Version
465
    {4, ttUnsignedLong, 1},   // MultiExposureMode
466
    {8, ttUnsignedLong, 1},   // MultiExposureShots
467
    {12, ttUnsignedLong, 1},  // MultiExposureAutoGain
468
};
469
470
//! Nikon Flash Info binary array - configuration 1
471
constexpr ArrayCfg nikonFl1Cfg = {
472
    IfdId::nikonFl1Id,  // Group for the elements
473
    invalidByteOrder,   // Use byte order from parent
474
    ttUndefined,        // Type for array entry
475
    notEncrypted,       // Not encrypted
476
    false,              // No size element
477
    true,               // Write all tags
478
    true,               // Concatenate gaps
479
    {0, ttUnsignedByte, 1},
480
};
481
//! Nikon Flash Info binary array - definition 1
482
constexpr ArrayDef nikonFl1Def[] = {
483
    {0, ttUndefined, 4},      // Version
484
    {4, ttUnsignedByte, 1},   // FlashSource
485
    {6, ttUnsignedShort, 1},  // ExternalFlashFirmware
486
    {8, ttUnsignedByte, 1},   // ExternalFlashFlags
487
    {11, ttUnsignedByte, 1},  // FlashFocalLength
488
    {12, ttUnsignedByte, 1},  // RepeatingFlashRate
489
    {13, ttUnsignedByte, 1},  // RepeatingFlashCount
490
    {14, ttUnsignedByte, 1},  // FlashGNDistance
491
    {15, ttUnsignedByte, 1},  // FlashGroupAControlMode
492
    {16, ttUnsignedByte, 1},  // FlashGroupBControlMode
493
};
494
//! Nikon Flash Info binary array - configuration 2
495
constexpr ArrayCfg nikonFl2Cfg = {
496
    IfdId::nikonFl2Id,  // Group for the elements
497
    invalidByteOrder,   // Use byte order from parent
498
    ttUndefined,        // Type for array entry
499
    notEncrypted,       // Not encrypted
500
    false,              // No size element
501
    true,               // Write all tags
502
    true,               // Concatenate gaps
503
    {0, ttUnsignedByte, 1},
504
};
505
//! Nikon Flash Info binary array - definition 2
506
constexpr ArrayDef nikonFl2Def[] = {
507
    {0, ttUndefined, 4},      // Version
508
    {4, ttUnsignedByte, 1},   // FlashSource
509
    {6, ttUnsignedShort, 1},  // ExternalFlashFirmware
510
    {8, ttUnsignedByte, 1},   // ExternalFlashFlags
511
    {12, ttUnsignedByte, 1},  // FlashFocalLength
512
    {13, ttUnsignedByte, 1},  // RepeatingFlashRate
513
    {14, ttUnsignedByte, 1},  // RepeatingFlashCount
514
    {15, ttUnsignedByte, 1},  // FlashGNDistance
515
};
516
//! Nikon Flash Info binary array - configuration 3
517
constexpr ArrayCfg nikonFl3Cfg = {
518
    IfdId::nikonFl3Id,  // Group for the elements
519
    invalidByteOrder,   // Use byte order from parent
520
    ttUndefined,        // Type for array entry
521
    notEncrypted,       // Not encrypted
522
    false,              // No size element
523
    true,               // Write all tags
524
    true,               // Concatenate gaps
525
    {0, ttUnsignedByte, 1},
526
};
527
//! Nikon Flash Info binary array - definition
528
constexpr ArrayDef nikonFl3Def[] = {
529
    {0, ttUndefined, 4},      // Version
530
    {4, ttUnsignedByte, 1},   // FlashSource
531
    {6, ttUnsignedShort, 1},  // ExternalFlashFirmware
532
    {8, ttUnsignedByte, 1},   // ExternalFlashFlags
533
    {12, ttUnsignedByte, 1},  // FlashFocalLength
534
    {13, ttUnsignedByte, 1},  // RepeatingFlashRate
535
    {14, ttUnsignedByte, 1},  // RepeatingFlashCount
536
    {15, ttUnsignedByte, 1},  // FlashGNDistance
537
    {16, ttUnsignedByte, 1},  // FlashColorFilter
538
};
539
//! Nikon Flash Info 6 (0106) binary array - configuration
540
constexpr ArrayCfg nikonFl6Cfg = {
541
    IfdId::nikonFl6Id,  // Group for the elements
542
    bigEndian,          // Use byte order from parent
543
    ttUndefined,        // Type for array entry
544
    notEncrypted,       // Not encrypted
545
    false,              // No size element
546
    true,               // Write all tags
547
    true,               // Concatenate gaps
548
    {0, ttUnsignedByte, 1},
549
};
550
//! Nikon Flash Info 6 (0106) binary array - definition
551
constexpr ArrayDef nikonFl6Def[] = {
552
    {0, ttUndefined, 4},      // Version
553
    {4, ttUnsignedByte, 1},   // FlashSource
554
    {6, ttUnsignedShort, 1},  // ExternalFlashFirmware
555
    {8, ttUnsignedByte, 1},   // ExternalFlashData1
556
    {9, ttUnsignedByte, 1},   // ExternalFlashData2
557
    {10, ttUnsignedByte, 1},  // FlashCompensationMaster
558
    {12, ttUnsignedByte, 1},  // FlashFocalLength
559
    {13, ttUnsignedByte, 1},  // RepeatingFlashRate
560
    {14, ttUnsignedByte, 1},  // RepeatingFlashCount
561
    {15, ttUnsignedByte, 1},  // FlashGNDistance
562
    {16, ttUnsignedByte, 1},  // FlashColorFilter
563
    {17, ttUnsignedByte, 1},  // FlashGroupAControlData
564
    {18, ttUnsignedByte, 1},  // FlashGroupBCControlData
565
    {19, ttUnsignedByte, 1},  // FlashCompensationGroupA
566
    {20, ttUnsignedByte, 1},  // FlashCompensationGroupB
567
    {21, ttUnsignedByte, 1},  // FlashCompensationGroupC
568
    {28, ttUnsignedByte, 1},  // CameraExposureCompensation
569
    {29, ttUnsignedByte, 1},  // CameraFlashCompensation
570
    {39, ttUnsignedByte, 1},  // FlashMasterOutput
571
    {40, ttUnsignedByte, 1},  // FlashGroupAOutput
572
    {41, ttUnsignedByte, 1},  // FlashGroupBOutput
573
    {42, ttUnsignedByte, 1},  // FlashGroupCOutput
574
};
575
//! Nikon Flash Info 7 (0107 and 0108) binary array - configuration
576
constexpr ArrayCfg nikonFl7Cfg = {
577
    IfdId::nikonFl7Id,  // Group for the elements
578
    bigEndian,          // Use byte order from parent
579
    ttUndefined,        // Type for array entry
580
    notEncrypted,       // Not encrypted
581
    false,              // No size element
582
    true,               // Write all tags
583
    true,               // Concatenate gaps
584
    {0, ttUnsignedByte, 1},
585
};
586
//! Nikon Flash Info 7 (0107 and 0108) binary array - definition
587
constexpr ArrayDef nikonFl7Def[] = {
588
    {0, ttUndefined, 4},      // Version
589
    {4, ttUnsignedByte, 1},   // FlashSource
590
    {6, ttUnsignedShort, 1},  // ExternalFlashFirmware
591
    {8, ttUnsignedByte, 1},   // ExternalFlashData1
592
    {9, ttUnsignedByte, 1},   // ExternalFlashData2
593
    {10, ttUnsignedByte, 1},  // FlashCompensationMaster
594
    {12, ttUnsignedByte, 1},  // FlashFocalLength
595
    {13, ttUnsignedByte, 1},  // RepeatingFlashRate
596
    {14, ttUnsignedByte, 1},  // RepeatingFlashCount
597
    {15, ttUnsignedByte, 1},  // FlashGNDistance
598
    {16, ttUnsignedByte, 1},  // FlashColorFilter
599
    {17, ttUnsignedByte, 1},  // FlashGroupAControlData
600
    {18, ttUnsignedByte, 1},  // FlashGroupBCControlData
601
    {19, ttUnsignedByte, 1},  // FlashCompensationGroupA
602
    {20, ttUnsignedByte, 1},  // FlashCompensationGroupB
603
    {21, ttUnsignedByte, 1},  // FlashCompensationGroupC
604
    {22, ttUnsignedByte, 1},  // ExternalFlashData3
605
    {27, ttUnsignedByte, 1},  // CameraFlashOutput
606
    {28, ttUnsignedByte, 1},  // CameraExposureCompensation
607
    {29, ttUnsignedByte, 1},  // CameraFlashCompensation
608
    {37, ttUnsignedByte, 1},  // ExternalFlashData4
609
    {38, ttUnsignedByte, 1},  // FlashZoomHeadPosition
610
    {39, ttUnsignedByte, 1},  // FlashMasterOutput
611
    {40, ttUnsignedByte, 1},  // FlashGroupAOutput
612
    {41, ttUnsignedByte, 1},  // FlashGroupBOutput
613
    {42, ttUnsignedByte, 1},  // FlashGroupCOutput
614
    {67, ttUnsignedByte, 1},  // WirelessFlashData
615
};
616
617
//! Nikon Flash Info Data configurations and definitions
618
constexpr ArraySet nikonFlSet[] = {
619
    {nikonFl1Cfg, nikonFl1Def, std::size(nikonFl1Def)}, {nikonFl2Cfg, nikonFl2Def, std::size(nikonFl2Def)},
620
    {nikonFl3Cfg, nikonFl3Def, std::size(nikonFl3Def)}, {nikonFl6Cfg, nikonFl6Def, std::size(nikonFl6Def)},
621
    {nikonFl7Cfg, nikonFl7Def, std::size(nikonFl7Def)},
622
};
623
624
//! Nikon Shot Info binary array - configuration 1 (D80)
625
constexpr ArrayCfg nikonSi1Cfg = {
626
    IfdId::nikonSi1Id,  // Group for the elements
627
    bigEndian,          // Use byte order from parent
628
    ttUndefined,        // Type for array entry
629
    nikonCrypt,         // Encryption function
630
    false,              // No size element
631
    true,               // Write all tags
632
    true,               // Concatenate gaps
633
    {0, ttUnsignedByte, 1},
634
};
635
//! Nikon Shot Info binary array - definition 1 (D80)
636
constexpr ArrayDef nikonSi1Def[] = {
637
    {0, ttUndefined, 4},        // Version
638
    {586, ttUnsignedLong, 1},   // ShutterCount
639
    {1155, ttUnsignedByte, 1},  // The array contains 1156 bytes
640
};
641
//! Nikon Shot Info binary array - configuration 2 (D40)
642
constexpr ArrayCfg nikonSi2Cfg = {
643
    IfdId::nikonSi2Id,  // Group for the elements
644
    bigEndian,          // Use byte order from parent
645
    ttUndefined,        // Type for array entry
646
    nikonCrypt,         // Encryption function
647
    false,              // No size element
648
    true,               // Write all tags
649
    true,               // Concatenate gaps
650
    {0, ttUnsignedByte, 1},
651
};
652
//! Nikon Shot Info binary array - definition 2 (D40)
653
constexpr ArrayDef nikonSi2Def[] = {
654
    {0, ttUndefined, 4},       // Version
655
    {582, ttUnsignedLong, 1},  // ShutterCount
656
    {738, ttUnsignedByte, 1},
657
    {1112, ttUnsignedByte, 1},  // The array contains 1113 bytes
658
};
659
//! Nikon Shot Info binary array - configuration 3 (D300a)
660
constexpr ArrayCfg nikonSi3Cfg = {
661
    IfdId::nikonSi3Id,  // Group for the elements
662
    bigEndian,          // Use byte order from parent
663
    ttUndefined,        // Type for array entry
664
    nikonCrypt,         // Encryption function
665
    false,              // No size element
666
    true,               // Write all tags
667
    true,               // Concatenate gaps
668
    {0, ttUnsignedByte, 1},
669
};
670
//! Nikon Shot Info binary array - definition 3 (D300a)
671
constexpr ArrayDef nikonSi3Def[] = {
672
    {0, ttUndefined, 4},        // Version
673
    {604, ttUnsignedByte, 1},   // ISO
674
    {633, ttUnsignedLong, 1},   // ShutterCount
675
    {721, ttUnsignedShort, 1},  // AFFineTuneAdj
676
    {814, ttUndefined, 4478},   // The array contains 5291 bytes
677
};
678
//! Nikon Shot Info binary array - configuration 4 (D300b)
679
constexpr ArrayCfg nikonSi4Cfg = {
680
    IfdId::nikonSi4Id,  // Group for the elements
681
    bigEndian,          // Use byte order from parent
682
    ttUndefined,        // Type for array entry
683
    nikonCrypt,         // Encryption function
684
    false,              // No size element
685
    true,               // Write all tags
686
    true,               // Concatenate gaps
687
    {0, ttUnsignedByte, 1},
688
};
689
//! Nikon Shot Info binary array - definition 4 (D300b)
690
constexpr ArrayDef nikonSi4Def[] = {
691
    {0, ttUndefined, 4},        // Version
692
    {644, ttUnsignedLong, 1},   // ShutterCount
693
    {732, ttUnsignedShort, 1},  // AFFineTuneAdj
694
    {826, ttUndefined, 4478},   // The array contains 5303 bytes
695
};
696
//! Nikon Shot Info binary array - configuration 5 (ver 02.xx)
697
constexpr ArrayCfg nikonSi5Cfg = {
698
    IfdId::nikonSi5Id,  // Group for the elements
699
    bigEndian,          // Use byte order from parent
700
    ttUndefined,        // Type for array entry
701
    nikonCrypt,         // Encryption function
702
    false,              // No size element
703
    false,              // Write all tags (don't know how many)
704
    true,               // Concatenate gaps
705
    {0, ttUnsignedByte, 1},
706
};
707
//! Nikon Shot Info binary array - definition 5 (ver 01.xx and ver 02.xx)
708
constexpr ArrayDef nikonSi5Def[] = {
709
    {0, ttUndefined, 4},       // Version
710
    {106, ttUnsignedLong, 1},  // ShutterCount1
711
    {110, ttUnsignedLong, 1},  // DeletedImageCount
712
    {117, ttUnsignedByte, 1},  // VibrationReduction
713
    {130, ttUnsignedByte, 1},  // VibrationReduction1
714
    {343, ttUndefined, 2},     // ShutterCount
715
    {430, ttUnsignedByte, 1},  // VibrationReduction2
716
    {598, ttUnsignedByte, 1},  // ISO
717
    {630, ttUnsignedLong, 1}   // ShutterCount
718
};
719
//! Nikon Shot Info binary array - configuration 6 (ver 01.xx)
720
constexpr ArrayCfg nikonSi6Cfg = {
721
    IfdId::nikonSi6Id,  // Group for the elements
722
    bigEndian,          // Use byte order from parent
723
    ttUndefined,        // Type for array entry
724
    notEncrypted,       // Encryption function
725
    false,              // No size element
726
    false,              // Write all tags (don't know how many)
727
    true,               // Concatenate gaps
728
    {0, ttUnsignedByte, 1},
729
};
730
//! Nikon Lens Data configurations and definitions
731
constexpr ArraySet nikonSiSet[] = {
732
    {nikonSi1Cfg, nikonSi1Def, std::size(nikonSi1Def)},
733
    {nikonSi2Cfg, nikonSi2Def, std::size(nikonSi2Def)},
734
    {nikonSi3Cfg, nikonSi3Def, std::size(nikonSi3Def)},
735
    {nikonSi4Cfg, nikonSi4Def, std::size(nikonSi4Def)},
736
    {nikonSi5Cfg, nikonSi5Def, std::size(nikonSi5Def)},
737
    {nikonSi6Cfg, nikonSi5Def, std::size(nikonSi5Def)},  // uses nikonSi5Def
738
};
739
740
//! Nikon Lens Data binary array - configuration 1
741
constexpr ArrayCfg nikonLd1Cfg = {
742
    IfdId::nikonLd1Id,  // Group for the elements
743
    invalidByteOrder,   // Use byte order from parent
744
    ttUndefined,        // Type for array entry
745
    notEncrypted,       // Encryption function
746
    false,              // No size element
747
    true,               // Write all tags
748
    false,              // Concatenate gaps
749
    {0, ttUnsignedByte, 1},
750
};
751
//! Nikon Lens Data binary array - configuration 2
752
constexpr ArrayCfg nikonLd2Cfg = {
753
    IfdId::nikonLd2Id,  // Group for the elements
754
    invalidByteOrder,   // Use byte order from parent
755
    ttUndefined,        // Type for array entry
756
    nikonCrypt,         // Encryption function
757
    false,              // No size element
758
    true,               // Write all tags
759
    false,              // Concatenate gaps
760
    {0, ttUnsignedByte, 1},
761
};
762
//! Nikon Lens Data binary array - configuration 3
763
constexpr ArrayCfg nikonLd3Cfg = {
764
    IfdId::nikonLd3Id,  // Group for the elements
765
    invalidByteOrder,   // Use byte order from parent
766
    ttUndefined,        // Type for array entry
767
    nikonCrypt,         // Encryption function
768
    false,              // No size element
769
    true,               // Write all tags
770
    false,              // Don't concatenate gaps
771
    {0, ttUnsignedByte, 1},
772
};
773
//! Nikon Lens Data binary array - configuration 3
774
constexpr ArrayCfg nikonLd4Cfg = {
775
    IfdId::nikonLd4Id,  // Group for the elements
776
    invalidByteOrder,   // Use byte order from parent
777
    ttUndefined,        // Type for array entry
778
    nikonCrypt,         // Encryption function
779
    false,              // No size element
780
    true,               // Write all tags
781
    false,              // Don't concatenate gaps
782
    {0, ttUnsignedByte, 1},
783
};
784
//! Nikon Lens Data binary array - definition
785
constexpr ArrayDef nikonLdDef[] = {
786
    {0, ttUndefined, 4},  // Version
787
};
788
//! Nikon Lens Data binary array - definition
789
constexpr ArrayDef nikonLd4Def[] = {
790
    {0, ttUndefined, 4},       // Version
791
    {48, ttUnsignedShort, 1},  // LensID
792
    {54, ttUnsignedShort, 1},  // MaxAperture
793
    {56, ttUnsignedShort, 1},  // FNumber
794
    {60, ttUnsignedShort, 1},  // FocalLength
795
    {78, ttUnsignedShort, 1},  // FocusDistance
796
};
797
//! Nikon Lens Data configurations and definitions
798
constexpr ArraySet nikonLdSet[] = {
799
    {nikonLd1Cfg, nikonLdDef, std::size(nikonLdDef)},
800
    {nikonLd2Cfg, nikonLdDef, std::size(nikonLdDef)},
801
    {nikonLd3Cfg, nikonLdDef, std::size(nikonLdDef)},
802
    {nikonLd4Cfg, nikonLd4Def, std::size(nikonLd4Def)},
803
};
804
805
//! Nikon Color Balance binary array - configuration 1
806
constexpr ArrayCfg nikonCb1Cfg = {
807
    IfdId::nikonCb1Id,  // Group for the elements
808
    invalidByteOrder,   // Use byte order from parent
809
    ttUndefined,        // Type for array entry
810
    notEncrypted,       // Encryption function
811
    false,              // No size element
812
    false,              // Write all tags
813
    true,               // Concatenate gaps
814
    {0, ttUnsignedShort, 1},
815
};
816
//! Nikon Color Balance binary array - configuration 2
817
constexpr ArrayCfg nikonCb2Cfg = {
818
    IfdId::nikonCb2Id,  // Group for the elements
819
    invalidByteOrder,   // Use byte order from parent
820
    ttUndefined,        // Type for array entry
821
    nikonCrypt,         // Encryption function
822
    false,              // No size element
823
    false,              // Write all tags
824
    true,               // Concatenate gaps
825
    {0, ttUnsignedShort, 1},
826
};
827
//! Nikon Color Balance binary array - configuration 2a
828
constexpr ArrayCfg nikonCb2aCfg = {
829
    IfdId::nikonCb2aId,  // Group for the elements
830
    invalidByteOrder,    // Use byte order from parent
831
    ttUndefined,         // Type for array entry
832
    nikonCrypt,          // Encryption function
833
    false,               // No size element
834
    false,               // Write all tags
835
    true,                // Concatenate gaps
836
    {0, ttUnsignedShort, 1},
837
};
838
//! Nikon Color Balance binary array - configuration 2b
839
constexpr ArrayCfg nikonCb2bCfg = {
840
    IfdId::nikonCb2bId,  // Group for the elements
841
    invalidByteOrder,    // Use byte order from parent
842
    ttUndefined,         // Type for array entry
843
    nikonCrypt,          // Encryption function
844
    false,               // No size element
845
    false,               // Write all tags
846
    true,                // Concatenate gaps
847
    {0, ttUnsignedShort, 1},
848
};
849
//! Nikon Color Balance binary array - configuration 3
850
constexpr ArrayCfg nikonCb3Cfg = {
851
    IfdId::nikonCb3Id,  // Group for the elements
852
    invalidByteOrder,   // Use byte order from parent
853
    ttUndefined,        // Type for array entry
854
    notEncrypted,       // Encryption function
855
    false,              // No size element
856
    false,              // Write all tags
857
    true,               // Concatenate gaps
858
    {0, ttUnsignedShort, 1},
859
};
860
//! Nikon Color Balance binary array - configuration 4
861
constexpr ArrayCfg nikonCb4Cfg = {
862
    IfdId::nikonCb4Id,  // Group for the elements
863
    invalidByteOrder,   // Use byte order from parent
864
    ttUndefined,        // Type for array entry
865
    nikonCrypt,         // Encryption function
866
    false,              // No size element
867
    false,              // Write all tags
868
    true,               // Concatenate gaps
869
    {0, ttUnsignedShort, 1},
870
};
871
//! Nikon Color Balance binary array - definition 1 (D100)
872
constexpr ArrayDef nikonCb1Def[] = {
873
    {0, ttUndefined, 4},       // Version
874
    {72, ttUnsignedShort, 4},  // Color balance levels
875
};
876
//! Nikon Color Balance binary array - definition 2 (D2H)
877
constexpr ArrayDef nikonCb2Def[] = {
878
    {0, ttUndefined, 4},       // Version
879
    {10, ttUnsignedShort, 4},  // Color balance levels
880
};
881
//! Nikon Color Balance binary array - definition 2a (D50)
882
constexpr ArrayDef nikonCb2aDef[] = {
883
    {0, ttUndefined, 4},       // Version
884
    {18, ttUnsignedShort, 4},  // Color balance levels
885
};
886
//! Nikon Color Balance binary array - definition 2b (D2X=0204,D2Hs=0206,D200=0207,D40=0208)
887
constexpr ArrayDef nikonCb2bDef[] = {
888
    {0, ttUndefined, 4},        // Version
889
    {4, ttUnsignedShort, 140},  // Unknown
890
    {284, ttUnsignedShort, 3},  // Unknown (encrypted)
891
    {290, ttUnsignedShort, 4},  // Color balance levels
892
};
893
//! Nikon Color Balance binary array - definition 3 (D70)
894
constexpr ArrayDef nikonCb3Def[] = {
895
    {0, ttUndefined, 4},       // Version
896
    {20, ttUnsignedShort, 4},  // Color balance levels
897
};
898
//! Nikon Color Balance binary array - definition 4 (D3)
899
constexpr ArrayDef nikonCb4Def[] = {
900
    {0, ttUndefined, 4},        // Version
901
    {4, ttUnsignedShort, 140},  // Unknown
902
    {284, ttUnsignedShort, 5},  // Unknown (encrypted)
903
    {294, ttUnsignedShort, 4},  // Color balance levels
904
};
905
//! Nikon Color Balance configurations and definitions
906
constexpr ArraySet nikonCbSet[] = {
907
    {nikonCb1Cfg, nikonCb1Def, std::size(nikonCb1Def)},    {nikonCb2Cfg, nikonCb2Def, std::size(nikonCb2Def)},
908
    {nikonCb2aCfg, nikonCb2aDef, std::size(nikonCb2aDef)}, {nikonCb2bCfg, nikonCb2bDef, std::size(nikonCb2bDef)},
909
    {nikonCb3Cfg, nikonCb3Def, std::size(nikonCb3Def)},    {nikonCb4Cfg, nikonCb4Def, std::size(nikonCb4Def)},
910
};
911
912
//! Minolta Camera Settings (old) binary array - configuration
913
constexpr ArrayCfg minoCsoCfg = {
914
    IfdId::minoltaCsOldId,  // Group for the elements
915
    bigEndian,              // Big endian
916
    ttUndefined,            // Type for array entry and size element
917
    notEncrypted,           // Not encrypted
918
    false,                  // No size element
919
    false,                  // No fillers
920
    false,                  // Don't concatenate gaps
921
    {0, ttUnsignedLong, 1},
922
};
923
924
//! Minolta Camera Settings (new) binary array - configuration
925
constexpr ArrayCfg minoCsnCfg = {
926
    IfdId::minoltaCsNewId,  // Group for the elements
927
    bigEndian,              // Big endian
928
    ttUndefined,            // Type for array entry and size element
929
    notEncrypted,           // Not encrypted
930
    false,                  // No size element
931
    false,                  // No fillers
932
    false,                  // Don't concatenate gaps
933
    {0, ttUnsignedLong, 1},
934
};
935
936
//! Minolta 7D Camera Settings binary array - configuration
937
constexpr ArrayCfg minoCs7Cfg = {
938
    IfdId::minoltaCs7DId,  // Group for the elements
939
    bigEndian,             // Big endian
940
    ttUndefined,           // Type for array entry and size element
941
    notEncrypted,          // Not encrypted
942
    false,                 // No size element
943
    false,                 // No fillers
944
    false,                 // Don't concatenate gaps
945
    {0, ttUnsignedShort, 1},
946
};
947
//! Minolta 7D Camera Settings binary array - definition
948
constexpr ArrayDef minoCs7Def[] = {
949
    {60, ttSignedShort, 1},   // Exif.MinoltaCs7D.ExposureCompensation
950
    {126, ttSignedShort, 1},  // Exif.MinoltaCs7D.ColorTemperature
951
};
952
953
//! Minolta 5D Camera Settings binary array - configuration
954
constexpr ArrayCfg minoCs5Cfg = {
955
    IfdId::minoltaCs5DId,  // Group for the elements
956
    bigEndian,             // Big endian
957
    ttUndefined,           // Type for array entry and size element
958
    notEncrypted,          // Not encrypted
959
    false,                 // No size element
960
    false,                 // No fillers
961
    false,                 // Don't concatenate gaps
962
    {0, ttUnsignedShort, 1},
963
};
964
//! Minolta 5D Camera Settings binary array - definition
965
constexpr ArrayDef minoCs5Def[] = {
966
    {146, ttSignedShort, 1},  // Exif.MinoltaCs5D.ColorTemperature
967
};
968
969
// Todo: Performance of the handling of Sony Camera Settings can be
970
//       improved by defining all known array elements in the definitions
971
//       sonyCsDef and sonyCs2Def below and enabling the 'concatenate gaps'
972
//       setting in all four configurations.
973
974
//! Sony1 Camera Settings binary array - configuration
975
constexpr ArrayCfg sony1CsCfg = {
976
    IfdId::sony1CsId,  // Group for the elements
977
    bigEndian,         // Big endian
978
    ttUndefined,       // Type for array entry and size element
979
    notEncrypted,      // Not encrypted
980
    false,             // No size element
981
    false,             // No fillers
982
    false,             // Don't concatenate gaps
983
    {0, ttUnsignedShort, 1},
984
};
985
//! Sony1 Camera Settings 2 binary array - configuration
986
constexpr ArrayCfg sony1Cs2Cfg = {
987
    IfdId::sony1Cs2Id,  // Group for the elements
988
    bigEndian,          // Big endian
989
    ttUndefined,        // Type for array entry and size element
990
    notEncrypted,       // Not encrypted
991
    false,              // No size element
992
    false,              // No fillers
993
    false,              // Don't concatenate gaps
994
    {0, ttUnsignedShort, 1},
995
};
996
997
constexpr ArrayCfg sony2FpCfg = {
998
    IfdId::sony2FpId,  // Group for the elements
999
    bigEndian,         // Big endian
1000
    ttUnsignedByte,    // Type for array entry and size element
1001
    sonyTagDecipher,   // (uint16_t, const byte*, uint32_t, TiffComponent* const);
1002
    false,             // No size element
1003
    false,             // No fillers
1004
    false,             // Don't concatenate gaps
1005
    {0, ttUnsignedByte, 1},
1006
};
1007
constexpr ArrayDef sony2FpDef[] = {
1008
    {0x4, ttSignedByte, 1},     // Exif.Sony2Fp.AmbientTemperature
1009
    {0x16, ttUnsignedByte, 1},  // Exif.Sony2Fp.FocusMode
1010
    {0x17, ttUnsignedByte, 1},  // Exif.Sony2Fp.AFAreaMode
1011
    {0x2d, ttUnsignedByte, 1},  // Exif.Sony2Fp.FocusPosition2
1012
};
1013
1014
//! Sony2Fp configurations and definitions
1015
constexpr ArraySet sony2FpSet[] = {
1016
    {sony2FpCfg, sony2FpDef, std::size(sony2FpDef)},
1017
};
1018
1019
constexpr ArrayCfg sonyMisc1Cfg = {
1020
    IfdId::sonyMisc1Id,  // Group for the elements
1021
    bigEndian,           // Big endian
1022
    ttUnsignedByte,      // Type for array entry and size element
1023
    sonyTagDecipher,     // (uint16_t, const byte*, uint32_t, TiffComponent* const);
1024
    false,               // No size element
1025
    false,               // No fillers
1026
    false,               // Don't concatenate gaps
1027
    {0, ttUnsignedByte, 1},
1028
};
1029
1030
constexpr ArrayDef sonyMisc1Def[] = {
1031
    {0x05, ttSignedByte, 1},  // Exif.SonyMisc1.CameraTemperature
1032
};
1033
1034
constexpr ArrayCfg sonyMisc2bCfg = {
1035
    IfdId::sonyMisc2bId,  // Group for the elements
1036
    littleEndian,         // Little endian
1037
    ttUnsignedByte,       // Type for array entry and size element
1038
    sonyTagDecipher,      // (uint16_t, const byte*, uint32_t, TiffComponent* const);
1039
    false,                // No size element
1040
    false,                // No fillers
1041
    false,                // Don't concatenate gaps
1042
    {0, ttUnsignedByte, 1},
1043
};
1044
1045
constexpr ArrayDef sonyMisc2bDef[] = {
1046
    {12, ttUnsignedByte, 1},   // Exif.SonyMisc2b.ExposureProgram
1047
    {14, ttUnsignedByte, 1},   // Exif.SonyMisc2b.IntelligentAuto
1048
    {30, ttUnsignedShort, 1},  // Exif.SonyMisc2b.LensZoomPosition
1049
    {32, ttUnsignedByte, 1},   // Exif.SonyMisc2b.FocusPosition2
1050
};
1051
1052
//! SonyMisc2b configurations and definitions
1053
constexpr ArraySet sonyMisc2bSet[] = {
1054
    {sonyMisc2bCfg, sonyMisc2bDef, std::size(sonyMisc2bDef)},
1055
};
1056
1057
constexpr ArrayCfg sonyMisc3cCfg = {
1058
    IfdId::sonyMisc3cId,  // Group for the elements
1059
    littleEndian,         // Little endian
1060
    ttUnsignedByte,       // Type for array entry and size element
1061
    sonyTagDecipher,      // (uint16_t, const byte*, uint32_t, TiffComponent* const);
1062
    false,                // No size element
1063
    false,                // No fillers
1064
    false,                // Don't concatenate gaps
1065
    {0, ttUnsignedByte, 1},
1066
};
1067
1068
constexpr ArrayDef sonyMisc3cDef[] = {
1069
    {0x09, ttUnsignedByte, 1},   // Exif.SonyMisc3c.ReleaseMode2
1070
    {0x0a, ttUnsignedLong, 1},   // Exif.SonyMisc3c.ShotNumberSincePowerUp
1071
    {0x12, ttUnsignedLong, 1},   // Exif.SonyMisc3c.SequenceImageNumber
1072
    {0x16, ttUnsignedByte, 1},   // Exif.SonyMisc3c.SequenceLength1
1073
    {0x1a, ttUnsignedLong, 1},   // Exif.SonyMisc3c.SequenceFileNumber
1074
    {0x1e, ttUnsignedByte, 1},   // Exif.SonyMisc3c.SequenceLength2
1075
    {0x29, ttUnsignedByte, 1},   // Exif.SonyMisc3c.CameraOrientation
1076
    {0x2a, ttUnsignedByte, 1},   // Exif.SonyMisc3c.Quality2
1077
    {0x47, ttUnsignedShort, 1},  // Exif.SonyMisc3c.SonyImageHeight
1078
    {0x53, ttUnsignedByte, 1},   // Exif.SonyMisc3c.ModelReleaseYear
1079
};
1080
1081
//! SonyMisc3c Settings configurations and definitions
1082
constexpr ArraySet sonyMisc3cSet[] = {
1083
    {sonyMisc3cCfg, sonyMisc3cDef, std::size(sonyMisc3cDef)},
1084
};
1085
1086
constexpr ArrayCfg sonySInfo1Cfg = {
1087
    IfdId::sonySInfo1Id,  // Group for the elements
1088
    littleEndian,         // Little endian
1089
    ttUnsignedByte,       // Type for array entry and size element
1090
    notEncrypted,         // (uint16_t, const byte*, uint32_t, TiffComponent* const);
1091
    false,                // No size element
1092
    false,                // No fillers
1093
    false,                // Don't concatenate gaps
1094
    {0, ttUnsignedByte, 1},
1095
};
1096
constexpr ArrayDef sonySInfo1Def[] = {
1097
    {6, ttAsciiString, 20},    // Exif.SonySInfo1.SonyDateTime
1098
    {26, ttUnsignedShort, 1},  // Exif.SonySInfo1.SonyImageHeight
1099
    {28, ttUnsignedShort, 1},  // Exif.SonySInfo1.SonyImageWidth
1100
    {48, ttUnsignedShort, 1},  // Exif.SonySInfo1.FacesDetected
1101
    {52, ttAsciiString, 16},   // Exif.SonySInfo1.MetaVersion
1102
                               //
1103
};
1104
1105
constexpr ArrayCfg sony2010eCfg = {
1106
    IfdId::sony2010eId,  // Group for the elements
1107
    invalidByteOrder,    // inherit from file.  Usually littleEndian
1108
    ttUnsignedByte,      // Type for array entry and size element
1109
    sonyTagDecipher,     // (uint16_t, const byte*, uint32_t, TiffComponent* const);
1110
    false,               // No size element
1111
    false,               // No fillers
1112
    false,               // Don't concatenate gaps
1113
    {0, ttUnsignedByte, 1},
1114
};
1115
constexpr ArrayDef sony2010eDef[] = {
1116
    {0, ttUnsignedLong, 1},      // Exif.Sony2010. SequenceImageNumber
1117
    {4, ttUnsignedLong, 1},      // Exif.Sony2010. SequenceFileNumber
1118
    {8, ttUnsignedLong, 1},      // Exif.Sony2010. ReleaseMode2
1119
    {540, ttUnsignedByte, 1},    // Exif.Sony2010. DigitalZoomRatio
1120
    {556, ttUndefined, 1},       // Exif.Sony2010. SonyDateTime
1121
    {808, ttUnsignedByte, 1},    // Exif.Sony2010. DynamicRangeOptimizer
1122
    {1208, ttUndefined, 1},      // Exif.Sony2010. MeterInfo
1123
    {4444, ttUnsignedByte, 1},   // Exif.Sony2010. ReleaseMode3
1124
    {4448, ttUnsignedByte, 1},   // Exif.Sony2010. ReleaseMode2
1125
    {4456, ttUnsignedByte, 1},   // Exif.Sony2010. SelfTimer
1126
    {4460, ttUnsignedByte, 1},   // Exif.Sony2010. FlashMode
1127
    {4466, ttUnsignedShort, 1},  // Exif.Sony2010. StopsAboveBaseISO
1128
    {4468, ttUnsignedShort, 1},  // Exif.Sony2010. BrightnessValue
1129
    {4472, ttUnsignedByte, 1},   // Exif.Sony2010. DynamicRangeOptimizer
1130
    {4476, ttUnsignedByte, 1},   // Exif.Sony2010. HDRSetting
1131
    {4480, ttSignedShort, 1},    // Exif.Sony2010. ExposureCompensation
1132
    {4502, ttUnsignedByte, 1},   // Exif.Sony2010. PictureProfile
1133
    {4503, ttUnsignedByte, 1},   // Exif.Sony2010. PictureProfile2
1134
    {4507, ttUnsignedByte, 1},   // Exif.Sony2010. PictureEffect2
1135
    {4520, ttUnsignedByte, 1},   // Exif.Sony2010. Quality2
1136
    {4524, ttUnsignedByte, 1},   // Exif.Sony2010. MeteringMode
1137
    {4525, ttUnsignedByte, 1},   // Exif.Sony2010. ExposureProgram
1138
    {4532, ttUnsignedShort, 3},  // Exif.Sony2010. WB_RGBLevels
1139
    {4692, ttUnsignedShort, 1},  // Exif.Sony2010. SonyISO
1140
    {4696, ttUnsignedShort, 1},  // Exif.Sony2010. SonyISO2
1141
    {4728, ttUnsignedShort, 1},  // Exif.Sony2010. FocalLength
1142
    {4730, ttUnsignedShort, 1},  // Exif.Sony2010. MinFocalLength
1143
    {4732, ttUnsignedShort, 1},  // Exif.Sony2010. MaxFocalLength
1144
    {4736, ttUnsignedShort, 1},  // Exif.Sony2010. SonyISO3
1145
    {6256, ttSignedShort, 16},   // Exif.Sony2010. DistortionCorrParams
1146
    {6289, ttUnsignedByte, 1},   // Exif.Sony2010. LensFormat
1147
    {6290, ttUnsignedByte, 1},   // Exif.Sony2010. LensMount
1148
    {6291, ttUnsignedShort, 1},  // Exif.Sony2010. LensType2
1149
    {6294, ttUnsignedShort, 1},  // Exif.Sony2010. LensType
1150
    {6296, ttUnsignedByte, 1},   // Exif.Sony2010. DistortionCorrParamsPresent
1151
    {6297, ttUnsignedByte, 1},   // Exif.Sony2010. DistortionCorrParamsNumber
1152
};
1153
1154
//! Sony1 Camera Settings configurations and definitions
1155
constexpr ArraySet sony2010eSet[] = {
1156
    {sony2010eCfg, sony2010eDef, std::size(sony2010eDef)},
1157
};
1158
1159
//! Sony[12] Camera Settings binary array - definition
1160
constexpr ArrayDef sonyCsDef[] = {
1161
    {12, ttSignedShort, 1},  // Exif.Sony[12]Cs.WhiteBalanceFineTune
1162
};
1163
//! Sony2 Camera Settings binary array - configuration
1164
constexpr ArrayCfg sony2CsCfg = {
1165
    IfdId::sony2CsId,  // Group for the elements
1166
    bigEndian,         // Big endian
1167
    ttUndefined,       // Type for array entry and size element
1168
    notEncrypted,      // Not encrypted
1169
    false,             // No size element
1170
    false,             // No fillers
1171
    false,             // Don't concatenate gaps
1172
    {0, ttUnsignedShort, 1},
1173
};
1174
//! Sony2 Camera Settings 2 binary array - configuration
1175
constexpr ArrayCfg sony2Cs2Cfg = {
1176
    IfdId::sony2Cs2Id,  // Group for the elements
1177
    bigEndian,          // Big endian
1178
    ttUndefined,        // Type for array entry and size element
1179
    notEncrypted,       // Not encrypted
1180
    false,              // No size element
1181
    false,              // No fillers
1182
    false,              // Don't concatenate gaps
1183
    {0, ttUnsignedShort, 1},
1184
};
1185
//! Sony[12] Camera Settings 2 binary array - definition
1186
constexpr ArrayDef sonyCs2Def[] = {
1187
    {44, ttUnsignedShort, 1},  // Exif.Sony[12]Cs2.FocusMode
1188
};
1189
//! Sony1 Camera Settings configurations and definitions
1190
constexpr ArraySet sony1CsSet[] = {
1191
    {sony1CsCfg, sonyCsDef, std::size(sonyCsDef)},
1192
    {sony1Cs2Cfg, sonyCs2Def, std::size(sonyCs2Def)},
1193
};
1194
//! Sony2 Camera Settings configurations and definitions
1195
constexpr ArraySet sony2CsSet[] = {
1196
    {sony2CsCfg, sonyCsDef, std::size(sonyCsDef)},
1197
    {sony2Cs2Cfg, sonyCs2Def, std::size(sonyCs2Def)},
1198
};
1199
1200
//! Sony Minolta Camera Settings (old) binary array - configuration
1201
constexpr ArrayCfg sony1MCsoCfg = {
1202
    IfdId::sony1MltCsOldId,  // Group for the elements
1203
    bigEndian,               // Big endian
1204
    ttUndefined,             // Type for array entry and size element
1205
    notEncrypted,            // Not encrypted
1206
    false,                   // No size element
1207
    false,                   // No fillers
1208
    false,                   // Don't concatenate gaps
1209
    {0, ttUnsignedLong, 1},
1210
};
1211
1212
//! Sony Minolta Camera Settings (new) binary array - configuration
1213
constexpr ArrayCfg sony1MCsnCfg = {
1214
    IfdId::sony1MltCsNewId,  // Group for the elements
1215
    bigEndian,               // Big endian
1216
    ttUndefined,             // Type for array entry and size element
1217
    notEncrypted,            // Not encrypted
1218
    false,                   // No size element
1219
    false,                   // No fillers
1220
    false,                   // Don't concatenate gaps
1221
    {0, ttUnsignedLong, 1},
1222
};
1223
1224
//! Sony Minolta 7D Camera Settings binary array - configuration
1225
constexpr ArrayCfg sony1MCs7Cfg = {
1226
    IfdId::sony1MltCs7DId,  // Group for the elements
1227
    bigEndian,              // Big endian
1228
    ttUndefined,            // Type for array entry and size element
1229
    notEncrypted,           // Not encrypted
1230
    false,                  // No size element
1231
    false,                  // No fillers
1232
    false,                  // Don't concatenate gaps
1233
    {0, ttUnsignedShort, 1},
1234
};
1235
1236
//! Sony Minolta A100 Camera Settings binary array - configuration
1237
constexpr ArrayCfg sony1MCsA100Cfg = {
1238
    IfdId::sony1MltCsA100Id,  // Group for the elements
1239
    bigEndian,                // Big endian
1240
    ttUndefined,              // Type for array entry and size element
1241
    notEncrypted,             // Not encrypted
1242
    false,                    // No size element
1243
    false,                    // No fillers
1244
    false,                    // Don't concatenate gaps
1245
    {0, ttUnsignedShort, 1},
1246
};
1247
//! Sony Minolta A100 Camera Settings binary array - definition
1248
constexpr ArrayDef sony1MCsA100Def[] = {
1249
    {112, ttSignedShort, 1},  // Exif.Sony1MltCsA100.WhiteBalanceFineTune
1250
    {116, ttSignedShort, 1},  // Exif.Sony1MltCsA100.ColorCompensationFilter
1251
    {190, ttSignedShort, 1},  // Exif.Sony1MltCsA100.ColorCompensationFilter2
1252
};
1253
1254
//! Samsung PictureWizard binary array - configuration
1255
constexpr ArrayCfg samsungPwCfg = {
1256
    IfdId::samsungPwId,  // Group for the elements
1257
    invalidByteOrder,    // Use byte order from parent
1258
    ttUnsignedShort,     // Type for array entry
1259
    notEncrypted,        // Not encrypted
1260
    false,               // No size element
1261
    true,                // Write all tags
1262
    true,                // Concatenate gaps
1263
    {0, ttUnsignedShort, 1},
1264
};
1265
//! Samsung PictureWizard binary array - definition
1266
constexpr ArrayDef samsungPwDef[] = {
1267
    {0, ttUnsignedShort, 1},  // Mode
1268
    {2, ttUnsignedShort, 1},  // Color
1269
    {4, ttUnsignedShort, 1},  // Saturation
1270
    {6, ttUnsignedShort, 1},  // Sharpness
1271
    {8, ttUnsignedShort, 1},  // Contrast
1272
};
1273
1274
/*
1275
  This table lists for each group in a tree, its parent group and tag.
1276
  Root identifies the root of a TIFF tree, as there is a need for multiple
1277
  trees. Groups are the nodes of a TIFF tree. A group is an IFD or any
1278
  other composite component.
1279
1280
  With this table, it is possible, for a given group (and tag) to find a
1281
  path, i.e., a list of groups and tags, from the root to that group (tag).
1282
*/
1283
const TiffTreeTable TiffCreator::tiffTreeTable_ = {
1284
    // root      group             parent group      parent tag
1285
    //---------  ----------------- ----------------- ----------
1286
    {{Tag::root, IfdId::ifdIdNotSet}, {IfdId::ifdIdNotSet, Tag::root}},
1287
    {{Tag::root, IfdId::ifd0Id}, {IfdId::ifdIdNotSet, Tag::root}},
1288
    {{Tag::root, IfdId::subImage1Id}, {IfdId::ifd0Id, 0x014a}},
1289
    {{Tag::root, IfdId::subImage2Id}, {IfdId::ifd0Id, 0x014a}},
1290
    {{Tag::root, IfdId::subImage3Id}, {IfdId::ifd0Id, 0x014a}},
1291
    {{Tag::root, IfdId::subImage4Id}, {IfdId::ifd0Id, 0x014a}},
1292
    {{Tag::root, IfdId::subImage5Id}, {IfdId::ifd0Id, 0x014a}},
1293
    {{Tag::root, IfdId::subImage6Id}, {IfdId::ifd0Id, 0x014a}},
1294
    {{Tag::root, IfdId::subImage7Id}, {IfdId::ifd0Id, 0x014a}},
1295
    {{Tag::root, IfdId::subImage8Id}, {IfdId::ifd0Id, 0x014a}},
1296
    {{Tag::root, IfdId::subImage9Id}, {IfdId::ifd0Id, 0x014a}},
1297
    {{Tag::root, IfdId::exifId}, {IfdId::ifd0Id, 0x8769}},
1298
    {{Tag::root, IfdId::gpsId}, {IfdId::ifd0Id, 0x8825}},
1299
    {{Tag::root, IfdId::iopId}, {IfdId::exifId, 0xa005}},
1300
    {{Tag::root, IfdId::ifd1Id}, {IfdId::ifd0Id, Tag::next}},
1301
    {{Tag::root, IfdId::ifd2Id}, {IfdId::ifd1Id, Tag::next}},
1302
    {{Tag::root, IfdId::ifd3Id}, {IfdId::ifd2Id, Tag::next}},
1303
    {{Tag::root, IfdId::olympusId}, {IfdId::exifId, 0x927c}},
1304
    {{Tag::root, IfdId::olympus2Id}, {IfdId::exifId, 0x927c}},
1305
    {{Tag::root, IfdId::subThumb1Id}, {IfdId::ifd1Id, 0x014a}},
1306
    {{Tag::root, IfdId::olympusEqId}, {IfdId::olympus2Id, 0x2010}},
1307
    {{Tag::root, IfdId::olympusCsId}, {IfdId::olympus2Id, 0x2020}},
1308
    {{Tag::root, IfdId::olympusRdId}, {IfdId::olympus2Id, 0x2030}},
1309
    {{Tag::root, IfdId::olympusRd2Id}, {IfdId::olympus2Id, 0x2031}},
1310
    {{Tag::root, IfdId::olympusIpId}, {IfdId::olympus2Id, 0x2040}},
1311
    {{Tag::root, IfdId::olympusFiId}, {IfdId::olympus2Id, 0x2050}},
1312
    {{Tag::root, IfdId::olympusFe1Id}, {IfdId::olympus2Id, 0x2100}},
1313
    {{Tag::root, IfdId::olympusFe2Id}, {IfdId::olympus2Id, 0x2200}},
1314
    {{Tag::root, IfdId::olympusFe3Id}, {IfdId::olympus2Id, 0x2300}},
1315
    {{Tag::root, IfdId::olympusFe4Id}, {IfdId::olympus2Id, 0x2400}},
1316
    {{Tag::root, IfdId::olympusFe5Id}, {IfdId::olympus2Id, 0x2500}},
1317
    {{Tag::root, IfdId::olympusFe6Id}, {IfdId::olympus2Id, 0x2600}},
1318
    {{Tag::root, IfdId::olympusFe7Id}, {IfdId::olympus2Id, 0x2700}},
1319
    {{Tag::root, IfdId::olympusFe8Id}, {IfdId::olympus2Id, 0x2800}},
1320
    {{Tag::root, IfdId::olympusFe9Id}, {IfdId::olympus2Id, 0x2900}},
1321
    {{Tag::root, IfdId::olympusRiId}, {IfdId::olympus2Id, 0x3000}},
1322
    {{Tag::root, IfdId::fujiId}, {IfdId::exifId, 0x927c}},
1323
    {{Tag::root, IfdId::canonId}, {IfdId::exifId, 0x927c}},
1324
    {{Tag::root, IfdId::canonCsId}, {IfdId::canonId, 0x0001}},
1325
    {{Tag::root, IfdId::canonSiId}, {IfdId::canonId, 0x0004}},
1326
    {{Tag::root, IfdId::canonPaId}, {IfdId::canonId, 0x0005}},
1327
    {{Tag::root, IfdId::canonCfId}, {IfdId::canonId, 0x000f}},
1328
    {{Tag::root, IfdId::canonPiId}, {IfdId::canonId, 0x0012}},
1329
    {{Tag::root, IfdId::canonTiId}, {IfdId::canonId, 0x0035}},
1330
    {{Tag::root, IfdId::canonFiId}, {IfdId::canonId, 0x0093}},
1331
    {{Tag::root, IfdId::canonPrId}, {IfdId::canonId, 0x00a0}},
1332
    {{Tag::root, IfdId::canonAfMiAdjId}, {IfdId::canonId, 0x4013}},
1333
    {{Tag::root, IfdId::canonVigCor2Id}, {IfdId::canonId, 0x4016}},
1334
    {{Tag::root, IfdId::canonLiOpId}, {IfdId::canonId, 0x4018}},
1335
    {{Tag::root, IfdId::canonLeId}, {IfdId::canonId, 0x4019}},
1336
    {{Tag::root, IfdId::canonAmId}, {IfdId::canonId, 0x4020}},
1337
    {{Tag::root, IfdId::canonMeId}, {IfdId::canonId, 0x4021}},
1338
    {{Tag::root, IfdId::canonFilId}, {IfdId::canonId, 0x4024}},
1339
    {{Tag::root, IfdId::canonHdrId}, {IfdId::canonId, 0x4025}},
1340
    {{Tag::root, IfdId::canonAfCId}, {IfdId::canonId, 0x4028}},
1341
    {{Tag::root, IfdId::canonRawBId}, {IfdId::canonId, 0x403f}},
1342
    {{Tag::root, IfdId::nikon1Id}, {IfdId::exifId, 0x927c}},
1343
    {{Tag::root, IfdId::nikon2Id}, {IfdId::exifId, 0x927c}},
1344
    {{Tag::root, IfdId::nikon3Id}, {IfdId::exifId, 0x927c}},
1345
    {{Tag::root, IfdId::nikonPvId}, {IfdId::nikon3Id, 0x0011}},
1346
    {{Tag::root, IfdId::nikonVrId}, {IfdId::nikon3Id, 0x001f}},
1347
    {{Tag::root, IfdId::nikonPcId}, {IfdId::nikon3Id, 0x0023}},
1348
    {{Tag::root, IfdId::nikonWtId}, {IfdId::nikon3Id, 0x0024}},
1349
    {{Tag::root, IfdId::nikonIiId}, {IfdId::nikon3Id, 0x0025}},
1350
    {{Tag::root, IfdId::nikonAfId}, {IfdId::nikon3Id, 0x0088}},
1351
    {{Tag::root, IfdId::nikonSi1Id}, {IfdId::nikon3Id, 0x0091}},
1352
    {{Tag::root, IfdId::nikonSi2Id}, {IfdId::nikon3Id, 0x0091}},
1353
    {{Tag::root, IfdId::nikonSi3Id}, {IfdId::nikon3Id, 0x0091}},
1354
    {{Tag::root, IfdId::nikonSi4Id}, {IfdId::nikon3Id, 0x0091}},
1355
    {{Tag::root, IfdId::nikonSi5Id}, {IfdId::nikon3Id, 0x0091}},
1356
    {{Tag::root, IfdId::nikonSi6Id}, {IfdId::nikon3Id, 0x0091}},
1357
    {{Tag::root, IfdId::nikonCb1Id}, {IfdId::nikon3Id, 0x0097}},
1358
    {{Tag::root, IfdId::nikonCb2Id}, {IfdId::nikon3Id, 0x0097}},
1359
    {{Tag::root, IfdId::nikonCb2aId}, {IfdId::nikon3Id, 0x0097}},
1360
    {{Tag::root, IfdId::nikonCb2bId}, {IfdId::nikon3Id, 0x0097}},
1361
    {{Tag::root, IfdId::nikonCb3Id}, {IfdId::nikon3Id, 0x0097}},
1362
    {{Tag::root, IfdId::nikonCb4Id}, {IfdId::nikon3Id, 0x0097}},
1363
    {{Tag::root, IfdId::nikonLd1Id}, {IfdId::nikon3Id, 0x0098}},
1364
    {{Tag::root, IfdId::nikonLd2Id}, {IfdId::nikon3Id, 0x0098}},
1365
    {{Tag::root, IfdId::nikonLd3Id}, {IfdId::nikon3Id, 0x0098}},
1366
    {{Tag::root, IfdId::nikonLd4Id}, {IfdId::nikon3Id, 0x0098}},
1367
    {{Tag::root, IfdId::nikonMeId}, {IfdId::nikon3Id, 0x00b0}},
1368
    {{Tag::root, IfdId::nikonAf21Id}, {IfdId::nikon3Id, 0x00b7}},
1369
    {{Tag::root, IfdId::nikonAf22Id}, {IfdId::nikon3Id, 0x00b7}},
1370
    {{Tag::root, IfdId::nikonFiId}, {IfdId::nikon3Id, 0x00b8}},
1371
    {{Tag::root, IfdId::nikonAFTId}, {IfdId::nikon3Id, 0x00b9}},
1372
    {{Tag::root, IfdId::nikonFl1Id}, {IfdId::nikon3Id, 0x00a8}},
1373
    {{Tag::root, IfdId::nikonFl2Id}, {IfdId::nikon3Id, 0x00a8}},
1374
    {{Tag::root, IfdId::nikonFl3Id}, {IfdId::nikon3Id, 0x00a8}},
1375
    {{Tag::root, IfdId::nikonFl6Id}, {IfdId::nikon3Id, 0x00a8}},
1376
    {{Tag::root, IfdId::nikonFl7Id}, {IfdId::nikon3Id, 0x00a8}},
1377
    {{Tag::root, IfdId::panasonicId}, {IfdId::exifId, 0x927c}},
1378
    {{Tag::root, IfdId::pentaxId}, {IfdId::exifId, 0x927c}},
1379
    {{Tag::root, IfdId::pentaxDngId}, {IfdId::ifd0Id, 0xc634}},
1380
    {{Tag::root, IfdId::samsung2Id}, {IfdId::exifId, 0x927c}},
1381
    {{Tag::root, IfdId::samsungPwId}, {IfdId::samsung2Id, 0x0021}},
1382
    {{Tag::root, IfdId::samsungPvId}, {IfdId::samsung2Id, 0x0035}},
1383
    {{Tag::root, IfdId::sigmaId}, {IfdId::exifId, 0x927c}},
1384
    {{Tag::root, IfdId::sony1Id}, {IfdId::exifId, 0x927c}},
1385
    {{Tag::root, IfdId::sony2010eId}, {IfdId::sony1Id, 0x2010}},
1386
    {{Tag::root, IfdId::sony2FpId}, {IfdId::sony1Id, 0x9402}},
1387
    {{Tag::root, IfdId::sonyMisc1Id}, {IfdId::sony1Id, 0x9403}},
1388
    {{Tag::root, IfdId::sonyMisc2bId}, {IfdId::sony1Id, 0x9404}},
1389
    {{Tag::root, IfdId::sonyMisc3cId}, {IfdId::sony1Id, 0x9400}},
1390
    {{Tag::root, IfdId::sonySInfo1Id}, {IfdId::sony1Id, 0x3000}},
1391
    {{Tag::root, IfdId::sony1CsId}, {IfdId::sony1Id, 0x0114}},
1392
    {{Tag::root, IfdId::sony1Cs2Id}, {IfdId::sony1Id, 0x0114}},
1393
    {{Tag::root, IfdId::sonyMltId}, {IfdId::sony1Id, 0xb028}},
1394
    {{Tag::root, IfdId::sony1MltCsOldId}, {IfdId::sonyMltId, 0x0001}},
1395
    {{Tag::root, IfdId::sony1MltCsNewId}, {IfdId::sonyMltId, 0x0003}},
1396
    {{Tag::root, IfdId::sony1MltCs7DId}, {IfdId::sonyMltId, 0x0004}},
1397
    {{Tag::root, IfdId::sony1MltCsA100Id}, {IfdId::sonyMltId, 0x0114}},
1398
    {{Tag::root, IfdId::sony2Id}, {IfdId::exifId, 0x927c}},
1399
    {{Tag::root, IfdId::sony2010eId}, {IfdId::sony2Id, 0x2010}},
1400
    {{Tag::root, IfdId::sony2FpId}, {IfdId::sony2Id, 0x9402}},
1401
    {{Tag::root, IfdId::sonyMisc1Id}, {IfdId::sony2Id, 0x9403}},
1402
    {{Tag::root, IfdId::sonyMisc2bId}, {IfdId::sony2Id, 0x9404}},
1403
    {{Tag::root, IfdId::sonyMisc3cId}, {IfdId::sony2Id, 0x9400}},
1404
    {{Tag::root, IfdId::sonySInfo1Id}, {IfdId::sony2Id, 0x3000}},
1405
    {{Tag::root, IfdId::sony2CsId}, {IfdId::sony2Id, 0x0114}},
1406
    {{Tag::root, IfdId::sony2Cs2Id}, {IfdId::sony2Id, 0x0114}},
1407
    {{Tag::root, IfdId::minoltaId}, {IfdId::exifId, 0x927c}},
1408
    {{Tag::root, IfdId::minoltaCsOldId}, {IfdId::minoltaId, 0x0001}},
1409
    {{Tag::root, IfdId::minoltaCsNewId}, {IfdId::minoltaId, 0x0003}},
1410
    {{Tag::root, IfdId::minoltaCs7DId}, {IfdId::minoltaId, 0x0004}},
1411
    {{Tag::root, IfdId::minoltaCs5DId}, {IfdId::minoltaId, 0x0114}},
1412
    {{Tag::root, IfdId::casioId}, {IfdId::exifId, 0x927c}},
1413
    {{Tag::root, IfdId::casio2Id}, {IfdId::exifId, 0x927c}},
1414
    // ---------------------------------------------------------
1415
    // Panasonic RW2 raw images
1416
    {{Tag::pana, IfdId::ifdIdNotSet}, {IfdId::ifdIdNotSet, Tag::pana}},
1417
    {{Tag::pana, IfdId::panaRawId}, {IfdId::ifdIdNotSet, Tag::pana}},
1418
    {{Tag::pana, IfdId::exifId}, {IfdId::panaRawId, 0x8769}},
1419
    {{Tag::pana, IfdId::gpsId}, {IfdId::panaRawId, 0x8825}},
1420
};
1421
1422
/*
1423
  This table describes the layout of each known TIFF group (including
1424
  non-standard structures and IFDs only seen in RAW images).
1425
1426
  The key of the table consists of the first two attributes, (extended) tag
1427
  and group. Tag is the TIFF tag or one of a few extended tags, group
1428
  identifies the IFD or any other composite component.
1429
1430
  Each entry of the table defines for a particular tag and group combination
1431
  the corresponding TIFF component create function.
1432
 */
1433
#define ignoreTiffComponent nullptr
1434
const TiffGroupTable TiffCreator::tiffGroupTable_ = {
1435
    // ext. tag  group             create function
1436
    //---------  ----------------- -----------------------------------------
1437
    // Root directory
1438
    {{Tag::root, IfdId::ifdIdNotSet}, &newTiffDirectory<IfdId::ifd0Id>},
1439
1440
    // Fujifilm RAF #1402.  Use different root when parsing embedded tiff.
1441
    {{Tag::fuji, IfdId::ifdIdNotSet}, &newTiffDirectory<IfdId::fujiId>},
1442
    {{0xf000, IfdId::fujiId}, &newTiffSubIfd<IfdId::fujiId>},
1443
1444
    // CR3 images #1475
1445
    {{Tag::cmt2, IfdId::ifdIdNotSet}, &newTiffDirectory<IfdId::exifId>},
1446
    {{Tag::cmt3, IfdId::ifdIdNotSet}, &newTiffDirectory<IfdId::canonId>},
1447
    {{Tag::cmt4, IfdId::ifdIdNotSet}, &newTiffDirectory<IfdId::gpsId>},
1448
1449
    // IFD0
1450
    {{0x8769, IfdId::ifd0Id}, &newTiffSubIfd<IfdId::exifId>},
1451
    {{0x8825, IfdId::ifd0Id}, &newTiffSubIfd<IfdId::gpsId>},
1452
    {{0x0111, IfdId::ifd0Id}, &newTiffImageData<0x0117, IfdId::ifd0Id>},
1453
    {{0x0117, IfdId::ifd0Id}, &newTiffImageSize<0x0111, IfdId::ifd0Id>},
1454
    {{0x0144, IfdId::ifd0Id}, &newTiffImageData<0x0145, IfdId::ifd0Id>},
1455
    {{0x0145, IfdId::ifd0Id}, &newTiffImageSize<0x0144, IfdId::ifd0Id>},
1456
    {{0x0201, IfdId::ifd0Id}, &newTiffImageData<0x0202, IfdId::ifd0Id>},
1457
    {{0x0202, IfdId::ifd0Id}, &newTiffImageSize<0x0201, IfdId::ifd0Id>},
1458
    {{0x014a, IfdId::ifd0Id}, &newTiffSubIfd<IfdId::subImage1Id>},
1459
    {{0xc634, IfdId::ifd0Id}, &newTiffMnEntry},
1460
    {{Tag::next, IfdId::ifd0Id}, &newTiffDirectory<IfdId::ifd1Id>},
1461
    {{Tag::all, IfdId::ifd0Id}, &newTiffEntry},
1462
1463
    // Subdir subImage1
1464
    {{0x0111, IfdId::subImage1Id}, &newTiffImageData<0x0117, IfdId::subImage1Id>},
1465
    {{0x0117, IfdId::subImage1Id}, &newTiffImageSize<0x0111, IfdId::subImage1Id>},
1466
    {{0x0144, IfdId::subImage1Id}, &newTiffImageData<0x0145, IfdId::subImage1Id>},
1467
    {{0x0145, IfdId::subImage1Id}, &newTiffImageSize<0x0144, IfdId::subImage1Id>},
1468
    {{0x0201, IfdId::subImage1Id}, &newTiffImageData<0x0202, IfdId::subImage1Id>},
1469
    {{0x0202, IfdId::subImage1Id}, &newTiffImageSize<0x0201, IfdId::subImage1Id>},
1470
    {{Tag::next, IfdId::subImage1Id}, ignoreTiffComponent},
1471
    {{Tag::all, IfdId::subImage1Id}, &newTiffEntry},
1472
1473
    // Subdir subImage2
1474
    {{0x0111, IfdId::subImage2Id}, &newTiffImageData<0x0117, IfdId::subImage2Id>},
1475
    {{0x0117, IfdId::subImage2Id}, &newTiffImageSize<0x0111, IfdId::subImage2Id>},
1476
    {{0x0144, IfdId::subImage2Id}, &newTiffImageData<0x0145, IfdId::subImage2Id>},
1477
    {{0x0145, IfdId::subImage2Id}, &newTiffImageSize<0x0144, IfdId::subImage2Id>},
1478
    {{0x0201, IfdId::subImage2Id}, &newTiffImageData<0x0202, IfdId::subImage2Id>},
1479
    {{0x0202, IfdId::subImage2Id}, &newTiffImageSize<0x0201, IfdId::subImage2Id>},
1480
    {{Tag::next, IfdId::subImage2Id}, ignoreTiffComponent},
1481
    {{Tag::all, IfdId::subImage2Id}, &newTiffEntry},
1482
1483
    // Subdir subImage3
1484
    {{0x0111, IfdId::subImage3Id}, &newTiffImageData<0x0117, IfdId::subImage3Id>},
1485
    {{0x0117, IfdId::subImage3Id}, &newTiffImageSize<0x0111, IfdId::subImage3Id>},
1486
    {{0x0144, IfdId::subImage3Id}, &newTiffImageData<0x0145, IfdId::subImage3Id>},
1487
    {{0x0145, IfdId::subImage3Id}, &newTiffImageSize<0x0144, IfdId::subImage3Id>},
1488
    {{0x0201, IfdId::subImage3Id}, &newTiffImageData<0x0202, IfdId::subImage3Id>},
1489
    {{0x0202, IfdId::subImage3Id}, &newTiffImageSize<0x0201, IfdId::subImage3Id>},
1490
    {{Tag::next, IfdId::subImage3Id}, ignoreTiffComponent},
1491
    {{Tag::all, IfdId::subImage3Id}, &newTiffEntry},
1492
1493
    // Subdir subImage4
1494
    {{0x0111, IfdId::subImage4Id}, &newTiffImageData<0x0117, IfdId::subImage4Id>},
1495
    {{0x0117, IfdId::subImage4Id}, &newTiffImageSize<0x0111, IfdId::subImage4Id>},
1496
    {{0x0144, IfdId::subImage4Id}, &newTiffImageData<0x0145, IfdId::subImage4Id>},
1497
    {{0x0145, IfdId::subImage4Id}, &newTiffImageSize<0x0144, IfdId::subImage4Id>},
1498
    {{0x0201, IfdId::subImage4Id}, &newTiffImageData<0x0202, IfdId::subImage4Id>},
1499
    {{0x0202, IfdId::subImage4Id}, &newTiffImageSize<0x0201, IfdId::subImage4Id>},
1500
    {{Tag::next, IfdId::subImage4Id}, ignoreTiffComponent},
1501
    {{Tag::all, IfdId::subImage4Id}, &newTiffEntry},
1502
1503
    // Subdir subImage5
1504
    {{0x0111, IfdId::subImage5Id}, &newTiffImageData<0x0117, IfdId::subImage5Id>},
1505
    {{0x0117, IfdId::subImage5Id}, &newTiffImageSize<0x0111, IfdId::subImage5Id>},
1506
    {{0x0144, IfdId::subImage5Id}, &newTiffImageData<0x0145, IfdId::subImage5Id>},
1507
    {{0x0145, IfdId::subImage5Id}, &newTiffImageSize<0x0144, IfdId::subImage5Id>},
1508
    {{0x0201, IfdId::subImage5Id}, &newTiffImageData<0x0202, IfdId::subImage5Id>},
1509
    {{0x0202, IfdId::subImage5Id}, &newTiffImageSize<0x0201, IfdId::subImage5Id>},
1510
    {{Tag::next, IfdId::subImage5Id}, ignoreTiffComponent},
1511
    {{Tag::all, IfdId::subImage5Id}, &newTiffEntry},
1512
1513
    // Subdir subImage6
1514
    {{0x0111, IfdId::subImage6Id}, &newTiffImageData<0x0117, IfdId::subImage6Id>},
1515
    {{0x0117, IfdId::subImage6Id}, &newTiffImageSize<0x0111, IfdId::subImage6Id>},
1516
    {{0x0144, IfdId::subImage6Id}, &newTiffImageData<0x0145, IfdId::subImage6Id>},
1517
    {{0x0145, IfdId::subImage6Id}, &newTiffImageSize<0x0144, IfdId::subImage6Id>},
1518
    {{0x0201, IfdId::subImage6Id}, &newTiffImageData<0x0202, IfdId::subImage6Id>},
1519
    {{0x0202, IfdId::subImage6Id}, &newTiffImageSize<0x0201, IfdId::subImage6Id>},
1520
    {{Tag::next, IfdId::subImage6Id}, ignoreTiffComponent},
1521
    {{Tag::all, IfdId::subImage6Id}, &newTiffEntry},
1522
1523
    // Subdir subImage7
1524
    {{0x0111, IfdId::subImage7Id}, &newTiffImageData<0x0117, IfdId::subImage7Id>},
1525
    {{0x0117, IfdId::subImage7Id}, &newTiffImageSize<0x0111, IfdId::subImage7Id>},
1526
    {{0x0144, IfdId::subImage7Id}, &newTiffImageData<0x0145, IfdId::subImage7Id>},
1527
    {{0x0145, IfdId::subImage7Id}, &newTiffImageSize<0x0144, IfdId::subImage7Id>},
1528
    {{0x0201, IfdId::subImage7Id}, &newTiffImageData<0x0202, IfdId::subImage7Id>},
1529
    {{0x0202, IfdId::subImage7Id}, &newTiffImageSize<0x0201, IfdId::subImage7Id>},
1530
    {{Tag::next, IfdId::subImage7Id}, ignoreTiffComponent},
1531
    {{Tag::all, IfdId::subImage7Id}, &newTiffEntry},
1532
1533
    // Subdir subImage8
1534
    {{0x0111, IfdId::subImage8Id}, &newTiffImageData<0x0117, IfdId::subImage8Id>},
1535
    {{0x0117, IfdId::subImage8Id}, &newTiffImageSize<0x0111, IfdId::subImage8Id>},
1536
    {{0x0144, IfdId::subImage8Id}, &newTiffImageData<0x0145, IfdId::subImage8Id>},
1537
    {{0x0145, IfdId::subImage8Id}, &newTiffImageSize<0x0144, IfdId::subImage8Id>},
1538
    {{0x0201, IfdId::subImage8Id}, &newTiffImageData<0x0202, IfdId::subImage8Id>},
1539
    {{0x0202, IfdId::subImage8Id}, &newTiffImageSize<0x0201, IfdId::subImage8Id>},
1540
    {{Tag::next, IfdId::subImage8Id}, ignoreTiffComponent},
1541
    {{Tag::all, IfdId::subImage8Id}, &newTiffEntry},
1542
1543
    // Subdir subImage9
1544
    {{0x0111, IfdId::subImage9Id}, &newTiffImageData<0x0117, IfdId::subImage9Id>},
1545
    {{0x0117, IfdId::subImage9Id}, &newTiffImageSize<0x0111, IfdId::subImage9Id>},
1546
    {{0x0144, IfdId::subImage9Id}, &newTiffImageData<0x0145, IfdId::subImage9Id>},
1547
    {{0x0145, IfdId::subImage9Id}, &newTiffImageSize<0x0144, IfdId::subImage9Id>},
1548
    {{0x0201, IfdId::subImage9Id}, &newTiffImageData<0x0202, IfdId::subImage9Id>},
1549
    {{0x0202, IfdId::subImage9Id}, &newTiffImageSize<0x0201, IfdId::subImage9Id>},
1550
    {{Tag::next, IfdId::subImage9Id}, ignoreTiffComponent},
1551
    {{Tag::all, IfdId::subImage9Id}, &newTiffEntry},
1552
1553
    // Exif subdir
1554
    {{0xa005, IfdId::exifId}, &newTiffSubIfd<IfdId::iopId>},
1555
    {{0x927c, IfdId::exifId}, &newTiffMnEntry},
1556
    {{Tag::next, IfdId::exifId}, ignoreTiffComponent},
1557
    {{Tag::all, IfdId::exifId}, &newTiffEntry},
1558
1559
    // GPS subdir
1560
    {{Tag::next, IfdId::gpsId}, ignoreTiffComponent},
1561
    {{Tag::all, IfdId::gpsId}, &newTiffEntry},
1562
1563
    // IOP subdir
1564
    {{Tag::next, IfdId::iopId}, ignoreTiffComponent},
1565
    {{Tag::all, IfdId::iopId}, &newTiffEntry},
1566
1567
    // IFD1
1568
    {{0x0111, IfdId::ifd1Id}, &newTiffThumbData<0x0117, IfdId::ifd1Id>},
1569
    {{0x0117, IfdId::ifd1Id}, &newTiffThumbSize<0x0111, IfdId::ifd1Id>},
1570
    {{0x0144, IfdId::ifd1Id}, &newTiffImageData<0x0145, IfdId::ifd1Id>},
1571
    {{0x0145, IfdId::ifd1Id}, &newTiffImageSize<0x0144, IfdId::ifd1Id>},
1572
    {{0x014a, IfdId::ifd1Id}, &newTiffSubIfd<IfdId::subThumb1Id>},
1573
    {{0x0201, IfdId::ifd1Id}, &newTiffThumbData<0x0202, IfdId::ifd1Id>},
1574
    {{0x0202, IfdId::ifd1Id}, &newTiffThumbSize<0x0201, IfdId::ifd1Id>},
1575
    {{Tag::next, IfdId::ifd1Id}, &newTiffDirectory<IfdId::ifd2Id>},
1576
    {{Tag::all, IfdId::ifd1Id}, &newTiffEntry},
1577
1578
    // Subdir subThumb1
1579
    {{0x0111, IfdId::subThumb1Id}, &newTiffImageData<0x0117, IfdId::subThumb1Id>},
1580
    {{0x0117, IfdId::subThumb1Id}, &newTiffImageSize<0x0111, IfdId::subThumb1Id>},
1581
    {{0x0144, IfdId::subThumb1Id}, &newTiffImageData<0x0145, IfdId::subThumb1Id>},
1582
    {{0x0145, IfdId::subThumb1Id}, &newTiffImageSize<0x0144, IfdId::subThumb1Id>},
1583
    {{0x0201, IfdId::subThumb1Id}, &newTiffImageData<0x0202, IfdId::subThumb1Id>},
1584
    {{0x0202, IfdId::subThumb1Id}, &newTiffImageSize<0x0201, IfdId::subThumb1Id>},
1585
    {{Tag::next, IfdId::subThumb1Id}, ignoreTiffComponent},
1586
    {{Tag::all, IfdId::subThumb1Id}, &newTiffEntry},
1587
1588
    // IFD2 (eg, in Pentax PEF and Canon CR2 files)
1589
    {{0x0111, IfdId::ifd2Id}, &newTiffImageData<0x0117, IfdId::ifd2Id>},
1590
    {{0x0117, IfdId::ifd2Id}, &newTiffImageSize<0x0111, IfdId::ifd2Id>},
1591
    {{0x0144, IfdId::ifd1Id}, &newTiffImageData<0x0145, IfdId::ifd2Id>},
1592
    {{0x0145, IfdId::ifd1Id}, &newTiffImageSize<0x0144, IfdId::ifd2Id>},
1593
    {{0x0201, IfdId::ifd2Id}, &newTiffImageData<0x0202, IfdId::ifd2Id>},
1594
    {{0x0202, IfdId::ifd2Id}, &newTiffImageSize<0x0201, IfdId::ifd2Id>},
1595
    {{Tag::next, IfdId::ifd2Id}, &newTiffDirectory<IfdId::ifd3Id>},
1596
    {{Tag::all, IfdId::ifd2Id}, &newTiffEntry},
1597
1598
    // IFD3 (eg, in Canon CR2 files)
1599
    {{0x0111, IfdId::ifd3Id}, &newTiffImageData<0x0117, IfdId::ifd3Id>},
1600
    {{0x0117, IfdId::ifd3Id}, &newTiffImageSize<0x0111, IfdId::ifd3Id>},
1601
    {{0x0144, IfdId::ifd1Id}, &newTiffImageData<0x0145, IfdId::ifd3Id>},
1602
    {{0x0145, IfdId::ifd1Id}, &newTiffImageSize<0x0144, IfdId::ifd3Id>},
1603
    {{0x0201, IfdId::ifd3Id}, &newTiffImageData<0x0202, IfdId::ifd3Id>},
1604
    {{0x0202, IfdId::ifd3Id}, &newTiffImageSize<0x0201, IfdId::ifd3Id>},
1605
    {{Tag::next, IfdId::ifd3Id}, ignoreTiffComponent},
1606
    {{Tag::all, IfdId::ifd3Id}, &newTiffEntry},
1607
1608
    // Olympus makernote - some Olympus cameras use Minolta structures
1609
    // Todo: Adding such tags will not work (maybe result in a Minolta makernote), need separate groups
1610
    {{0x0001, IfdId::olympusId}, EXV_SIMPLE_BINARY_ARRAY(minoCsoCfg)},
1611
    {{0x0003, IfdId::olympusId}, EXV_SIMPLE_BINARY_ARRAY(minoCsnCfg)},
1612
    {{Tag::next, IfdId::olympusId}, ignoreTiffComponent},
1613
    {{Tag::all, IfdId::olympusId}, &newTiffEntry},
1614
1615
    // Olympus2 makernote
1616
    {{0x0001, IfdId::olympus2Id}, EXV_SIMPLE_BINARY_ARRAY(minoCsoCfg)},
1617
    {{0x0003, IfdId::olympus2Id}, EXV_SIMPLE_BINARY_ARRAY(minoCsnCfg)},
1618
    {{0x2010, IfdId::olympus2Id}, &newTiffSubIfd<IfdId::olympusEqId>},
1619
    {{0x2020, IfdId::olympus2Id}, &newTiffSubIfd<IfdId::olympusCsId>},
1620
    {{0x2030, IfdId::olympus2Id}, &newTiffSubIfd<IfdId::olympusRdId>},
1621
    {{0x2031, IfdId::olympus2Id}, &newTiffSubIfd<IfdId::olympusRd2Id>},
1622
    {{0x2040, IfdId::olympus2Id}, &newTiffSubIfd<IfdId::olympusIpId>},
1623
    {{0x2050, IfdId::olympus2Id}, &newTiffSubIfd<IfdId::olympusFiId>},
1624
    {{0x2100, IfdId::olympus2Id}, &newTiffSubIfd<IfdId::olympusFe1Id>},
1625
    {{0x2200, IfdId::olympus2Id}, &newTiffSubIfd<IfdId::olympusFe2Id>},
1626
    {{0x2300, IfdId::olympus2Id}, &newTiffSubIfd<IfdId::olympusFe3Id>},
1627
    {{0x2400, IfdId::olympus2Id}, &newTiffSubIfd<IfdId::olympusFe4Id>},
1628
    {{0x2500, IfdId::olympus2Id}, &newTiffSubIfd<IfdId::olympusFe5Id>},
1629
    {{0x2600, IfdId::olympus2Id}, &newTiffSubIfd<IfdId::olympusFe6Id>},
1630
    {{0x2700, IfdId::olympus2Id}, &newTiffSubIfd<IfdId::olympusFe7Id>},
1631
    {{0x2800, IfdId::olympus2Id}, &newTiffSubIfd<IfdId::olympusFe8Id>},
1632
    {{0x2900, IfdId::olympus2Id}, &newTiffSubIfd<IfdId::olympusFe9Id>},
1633
    {{0x3000, IfdId::olympus2Id}, &newTiffSubIfd<IfdId::olympusRiId>},
1634
    {{Tag::next, IfdId::olympus2Id}, ignoreTiffComponent},
1635
    {{Tag::all, IfdId::olympus2Id}, &newTiffEntry},
1636
1637
    // Olympus2 equipment subdir
1638
    {{Tag::all, IfdId::olympusEqId}, &newTiffEntry},
1639
1640
    // Olympus2 camera settings subdir
1641
    {{0x0101, IfdId::olympusCsId}, &newTiffImageData<0x0102, IfdId::olympusCsId>},
1642
    {{0x0102, IfdId::olympusCsId}, &newTiffImageSize<0x0101, IfdId::olympusCsId>},
1643
    {{Tag::all, IfdId::olympusCsId}, &newTiffEntry},
1644
1645
    // Olympus2 raw development subdir
1646
    {{Tag::all, IfdId::olympusRdId}, &newTiffEntry},
1647
1648
    // Olympus2 raw development 2 subdir
1649
    {{Tag::all, IfdId::olympusRd2Id}, &newTiffEntry},
1650
1651
    // Olympus2 image processing subdir
1652
    {{Tag::all, IfdId::olympusIpId}, &newTiffEntry},
1653
1654
    // Olympus2 focus info subdir
1655
    {{Tag::all, IfdId::olympusFiId}, &newTiffEntry},
1656
1657
    // Olympus2 FE 1 subdir
1658
    {{Tag::all, IfdId::olympusFe1Id}, &newTiffEntry},
1659
1660
    // Olympus2 FE 2 subdir
1661
    {{Tag::all, IfdId::olympusFe2Id}, &newTiffEntry},
1662
1663
    // Olympus2 FE 3 subdir
1664
    {{Tag::all, IfdId::olympusFe3Id}, &newTiffEntry},
1665
1666
    // Olympus2 FE 4 subdir
1667
    {{Tag::all, IfdId::olympusFe4Id}, &newTiffEntry},
1668
1669
    // Olympus2 FE 5 subdir
1670
    {{Tag::all, IfdId::olympusFe5Id}, &newTiffEntry},
1671
1672
    // Olympus2 FE 6 subdir
1673
    {{Tag::all, IfdId::olympusFe6Id}, &newTiffEntry},
1674
1675
    // Olympus2 FE 7 subdir
1676
    {{Tag::all, IfdId::olympusFe7Id}, &newTiffEntry},
1677
1678
    // Olympus2 FE 8 subdir
1679
    {{Tag::all, IfdId::olympusFe8Id}, &newTiffEntry},
1680
1681
    // Olympus2 FE 9 subdir
1682
    {{Tag::all, IfdId::olympusFe9Id}, &newTiffEntry},
1683
1684
    // Olympus2 Raw Info subdir
1685
    {{Tag::all, IfdId::olympusRiId}, &newTiffEntry},
1686
1687
    // Fujifilm makernote
1688
    {{Tag::next, IfdId::fujiId}, ignoreTiffComponent},
1689
    {{Tag::all, IfdId::fujiId}, &newTiffEntry},
1690
1691
    // Canon makernote
1692
    {{0x0001, IfdId::canonId}, EXV_BINARY_ARRAY(canonCsCfg, canonCsDef)},
1693
    {{0x0004, IfdId::canonId}, EXV_SIMPLE_BINARY_ARRAY(canonSiCfg)},
1694
    {{0x0005, IfdId::canonId}, EXV_SIMPLE_BINARY_ARRAY(canonPaCfg)},
1695
    {{0x000f, IfdId::canonId}, EXV_SIMPLE_BINARY_ARRAY(canonCfCfg)},
1696
    {{0x0012, IfdId::canonId}, EXV_SIMPLE_BINARY_ARRAY(canonPiCfg)},
1697
    {{0x0035, IfdId::canonId}, EXV_SIMPLE_BINARY_ARRAY(canonTiCfg)},
1698
    {{0x0093, IfdId::canonId}, EXV_BINARY_ARRAY(canonFiCfg, canonFiDef)},
1699
    {{0x00a0, IfdId::canonId}, EXV_SIMPLE_BINARY_ARRAY(canonPrCfg)},
1700
    {{0x4013, IfdId::canonId}, EXV_SIMPLE_BINARY_ARRAY(canonAfMiAdjCfg)},
1701
    //  {{    0x4015, IfdId::canonId,          EXV_SIMPLE_BINARY_ARRAY(canonVigCorCfg)   },
1702
    {{0x4016, IfdId::canonId}, EXV_SIMPLE_BINARY_ARRAY(canonVigCor2Cfg)},
1703
    {{0x4018, IfdId::canonId}, EXV_SIMPLE_BINARY_ARRAY(canonLiOpCfg)},
1704
    {{0x4019, IfdId::canonId}, EXV_BINARY_ARRAY(canonLeCfg, canonLeDef)},
1705
    {{0x4020, IfdId::canonId}, EXV_SIMPLE_BINARY_ARRAY(canonAmCfg)},
1706
    {{0x4021, IfdId::canonId}, EXV_SIMPLE_BINARY_ARRAY(canonMeCfg)},
1707
    {{0x4024, IfdId::canonId}, EXV_SIMPLE_BINARY_ARRAY(canonFilCfg)},
1708
    {{0x4025, IfdId::canonId}, EXV_SIMPLE_BINARY_ARRAY(canonHdrCfg)},
1709
    {{0x4028, IfdId::canonId}, EXV_SIMPLE_BINARY_ARRAY(canonAfCCfg)},
1710
    {{0x403f, IfdId::canonId}, EXV_SIMPLE_BINARY_ARRAY(canonRawBCfg)},
1711
    {{Tag::next, IfdId::canonId}, ignoreTiffComponent},
1712
    {{Tag::all, IfdId::canonId}, &newTiffEntry},
1713
1714
    // Canon makernote composite tags
1715
    {{Tag::all, IfdId::canonCsId}, &newTiffBinaryElement},
1716
    {{Tag::all, IfdId::canonSiId}, &newTiffBinaryElement},
1717
    {{Tag::all, IfdId::canonPaId}, &newTiffBinaryElement},
1718
    {{Tag::all, IfdId::canonCfId}, &newTiffBinaryElement},
1719
    {{Tag::all, IfdId::canonPiId}, &newTiffBinaryElement},
1720
    {{Tag::all, IfdId::canonTiId}, &newTiffBinaryElement},
1721
    {{Tag::all, IfdId::canonFiId}, &newTiffBinaryElement},
1722
    {{Tag::all, IfdId::canonPrId}, &newTiffBinaryElement},
1723
    {{Tag::all, IfdId::canonAfMiAdjId}, &newTiffBinaryElement},
1724
    // {{  Tag::all, IfdId::canonVigCorId,    newTiffBinaryElement                      },
1725
    {{Tag::all, IfdId::canonVigCor2Id}, &newTiffBinaryElement},
1726
    {{Tag::all, IfdId::canonLiOpId}, &newTiffBinaryElement},
1727
    {{Tag::all, IfdId::canonLeId}, &newTiffBinaryElement},
1728
    {{Tag::all, IfdId::canonAmId}, &newTiffBinaryElement},
1729
    {{Tag::all, IfdId::canonMeId}, &newTiffBinaryElement},
1730
    {{Tag::all, IfdId::canonFilId}, &newTiffBinaryElement},
1731
    {{Tag::all, IfdId::canonHdrId}, &newTiffBinaryElement},
1732
    {{Tag::all, IfdId::canonAfCId}, &newTiffBinaryElement},
1733
    {{Tag::all, IfdId::canonRawBId}, &newTiffBinaryElement},
1734
1735
    // Nikon1 makernote
1736
    {{Tag::next, IfdId::nikon1Id}, ignoreTiffComponent},
1737
    {{Tag::all, IfdId::nikon1Id}, &newTiffEntry},
1738
1739
    // Nikon2 makernote
1740
    {{Tag::next, IfdId::nikon2Id}, ignoreTiffComponent},
1741
    {{Tag::all, IfdId::nikon2Id}, &newTiffEntry},
1742
1743
    // Nikon3 makernote
1744
    {{Tag::next, IfdId::nikon3Id}, ignoreTiffComponent},
1745
    {{0x0011, IfdId::nikon3Id}, &newTiffSubIfd<IfdId::nikonPvId>},
1746
    {{0x001f, IfdId::nikon3Id}, EXV_BINARY_ARRAY(nikonVrCfg, nikonVrDef)},
1747
    {{0x0023, IfdId::nikon3Id}, EXV_BINARY_ARRAY(nikonPcCfg, nikonPcDef)},
1748
    {{0x0024, IfdId::nikon3Id}, EXV_BINARY_ARRAY(nikonWtCfg, nikonWtDef)},
1749
    {{0x0025, IfdId::nikon3Id}, EXV_BINARY_ARRAY(nikonIiCfg, nikonIiDef)},
1750
    {{0x0088, IfdId::nikon3Id}, EXV_BINARY_ARRAY(nikonAfCfg, nikonAfDef)},
1751
    {{0x0091, IfdId::nikon3Id}, EXV_COMPLEX_BINARY_ARRAY(nikonSiSet, &nikonSelector)},
1752
    {{0x0097, IfdId::nikon3Id}, EXV_COMPLEX_BINARY_ARRAY(nikonCbSet, &nikonSelector)},
1753
    {{0x0098, IfdId::nikon3Id}, EXV_COMPLEX_BINARY_ARRAY(nikonLdSet, &nikonSelector)},
1754
    {{0x00a8, IfdId::nikon3Id}, EXV_COMPLEX_BINARY_ARRAY(nikonFlSet, &nikonSelector)},
1755
    {{0x00b0, IfdId::nikon3Id}, EXV_BINARY_ARRAY(nikonMeCfg, nikonMeDef)},
1756
    {{0x00b7, IfdId::nikon3Id}, EXV_COMPLEX_BINARY_ARRAY(nikonAf2Set, &nikonSelector)},
1757
    {{0x00b8, IfdId::nikon3Id}, EXV_BINARY_ARRAY(nikonFiCfg, nikonFiDef)},
1758
    {{0x00b9, IfdId::nikon3Id}, EXV_BINARY_ARRAY(nikonAFTCfg, nikonAFTDef)},
1759
    {{Tag::all, IfdId::nikon3Id}, &newTiffEntry},
1760
1761
    // Nikon3 makernote preview subdir
1762
    {{0x0201, IfdId::nikonPvId}, &newTiffThumbData<0x0202, IfdId::nikonPvId>},
1763
    {{0x0202, IfdId::nikonPvId}, &newTiffThumbSize<0x0201, IfdId::nikonPvId>},
1764
    {{Tag::next, IfdId::nikonPvId}, ignoreTiffComponent},
1765
    {{Tag::all, IfdId::nikonPvId}, &newTiffEntry},
1766
1767
    // Nikon3 vibration reduction
1768
    {{Tag::all, IfdId::nikonVrId}, &newTiffBinaryElement},
1769
1770
    // Nikon3 picture control
1771
    {{Tag::all, IfdId::nikonPcId}, &newTiffBinaryElement},
1772
1773
    // Nikon3 world time
1774
    {{Tag::all, IfdId::nikonWtId}, &newTiffBinaryElement},
1775
1776
    // Nikon3 ISO info
1777
    {{Tag::all, IfdId::nikonIiId}, &newTiffBinaryElement},
1778
1779
    // Nikon3 auto focus
1780
    {{Tag::all, IfdId::nikonAfId}, &newTiffBinaryElement},
1781
1782
    // Nikon3 auto focus 2
1783
    {{Tag::all, IfdId::nikonAf21Id}, &newTiffBinaryElement},
1784
    {{Tag::all, IfdId::nikonAf22Id}, &newTiffBinaryElement},
1785
1786
    // Nikon3 AF Fine Tune
1787
    {{Tag::all, IfdId::nikonAFTId}, &newTiffBinaryElement},
1788
1789
    // Nikon3 file info
1790
    {{Tag::all, IfdId::nikonFiId}, &newTiffBinaryElement},
1791
1792
    // Nikon3 multi exposure
1793
    {{Tag::all, IfdId::nikonMeId}, &newTiffBinaryElement},
1794
1795
    // Nikon3 flash info
1796
    {{Tag::all, IfdId::nikonFl1Id}, &newTiffBinaryElement},
1797
    {{Tag::all, IfdId::nikonFl2Id}, &newTiffBinaryElement},
1798
    {{Tag::all, IfdId::nikonFl3Id}, &newTiffBinaryElement},
1799
    {{Tag::all, IfdId::nikonFl6Id}, &newTiffBinaryElement},
1800
    {{Tag::all, IfdId::nikonFl7Id}, &newTiffBinaryElement},
1801
1802
    // Nikon3 shot info
1803
    {{Tag::all, IfdId::nikonSi1Id}, &newTiffBinaryElement},
1804
    {{Tag::all, IfdId::nikonSi2Id}, &newTiffBinaryElement},
1805
    {{Tag::all, IfdId::nikonSi3Id}, &newTiffBinaryElement},
1806
    {{Tag::all, IfdId::nikonSi4Id}, &newTiffBinaryElement},
1807
    {{Tag::all, IfdId::nikonSi5Id}, &newTiffBinaryElement},
1808
    {{Tag::all, IfdId::nikonSi6Id}, &newTiffBinaryElement},
1809
1810
    // Nikon3 color balance
1811
    {{Tag::all, IfdId::nikonCb1Id}, &newTiffBinaryElement},
1812
    {{Tag::all, IfdId::nikonCb2Id}, &newTiffBinaryElement},
1813
    {{Tag::all, IfdId::nikonCb2aId}, &newTiffBinaryElement},
1814
    {{Tag::all, IfdId::nikonCb2bId}, &newTiffBinaryElement},
1815
    {{Tag::all, IfdId::nikonCb3Id}, &newTiffBinaryElement},
1816
    {{Tag::all, IfdId::nikonCb4Id}, &newTiffBinaryElement},
1817
1818
    // Nikon3 lens data
1819
    {{Tag::all, IfdId::nikonLd1Id}, &newTiffBinaryElement},
1820
    {{Tag::all, IfdId::nikonLd2Id}, &newTiffBinaryElement},
1821
    {{Tag::all, IfdId::nikonLd3Id}, &newTiffBinaryElement},
1822
    {{Tag::all, IfdId::nikonLd4Id}, &newTiffBinaryElement},
1823
1824
    // Panasonic makernote
1825
    {{Tag::next, IfdId::panasonicId}, ignoreTiffComponent},
1826
    {{Tag::all, IfdId::panasonicId}, &newTiffEntry},
1827
1828
    // Pentax DNG makernote
1829
    {{0x0003, IfdId::pentaxDngId}, &newTiffThumbSize<0x0004, IfdId::pentaxDngId>},
1830
    {{0x0004, IfdId::pentaxDngId}, &newTiffThumbData<0x0003, IfdId::pentaxDngId>},
1831
    {{Tag::next, IfdId::pentaxDngId}, ignoreTiffComponent},
1832
    {{Tag::all, IfdId::pentaxDngId}, &newTiffEntry},
1833
1834
    // Pentax makernote
1835
    {{0x0003, IfdId::pentaxId}, &newTiffThumbSize<0x0004, IfdId::pentaxId>},
1836
    {{0x0004, IfdId::pentaxId}, &newTiffThumbData<0x0003, IfdId::pentaxId>},
1837
    {{Tag::next, IfdId::pentaxId}, ignoreTiffComponent},
1838
    {{Tag::all, IfdId::pentaxId}, &newTiffEntry},
1839
1840
    // Samsung2 makernote
1841
    {{0x0021, IfdId::samsung2Id}, EXV_BINARY_ARRAY(samsungPwCfg, samsungPwDef)},
1842
    {{0x0035, IfdId::samsung2Id}, &newTiffSubIfd<IfdId::samsungPvId>},
1843
    {{Tag::next, IfdId::samsung2Id}, ignoreTiffComponent},
1844
    {{Tag::all, IfdId::samsung2Id}, &newTiffEntry},
1845
1846
    // Samsung PictureWizard binary array
1847
    {{Tag::all, IfdId::samsungPwId}, &newTiffBinaryElement},
1848
1849
    // Samsung2 makernote preview subdir
1850
    {{0x0201, IfdId::samsungPvId}, &newTiffThumbData<0x0202, IfdId::samsungPvId>},
1851
    {{0x0202, IfdId::samsungPvId}, &newTiffThumbSize<0x0201, IfdId::samsungPvId>},
1852
    {{Tag::next, IfdId::samsungPvId}, ignoreTiffComponent},
1853
    {{Tag::all, IfdId::samsungPvId}, &newTiffEntry},
1854
1855
    // Sigma/Foveon makernote
1856
    {{Tag::next, IfdId::sigmaId}, ignoreTiffComponent},
1857
    {{Tag::all, IfdId::sigmaId}, &newTiffEntry},
1858
1859
    {{Tag::all, IfdId::sony2010eId}, &newTiffBinaryElement},
1860
    {{0x2010, IfdId::sony1Id}, EXV_COMPLEX_BINARY_ARRAY(sony2010eSet, &sony2010eSelector)},
1861
1862
    // Tag 0x9402 Sony2Fp Focus Position
1863
    {{Tag::all, IfdId::sony2FpId}, &newTiffBinaryElement},
1864
    {{0x9402, IfdId::sony1Id}, EXV_COMPLEX_BINARY_ARRAY(sony2FpSet, &sony2FpSelector)},
1865
1866
    // Tag 0x9404 SonyMisc2b
1867
    {{Tag::all, IfdId::sonyMisc2bId}, &newTiffBinaryElement},
1868
    {{0x9404, IfdId::sony1Id}, EXV_COMPLEX_BINARY_ARRAY(sonyMisc2bSet, &sonyMisc2bSelector)},
1869
1870
    // Tag 0x9400 SonyMisc3c
1871
    {{Tag::all, IfdId::sonyMisc3cId}, &newTiffBinaryElement},
1872
    {{0x9400, IfdId::sony1Id}, EXV_COMPLEX_BINARY_ARRAY(sonyMisc3cSet, &sonyMisc3cSelector)},
1873
1874
    // Tag 0x9403 SonyMisc1
1875
    {{Tag::all, IfdId::sonyMisc1Id}, &newTiffBinaryElement},
1876
    {{0x9403, IfdId::sony1Id}, EXV_BINARY_ARRAY(sonyMisc1Cfg, sonyMisc1Def)},
1877
1878
    // Tag 0x3000 SonySInfo1
1879
    {{Tag::all, IfdId::sonySInfo1Id}, &newTiffBinaryElement},
1880
    {{0x3000, IfdId::sony1Id}, EXV_BINARY_ARRAY(sonySInfo1Cfg, sonySInfo1Def)},
1881
1882
    // Sony1 makernote
1883
    {{0x0114, IfdId::sony1Id}, EXV_COMPLEX_BINARY_ARRAY(sony1CsSet, &sonyCsSelector)},
1884
    {{0xb028, IfdId::sony1Id}, &newTiffSubIfd<IfdId::sonyMltId>},
1885
    {{Tag::next, IfdId::sony1Id}, ignoreTiffComponent},
1886
    {{Tag::all, IfdId::sony1Id}, &newTiffEntry},
1887
1888
    // Sony1 camera settings
1889
    {{Tag::all, IfdId::sony1CsId}, &newTiffBinaryElement},
1890
    {{Tag::all, IfdId::sony1Cs2Id}, &newTiffBinaryElement},
1891
1892
    {{Tag::all, IfdId::sony2010eId}, &newTiffBinaryElement},
1893
    {{0x2010, IfdId::sony2Id}, EXV_COMPLEX_BINARY_ARRAY(sony2010eSet, &sony2010eSelector)},
1894
1895
    // Tag 0x9402 Sony2Fp Focus Position
1896
    {{Tag::all, IfdId::sony2FpId}, &newTiffBinaryElement},
1897
    {{0x9402, IfdId::sony2Id}, EXV_COMPLEX_BINARY_ARRAY(sony2FpSet, &sony2FpSelector)},
1898
1899
    // Tag 0x9403 SonyMisc1
1900
    {{Tag::all, IfdId::sonyMisc1Id}, &newTiffBinaryElement},
1901
    {{0x9403, IfdId::sony2Id}, EXV_BINARY_ARRAY(sonyMisc1Cfg, sonyMisc1Def)},
1902
1903
    // Tag 0x9404 SonyMisc2b
1904
    {{Tag::all, IfdId::sonyMisc2bId}, &newTiffBinaryElement},
1905
    {{0x9404, IfdId::sony2Id}, EXV_COMPLEX_BINARY_ARRAY(sonyMisc2bSet, &sonyMisc2bSelector)},
1906
1907
    // Tag 0x9400 SonyMisc3c
1908
    {{Tag::all, IfdId::sonyMisc3cId}, &newTiffBinaryElement},
1909
    {{0x9400, IfdId::sony2Id}, EXV_COMPLEX_BINARY_ARRAY(sonyMisc3cSet, &sonyMisc3cSelector)},
1910
1911
    // Tag 0x3000 SonySInfo1
1912
    {{Tag::all, IfdId::sonySInfo1Id}, &newTiffBinaryElement},
1913
    {{0x3000, IfdId::sony2Id}, EXV_BINARY_ARRAY(sonySInfo1Cfg, sonySInfo1Def)},
1914
1915
    // Sony2 makernote
1916
    {{0x0114, IfdId::sony2Id}, EXV_COMPLEX_BINARY_ARRAY(sony2CsSet, &sonyCsSelector)},
1917
    {{Tag::next, IfdId::sony2Id}, ignoreTiffComponent},
1918
    {{Tag::all, IfdId::sony2Id}, &newTiffEntry},
1919
1920
    // Sony2 camera settings
1921
    {{Tag::all, IfdId::sony2CsId}, &newTiffBinaryElement},
1922
    {{Tag::all, IfdId::sony2Cs2Id}, &newTiffBinaryElement},
1923
1924
    // Sony1 Minolta makernote
1925
    {{0x0001, IfdId::sonyMltId}, EXV_SIMPLE_BINARY_ARRAY(sony1MCsoCfg)},
1926
    {{0x0003, IfdId::sonyMltId}, EXV_SIMPLE_BINARY_ARRAY(sony1MCsnCfg)},
1927
    {{0x0004, IfdId::sonyMltId}, EXV_BINARY_ARRAY(sony1MCs7Cfg, minoCs7Def)},  // minoCs7Def [sic]
1928
    {{0x0088, IfdId::sonyMltId}, &newTiffThumbData<0x0089, IfdId::sonyMltId>},
1929
    {{0x0089, IfdId::sonyMltId}, &newTiffThumbSize<0x0088, IfdId::sonyMltId>},
1930
    {{0x0114, IfdId::sonyMltId}, EXV_BINARY_ARRAY(sony1MCsA100Cfg, sony1MCsA100Def)},
1931
    {{Tag::next, IfdId::sonyMltId}, ignoreTiffComponent},
1932
    {{Tag::all, IfdId::sonyMltId}, &newTiffEntry},
1933
1934
    // Sony1 Minolta makernote composite tags
1935
    {{Tag::all, IfdId::sony1MltCsOldId}, &newTiffBinaryElement},
1936
    {{Tag::all, IfdId::sony1MltCsNewId}, &newTiffBinaryElement},
1937
    {{Tag::all, IfdId::sony1MltCs7DId}, &newTiffBinaryElement},
1938
    {{Tag::all, IfdId::sony1MltCsA100Id}, &newTiffBinaryElement},
1939
1940
    // Minolta makernote
1941
    {{0x0001, IfdId::minoltaId}, EXV_SIMPLE_BINARY_ARRAY(minoCsoCfg)},
1942
    {{0x0003, IfdId::minoltaId}, EXV_SIMPLE_BINARY_ARRAY(minoCsnCfg)},
1943
    {{0x0004, IfdId::minoltaId}, EXV_BINARY_ARRAY(minoCs7Cfg, minoCs7Def)},
1944
    {{0x0088, IfdId::minoltaId}, &newTiffThumbData<0x0089, IfdId::minoltaId>},
1945
    {{0x0089, IfdId::minoltaId}, &newTiffThumbSize<0x0088, IfdId::minoltaId>},
1946
    {{0x0114, IfdId::minoltaId}, EXV_BINARY_ARRAY(minoCs5Cfg, minoCs5Def)},
1947
    {{Tag::next, IfdId::minoltaId}, ignoreTiffComponent},
1948
    {{Tag::all, IfdId::minoltaId}, &newTiffEntry},
1949
1950
    // Minolta makernote composite tags
1951
    {{Tag::all, IfdId::minoltaCsOldId}, &newTiffBinaryElement},
1952
    {{Tag::all, IfdId::minoltaCsNewId}, &newTiffBinaryElement},
1953
    {{Tag::all, IfdId::minoltaCs7DId}, &newTiffBinaryElement},
1954
    {{Tag::all, IfdId::minoltaCs5DId}, &newTiffBinaryElement},
1955
1956
    // -----------------------------------------------------------------------
1957
    // Root directory of Panasonic RAW images
1958
    {{Tag::pana, IfdId::ifdIdNotSet}, &newTiffDirectory<IfdId::panaRawId>},
1959
1960
    // IFD0 of Panasonic RAW images
1961
    {{0x8769, IfdId::panaRawId}, &newTiffSubIfd<IfdId::exifId>},
1962
    {{0x8825, IfdId::panaRawId}, &newTiffSubIfd<IfdId::gpsId>},
1963
    //        {{    0x0111, IfdId::panaRawId,        newTiffImageData<0x0117, IfdId::panaRawId>       },
1964
    //        {{    0x0117, IfdId::panaRawId,        newTiffImageSize<0x0111, IfdId::panaRawId>       },
1965
    {{Tag::next, IfdId::panaRawId}, ignoreTiffComponent},
1966
    {{Tag::all, IfdId::panaRawId}, &newTiffEntry},
1967
1968
    // Casio makernote
1969
    {{Tag::next, IfdId::casioId}, ignoreTiffComponent},
1970
    {{Tag::all, IfdId::casioId}, &newTiffEntry},
1971
1972
    // Casio2 makernote
1973
    {{Tag::next, IfdId::casio2Id}, ignoreTiffComponent},
1974
    {{Tag::all, IfdId::casio2Id}, &newTiffEntry},
1975
1976
    // -----------------------------------------------------------------------
1977
    // Tags which are not de/encoded
1978
    {{Tag::next, IfdId::ignoreId}, ignoreTiffComponent},
1979
    {{Tag::all, IfdId::ignoreId}, &newTiffEntry},
1980
};
1981
1982
// TIFF mapping table for special decoding and encoding requirements
1983
const TiffMappingInfo TiffMapping::tiffMappingInfo_[] = {
1984
    {"*", Tag::all, IfdId::ignoreId, nullptr, nullptr},  // Do not decode tags with group == IfdId::ignoreId
1985
    {"*", 0x02bc, IfdId::ifd0Id, &TiffDecoder::decodeXmp, nullptr /*done before the tree is traversed*/},
1986
    {"*", 0x83bb, IfdId::ifd0Id, &TiffDecoder::decodeIptc, nullptr /*done before the tree is traversed*/},
1987
    {"*", 0x8649, IfdId::ifd0Id, &TiffDecoder::decodeIptc, nullptr /*done before the tree is traversed*/},
1988
    {"*", 0x0026, IfdId::canonId, &TiffDecoder::decodeCanonAFInfo, nullptr /* Exiv2.Canon.AFInfo is read-only */},
1989
};
1990
1991
910k
DecoderFct TiffMapping::findDecoder(std::string_view make, uint32_t extendedTag, IfdId group) {
1992
910k
  DecoderFct decoderFct = &TiffDecoder::decodeStdTiffEntry;
1993
910k
  if (auto td = Exiv2::find(tiffMappingInfo_, TiffMappingInfo::Key{make, extendedTag, group})) {
1994
    // This may set decoderFct to 0, meaning that the tag should not be decoded
1995
67.9k
    decoderFct = td->decoderFct_;
1996
67.9k
  }
1997
910k
  return decoderFct;
1998
910k
}
1999
2000
0
EncoderFct TiffMapping::findEncoder(std::string_view make, uint32_t extendedTag, IfdId group) {
2001
0
  EncoderFct encoderFct = nullptr;
2002
0
  if (auto td = Exiv2::find(tiffMappingInfo_, TiffMappingInfo::Key{make, extendedTag, group})) {
2003
    // Returns 0 if no special encoder function is found
2004
0
    encoderFct = td->encoderFct_;
2005
0
  }
2006
0
  return encoderFct;
2007
0
}
2008
2009
1.39M
TiffComponent::UniquePtr TiffCreator::create(uint32_t extendedTag, IfdId group) {
2010
1.39M
  auto tag = static_cast<uint16_t>(extendedTag);
2011
1.39M
  auto i = tiffGroupTable_.find(TiffGroupKey(extendedTag, group));
2012
  // If the lookup failed then try again with Tag::all.
2013
1.39M
  if (i == tiffGroupTable_.end()) {
2014
1.31M
    i = tiffGroupTable_.find(TiffGroupKey(Tag::all, group));
2015
1.31M
  }
2016
1.39M
  if (i != tiffGroupTable_.end() && i->second) {
2017
1.39M
    return i->second(tag, group);
2018
1.39M
  }
2019
#ifdef EXIV2_DEBUG_MESSAGES
2020
  if (i == tiffGroupTable_.end())
2021
    std::cerr << "Warning: No TIFF structure entry found for ";
2022
  else
2023
    std::cerr << "Warning: No TIFF component creator found for ";
2024
  std::cerr << "extended tag 0x" << std::setw(4) << std::setfill('0') << std::hex << std::right << extendedTag
2025
            << ", group " << groupName(group) << "\n";
2026
#endif
2027
3.73k
  return nullptr;
2028
1.39M
}  // TiffCreator::create
2029
2030
0
TiffPath TiffCreator::getPath(uint32_t extendedTag, IfdId group, uint32_t root) {
2031
0
  TiffPath ret;
2032
0
  while (true) {
2033
0
    ret.emplace(extendedTag, group);
2034
0
    const auto ts = tiffTreeTable_.find(TiffGroupKey(root, group));
2035
0
    assert(ts != tiffTreeTable_.end());
2036
0
    extendedTag = ts->second.second;
2037
0
    group = ts->second.first;
2038
0
    if (ts->first == TiffGroupKey(root, IfdId::ifdIdNotSet)) {
2039
0
      break;
2040
0
    }
2041
0
  }
2042
0
  return ret;
2043
0
}
2044
2045
ByteOrder TiffParserWorker::decode(ExifData& exifData, IptcData& iptcData, XmpData& xmpData, const byte* pData,
2046
25.9k
                                   size_t size, uint32_t root, FindDecoderFct findDecoderFct, TiffHeaderBase* pHeader) {
2047
  // Create standard TIFF header if necessary
2048
25.9k
  std::unique_ptr<TiffHeaderBase> ph;
2049
25.9k
  if (!pHeader) {
2050
25.2k
    ph = std::make_unique<TiffHeader>();
2051
25.2k
    pHeader = ph.get();
2052
25.2k
  }
2053
2054
25.9k
  if (auto rootDir = parse(pData, size, root, pHeader)) {
2055
25.7k
    auto decoder = TiffDecoder(exifData, iptcData, xmpData, rootDir.get(), findDecoderFct);
2056
25.7k
    rootDir->accept(decoder);
2057
25.7k
  }
2058
25.9k
  return pHeader->byteOrder();
2059
2060
25.9k
}  // TiffParserWorker::decode
2061
2062
WriteMethod TiffParserWorker::encode(BasicIo& io, const byte* pData, size_t size, const ExifData& exifData,
2063
                                     const IptcData& iptcData, const XmpData& xmpData, uint32_t root,
2064
                                     FindEncoderFct findEncoderFct, TiffHeaderBase* pHeader,
2065
0
                                     OffsetWriter* pOffsetWriter) {
2066
  /*
2067
     1) parse the binary image, if one is provided, and
2068
     2) attempt updating the parsed tree in-place ("non-intrusive writing")
2069
     3) else, create a new tree and write a new TIFF structure ("intrusive
2070
        writing"). If there is a parsed tree, it is only used to access the
2071
        image data in this case.
2072
   */
2073
0
  WriteMethod writeMethod = wmIntrusive;
2074
0
  auto parsedTree = parse(pData, size, root, pHeader);
2075
0
  auto primaryGroups = findPrimaryGroups(parsedTree);
2076
0
  if (parsedTree) {
2077
    // Attempt to update existing TIFF components based on metadata entries
2078
0
    TiffEncoder encoder(exifData, iptcData, xmpData, parsedTree.get(), false, primaryGroups, pHeader, findEncoderFct);
2079
0
    parsedTree->accept(encoder);
2080
0
    if (!encoder.dirty())
2081
0
      writeMethod = wmNonIntrusive;
2082
0
  }
2083
0
  if (writeMethod == wmIntrusive) {
2084
0
    auto createdTree = TiffCreator::create(root, IfdId::ifdIdNotSet);
2085
0
    if (parsedTree) {
2086
      // Copy image tags from the original image to the composite
2087
0
      TiffCopier copier(createdTree.get(), root, pHeader, primaryGroups);
2088
0
      parsedTree->accept(copier);
2089
0
    }
2090
    // Add entries from metadata to composite
2091
0
    TiffEncoder encoder(exifData, iptcData, xmpData, createdTree.get(), !parsedTree, std::move(primaryGroups), pHeader,
2092
0
                        findEncoderFct);
2093
0
    encoder.add(createdTree.get(), std::move(parsedTree), root);
2094
    // Write binary representation from the composite tree
2095
0
    DataBuf header = pHeader->write();
2096
0
    auto tempIo = MemIo();
2097
0
    IoWrapper ioWrapper(tempIo, header.c_data(), header.size(), pOffsetWriter);
2098
0
    auto imageIdx(std::string::npos);
2099
0
    createdTree->write(ioWrapper, pHeader->byteOrder(), header.size(), std::string::npos, std::string::npos, imageIdx);
2100
0
    if (pOffsetWriter)
2101
0
      pOffsetWriter->writeOffsets(tempIo);
2102
0
    io.transfer(tempIo);  // may throw
2103
0
#ifndef SUPPRESS_WARNINGS
2104
0
    EXV_INFO << "Write strategy: Intrusive\n";
2105
0
#endif
2106
0
  }
2107
0
#ifndef SUPPRESS_WARNINGS
2108
0
  else {
2109
0
    EXV_INFO << "Write strategy: Non-intrusive\n";
2110
0
  }
2111
0
#endif
2112
0
  return writeMethod;
2113
0
}  // TiffParserWorker::encode
2114
2115
TiffComponent::UniquePtr TiffParserWorker::parse(const byte* pData, size_t size, uint32_t root,
2116
25.9k
                                                 TiffHeaderBase* pHeader) {
2117
25.9k
  TiffComponent::UniquePtr rootDir;
2118
25.9k
  if (!pData || size == 0)
2119
36
    return rootDir;
2120
25.9k
  if (!pHeader->read(pData, size) || pHeader->offset() >= size) {
2121
201
    throw Error(ErrorCode::kerNotAnImage, "TIFF");
2122
201
  }
2123
25.7k
  rootDir = TiffCreator::create(root, IfdId::ifdIdNotSet);
2124
25.7k
  if (rootDir) {
2125
25.7k
    rootDir->setStart(pData + pHeader->offset());
2126
25.7k
    auto state = TiffRwState{pHeader->byteOrder(), 0};
2127
25.7k
    auto reader = TiffReader{pData, size, rootDir.get(), state};
2128
25.7k
    rootDir->accept(reader);
2129
25.7k
    reader.postProcess();
2130
25.7k
  }
2131
25.7k
  return rootDir;
2132
2133
25.9k
}  // TiffParserWorker::parse
2134
2135
0
PrimaryGroups TiffParserWorker::findPrimaryGroups(const TiffComponent::UniquePtr& pSourceDir) {
2136
0
  PrimaryGroups ret;
2137
0
  if (!pSourceDir)
2138
0
    return ret;
2139
2140
0
  static constexpr auto imageGroups = std::array{
2141
0
      IfdId::ifd0Id,      IfdId::ifd1Id,      IfdId::ifd2Id,      IfdId::ifd3Id,      IfdId::subImage1Id,
2142
0
      IfdId::subImage2Id, IfdId::subImage3Id, IfdId::subImage4Id, IfdId::subImage5Id, IfdId::subImage6Id,
2143
0
      IfdId::subImage7Id, IfdId::subImage8Id, IfdId::subImage9Id,
2144
0
  };
2145
2146
0
  for (auto imageGroup : imageGroups) {
2147
0
    TiffFinder finder(0x00fe, imageGroup);
2148
0
    pSourceDir->accept(finder);
2149
0
    auto te = dynamic_cast<const TiffEntryBase*>(finder.result());
2150
0
    if (!te)
2151
0
      continue;
2152
0
    const Value* pV = te->pValue();
2153
0
    if (pV && pV->typeId() == unsignedLong && pV->count() == 1 && (pV->toInt64() & 1) == 0) {
2154
0
      ret.push_back(te->group());
2155
0
    }
2156
0
  }
2157
0
  return ret;
2158
0
}  // TiffParserWorker::findPrimaryGroups
2159
2160
TiffHeaderBase::TiffHeaderBase(uint16_t tag, uint32_t size, ByteOrder byteOrder, uint32_t offset) :
2161
202k
    tag_(tag), size_(size), byteOrder_(byteOrder), offset_(offset) {
2162
202k
}
2163
2164
164k
bool TiffHeaderBase::read(const byte* pData, size_t size) {
2165
164k
  if (!pData || size < 8)
2166
14
    return false;
2167
2168
164k
  if (pData[0] == 'I' && pData[0] == pData[1]) {
2169
33.8k
    byteOrder_ = littleEndian;
2170
130k
  } else if (pData[0] == 'M' && pData[0] == pData[1]) {
2171
620
    byteOrder_ = bigEndian;
2172
130k
  } else {
2173
130k
    return false;
2174
130k
  }
2175
34.4k
  uint16_t t = getUShort(pData + 2, byteOrder_);
2176
34.4k
  if (t != 444 && t != 17234 && tag_ != t)
2177
2.42k
    return false;  // 444 is for the JPEG-XR; 17234 is for DCP
2178
32.0k
  tag_ = t;
2179
32.0k
  offset_ = getULong(pData + 4, byteOrder_);
2180
2181
32.0k
  return true;
2182
34.4k
}
2183
2184
0
DataBuf TiffHeaderBase::write() const {
2185
0
  DataBuf buf(8);
2186
0
  switch (byteOrder_) {
2187
0
    case littleEndian:
2188
0
      buf.write_uint8(0, 'I');
2189
0
      break;
2190
0
    case bigEndian:
2191
0
      buf.write_uint8(0, 'M');
2192
0
      break;
2193
0
    case invalidByteOrder:
2194
0
      break;
2195
0
  }
2196
0
  buf.write_uint8(1, buf.read_uint8(0));
2197
0
  buf.write_uint16(2, tag_, byteOrder_);
2198
0
  buf.write_uint32(4, 0x00000008, byteOrder_);
2199
0
  return buf;
2200
0
}
2201
2202
0
void TiffHeaderBase::print(std::ostream& os, const char* prefix) const {
2203
0
  os << stringFormat("{}{} = 0x{:08x}", prefix, _("TIFF header, offset"), offset_);
2204
2205
0
  switch (byteOrder_) {
2206
0
    case littleEndian:
2207
0
      os << ", " << _("little endian encoded");
2208
0
      break;
2209
0
    case bigEndian:
2210
0
      os << ", " << _("big endian encoded");
2211
0
      break;
2212
0
    case invalidByteOrder:
2213
0
      break;
2214
0
  }
2215
0
  os << "\n";
2216
0
}  // TiffHeaderBase::print
2217
2218
61.3k
ByteOrder TiffHeaderBase::byteOrder() const {
2219
61.3k
  return byteOrder_;
2220
61.3k
}
2221
2222
4.61k
void TiffHeaderBase::setByteOrder(ByteOrder byteOrder) {
2223
4.61k
  byteOrder_ = byteOrder;
2224
4.61k
}
2225
2226
51.4k
uint32_t TiffHeaderBase::offset() const {
2227
51.4k
  return offset_;
2228
51.4k
}
2229
2230
3.89k
void TiffHeaderBase::setOffset(uint32_t offset) {
2231
3.89k
  offset_ = offset;
2232
3.89k
}
2233
2234
0
uint32_t TiffHeaderBase::size() const {
2235
0
  return size_;
2236
0
}
2237
2238
4.61k
uint16_t TiffHeaderBase::tag() const {
2239
4.61k
  return tag_;
2240
4.61k
}
2241
2242
0
bool TiffHeaderBase::isImageTag(uint16_t /*tag*/, IfdId /*group*/, const PrimaryGroups& /*primaryGroups*/) const {
2243
0
  return false;
2244
0
}
2245
2246
0
static bool isTiffImageTagLookup(uint16_t tag, IfdId group) {
2247
0
  if (group != IfdId::ifd0Id) {
2248
0
    return false;
2249
0
  }
2250
  //! List of TIFF image tags
2251
0
  switch (tag) {
2252
0
    case 0x00fe:  // Exif.Image.NewSubfileType
2253
0
    case 0x00ff:  // Exif.Image.SubfileType
2254
0
    case 0x0100:  // Exif.Image.ImageWidth
2255
0
    case 0x0101:  // Exif.Image.ImageLength
2256
0
    case 0x0102:  // Exif.Image.BitsPerSample
2257
0
    case 0x0103:  // Exif.Image.Compression
2258
0
    case 0x0106:  // Exif.Image.PhotometricInterpretation
2259
0
    case 0x010a:  // Exif.Image.FillOrder
2260
0
    case 0x0111:  // Exif.Image.StripOffsets
2261
0
    case 0x0115:  // Exif.Image.SamplesPerPixel
2262
0
    case 0x0116:  // Exif.Image.RowsPerStrip
2263
0
    case 0x0117:  // Exif.Image.StripByteCounts
2264
0
    case 0x011a:  // Exif.Image.XResolution
2265
0
    case 0x011b:  // Exif.Image.YResolution
2266
0
    case 0x011c:  // Exif.Image.PlanarConfiguration
2267
0
    case 0x0122:  // Exif.Image.GrayResponseUnit
2268
0
    case 0x0123:  // Exif.Image.GrayResponseCurve
2269
0
    case 0x0124:  // Exif.Image.T4Options
2270
0
    case 0x0125:  // Exif.Image.T6Options
2271
0
    case 0x0128:  // Exif.Image.ResolutionUnit
2272
0
    case 0x0129:  // Exif.Image.PageNumber
2273
0
    case 0x012d:  // Exif.Image.TransferFunction
2274
0
    case 0x013d:  // Exif.Image.Predictor
2275
0
    case 0x013e:  // Exif.Image.WhitePoint
2276
0
    case 0x013f:  // Exif.Image.PrimaryChromaticities
2277
0
    case 0x0140:  // Exif.Image.ColorMap
2278
0
    case 0x0141:  // Exif.Image.HalftoneHints
2279
0
    case 0x0142:  // Exif.Image.TileWidth
2280
0
    case 0x0143:  // Exif.Image.TileLength
2281
0
    case 0x0144:  // Exif.Image.TileOffsets
2282
0
    case 0x0145:  // Exif.Image.TileByteCounts
2283
0
    case 0x014c:  // Exif.Image.InkSet
2284
0
    case 0x014d:  // Exif.Image.InkNames
2285
0
    case 0x014e:  // Exif.Image.NumberOfInks
2286
0
    case 0x0150:  // Exif.Image.DotRange
2287
0
    case 0x0151:  // Exif.Image.TargetPrinter
2288
0
    case 0x0152:  // Exif.Image.ExtraSamples
2289
0
    case 0x0153:  // Exif.Image.SampleFormat
2290
0
    case 0x0154:  // Exif.Image.SMinSampleValue
2291
0
    case 0x0155:  // Exif.Image.SMaxSampleValue
2292
0
    case 0x0156:  // Exif.Image.TransferRange
2293
0
    case 0x0157:  // Exif.Image.ClipPath
2294
0
    case 0x0158:  // Exif.Image.XClipPathUnits
2295
0
    case 0x0159:  // Exif.Image.YClipPathUnits
2296
0
    case 0x015a:  // Exif.Image.Indexed
2297
0
    case 0x015b:  // Exif.Image.JPEGTables
2298
0
    case 0x0200:  // Exif.Image.JPEGProc
2299
0
    case 0x0201:  // Exif.Image.JPEGInterchangeFormat
2300
0
    case 0x0202:  // Exif.Image.JPEGInterchangeFormatLength
2301
0
    case 0x0203:  // Exif.Image.JPEGRestartInterval
2302
0
    case 0x0205:  // Exif.Image.JPEGLosslessPredictors
2303
0
    case 0x0206:  // Exif.Image.JPEGPointTransforms
2304
0
    case 0x0207:  // Exif.Image.JPEGQTables
2305
0
    case 0x0208:  // Exif.Image.JPEGDCTables
2306
0
    case 0x0209:  // Exif.Image.JPEGACTables
2307
0
    case 0x0211:  // Exif.Image.YCbCrCoefficients
2308
0
    case 0x0212:  // Exif.Image.YCbCrSubSampling
2309
0
    case 0x0213:  // Exif.Image.YCbCrPositioning
2310
0
    case 0x0214:  // Exif.Image.ReferenceBlackWhite
2311
0
    case 0x828d:  // Exif.Image.CFARepeatPatternDim
2312
0
    case 0x828e:  // Exif.Image.CFAPattern
2313
    // case 0x8773:  // Exif.Image.InterColorProfile
2314
0
    case 0x8824:  // Exif.Image.SpectralSensitivity
2315
0
    case 0x8828:  // Exif.Image.OECF
2316
0
    case 0x9102:  // Exif.Image.CompressedBitsPerPixel
2317
0
    case 0x9217:  // Exif.Image.SensingMethod
2318
0
      return true;
2319
0
    default:
2320
0
      return false;
2321
0
  }
2322
0
}
2323
2324
0
bool isTiffImageTag(uint16_t tag, IfdId group) {
2325
0
  const bool result = isTiffImageTagLookup(tag, group);
2326
#ifdef EXIV2_DEBUG_MESSAGES
2327
  if (result) {
2328
    ExifKey key(tag, groupName(group));
2329
    std::cerr << "Image tag: " << key << " (3)\n";
2330
  } else {
2331
    std::cerr << "Not an image tag: " << tag << " (4)\n";
2332
  }
2333
#endif
2334
0
  return result;
2335
0
}
2336
2337
TiffHeader::TiffHeader(ByteOrder byteOrder, uint32_t offset, bool hasImageTags) :
2338
147k
    TiffHeaderBase(42, 8, byteOrder, offset), hasImageTags_(hasImageTags) {
2339
147k
}
2340
2341
0
bool TiffHeader::isImageTag(uint16_t tag, IfdId group, const PrimaryGroups& pPrimaryGroups) const {
2342
0
  if (!hasImageTags_) {
2343
#ifdef EXIV2_DEBUG_MESSAGES
2344
    std::cerr << "No image tags in this image\n";
2345
#endif
2346
0
    return false;
2347
0
  }
2348
#ifdef EXIV2_DEBUG_MESSAGES
2349
  ExifKey key(tag, groupName(group));
2350
#endif
2351
  // If there are primary groups and none matches group, we're done
2352
0
  if (!pPrimaryGroups.empty() &&
2353
0
      std::find(pPrimaryGroups.begin(), pPrimaryGroups.end(), group) == pPrimaryGroups.end()) {
2354
#ifdef EXIV2_DEBUG_MESSAGES
2355
    std::cerr << "Not an image tag: " << key << " (1)\n";
2356
#endif
2357
0
    return false;
2358
0
  }
2359
  // All tags of marked primary groups other than IFD0 are considered
2360
  // image tags. That should take care of NEFs until we know better.
2361
0
  if (!pPrimaryGroups.empty() && group != IfdId::ifd0Id) {
2362
#ifdef EXIV2_DEBUG_MESSAGES
2363
    ExifKey key(tag, groupName(group));
2364
    std::cerr << "Image tag: " << key << " (2)\n";
2365
#endif
2366
0
    return true;
2367
0
  }
2368
  // Finally, if tag, group is one of the TIFF image tags -> bingo!
2369
0
  return isTiffImageTag(tag, group);
2370
0
}  // TiffHeader::isImageTag
2371
2372
0
void OffsetWriter::setOrigin(OffsetId id, uint32_t origin, ByteOrder byteOrder) {
2373
0
  offsetList_[id] = OffsetData{origin, 0, byteOrder};
2374
0
}
2375
2376
0
void OffsetWriter::setTarget(OffsetId id, uint32_t target) {
2377
0
  auto it = offsetList_.find(id);
2378
0
  if (it != offsetList_.end())
2379
0
    it->second.target_ = target;
2380
0
}
2381
2382
0
void OffsetWriter::writeOffsets(BasicIo& io) const {
2383
0
  for (const auto& [_, off] : offsetList_) {
2384
0
    io.seek(off.origin_, BasicIo::beg);
2385
0
    byte buf[4] = {0, 0, 0, 0};
2386
0
    l2Data(buf, off.target_, off.byteOrder_);
2387
0
    io.write(buf, 4);
2388
0
  }
2389
0
}
2390
2391
}  // namespace Exiv2::Internal