Coverage Report

Created: 2025-10-10 06:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/exiv2/src/sonymn_int.cpp
Line
Count
Source
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
3
// included header files
4
#include "sonymn_int.hpp"
5
6
#include "error.hpp"
7
#include "exif.hpp"
8
#include "i18n.h"  // NLS support.
9
#include "image_int.hpp"
10
#include "minoltamn_int.hpp"
11
#include "tags_int.hpp"
12
#include "tiffcomposite_int.hpp"
13
#include "utils.hpp"
14
#include "value.hpp"
15
16
#include <array>
17
#include <cmath>
18
#include <iomanip>
19
20
// *****************************************************************************
21
// class member definitions
22
namespace Exiv2::Internal {
23
// -- Standard Sony Makernotes tags ---------------------------------------------------------------
24
25
//! Lookup table to translate Sony image quality values to readable labels
26
constexpr TagDetails sonyImageQuality[] = {
27
    {0, N_("RAW")},
28
    {1, N_("Super Fine")},
29
    {2, N_("Fine")},
30
    {3, N_("Standard")},
31
    {4, N_("Economy")},
32
    {5, N_("Extra Fine")},
33
    {6, N_("RAW + JPEG/HEIF")},
34
    {7, N_("Compressed RAW")},
35
    {8, N_("Compressed RAW + JPEG")},
36
    {9, N_("Light")},
37
    {0xffffffff, N_("n/a")},
38
};
39
40
//! Lookup table to translate Sony white balance (main group) values to readable labels
41
constexpr TagDetails sonyWhiteBalanceStd[] = {
42
    {0x00, N_("Auto")},     {0x01, N_("Color Temperature/Color Filter")},
43
    {0x10, N_("Daylight")}, {0x20, N_("Cloudy")},
44
    {0x30, N_("Shade")},    {0x40, N_("Tungsten")},
45
    {0x50, N_("Flash")},    {0x60, N_("Fluorescent")},
46
    {0x70, N_("Custom")},   {0x80, N_("Underwater")},
47
};
48
49
//! Lookup table to translate Sony auto HDR (part 1) values to readable labels
50
constexpr TagDetails sonyHDRStdPart1[] = {
51
    {0x00, N_("Off")}, {0x01, N_("Auto")}, {0x10, "1.0 EV"}, {0x11, "1.5 EV"}, {0x12, "2.0 EV"},
52
    {0x13, "2.5 EV"},  {0x14, "3.0 EV"},   {0x15, "3.5 EV"}, {0x16, "4.0 EV"}, {0x17, "4.5 EV"},
53
    {0x18, "5.0 EV"},  {0x19, "5.5 EV"},   {0x1a, "6.0 EV"},
54
};
55
56
//! Lookup table to translate Sony auto HDR (part 2) values to readable labels
57
constexpr TagDetails sonyHDRStdPart2[] = {
58
    {0, N_("Uncorrected image")},
59
    {1, N_("HDR image (good)")},
60
    {2, N_("HDR (fail 1)")},
61
    {3, N_("HDR (fail 2)")},
62
};
63
64
//! Lookup table to translate Sony off/on/(n/a) (1) values to readable labels
65
constexpr TagDetails sonyOffOnNA1[] = {
66
    {0, N_("Off")},
67
    {1, N_("On")},
68
    {256, N_("n/a")},
69
};
70
71
//! Lookup table to translate Sony off/on/(n/a) (2) values to readable labels
72
constexpr TagDetails sonyOffOnNA2[] = {
73
    {0, N_("Off")},
74
    {1, N_("On")},
75
    {0xffffffff, N_("n/a")},
76
};
77
78
//! Lookup table to translate Sony no/yes values to readable labels
79
constexpr TagDetails sonyNoYes[] = {
80
    {0, N_("No")},
81
    {1, N_("Yes")},
82
};
83
84
//! Lookup table to translate Sony picture effect values to readable labels
85
constexpr TagDetails sonyPictureEffect[] = {
86
    {0, N_("Off")},
87
    {1, N_("Toy Camera")},
88
    {2, N_("Pop Color")},
89
    {3, N_("Posterization")},
90
    {4, N_("Posterization B/W")},
91
    {5, N_("Retro Photo")},
92
    {6, N_("Soft High Key")},
93
    {7, N_("Partial Color (red)")},
94
    {8, N_("Partial Color (green)")},
95
    {9, N_("Partial Color (blue)")},
96
    {10, N_("Partial Color (yellow)")},
97
    {13, N_("High Contrast Monochrome")},
98
    {16, N_("Toy Camera (normal)")},
99
    {17, N_("Toy Camera (cool)")},
100
    {18, N_("Toy Camera (warm)")},
101
    {19, N_("Toy Camera (green)")},
102
    {20, N_("Toy Camera (magenta)")},
103
    {32, N_("Soft Focus (low)")},
104
    {33, N_("Soft Focus")},
105
    {34, N_("Soft Focus (high)")},
106
    {48, N_("Miniature (auto)")},
107
    {49, N_("Miniature (top)")},
108
    {50, N_("Miniature (middle horizontal)")},
109
    {51, N_("Miniature (bottom)")},
110
    {52, N_("Miniature (left)")},
111
    {53, N_("Miniature (middle vertical)")},
112
    {54, N_("Miniature (right)")},
113
    {64, N_("HDR Painting (low)")},
114
    {65, N_("HDR Painting")},
115
    {66, N_("HDR Painting (high)")},
116
    {80, N_("Rich-tone Monochrome")},
117
    {97, N_("Watercolor")},
118
    {98, N_("Watercolor 2")},
119
    {112, N_("Illustration (low)")},
120
    {113, N_("Illustration")},
121
    {114, N_("Illustration (high)")},
122
};
123
124
//! Lookup table to translate Sony soft skin effect values to readable labels
125
constexpr TagDetails sonySoftSkinEffect[] = {
126
    {0, N_("Off")}, {1, N_("Low")}, {2, N_("Mid")}, {3, N_("High")}, {0xffffffff, N_("n/a")},
127
};
128
129
//! Lookup table to translate Sony vignetting correction values to readable labels
130
constexpr TagDetails sonyVignettingCorrection[] = {
131
    {0, N_("Off")},
132
    {2, N_("Auto")},
133
    {0xffffffff, N_("n/a")},
134
};
135
136
//! Lookup table to translate Sony lateral chromatic aberration values to readable labels
137
constexpr TagDetails sonyLateralChromaticAberration[] = {
138
    {0, N_("Off")},
139
    {2, N_("Auto")},
140
    {0xffffffff, N_("n/a")},
141
};
142
143
//! Lookup table to translate Sony distortion correction settings values to readable labels
144
constexpr TagDetails sonyDistortionCorrectionSettings[] = {
145
    {0, N_("Off")},
146
    {2, N_("Auto")},
147
    {0xffffffff, N_("n/a")},
148
};
149
150
//! Lookup table to translate Sony flash action values to readable labels
151
constexpr TagDetails sonyFlashAction[] = {
152
    {0, N_("Did not fire")},
153
    {1, N_("Flash fired")},
154
    {2, N_("External flash fired")},
155
    {3, N_("Wireless controlled flash fired")},
156
};
157
158
//! Lookup table to translate Sony auto focus point selected (set 1) values to readable labels
159
constexpr TagDetails sonyAFPointSelectedSet1[] = {
160
    {0, N_("Auto")},
161
    {1, N_("Center")},
162
    {2, N_("Top")},
163
    {3, N_("Upper-right")},
164
    {4, N_("Right")},
165
    {5, N_("Lower-right")},
166
    {6, N_("Bottom")},
167
    {7, N_("Lower-left")},
168
    {8, N_("Left")},
169
    {9, N_("Upper-left")},
170
    {10, N_("Far Right")},
171
    {11, N_("Far Left")},
172
    {12, N_("Upper-middle")},
173
    {13, N_("Near Right")},
174
    {14, N_("Lower-middle")},
175
    {15, N_("Near Left")},
176
    {16, N_("Upper Far Right")},
177
    {17, N_("Lower Far Right")},
178
    {18, N_("Lower Far Left")},
179
    {19, N_("Upper Far Left")},
180
};
181
182
//! Lookup table to translate Sony auto focus point selected (set 2) values to readable labels
183
constexpr TagDetails sonyAFPointSelectedSet2[] = {
184
    {0, N_("Auto")}, {1, "A6"},   {2, "A7"},   {3, "B2"},   {4, "B3"},
185
    {5, "B4"},       {6, "B5"},   {7, "B6"},   {8, "B7"},   {9, "B8"},
186
    {10, "B9"},      {11, "B10"}, {12, "C1"},  {13, "C2"},  {14, "C3"},
187
    {15, "C4"},      {16, "C5"},  {17, "C6"},  {18, "C7"},  {19, "C8"},
188
    {20, "C9"},      {21, "C10"}, {22, "C11"}, {23, "D1"},  {24, "D2"},
189
    {25, "D3"},      {26, "D4"},  {27, "D5"},  {28, "D6"},  {29, "D7"},
190
    {30, "D8"},      {31, "D9"},  {32, "D10"}, {33, "D11"}, {34, "E1"},
191
    {35, "E2"},      {36, "E3"},  {37, "E4"},  {38, "E5"},  {39, N_("E6 (Center)")},
192
    {40, "E7"},      {41, "E8"},  {42, "E9"},  {43, "E10"}, {44, "E11"},
193
    {45, "F1"},      {46, "F2"},  {47, "F3"},  {48, "F4"},  {49, "F5"},
194
    {50, "F6"},      {51, "F7"},  {52, "F8"},  {53, "F9"},  {54, "F10"},
195
    {55, "F11"},     {56, "G1"},  {57, "G2"},  {58, "G3"},  {59, "G4"},
196
    {60, "G5"},      {61, "G6"},  {62, "G7"},  {63, "G8"},  {64, "G9"},
197
    {65, "G10"},     {66, "G11"}, {67, "H2"},  {68, "H3"},  {69, "H4"},
198
    {70, "H5"},      {71, "H6"},  {72, "H7"},  {73, "H8"},  {74, "H9"},
199
    {75, "H10"},     {76, "I5"},  {77, "I6"},  {78, "I7"},  {128, N_("Auto")},
200
};
201
202
//! Lookup table to translate Sony auto focus point selected (set 3) values to readable labels
203
constexpr TagDetails sonyAFPointSelectedSet3[] = {
204
    {0, N_("Auto")},
205
    {93, "A5"},
206
    {94, "A6"},
207
    {95, "A7"},
208
    {106, "B2"},
209
    {107, "B3"},
210
    {108, "B4"},
211
    {110, "B5"},
212
    {111, "B6"},
213
    {112, "B7"},
214
    {114, "B8"},
215
    {115, "B9"},
216
    {116, "B10"},
217
    {122, "C1"},
218
    {123, "C2"},
219
    {124, "C3"},
220
    {215, "C4"},
221
    {127, "C5"},
222
    {128, "C6"},
223
    {129, "C7"},
224
    {131, "C8"},
225
    {132, "C9"},
226
    {133, "C10"},
227
    {134, "C11"},
228
    {139, "D1"},
229
    {140, "D2"},
230
    {141, "D3"},
231
    {142, "D4"},
232
    {144, "D5"},
233
    {145, "D6"},
234
    {146, "D7"},
235
    {148, "D8"},
236
    {149, "D9"},
237
    {150, "D10"},
238
    {151, "D11"},
239
    {156, "E1"},
240
    {157, "E2"},
241
    {158, "E3"},
242
    {159, "E4"},
243
    {161, "E5"},
244
    {162, N_("E6 (Center")},
245
    {163, "E7"},
246
    {165, "E8"},
247
    {166, "E9"},
248
    {167, "E10"},
249
    {168, "E11"},
250
    {173, "F1"},
251
    {174, "F2"},
252
    {175, "F3"},
253
    {176, "F4"},
254
    {178, "F5"},
255
    {179, "F6"},
256
    {180, "F7"},
257
    {182, "F8"},
258
    {183, "F9"},
259
    {184, "F10"},
260
    {185, "F11"},
261
    {190, "G1"},
262
    {191, "G2"},
263
    {192, "G3"},
264
    {193, "G4"},
265
    {195, "G5"},
266
    {196, "G6"},
267
    {197, "G7"},
268
    {199, "G8"},
269
    {200, "G9"},
270
    {201, "G10"},
271
    {202, "G11"},
272
    {208, "H2"},
273
    {209, "H3"},
274
    {210, "H4"},
275
    {212, "H5"},
276
    {213, "H6"},
277
    {214, "H7"},
278
    {216, "H8"},
279
    {217, "H9"},
280
    {218, "H10"},
281
    {229, "I5"},
282
    {230, "I6"},
283
    {231, "I7"},
284
};
285
286
//! Lookup table to translate Sony auto focus point selected (set 4) values to readable labels
287
constexpr TagDetails sonyAFPointSelectedSet4[] = {
288
    {0, N_("n/a")},         {1, N_("Top Left Zone")},     {2, N_("Top Zone")},   {3, N_("Top Right Zone")},
289
    {4, N_("Left Zone")},   {5, N_("Center Zone")},       {6, N_("Right Zone")}, {7, N_("Bottom Left Zone")},
290
    {8, N_("Bottom Zone")}, {9, N_("Bottom Right Zone")},
291
};
292
293
//! Lookup table to translate Sony auto focus point selected (set 5) values to readable labels
294
constexpr TagDetails sonyAFPointSelectedSet5[] = {
295
    {0, N_("n/a")},           {1, N_("Center Zone")},    {2, N_("Top Zone")},          {3, N_("Right Zone")},
296
    {4, N_("Left Zone")},     {5, N_("Bottom Zone")},    {6, N_("Bottom Right Zone")}, {7, N_("Bottom Left Zone")},
297
    {8, N_("Top Left Zone")}, {9, N_("Top Right Zone")},
298
};
299
300
//! Lookup table to translate Sony auto focus points used (set 1) values to readable labels
301
constexpr TagDetailsBitlistSorted sonyAFPointsUsedSet1[] = {
302
    {0, N_("Center")},           {1, N_("Top")},
303
    {2, N_("Upper-right")},      {3, N_("Right")},
304
    {4, N_("Lower-right")},      {5, N_("Bottom")},
305
    {6, N_("Lower-left")},       {7, N_("Left")},
306
    {8, N_("Upper-left")},       {9, N_("Far right")},
307
    {10, N_("Far left")},        {11, N_("Upper-middle")},
308
    {12, N_("Near right")},      {13, N_("Lower-middle")},
309
    {14, N_("Near left")},       {15, N_("Upper far right")},
310
    {16, N_("Lower far right")}, {17, N_("Lower far left")},
311
    {18, N_("Upper far left")},
312
};
313
314
//! Lookup table to translate Sony auto focus points used (set 2) values to readable labels
315
constexpr TagDetailsBitlistSorted sonyAFPointsUsedSet2[] = {
316
    {0, "A5"},   {1, "A6"},   {2, "A7"},   {3, "B2"},   {4, "B3"},   {5, "B4"},   {6, "B5"},   {7, "B6"},
317
    {8, "B7"},   {9, "B8"},   {10, "B9"},  {11, "B10"}, {12, "C1"},  {13, "C2"},  {14, "C3"},  {15, "C4"},
318
    {16, "C5"},  {17, "C6"},  {18, "C7"},  {19, "C8"},  {20, "C9"},  {21, "C10"}, {22, "C11"}, {23, "D1"},
319
    {24, "D2"},  {25, "D3"},  {26, "D4"},  {27, "D5"},  {28, "D6"},  {29, "D7"},  {30, "D8"},  {31, "D9"},
320
    {32, "D10"}, {33, "D11"}, {34, "E1"},  {35, "E2"},  {36, "E3"},  {37, "E4"},  {38, "E5"},  {39, N_("E6")},
321
    {40, "E7"},  {41, "E8"},  {42, "E9"},  {43, "E10"}, {44, "E11"}, {45, "F1"},  {46, "F2"},  {47, "F3"},
322
    {48, "F4"},  {49, "F5"},  {50, "F6"},  {51, "F7"},  {52, "F8"},  {53, "F9"},  {54, "F10"}, {55, "F11"},
323
    {56, "G1"},  {57, "G2"},  {58, "G3"},  {59, "G4"},  {60, "G5"},  {61, "G6"},  {62, "G7"},  {63, "G8"},
324
    {64, "G9"},  {65, "G10"}, {66, "G11"}, {67, "H2"},  {68, "H3"},  {69, "H4"},  {70, "H5"},  {71, "H6"},
325
    {72, "H7"},  {73, "H8"},  {74, "H9"},  {75, "H10"}, {76, "I5"},  {77, "I6"},  {78, "I7"},  {128, N_("Auto")},
326
};
327
328
//! Lookup table to translate Sony focus mode 2 values to readable labels
329
constexpr TagDetails sonyFocusMode2[] = {
330
    {0, N_("Manual")}, {2, N_("AF-S")}, {3, N_("AF-C")}, {4, N_("AF-A")}, {6, N_("DMF")}, {7, N_("AF-D")},
331
};
332
333
//! Lookup table to translate Sony auto focus area mode setting (set 1) values to readable labels
334
constexpr TagDetails sonyAFAreaModeSettingSet1[] = {
335
    {0, N_("Wide")},
336
    {4, N_("Local")},
337
    {8, N_("Zone")},
338
    {9, N_("Spot")},
339
};
340
341
//! Lookup table to translate Sony auto focus area mode setting (set 2) values to readable labels
342
constexpr TagDetails sonyAFAreaModeSettingSet2[] = {
343
    {0, N_("Wide")},
344
    {1, N_("Center")},
345
    {3, N_("Flexible Spot")},
346
    {4, N_("Flexible Spot (LA-EA4)")},
347
    {9, N_("Center (LA-EA4)")},
348
    {11, N_("Zone")},
349
    {12, N_("Expanded flexible spot")},
350
};
351
352
//! Lookup table to translate Sony auto focus area mode setting (set 3) values to readable labels
353
constexpr TagDetails sonyAFAreaModeSettingSet3[] = {
354
    {0, N_("Wide")}, {4, N_("Flexible spot")}, {8, N_("Zone")}, {9, N_("Center")}, {12, N_("Expanded flexible spot")},
355
};
356
357
//! Lookup table to translate Sony auto focus tracking values to readable labels
358
constexpr TagDetails sonyAFTracking[] = {
359
    {0, N_("Off")},
360
    {1, N_("Face tracking")},
361
    {2, N_("Lock on AF")},
362
};
363
364
//! Lookup table to translate Sony multi-frame noise reduction effect values to readable labels
365
constexpr TagDetails sonyMultiFrameNREffect[] = {
366
    {0, N_("Normal")},
367
    {1, N_("High")},
368
};
369
370
//! Lookup table to translate Sony variable low pass filter values to readable labels
371
constexpr StringTagDetails sonyVariableLowPassFilter[] = {
372
    {"0 0", N_("n/a")}, {"1 0", N_("Off")}, {"1 1", N_("Standard")}, {"1 2", N_("High")}, {"65535 65535", N_("n/a")},
373
};
374
375
//! Lookup table to translate Sony RAW file type values to readable labels
376
constexpr TagDetails sonyRAWFileType[] = {
377
    {0, N_("Compressed RAW")},
378
    {1, N_("Uncompressed RAW")},
379
    {2, N_("Lossless Compressed RAW")},
380
    {0xffff, N_("n/a")},
381
};
382
383
//! Lookup table to translate Sony metering mode 2 values to readable labels
384
constexpr TagDetails sonyMeteringMode2[] = {
385
    {0x100, N_("Multi-segment")},   {0x200, N_("Center-weighted average")},
386
    {0x301, N_("Spot (Standard)")}, {0x302, N_("Spot (Large)")},
387
    {0x400, N_("Average")},         {0x500, N_("Highlight")},
388
};
389
390
//! Lookup table to translate Sony priority set in automatic white balance values to readable labels
391
constexpr TagDetails sonyPrioritySetInAWB[] = {
392
    {0, N_("Standard")},
393
    {1, N_("Ambience")},
394
    {2, N_("White")},
395
};
396
397
//! Lookup table to translate Sony quality 2 (main group) values to readable labels
398
constexpr StringTagDetails sonyQuality2Std[] = {
399
    {"0 0", N_("n/a")},
400
    {"0 1", N_("Standard")},
401
    {"0 2", N_("Fine")},
402
    {"0 3", N_("Extra fine")},
403
    {"0 4", N_("Light")},
404
    {"1 0", N_("RAW")},
405
    {"1 1", N_("RAW + standard")},
406
    {"1 2", N_("RAW + fine")},
407
    {"1 3", N_("RAW + extra fine")},
408
    {"1 4", N_("RAW + light")},
409
};
410
411
//! Lookup table to translate Sony JPEG/HEIF switch values to readable labels
412
constexpr TagDetails sonyJPEGHEIFSwitch[] = {
413
    {0, "JPEG"},
414
    {1, "HEIF"},
415
    {0xffff, N_("n/a")},
416
};
417
418
//! Lookup table to translate Sony model ID values to readable labels
419
//  FORMAT: Uses a space before alternative models and caveats
420
//  NOTE:   Keep the array format in sync with the getModel() function
421
constexpr TagDetails sonyModelId[] = {
422
    {0, N_("Multiple camera models")},
423
    {2, "DSC-R1"},
424
    {256, "DSLR-A100"},
425
    {257, "DSLR-A900"},
426
    {258, "DSLR-A700"},
427
    {259, "DSLR-A200"},
428
    {260, "DSLR-A350"},
429
    {261, "DSLR-A300"},
430
    {262, "DSLR-A900 (APS-C mode)"},
431
    {263, "DSLR-A380 / DSLR-A390"},
432
    {264, "DSLR-A330"},
433
    {265, "DSLR-A230"},
434
    {266, "DSLR-A290"},
435
    {269, "DSLR-A850"},
436
    {270, "DSLR-A850 (APS-C mode)"},
437
    {273, "DSLR-A550"},
438
    {274, "DSLR-A500"},
439
    {275, "DSLR-A450"},
440
    {278, "NEX-5"},
441
    {279, "NEX-3"},
442
    {280, "SLT-A33"},
443
    {281, "SLT-A55 / SLT-A55V"},
444
    {282, "DSLR-A560"},
445
    {283, "DSLR-A580"},
446
    {284, "NEX-C3"},
447
    {285, "SLT-A35"},
448
    {286, "SLT-A65 / SLT-A65V"},
449
    {287, "SLT-A77 / SLT-A77V"},
450
    {288, "NEX-5N"},
451
    {289, "NEX-7"},
452
    {290, "NEX-VG20E"},
453
    {291, "SLT-A37"},
454
    {292, "SLT-A57"},
455
    {293, "NEX-F3"},
456
    {294, "SLT-A99 / SLT-A99V"},
457
    {295, "NEX-6"},
458
    {296, "NEX-5R"},
459
    {297, "DSC-RX100"},
460
    {298, "DSC-RX1"},
461
    {299, "NEX-VG900"},
462
    {300, "NEX-VG30E"},
463
    {302, "ILCE-3000 / ILCE-3500"},
464
    {303, "SLT-A58"},
465
    {305, "NEX-3N"},
466
    {306, "ILCE-7"},
467
    {307, "NEX-5T"},
468
    {308, "DSC-RX100M2"},
469
    {309, "DSC-RX10"},
470
    {310, "DSC-RX1R"},
471
    {311, "ILCE-7R"},
472
    {312, "ILCE-6000"},
473
    {313, "ILCE-5000"},
474
    {317, "DSC-RX100M3"},
475
    {318, "ILCE-7S"},
476
    {319, "ILCA-77M2"},
477
    {339, "ILCE-5100"},
478
    {340, "ILCE-7M2"},
479
    {341, "DSC-RX100M4"},
480
    {342, "DSC-RX10M2"},
481
    {344, "DSC-RX1RM2"},
482
    {346, "ILCE-QX1"},
483
    {347, "ILCE-7RM2"},
484
    {350, "ILCE-7SM2"},
485
    {353, "ILCA-68"},
486
    {354, "ILCA-99M2"},
487
    {355, "DSC-RX10M3"},
488
    {356, "DSC-RX100M5"},
489
    {357, "ILCE-6300"},
490
    {358, "ILCE-9"},
491
    {360, "ILCE-6500"},
492
    {362, "ILCE-7RM3"},
493
    {363, "ILCE-7M3"},
494
    {364, "DSC-RX0"},
495
    {365, "DSC-RX10M4"},
496
    {366, "DSC-RX100M6"},
497
    {367, "DSC-HX99"},
498
    {369, "DSC-RX100M5A"},
499
    {371, "ILCE-6400"},
500
    {372, "DSC-RX0M2"},
501
    {373, "DSC-HX95"},
502
    {374, "DSC-RX100M7"},
503
    {375, "ILCE-7RM4"},
504
    {376, "ILCE-9M2"},
505
    {378, "ILCE-6600"},
506
    {379, "ILCE-6100"},
507
    {380, "ZV-1"},
508
    {381, "ILCE-7C"},
509
    {382, "ZV-E10"},
510
    {383, "ILCE-7SM3"},
511
    {384, "ILCE-1"},
512
    {385, "ILME-FX3"},
513
    {386, "ILCE-7RM3A"},
514
    {387, "ILCE-7RM4A"},
515
    {388, "ILCE-7M4"},
516
    {389, "ZV-1F"},
517
    {390, "ILCE-7RM5"},
518
    {391, "ILME-FX30"},
519
    {392, "ILCE-9M3"},
520
    {393, "ZV-E1"},
521
    {394, "ILCE-6700"},
522
    {395, "ZV-1M2"},
523
    {396, "ILCE-7CR"},
524
    {397, "ILCE-7CM2"},
525
    {398, "ILX-LR1"},
526
    {399, "ZV-E10M2"},
527
    {400, "ILCE-1M2"},
528
    {401, "DSC-RX1RM3"},
529
    {402, "ILCE-6400A"},
530
    {403, "ILCE-6100A"},
531
    {404, "DSC-RX100M7A"},
532
    {406, "ILME-FX2"},
533
    {408, "ZV-1A"},
534
};
535
536
//! Lookup table to translate Sony creative style (main group) values to readable labels
537
constexpr StringTagDetails sonyCreativeStyleStd[] = {
538
    {"AdobeRGB", N_("Adobe RGB")},
539
    {"Autumnleaves", N_("Autumn leaves")},
540
    {"BW", N_("Black and White")},
541
    {"Clear", N_("Clear")},
542
    {"Deep", N_("Deep")},
543
    {"FL", N_("FL")},
544
    {"IN", "IN"},
545
    {"Landscape", N_("Landscape")},
546
    {"Light", N_("Light")},
547
    {"Neutral", N_("Neutral")},
548
    {"None", N_("None")},
549
    {"Portrait", N_("Portrait")},
550
    {"Real", N_("Real")},
551
    {"SH", N_("SH")},
552
    {"Sepia", N_("Sepia")},
553
    {"Standard", N_("Standard")},
554
    {"Sunset", N_("Sunset")},
555
    {"Vivid", N_("Vivid")},
556
    {"VV2", N_("VV2")},
557
};
558
559
//! Lookup table to translate Sony file format values to readable labels
560
constexpr StringTagDetails sonyFileFormat[] = {
561
    {"0 0 0 2", "JPEG"},      {"1 0 0 0", "SR2 1.0"},   {"2 0 0 0", "ARW 1.0"},   {"3 0 0 0", "ARW 2.0"},
562
    {"3 1 0 0", "ARW 2.1"},   {"3 2 0 0", "ARW 2.2"},   {"3 3 0 0", "ARW 2.3"},   {"3 3 1 0", "ARW 2.3.1"},
563
    {"3 3 2 0", "ARW 2.3.2"}, {"3 3 3 0", "ARW 2.3.3"}, {"3 3 5 0", "ARW 2.3.5"}, {"4 0 0 0", "ARW 4.0"},
564
    {"4 0 1 0", "ARW 4.0.1"}, {"5 0 0 0", "ARW 5.0.0"}, {"5 0 1 0", "ARW 5.0.1"},
565
};
566
567
//! Lookup table to translate Sony dynamic range optimizer values to readable labels
568
constexpr TagDetails print0xb025[] = {
569
    {0, N_("Off")},
570
    {1, N_("Standard")},
571
    {2, N_("Advanced Auto")},
572
    {3, N_("Auto")},
573
    {8, N_("Advanced Lv1")},
574
    {9, N_("Advanced Lv2")},
575
    {10, N_("Advanced Lv3")},
576
    {11, N_("Advanced Lv4")},
577
    {12, N_("Advanced Lv5")},
578
    {16, "Lv1"},
579
    {17, "Lv2"},
580
    {18, "Lv3"},
581
    {19, "Lv4"},
582
    {20, "Lv5"},
583
};
584
585
//! Lookup table to translate Sony color mode values to readable labels
586
constexpr TagDetails sonyColorMode[] = {
587
    {0, N_("Standard")},       {1, N_("Vivid")},        {2, N_("Portrait")},
588
    {3, N_("Landscape")},      {4, N_("Sunset")},       {5, N_("Night View/Portrait")},
589
    {6, N_("Black & White")},  {7, N_("Adobe RGB")},    {12, N_("Neutral")},
590
    {13, N_("Clear")},         {14, N_("Deep")},        {15, N_("Light")},
591
    {16, N_("Autumn leaves")}, {17, N_("Sepia")},       {18, N_("FL")},
592
    {19, N_("Vivid 2")},       {20, N_("IN")},          {21, N_("SH")},
593
    {100, N_("Neutral")},      {101, N_("Clear")},      {102, N_("Deep")},
594
    {103, N_("Light")},        {104, N_("Night view")}, {105, N_("Autumn leaves")},
595
    {255, N_("Off")},          {0xffffffff, N_("n/a")},
596
};
597
598
//! Lookup table to translate Sony exposure mode values to readable labels
599
constexpr TagDetails sonyExposureMode[] = {
600
    {0, N_("Program AE")},
601
    {1, N_("Portrait")},
602
    {2, N_("Beach")},
603
    {3, N_("Sports")},
604
    {4, N_("Snow")},
605
    {5, N_("Landscape")},
606
    {6, N_("Auto")},
607
    {7, N_("Aperture-priority AE")},
608
    {8, N_("Shutter speed priority AE")},
609
    {9, N_("Night Scene/Twilight")},
610
    {10, N_("Hi-Speed Shutter")},
611
    {11, N_("Twilight Portrait")},
612
    {12, N_("Soft Snap/Portrait")},
613
    {13, N_("Fireworks")},
614
    {14, N_("Smile Shutter")},
615
    {15, N_("Manual")},
616
    {18, N_("High Sensitivity")},
617
    {19, N_("Macro")},
618
    {20, N_("Advanced Sports Shooting")},
619
    {29, N_("Underwater")},
620
    {33, N_("Food")},
621
    {34, N_("Sweep Panorama")},
622
    {35, N_("Handheld Night Shot")},
623
    {36, N_("Anti Motion Blur")},
624
    {37, N_("Pet")},
625
    {38, N_("Backlight Correction HDR")},
626
    {39, N_("Superior Auto")},
627
    {40, N_("Background Defocus")},
628
    {41, N_("Soft Skin")},
629
    {42, N_("3D Image")},
630
    {0xffff, N_("n/a")},
631
};
632
633
//! Lookup table to translate Sony JPEG quality values to readable labels
634
constexpr TagDetails sonyJPEGQuality[] = {
635
    {0, N_("Standard")},
636
    {1, N_("Fine")},
637
    {2, N_("Extra Fine")},
638
    {0xffff, N_("n/a")},
639
};
640
641
//! Lookup table to translate Sony anti-blur values to readable labels
642
constexpr TagDetails sonyAntiBlur[] = {
643
    {0, N_("Off")},
644
    {1, N_("On (Continuous)")},
645
    {2, N_("On (Shooting)")},
646
    {0xffff, N_("n/a")},
647
};
648
649
//! Lookup table to translate Sony dynamic range optimizer 2 values to readable labels
650
constexpr TagDetails print0xb04f[] = {
651
    {0, N_("Off")},
652
    {1, N_("Standard")},
653
    {2, N_("Plus")},
654
};
655
656
//! Lookup table to translate Sony intelligent auto values to readable labels
657
constexpr TagDetails sonyIntelligentAuto[] = {
658
    {0, N_("Off")},
659
    {1, N_("On")},
660
    {2, N_("Advanced")},
661
};
662
663
//! Lookup table to translate Sony white balance 2 values to readable labels
664
constexpr TagDetails sonyWhiteBalance2[] = {
665
    {0, N_("Auto")},
666
    {4, N_("Manual")},
667
    {5, N_("Daylight")},
668
    {6, N_("Cloudy")},
669
    {7, N_("Cool White Fluorescent")},
670
    {8, N_("Day White Fluorescent")},
671
    {9, N_("Daylight Fluorescent")},
672
    {10, N_("Incandescent2")},
673
    {11, N_("Warm White Fluorescent")},
674
    {14, N_("Incandescent")},
675
    {15, N_("Flash")},
676
    {17, N_("Underwater 1 (Blue Water)")},
677
    {18, N_("Underwater 2 (Green Water)")},
678
    {19, N_("Underwater Auto")},
679
};
680
681
//! Lookup table to translate Sony focus mode values to readable labels
682
constexpr TagDetails sonyFocusMode[] = {
683
    {1, "AF-S"},
684
    {2, "AF-C"},
685
    {4, N_("Permanent-AF")},
686
    {0xffff, N_("n/a")},
687
};
688
689
//! Lookup table to translate Sony auto focus mode (set 1) values to readable labels
690
constexpr TagDetails sonyAFModeSet1[] = {
691
    {0, N_("Default")}, {1, N_("Multi")},     {2, N_("Center")},         {3, N_("Spot")},     {4, N_("Flexible Spot")},
692
    {6, N_("Touch")},   {14, N_("Tracking")}, {15, N_("Face Detected")}, {0xffff, N_("n/a")},
693
};
694
695
//! Lookup table to translate Sony auto focus mode (set 2) values to readable labels
696
constexpr TagDetails sonyAFModeSet2[] = {
697
    {0, N_("Multi")},
698
    {1, N_("Center")},
699
    {2, N_("Spot")},
700
    {3, N_("Flexible spot")},
701
    {10, N_("Selective (for miniature effect)")},
702
    {14, N_("Tracking")},
703
    {15, N_("Face tracking")},
704
    {255, N_("Manual")},
705
};
706
707
//! Lookup table to translate Sony auto focus illuminator values to readable labels
708
constexpr TagDetails sonyAFIlluminator[] = {
709
    {0, N_("Off")},
710
    {1, N_("Auto")},
711
    {0xffff, N_("n/a")},
712
};
713
714
//! Lookup table to translate Sony macro values to readable labels
715
constexpr TagDetails sonyMacro[] = {
716
    {0, N_("Off")},
717
    {1, N_("On")},
718
    {2, N_("Close Focus")},
719
    {0xffff, N_("n/a")},
720
};
721
722
//! Lookup table to translate Sony flash level values to readable labels
723
constexpr TagDetails sonyFlashLevel[] = {
724
    {-32768, N_("Low")}, {-9, "-3.0 EV"}, {-8, "-2.7 EV"},  {-7, "-2.3 EV"},     {-6, "-2.0 EV"},   {-5, "-1.7 EV"},
725
    {-4, "-1.3 EV"},     {-3, "-1.0 EV"}, {-2, "-0.7 EV"},  {-1, "-0.3 EV"},     {0, N_("Normal")}, {1, "+0.3 EV"},
726
    {2, "+0.7 EV"},      {3, "+1.0 EV"},  {4, "+1.3 EV"},   {5, "+1.7 EV"},      {6, "+2.0 EV"},    {7, "+2.3 EV"},
727
    {8, "+2.7 EV"},      {9, "+3.0 EV"},  {128, N_("n/a")}, {32767, N_("High")},
728
};
729
730
//! Lookup table to translate Sony release mode values to readable labels
731
constexpr TagDetails sonyReleaseMode[] = {
732
    {0, N_("Normal")},
733
    {2, N_("Continuous")},
734
    {5, N_("Exposure Bracketing")},
735
    {6, N_("White Balance Bracketing")},
736
    {8, N_("DRO Bracketing")},
737
    {0xffff, N_("n/a")},
738
};
739
740
//! Lookup table to translate Sony sequence number values to readable labels
741
constexpr TagDetails sonySequenceNumber[] = {
742
    {0, N_("Single")},
743
    {0xffff, N_("n/a")},
744
};
745
746
//! Lookup table to translate Sony focus mode 3 values to readable labels
747
constexpr TagDetails sonyFocusMode3[] = {
748
    {0, N_("Manual")}, {2, N_("AF-S")}, {3, N_("AF-C")}, {5, N_("Semi-manual")}, {6, N_("DMF")},
749
};
750
751
//! Lookup table to translate Sony high ISO noise reduction 2 values to readable labels
752
constexpr TagDetails sonyHighISONoiseReduction2[] = {
753
    {0, N_("Normal")}, {1, N_("High")}, {2, N_("Low")}, {3, N_("Off")}, {0xffff, N_("n/a")},
754
};
755
756
//! Lookup table to translate Sony release mode 2 values to readable labels
757
constexpr TagDetails sonyReleaseMode2[] = {
758
    {0, N_("Normal")},
759
    {1, N_("Continuous")},
760
    {2, N_("Continuous - Exposure Bracketing")},
761
    {3, N_("DRO or White Balance Bracketing")},
762
    {5, N_("Continuous - Burst")},
763
    {6, N_("Single Frame - Capture During Movie")},
764
    {7, N_("Continuous - Sweep Panorama")},
765
    {8, N_("Continuous - Anti-Motion Blur, Hand-held Twilight")},
766
    {9, N_("Continuous - HDR")},
767
    {10, N_("Continuous - Background defocus")},
768
    {13, N_("Continuous - 3D Sweep Panorama")},
769
    {15, N_("Continuous - High Resolution Sweep Panorama")},
770
    {16, N_("Continuous - 3D Image")},
771
    {17, N_("Continuous - Burst 2")},
772
    {18, N_("Normal - iAuto+")},
773
    {19, N_("Continuous - Speed/Advance Priority")},
774
    {20, N_("Continuous - Multi-Frame NR")},
775
    {23, N_("Single-frame - Exposure Bracketing")},
776
    {26, N_("Continuous Low")},
777
    {27, N_("Continuous - High Sensitivity")},
778
    {28, N_("Smile Shutter")},
779
    {29, N_("Continuous - Tele-zoom Advance Priority")},
780
    {146, N_("Single Frame - Movie Capture")},
781
};
782
783
//! Lookup table to translate Sony long exposure noise reduction values to readable labels
784
constexpr TagDetails sonyLongExposureNoiseReduction[] = {
785
    {0x00000000, N_("Off")},         {0x00000001, N_("On (unused)")}, {0x00010001, N_("On (dark subtracted)")},
786
    {0xffff0000, N_("Off (65535)")}, {0xffff0001, N_("On (65535)")},  {0xffffffff, N_("n/a")},
787
};
788
789
//! Lookup table to translate Sony high ISO Noise reduction values to readable labels
790
constexpr TagDetails sonyHighISONoiseReductionStd[] = {
791
    {0, N_("Off")}, {1, N_("Low")}, {2, N_("Normal")}, {3, N_("High")}, {256, N_("Auto")}, {0xffff, N_("n/a")},
792
};
793
794
0
static auto getModel(const ExifData* metadata, std::string& val) {
795
0
  auto pos = metadata->findKey(ExifKey("Exif.Image.Model"));
796
0
  if (pos != metadata->end() && pos->size() != 0 && pos->typeId() == asciiString) {
797
0
    val = pos->toString(0);
798
0
    return true;
799
0
  }
800
801
  // NOTE: As using the translated SonyModelID value, need to be synchronized with the array format
802
0
  pos = metadata->findKey(ExifKey("Exif.Sony1.SonyModelID"));
803
0
  if (pos != metadata->end() && pos->size() != 0 && pos->typeId() == unsignedShort) {
804
0
    if (auto temp = pos->print(metadata); !Internal::contains(temp, ' ')) {
805
0
      val = std::move(temp);
806
0
      return true;
807
0
    }
808
0
    val = "";
809
0
    return false;
810
0
  }
811
0
  pos = metadata->findKey(ExifKey("Exif.Sony2.SonyModelID"));
812
0
  if (pos != metadata->end() && pos->size() != 0 && pos->typeId() == unsignedShort) {
813
0
    if (auto temp = pos->print(metadata); !Internal::contains(temp, ' ')) {
814
0
      val = std::move(temp);
815
0
      return true;
816
0
    }
817
0
    val = "";
818
0
    return false;
819
0
  }
820
821
0
  val = "";
822
0
  return false;
823
0
}
824
825
0
static auto getAFAreaModeSetting(const ExifData* metadata, uint32_t& val) {
826
0
  auto pos = metadata->findKey(ExifKey("Exif.Sony1.AFAreaModeSetting"));
827
0
  if (pos != metadata->end() && pos->size() != 0 && pos->typeId() == unsignedByte) {
828
0
    std::ostringstream oss;
829
0
    pos->write(oss, metadata);
830
0
    if (oss.str() == _("n/a")) {
831
0
      val = 0;
832
0
      return false;
833
0
    }
834
835
0
    val = pos->toUint32(0);
836
0
    return true;
837
0
  }
838
0
  pos = metadata->findKey(ExifKey("Exif.Sony2.AFAreaModeSetting"));
839
0
  if (pos != metadata->end() && pos->size() != 0 && pos->typeId() == unsignedByte) {
840
0
    std::ostringstream oss;
841
0
    pos->write(oss, metadata);
842
0
    if (oss.str() == _("n/a")) {
843
0
      val = 0;
844
0
      return false;
845
0
    }
846
847
0
    val = pos->toUint32(0);
848
0
    return true;
849
0
  }
850
851
0
  val = 0;
852
0
  return false;
853
0
}
854
855
0
static auto getMetaVersion(const ExifData* metadata, std::string& val) {
856
0
  const auto pos = metadata->findKey(ExifKey("Exif.SonySInfo1.MetaVersion"));
857
858
0
  if (pos != metadata->end() && pos->typeId() == asciiString) {
859
0
    std::string temp = pos->toString();
860
0
    if (!temp.empty()) {
861
0
      val = std::move(temp);
862
0
      return true;
863
0
    }
864
0
  }
865
0
  val = "";
866
0
  return false;
867
0
}
868
869
0
static auto getFocusMode2(const ExifData* metadata, uint32_t& val) {
870
0
  auto pos = metadata->findKey(ExifKey("Exif.Sony1.FocusMode2"));
871
872
0
  if (pos != metadata->end() && pos->size() != 0 && pos->typeId() == unsignedByte) {
873
0
    std::ostringstream oss;
874
0
    pos->write(oss, metadata);
875
0
    if (oss.str() == _("n/a")) {
876
0
      val = 0;
877
0
      return false;
878
0
    }
879
880
0
    val = pos->toUint32(0);
881
0
    return true;
882
0
  }
883
0
  pos = metadata->findKey(ExifKey("Exif.Sony2.FocusMode2"));
884
0
  if (pos != metadata->end() && pos->size() != 0 && pos->typeId() == unsignedByte) {
885
0
    std::ostringstream oss;
886
0
    pos->write(oss, metadata);
887
0
    if (oss.str() == _("n/a")) {
888
0
      val = 0;
889
0
      return false;
890
0
    }
891
0
    val = pos->toUint32(0);
892
0
    return true;
893
0
  }
894
895
0
  val = 0;
896
0
  return false;
897
0
}
898
899
0
std::ostream& SonyMakerNote::printWhiteBalanceFineTune(std::ostream& os, const Value& value, const ExifData*) {
900
0
  if (value.count() != 1 || value.typeId() != unsignedLong) {
901
0
    os << "(" << value << ")";
902
0
    return os;
903
0
  }
904
  // Sony writes the tag as an unsignedLong but treat it as a signedLong. Source:
905
  // https://github.com/exiftool/exiftool/blob/1e17485cbb372a502e5b9d052d01303db735e6fa/lib/Image/ExifTool/Sony.pm#L681
906
0
  os << static_cast<int32_t>(value.toUint32(0));
907
0
  return os;
908
0
}
909
910
0
std::ostream& SonyMakerNote::printMultiBurstMode(std::ostream& os, const Value& value, const ExifData* metadata) {
911
0
  if (value.count() != 1 || value.typeId() != undefined) {
912
0
    os << "(" << value << ")";
913
0
    return os;
914
0
  }
915
  // Some cameras do not set the type to undefined. Source:
916
  // https://github.com/exiftool/exiftool/blob/1e17485cbb372a502e5b9d052d01303db735e6fa/lib/Image/ExifTool/Sony.pm#L763
917
918
0
  printMinoltaSonyBoolValue(os, value, metadata);
919
0
  return os;
920
0
}
921
922
0
std::ostream& SonyMakerNote::printMultiBurstSize(std::ostream& os, const Value& value, const ExifData*) {
923
0
  if (value.count() != 1 || value.typeId() != unsignedShort) {
924
0
    os << "(" << value << ")";
925
0
    return os;
926
0
  }
927
  // Some cameras do not set the type to unsignedShort. Source:
928
  // https://github.com/exiftool/exiftool/blob/1e17485cbb372a502e5b9d052d01303db735e6fa/lib/Image/ExifTool/Sony.pm#L771
929
930
0
  os << value.toUint32(0);
931
0
  return os;
932
0
}
933
934
0
std::ostream& SonyMakerNote::printAutoHDRStd(std::ostream& os, const Value& value, const ExifData* metadata) {
935
0
  if (value.count() != 1 || value.typeId() != unsignedLong) {
936
0
    os << "(" << value << ")";
937
0
    return os;
938
0
  }
939
940
  // Sony writes the tag as an unsignedLong but treat it as 2 unsignedShort values. Source:
941
  // https://github.com/exiftool/exiftool/blob/1e17485cbb372a502e5b9d052d01303db735e6fa/lib/Image/ExifTool/Sony.pm#L887
942
943
0
  const auto v0 = value.toUint32(0);
944
0
  EXV_PRINT_TAG(sonyHDRStdPart1)(os, (v0 & 0x00ff), metadata);
945
0
  os << ", ";
946
0
  EXV_PRINT_TAG(sonyHDRStdPart2)(os, (v0 >> 16), metadata);
947
948
0
  return os;
949
0
}
950
951
0
std::ostream& SonyMakerNote::printWBShiftABGM(std::ostream& os, const Value& value, const ExifData*) {
952
0
  if (value.count() != 2 || value.typeId() != signedLong) {
953
0
    os << "(" << value << ")";
954
0
    return os;
955
0
  }
956
  // Examples of Output:
957
  // 1. "A/B: 0, G/M: 0"
958
  // 2. "A/B: 1B, G/M: 2M"
959
960
0
  const auto v0 = value.toInt64(0);
961
0
  const auto v1 = value.toInt64(1);
962
963
0
  os << "A/B: ";
964
0
  if (v0 == 0) {
965
0
    os << 0;
966
0
  } else if (v0 < 0) {
967
0
    os << "A" << -v0;
968
0
  } else {
969
0
    os << "B" << v0;
970
0
  }
971
972
0
  os << ", G/M: ";
973
0
  if (v1 == 0) {
974
0
    os << 0;
975
0
  } else if (v1 < 0) {
976
0
    os << "G" << -v1;
977
0
  } else {
978
0
    os << "M" << v1;
979
0
  }
980
0
  return os;
981
0
}
982
983
0
std::ostream& SonyMakerNote::printFocusMode2(std::ostream& os, const Value& value, const ExifData* metadata) {
984
0
  if (value.count() != 1 || value.typeId() != unsignedByte || !metadata) {
985
0
    os << "(" << value << ")";
986
0
    return os;
987
0
  }
988
989
  // Tag only valid for certain camera models. See
990
  // https://github.com/exiftool/exiftool/blob/1e17485cbb372a502e5b9d052d01303db735e6fa/lib/Image/ExifTool/Sony.pm#L1123
991
0
  std::string model;
992
0
  if (!getModel(metadata, model)) {
993
0
    os << "(" << value << ")";
994
0
    return os;
995
0
  }
996
0
  const auto v0 = value.toUint32(0);
997
998
0
  constexpr std::array models{"DSC-RX10M4", "DSC-RX100M6", "DSC-RX100M7", "DSC-RX100M5A", "DSC-HX99", "DSC-RX0M2"};
999
0
  if (!model.starts_with("DSC-") ||
1000
0
      std::any_of(models.begin(), models.end(), [&model](auto m) { return model.starts_with(m); })) {
1001
0
    EXV_PRINT_TAG(sonyFocusMode2)(os, v0, metadata);
1002
0
    return os;
1003
0
  }
1004
1005
0
  os << _("n/a");
1006
1007
0
  return os;
1008
0
}
1009
1010
0
std::ostream& SonyMakerNote::printAFAreaModeSetting(std::ostream& os, const Value& value, const ExifData* metadata) {
1011
0
  if (value.count() != 1 || value.typeId() != unsignedByte || !metadata) {
1012
0
    os << "(" << value << ")";
1013
0
    return os;
1014
0
  }
1015
1016
  // Tag only valid for certain camera models. See
1017
  // https://github.com/exiftool/exiftool/blob/1e17485cbb372a502e5b9d052d01303db735e6fa/lib/Image/ExifTool/Sony.pm#L1139
1018
0
  std::string model;
1019
0
  if (!getModel(metadata, model)) {
1020
0
    os << "(" << value << ")";
1021
0
    return os;
1022
0
  }
1023
0
  const auto v0 = value.toUint32(0);
1024
1025
0
  constexpr std::array models1{"SLT-", "HV"};
1026
0
  if (std::any_of(models1.begin(), models1.end(), [&model](auto m) { return model.starts_with(m); })) {
1027
0
    EXV_PRINT_TAG(sonyAFAreaModeSettingSet1)(os, v0, metadata);
1028
0
    return os;
1029
0
  }
1030
1031
0
  constexpr std::array models2{"NEX-",        "ILCE-",        "ILME-",    "DSC-RX10M4", "DSC-RX100M6",
1032
0
                               "DSC-RX100M7", "DSC-RX100M5A", "DSC-HX99", "DSC-RX0M2"};
1033
0
  if (std::any_of(models2.begin(), models2.end(), [&model](auto m) { return model.starts_with(m); })) {
1034
0
    EXV_PRINT_TAG(sonyAFAreaModeSettingSet2)(os, v0, metadata);
1035
0
    return os;
1036
0
  }
1037
1038
0
  if (model.starts_with("ILCA-")) {
1039
0
    EXV_PRINT_TAG(sonyAFAreaModeSettingSet3)(os, v0, metadata);
1040
0
    return os;
1041
0
  }
1042
1043
0
  os << _("n/a");
1044
0
  return os;
1045
0
}
1046
1047
0
std::ostream& SonyMakerNote::printFlexibleSpotPosition(std::ostream& os, const Value& value, const ExifData* metadata) {
1048
0
  if (value.count() != 2 || value.typeId() != unsignedShort || !metadata) {
1049
0
    os << "(" << value << ")";
1050
0
    return os;
1051
0
  }
1052
1053
  // Tag only valid for certain camera models. See
1054
  // https://github.com/exiftool/exiftool/blob/1e17485cbb372a502e5b9d052d01303db735e6fa/lib/Image/ExifTool/Sony.pm#L1189
1055
0
  std::string model;
1056
0
  if (!getModel(metadata, model)) {
1057
0
    os << "(" << value << ")";
1058
0
    return os;
1059
0
  }
1060
1061
0
  constexpr std::array models{"NEX-",        "ILCE-",        "ILME-",    "DSC-RX10M4", "DSC-RX100M6",
1062
0
                              "DSC-RX100M7", "DSC-RX100M5A", "DSC-HX99", "DSC-RX0M2"};
1063
0
  if (std::any_of(models.begin(), models.end(), [&model](auto m) { return model.starts_with(m); })) {
1064
0
    os << value.toUint32(0) << ", " << value.toUint32(1);
1065
0
    return os;
1066
0
  }
1067
1068
0
  os << _("n/a");
1069
0
  return os;
1070
0
}
1071
1072
0
std::ostream& SonyMakerNote::printAFPointSelected(std::ostream& os, const Value& value, const ExifData* metadata) {
1073
0
  if (value.count() != 1 || value.typeId() != unsignedByte || !metadata) {
1074
0
    os << "(" << value << ")";
1075
0
    return os;
1076
0
  }
1077
1078
  // Tag only valid for certain camera models. See
1079
  // https://github.com/exiftool/exiftool/blob/1e17485cbb372a502e5b9d052d01303db735e6fa/lib/Image/ExifTool/Sony.pm#L1203
1080
0
  std::string model;
1081
0
  if (!getModel(metadata, model)) {
1082
0
    os << "(" << value << ")";
1083
0
    return os;
1084
0
  }
1085
1086
0
  uint32_t aFAreaModeSetting = 0;
1087
0
  const auto status = getAFAreaModeSetting(metadata, aFAreaModeSetting);
1088
0
  constexpr std::array models1{"SLT-", "HV-"};
1089
0
  constexpr std::array models2{"ILCE-", "ILME-"};
1090
0
  constexpr std::array models3{"ILCA-68", "ILCA-77M2"};
1091
0
  constexpr std::array models4{"NEX-", "ILCE-", "ILME-"};
1092
1093
0
  if (std::any_of(models1.begin(), models1.end(), [&model](auto m) { return model.starts_with(m); })) {
1094
0
    EXV_PRINT_TAG(sonyAFPointSelectedSet1)(os, value.toUint32(0), metadata);
1095
0
    return os;
1096
0
  }
1097
0
  if (std::any_of(models2.begin(), models2.end(), [&model](auto& m) { return model.starts_with(m); }) && status &&
1098
0
      aFAreaModeSetting == 4) {
1099
0
    EXV_PRINT_TAG(sonyAFPointSelectedSet1)(os, value.toUint32(0), metadata);
1100
0
    return os;
1101
0
  }
1102
0
  if (std::any_of(models3.begin(), models3.end(), [&model](auto m) { return model.starts_with(m); }) && status &&
1103
0
      aFAreaModeSetting != 8) {
1104
0
    EXV_PRINT_TAG(sonyAFPointSelectedSet2)(os, value, metadata);
1105
0
    return os;
1106
0
  }
1107
0
  if (model.starts_with("ILCA-99M2") && status && aFAreaModeSetting != 8) {
1108
0
    EXV_PRINT_TAG(sonyAFPointSelectedSet3)(os, value, metadata);
1109
0
    return os;
1110
0
  }
1111
0
  if (model.starts_with("ILCA-") && status && aFAreaModeSetting == 8) {
1112
0
    EXV_PRINT_TAG(sonyAFPointSelectedSet4)(os, value.toUint32(0), metadata);
1113
0
    return os;
1114
0
  }
1115
0
  if (std::any_of(models4.begin(), models4.end(), [&model](auto m) { return model.starts_with(m); })) {
1116
0
    EXV_PRINT_TAG(sonyAFPointSelectedSet5)(os, value.toUint32(0), metadata);
1117
0
    return os;
1118
0
  }
1119
0
  os << _("n/a");
1120
0
  return os;
1121
0
}
1122
1123
0
std::ostream& SonyMakerNote::printAFPointsUsed(std::ostream& os, const Value& value, const ExifData* metadata) {
1124
0
  if (value.typeId() != unsignedByte || !metadata) {
1125
0
    os << "(" << value << ")";
1126
0
    return os;
1127
0
  }
1128
1129
0
  std::string model;
1130
0
  if (!getModel(metadata, model)) {
1131
0
    os << "(" << value << ")";
1132
0
    return os;
1133
0
  }
1134
1135
0
  constexpr std::array models1{"ILCA-", "DSC-"};
1136
0
  constexpr std::array models2{"ILCA-68", "ILCA-77M2"};
1137
1138
0
  if (std::none_of(models1.begin(), models1.end(), [&model](auto m) { return model.starts_with(m); })) {
1139
0
    EXV_PRINT_TAG_BITLIST_ALL_LE(sonyAFPointsUsedSet1)(os, value, metadata);
1140
0
    return os;
1141
0
  }
1142
0
  if (std::any_of(models2.begin(), models2.end(), [&model](auto m) { return model.starts_with(m); })) {
1143
0
    EXV_PRINT_TAG_BITLIST_ALL_LE(sonyAFPointsUsedSet2)(os, value, metadata);
1144
0
    return os;
1145
0
  }
1146
0
  os << _("n/a");
1147
0
  return os;
1148
0
}
1149
1150
0
std::ostream& SonyMakerNote::printAFTracking(std::ostream& os, const Value& value, const ExifData* metadata) {
1151
0
  if (value.count() != 1 || value.typeId() != unsignedByte || !metadata) {
1152
0
    os << "(" << value << ")";
1153
0
    return os;
1154
0
  }
1155
1156
  // Tag only valid for certain camera models. See
1157
  // https://github.com/exiftool/exiftool/blob/1e17485cbb372a502e5b9d052d01303db735e6fa/lib/Image/ExifTool/Sony.pm#L1353
1158
0
  std::string model;
1159
0
  if (!getModel(metadata, model)) {
1160
0
    os << "(" << value << ")";
1161
0
    return os;
1162
0
  }
1163
1164
0
  constexpr std::array models{"DSC-RX10M4", "DSC-RX100M6", "DSC-RX100M7", "DSC-RX100M5A", "DSC-HX99", "DSC-RX0M2"};
1165
0
  if (!model.starts_with("DSC-") ||
1166
0
      std::any_of(models.begin(), models.end(), [&model](auto m) { return model.starts_with(m); })) {
1167
0
    EXV_PRINT_TAG(sonyAFTracking)(os, value.toUint32(0), metadata);
1168
0
    return os;
1169
0
  }
1170
1171
0
  os << _("n/a");
1172
0
  return os;
1173
0
}
1174
1175
0
std::ostream& SonyMakerNote::printFocalPlaneAFPointsUsed(std::ostream& os, const Value& value, const ExifData*) {
1176
0
  if (value.typeId() != unsignedByte) {
1177
0
    os << "(" << value << ")";
1178
0
    return os;
1179
0
  }
1180
0
  if (value.toUint32(0) == 0) {
1181
0
    os << _("None");
1182
0
    return os;
1183
0
  }
1184
0
  os << "(" << value << ")";
1185
0
  return os;
1186
0
}
1187
1188
0
std::ostream& SonyMakerNote::printWBShiftABGMPrecise(std::ostream& os, const Value& value, const ExifData*) {
1189
0
  if (value.count() != 2 || value.typeId() != signedLong) {
1190
0
    os << "(" << value << ")";
1191
0
    return os;
1192
0
  }
1193
0
  std::ios::fmtflags f(os.flags());
1194
1195
0
  const auto temp0 = static_cast<double>(value.toInt64(0)) / 1000.0;
1196
0
  const auto temp1 = static_cast<double>(value.toInt64(1)) / 1000.0;
1197
1198
0
  os << "A/B: ";
1199
0
  if (temp0 == 0) {
1200
0
    os << 0;
1201
0
  } else if (temp0 < 0) {
1202
0
    os << "A" << std::fixed << std::setprecision(2) << -temp0;
1203
0
  } else {
1204
0
    os << "B" << std::fixed << std::setprecision(2) << temp0;
1205
0
  }
1206
0
  os << ", G/M: ";
1207
0
  if (temp1 == 0) {
1208
0
    os << 0;
1209
0
  } else if (temp1 < 0) {
1210
0
    os << "G" << std::fixed << std::setprecision(2) << -temp1;
1211
0
  } else {
1212
0
    os << "M" << std::fixed << std::setprecision(2) << temp1;
1213
0
  }
1214
1215
0
  os.flags(f);
1216
0
  return os;
1217
0
}
1218
1219
0
std::ostream& SonyMakerNote::printExposureStandardAdjustment(std::ostream& os, const Value& value, const ExifData*) {
1220
0
  if (value.count() != 1 || value.typeId() != signedRational) {
1221
0
    return os << "(" << value << ")";
1222
0
  }
1223
1224
0
  const auto [r, s] = value.toRational();
1225
0
  return os << stringFormat("{:.1f}", static_cast<double>(r) / static_cast<double>(s));
1226
0
}
1227
1228
0
std::ostream& SonyMakerNote::printPixelShiftInfo(std::ostream& os, const Value& value, const ExifData*) {
1229
0
  if (value.count() != 6 || value.typeId() != undefined) {
1230
0
    os << "(" << value << ")";
1231
0
    return os;
1232
0
  }
1233
1234
  // Tag format:
1235
  // https://github.com/exiftool/exiftool/blob/1e17485cbb372a502e5b9d052d01303db735e6fa/lib/Image/ExifTool/Sony.pm#L1504
1236
0
  if (value.toString() == "0 0 0 0 0 0") {
1237
0
    os << _("n/a");
1238
0
    return os;
1239
0
  }
1240
1241
  // Convert from little endian format
1242
0
  auto groupID = (value.toUint32(3) << 24) + (value.toUint32(2) << 16) + (value.toUint32(1) << 8) + value.toUint32(0);
1243
1244
0
  return os << stringFormat("Group {:02}{:02}{:02}{:02}, Shot {}/{} (0x{:x})", (groupID >> 17) & 0x1f,
1245
0
                            (groupID >> 12) & 0x1f, (groupID >> 6) & 0x3f, groupID & 0x3f, value.toUint32(4),
1246
0
                            value.toUint32(5), (groupID >> 22));
1247
0
}
1248
1249
0
std::ostream& SonyMakerNote::printFocusFrameSize(std::ostream& os, const Value& value, const ExifData*) {
1250
0
  if (value.count() != 6 || value.typeId() != undefined) {
1251
0
    os << "(" << value << ")";
1252
0
    return os;
1253
0
  }
1254
1255
  // Tag is written as undefined type but is used as unsignedShort. See
1256
  // https://github.com/exiftool/exiftool/blob/1e17485cbb372a502e5b9d052d01303db735e6fa/lib/Image/ExifTool/Sony.pm#L1578
1257
1258
0
  if (value.toUint32(4) == 0 && value.toUint32(5) == 0) {
1259
0
    os << _("n/a");
1260
0
    return os;
1261
0
  }
1262
  // Convert from little endian format
1263
0
  os << ((value.toUint32(1) << 8) + value.toUint32(0)) << "x" << ((value.toUint32(3) << 8) + value.toUint32(2));
1264
0
  return os;
1265
0
}
1266
1267
0
std::ostream& SonyMakerNote::printColorTemperature(std::ostream& os, const Value& value, const ExifData*) {
1268
0
  if (value.count() != 1 || value.typeId() != unsignedLong) {
1269
0
    os << "(" << value << ")";
1270
0
    return os;
1271
0
  }
1272
0
  if (auto v0 = value.toUint32(0); v0 == 0)
1273
0
    os << _("Auto");
1274
0
  else if (v0 == 0xffffffff)
1275
0
    os << _("n/a");
1276
0
  else
1277
0
    os << v0 << " K";
1278
0
  return os;
1279
0
}
1280
1281
0
std::ostream& SonyMakerNote::printColorCompensationFilter(std::ostream& os, const Value& value, const ExifData*) {
1282
0
  if (value.count() != 1 || value.typeId() != unsignedLong) {
1283
0
    os << "(" << value << ")";
1284
0
    return os;
1285
0
  }
1286
  // Tag is written as an unsignedLong but used as a signedLong. See
1287
  // https://github.com/exiftool/exiftool/blob/1e17485cbb372a502e5b9d052d01303db735e6fa/lib/Image/ExifTool/Sony.pm#L2093
1288
1289
0
  int64_t temp = static_cast<int32_t>(value.toUint32(0));
1290
0
  os << "G/M: ";
1291
0
  if (temp == 0)
1292
0
    os << "0";
1293
0
  else if (temp < 0)
1294
0
    os << "G" << -temp;
1295
0
  else
1296
0
    os << "M" << temp;
1297
1298
0
  return os;
1299
0
}
1300
1301
0
static void findLensSpecFlags(const Value& value, std::string& flagsStart, std::string& flagsEnd) {
1302
0
  static constexpr struct LensSpecFlags {
1303
0
    int64_t mask;  // Contains all the bits set in the flags.val_ array values
1304
0
    TagDetails flags[4];
1305
0
    bool prepend;
1306
0
  } lSFArray[] = {
1307
0
      {0x4000, {{0x4000, "PZ"}}, true},
1308
0
      {0x0300, {{0x0100, "DT"}, {0x0200, "FE"}, {0x0300, "E"}}, true},
1309
0
      {0x00e0, {{0x0020, "STF"}, {0x0040, N_("Reflex")}, {0x0060, N_("Macro")}, {0x0080, N_("Fisheye")}}, false},
1310
0
      {0x000c, {{0x0004, "ZA"}, {0x0008, "G"}}, false},
1311
0
      {0x0003, {{0x0001, "SSM"}, {0x0002, "SAM"}}, false},
1312
0
      {0x8000, {{0x8000, "OSS"}}, false},
1313
0
      {0x2000, {{0x2000, "LE"}}, false},
1314
0
      {0x0800, {{0x0800, "II"}}, false},
1315
0
  };
1316
1317
  // When processing, a bitwise 'AND' selects a compatible LensSpecFlags entry,
1318
  // then search inside the 'flags' array for one match.
1319
  //
1320
  // See
1321
  // https://github.com/exiftool/exiftool/blob/1e17485cbb372a502e5b9d052d01303db735e6fa/lib/Image/ExifTool/Sony.pm#L10545
1322
1323
0
  const auto joinedV0V7 = ((value.toUint32(0) << 8) + value.toUint32(7));
1324
0
  for (const auto& i : lSFArray) {
1325
0
    if (auto temp = i.mask & joinedV0V7) {  // Check if a flag matches in the current LensSpecFlags
1326
0
      if (auto f = Exiv2::find(i.flags, temp)) {
1327
0
        if (i.prepend)
1328
0
          flagsStart = flagsStart.empty() ? f->label_ : stringFormat("{} {}", f->label_, flagsStart);
1329
0
        else
1330
0
          flagsEnd = flagsEnd.empty() ? f->label_ : stringFormat("{} {}", flagsEnd, f->label_);
1331
0
        continue;
1332
0
      }
1333
      // Should never get in here. LensSpecFlags.mask should contain all the
1334
      // bits in all the LensSpecFlags.flags.val_ entries
1335
0
      throw Error(ErrorCode::kerErrorMessage, "LensSpecFlags mask doesn't match the bits in the flags array");
1336
0
    }
1337
0
  }
1338
0
}
1339
1340
0
std::ostream& SonyMakerNote::printLensSpec(std::ostream& os, const Value& value, const ExifData*) {
1341
0
  if (value.count() != 8 || value.typeId() != unsignedByte) {
1342
0
    os << "(" << value << ")";
1343
0
    return os;
1344
0
  }
1345
1346
  // Tag uses 8 bytes in the format:
1347
  // <Flgs 1> <Flgs 2> <Focal len min> <Focal len max 1> <Focal len max 2> <Aperture min> <Aperture max> <Flags
1348
  // 3>
1349
  //   (0)       (1)         (2)              (3)               (4)             (5)            (6)          (7)
1350
  //
1351
  // Bytes 2-6 are each interpreted as 2 nibbles which are used as decimal. Nibbles have a value less than 10.
1352
  // e.g., 36 == 0x24, converts to "2" and "4".
1353
  // Optional elements (==0) are <Flgs 1>, <Flgs 2>, <Focal len max 1>, <Focal len max 2>, <Aperture max> and
1354
  // <Flgs 3>
1355
  //
1356
  // Values for the tag are only set with compatible lenses, otherwise all 8 are set to 0.
1357
  //
1358
  // Examples of final output:
1359
  // 1. "FE 90mm F2.8 Macro G OSS"
1360
  // 2. "E PZ 16-50mm F3.5-5.6 OSS"
1361
  // 3. "DT 18-55mm F3.5-5.6 SAM"
1362
  // 4. "28-100mm F1.8-4.9"
1363
  // 5. "35mm F2.0"
1364
  //
1365
  // See:
1366
  // https://github.com/exiftool/exiftool/blob/1e17485cbb372a502e5b9d052d01303db735e6fa/lib/Image/ExifTool/Sony.pm#L2170
1367
1368
0
  const auto focalLenMin = value.toUint32(2);
1369
0
  const auto focalLenMax1 = value.toUint32(3);
1370
0
  const auto focalLenMax2 = value.toUint32(4);
1371
0
  const auto appertureMin = value.toUint32(5);
1372
0
  const auto apertureMax = value.toUint32(6);
1373
1374
0
  if (value.toString() == "0 0 0 0 0 0 0 0" || focalLenMin == 0 || appertureMin == 0) {
1375
0
    os << _("Unknown");
1376
0
    return os;
1377
0
  }
1378
1379
0
  std::string flagsStart;
1380
0
  std::string flagsEnd;
1381
0
  findLensSpecFlags(value, flagsStart, flagsEnd);
1382
1383
  // Output <Flgs 1>
1384
0
  if (!flagsStart.empty())
1385
0
    os << flagsStart << " ";
1386
1387
  // Output <Focal len min>
1388
0
  auto temp = ((focalLenMin >> 4) & 0x0f);
1389
0
  if (temp != 0)  // Remove leading zero
1390
0
    os << temp;
1391
1392
0
  os << (focalLenMin & 0x0f);
1393
1394
0
  if (focalLenMax1 != 0 || focalLenMax2 != 0) {
1395
0
    os << "-";
1396
0
  }
1397
1398
0
  if (focalLenMax1 != 0) {
1399
    // Output <Focal len max 1>
1400
0
    temp = ((focalLenMax1 >> 4) & 0x0f);
1401
0
    if (temp != 0)  // Remove leading zero
1402
0
      os << temp;
1403
0
    os << (focalLenMax1 & 0x0f);
1404
1405
    // Output <Focal len max 2>
1406
0
    os << ((focalLenMax2 >> 4) & 0x0f) << (focalLenMax2 & 0x0f);
1407
0
  } else {
1408
    // Output <Focal len max 2>
1409
0
    if (focalLenMax2 != 0)
1410
0
      os << ((focalLenMax2 >> 4) & 0x0f) << (focalLenMax2 & 0x0f);
1411
0
  }
1412
1413
0
  os << "mm";
1414
1415
  // Output <Aperture min>
1416
0
  os << " F" << ((appertureMin >> 4) & 0x0f) << "." << (appertureMin & 0x0f);
1417
1418
  // Output <Aperture max>
1419
0
  if (apertureMax != 0)
1420
0
    os << "-" << ((apertureMax >> 4) & 0x0f) << "." << (apertureMax & 0x0f);
1421
1422
  // Output <Flags 3>
1423
0
  if (!flagsEnd.empty())
1424
0
    os << " " << flagsEnd;
1425
0
  return os;
1426
0
}
1427
1428
0
std::ostream& SonyMakerNote::printImageSize(std::ostream& os, const Value& value, const ExifData*) {
1429
0
  if (value.count() != 2 || value.typeId() != unsignedLong) {
1430
0
    os << "(" << value << ")";
1431
0
    return os;
1432
0
  }
1433
  // Values are stored as Height then Width
1434
0
  os << value.toString(1) << " x " << value.toString(0);
1435
1436
0
  return os;
1437
0
}
1438
1439
0
std::ostream& SonyMakerNote::printFocusMode(std::ostream& os, const Value& value, const ExifData* metadata) {
1440
0
  if (value.count() != 1 || value.typeId() != unsignedShort || !metadata) {
1441
0
    os << "(" << value << ")";
1442
0
    return os;
1443
0
  }
1444
  // Only valid for certain models of camera. See
1445
  // https://github.com/exiftool/exiftool/blob/1e17485cbb372a502e5b9d052d01303db735e6fa/lib/Image/ExifTool/Sony.pm#L2255
1446
1447
0
  if (std::string metaVersion; !getMetaVersion(metadata, metaVersion) || metaVersion != "DC7303320222000") {
1448
0
    EXV_PRINT_TAG(sonyFocusMode)(os, value.toUint32(0), metadata);
1449
0
    return os;
1450
0
  }
1451
1452
0
  os << _("n/a");
1453
0
  return os;
1454
0
}
1455
1456
0
std::ostream& SonyMakerNote::printAFMode(std::ostream& os, const Value& value, const ExifData* metadata) {
1457
0
  if (value.count() != 1 || value.typeId() != unsignedShort || !metadata) {
1458
0
    os << "(" << value << ")";
1459
0
    return os;
1460
0
  }
1461
1462
  // Only valid for certain models of camera. See
1463
  // https://github.com/exiftool/exiftool/blob/1e17485cbb372a502e5b9d052d01303db735e6fa/lib/Image/ExifTool/Sony.pm#L2275
1464
0
  if (std::string metaVersion; !getMetaVersion(metadata, metaVersion) || metaVersion != "DC7303320222000") {
1465
0
    EXV_PRINT_TAG(sonyAFModeSet1)(os, value.toUint32(0), metadata);
1466
0
    return os;
1467
0
  }
1468
1469
0
  if (uint32_t focusMode2 = 0; getFocusMode2(metadata, focusMode2) && focusMode2 != 0) {
1470
0
    EXV_PRINT_TAG(sonyAFModeSet2)(os, value.toUint32(0), metadata);
1471
0
    return os;
1472
0
  }
1473
1474
0
  os << _("n/a");
1475
0
  return os;
1476
0
}
1477
1478
0
std::ostream& SonyMakerNote::printFocusMode3(std::ostream& os, const Value& value, const ExifData* metadata) {
1479
0
  if (value.count() != 1 || value.typeId() != unsignedShort || !metadata) {
1480
0
    os << "(" << value << ")";
1481
0
    return os;
1482
0
  }
1483
1484
  // Only valid for certain models of camera. See
1485
  // https://github.com/exiftool/exiftool/blob/1e17485cbb372a502e5b9d052d01303db735e6fa/lib/Image/ExifTool/Sony.pm#L2411
1486
0
  if (std::string metaVersion; getMetaVersion(metadata, metaVersion) && metaVersion == "DC7303320222000") {
1487
0
    EXV_PRINT_TAG(sonyFocusMode3)(os, value.toUint32(0), metadata);
1488
0
    return os;
1489
0
  }
1490
0
  os << _("n/a");
1491
0
  return os;
1492
0
}
1493
1494
std::ostream& SonyMakerNote::printHighISONoiseReduction2(std::ostream& os, const Value& value,
1495
0
                                                         const ExifData* metadata) {
1496
0
  if (value.count() != 1 || value.typeId() != unsignedShort || !metadata) {
1497
0
    os << "(" << value << ")";
1498
0
    return os;
1499
0
  }
1500
1501
  // Only valid for certain models of camera. See
1502
  // https://github.com/exiftool/exiftool/blob/1e17485cbb372a502e5b9d052d01303db735e6fa/lib/Image/ExifTool/Sony.pm#L2437
1503
0
  std::string model;
1504
0
  if (!getModel(metadata, model)) {
1505
0
    os << "(" << value << ")";
1506
0
    return os;
1507
0
  }
1508
1509
0
  if (model.starts_with("DSC-") || model.starts_with("Stellar")) {
1510
0
    EXV_PRINT_TAG(sonyHighISONoiseReduction2)(os, value.toUint32(0), metadata);
1511
0
    return os;
1512
0
  }
1513
1514
0
  os << _("n/a");
1515
0
  return os;
1516
0
}
1517
1518
// Sony MakerNote Tag Info
1519
constexpr TagInfo SonyMakerNote::tagInfo_[] = {
1520
    {0x0102, "Quality", N_("Quality"), N_("Image quality"), IfdId::sony1Id, SectionId::makerTags, unsignedLong, -1,
1521
     EXV_PRINT_TAG(sonyImageQuality)},
1522
    {0x0104, "FlashExposureComp", N_("Flash Exposure Compensation"), N_("Flash exposure compensation in EV"),
1523
     IfdId::sony1Id, SectionId::makerTags, signedRational, -1, print0x9204},
1524
    {0x0105, "Teleconverter", N_("Teleconverter Model"), N_("Teleconverter Model"), IfdId::sony1Id,
1525
     SectionId::makerTags, unsignedLong, -1, printMinoltaSonyTeleconverterModel},
1526
    {0x0112, "WhiteBalanceFineTune", N_("White Balance Fine Tune"), N_("White Balance Fine Tune"), IfdId::sony1Id,
1527
     SectionId::makerTags, unsignedLong, -1, printWhiteBalanceFineTune},
1528
    {0x0115, "WhiteBalance", N_("White balance"), N_("White balance"), IfdId::sony1Id, SectionId::makerTags,
1529
     unsignedLong, -1, EXV_PRINT_TAG(sonyWhiteBalanceStd)},
1530
    {0x1000, "MultiBurstMode", N_("Multi Burst Mode"), N_("Multi Burst Mode"), IfdId::sony1Id, SectionId::makerTags,
1531
     undefined, -1, printMultiBurstMode},
1532
    {0x1001, "MultiBurstImageWidth", N_("Multi Burst Image Width"), N_("Multi Burst Image Width"), IfdId::sony1Id,
1533
     SectionId::makerTags, unsignedShort, -1, printMultiBurstSize},
1534
    {0x1002, "MultiBurstImageHeight", N_("Multi Burst Image Height"), N_("Multi Burst Image Height"), IfdId::sony1Id,
1535
     SectionId::makerTags, unsignedShort, -1, printMultiBurstSize},
1536
    {0x2001, "PreviewImage", N_("Preview Image"), N_("JPEG preview image"), IfdId::sony1Id, SectionId::makerTags,
1537
     undefined, -1, printValue},
1538
    {0x2002, "Rating", "Rating", N_("Rating"), IfdId::sony1Id, SectionId::makerTags, unsignedLong, -1, printValue},
1539
    {0x2004, "Contrast", "Contrast", N_("Contrast"), IfdId::sony1Id, SectionId::makerTags, signedLong, -1, printValue},
1540
    {0x2005, "Saturation", "Saturation", N_("Saturation"), IfdId::sony1Id, SectionId::makerTags, signedLong, -1,
1541
     printValue},
1542
    {0x2006, "Sharpness", "Sharpness", N_("Sharpness"), IfdId::sony1Id, SectionId::makerTags, signedLong, -1,
1543
     printValue},
1544
    {0x2007, "Brightness", "Brightness", N_("Brightness"), IfdId::sony1Id, SectionId::makerTags, signedLong, -1,
1545
     printValue},
1546
    {0x2008, "LongExposureNoiseReduction", "Long exposure noise reduction", N_("Long exposure noise reduction"),
1547
     IfdId::sony1Id, SectionId::makerTags, unsignedLong, -1, EXV_PRINT_TAG(sonyLongExposureNoiseReduction)},
1548
    {0x2009, "HighISONoiseReduction", "High ISO noise reduction", N_("High ISO noise reduction"), IfdId::sony1Id,
1549
     SectionId::makerTags, unsignedShort, -1, EXV_PRINT_TAG(sonyHighISONoiseReductionStd)},
1550
    {0x200a, "AutoHDR", N_("Auto high dynamic range mode"), N_("Auto high dynamic range mode"), IfdId::sony1Id,
1551
     SectionId::makerTags, unsignedLong, -1, printAutoHDRStd},
1552
    {0x200b, "MultiFrameNoiseReduction", N_("Multi frame noise reduction"), N_("Multi frame noise reduction"),
1553
     IfdId::sony1Id, SectionId::makerTags, unsignedLong, -1, EXV_PRINT_TAG(sonyOffOnNA1)},
1554
    {0x200e, "PictureEffect", N_("Picture effect"), N_("Picture effect"), IfdId::sony1Id, SectionId::makerTags,
1555
     unsignedShort, -1, EXV_PRINT_TAG(sonyPictureEffect)},
1556
    {0x200f, "SoftSkinEffect", N_("Soft skin effect"), N_("Soft skin effect"), IfdId::sony1Id, SectionId::makerTags,
1557
     unsignedLong, -1, EXV_PRINT_TAG(sonySoftSkinEffect)},
1558
    {0x2011, "VignettingCorrection", N_("Vignetting correction"), N_("Vignetting correction"), IfdId::sony1Id,
1559
     SectionId::makerTags, unsignedLong, -1, EXV_PRINT_TAG(sonyVignettingCorrection)},
1560
    {0x2012, "LateralChromaticAberration", N_("Lateral chromatic aberration"), N_("Lateral chromatic aberration"),
1561
     IfdId::sony1Id, SectionId::makerTags, unsignedLong, -1, EXV_PRINT_TAG(sonyLateralChromaticAberration)},
1562
    {0x2013, "DistortionCorrectionSetting", N_("Distortion correction setting"), N_("Distortion correction setting"),
1563
     IfdId::sony1Id, SectionId::makerTags, unsignedLong, -1, EXV_PRINT_TAG(sonyDistortionCorrectionSettings)},
1564
    {0x2014, "WBShiftABGM", N_("White balance Shift (amber/blue, green/magenta)"),
1565
     N_("First number is amber/blue, second is green/magenta"), IfdId::sony1Id, SectionId::makerTags, signedLong, 2,
1566
     printWBShiftABGM},
1567
    {0x2016, "AutoPortraitFramed", N_("Auto portrait framed"), N_("Indicates if the Portrait Framing feature was used"),
1568
     IfdId::sony1Id, SectionId::makerTags, unsignedShort, -1, EXV_PRINT_TAG(sonyNoYes)},
1569
    {0x2017, "FlashAction", N_("Flash action"), N_("Flash action"), IfdId::sony1Id, SectionId::makerTags, unsignedLong,
1570
     -1, EXV_PRINT_TAG(sonyFlashAction)},
1571
    {0x201a, "ElectronicFrontCurtainShutter", N_("Electronic front curtain shutter"),
1572
     N_("Electronic front curtain shutter"), IfdId::sony1Id, SectionId::makerTags, unsignedLong, -1,
1573
     printMinoltaSonyBoolValue},
1574
    {0x201b, "FocusMode2", N_("Focus mode 2"), N_("Focus mode 2"), IfdId::sony1Id, SectionId::makerTags, unsignedByte,
1575
     -1, printFocusMode2},
1576
    {0x201c, "AFAreaModeSetting", N_("Auto focus area mode setting"), N_("Auto focus area mode setting"),
1577
     IfdId::sony1Id, SectionId::makerTags, unsignedByte, -1, printAFAreaModeSetting},
1578
    {0x201d, "FlexibleSpotPosition", N_("Flexible spot position"),
1579
     N_("X and Y co-ordinates or the auto focus point. Only valid when AFAreaModeSetting is Flexible"), IfdId::sony1Id,
1580
     SectionId::makerTags, unsignedShort, 2, printFlexibleSpotPosition},
1581
    {0x201e, "AFPointSelected", N_("Auto focus point selected"), N_("Auto focus point selected"), IfdId::sony1Id,
1582
     SectionId::makerTags, unsignedByte, -1, printAFPointSelected},
1583
    {0x2020, "AFPointsUsed", N_("Auto focus points used"), N_("Auto focus points used"), IfdId::sony1Id,
1584
     SectionId::makerTags, unsignedByte, -1, printAFPointsUsed},
1585
    {0x2021, "AFTracking", N_("Auto focus tracking"), N_("Auto focus tracking"), IfdId::sony1Id, SectionId::makerTags,
1586
     unsignedByte, -1, printAFTracking},
1587
    {0x2022, "FocalPlaneAFPointsUsed", N_("Focal plane auto focus points used"),
1588
     N_("Focal plane auto focus points used"), IfdId::sony1Id, SectionId::makerTags, unsignedByte, -1,
1589
     printFocalPlaneAFPointsUsed},
1590
    {0x2023, "MultiFrameNREffect", N_("Multi frame noise reduction effect"), N_("Multi frame noise reduction effect"),
1591
     IfdId::sony1Id, SectionId::makerTags, unsignedLong, -1, EXV_PRINT_TAG(sonyMultiFrameNREffect)},
1592
    {0x2026, "WBShiftABGMPrecise", N_("White balance shift (amber/blue, green/magenta) precise"),
1593
     N_("First number is amber/blue, second is green/magenta"), IfdId::sony1Id, SectionId::makerTags, signedLong, 2,
1594
     printWBShiftABGMPrecise},
1595
    {0x2027, "FocusLocation", N_("Focus location"),
1596
     N_("Location in the image where the camera focused, used for Playback Zoom. Origin is top left with the first "
1597
        "co-ordinate to the right and the second co-ordinate down. If focus location information cannot be obtained, "
1598
        "the center of the image is used"),
1599
     IfdId::sony1Id, SectionId::makerTags, unsignedShort, -1, printValue},
1600
    {0x2028, "VariableLowPassFilter", N_("Variable low pass filter"), N_("Variable low pass filter"), IfdId::sony1Id,
1601
     SectionId::makerTags, unsignedShort, -1, EXV_PRINT_STRING_TAG_2(sonyVariableLowPassFilter)},
1602
    {0x2029, "RAWFileType", N_("RAW file type"), N_("RAW file type"), IfdId::sony1Id, SectionId::makerTags,
1603
     unsignedShort, -1, EXV_PRINT_TAG(sonyRAWFileType)},
1604
    {0x202b, "PrioritySetInAWB", N_("Priority set in automatic white balance"),
1605
     N_("Priority set in automatic white balance"), IfdId::sony1Id, SectionId::makerTags, unsignedByte, -1,
1606
     EXV_PRINT_TAG(sonyPrioritySetInAWB)},
1607
    {0x202c, "MeteringMode2", N_("Metering mode 2"), N_("Metering mode 2"), IfdId::sony1Id, SectionId::makerTags,
1608
     unsignedShort, -1, EXV_PRINT_TAG(sonyMeteringMode2)},
1609
    {0x202d, "ExposureStandardAdjustment", N_("Exposure standard adjustment"), N_("Exposure standard adjustment"),
1610
     IfdId::sony1Id, SectionId::makerTags, signedRational, -1, printExposureStandardAdjustment},
1611
    {0x202e, "Quality2", N_("Quality 2"), N_("Image quality 2"), IfdId::sony1Id, SectionId::makerTags, unsignedShort, 2,
1612
     EXV_PRINT_STRING_TAG_2(sonyQuality2Std)},
1613
    {0x202f, "PixelShiftInfo", N_("Pixel shift info"),
1614
     N_("Pixel shift information consisting of the group ID and shot number"), IfdId::sony1Id, SectionId::makerTags,
1615
     undefined, -1, printPixelShiftInfo},
1616
    {0x2031, "SerialNumber", N_("Serial number"), N_("Serial number"), IfdId::sony1Id, SectionId::makerTags,
1617
     asciiString, -1, printValue},
1618
    {0x2032, "Shadows", N_("Shadows"), N_("Shadows"), IfdId::sony1Id, SectionId::makerTags, signedLong, -1, printValue},
1619
    {0x2033, "Highlights", N_("Highlights"), N_("Highlights"), IfdId::sony1Id, SectionId::makerTags, signedLong, -1,
1620
     printValue},
1621
    {0x2034, "Fade", N_("Fade"), N_("Fade"), IfdId::sony1Id, SectionId::makerTags, signedLong, -1, printValue},
1622
    {0x2035, "SharpnessRange", N_("Sharpness range"), N_("Sharpness range"), IfdId::sony1Id, SectionId::makerTags,
1623
     signedLong, -1, printValue},
1624
    {0x2036, "Clarity", N_("Clarity"), N_("Clarity"), IfdId::sony1Id, SectionId::makerTags, signedLong, -1, printValue},
1625
    {0x2037, "FocusFrameSize", N_("Focus frame size"),
1626
     N_("Width and height of the focus frame, centered on FocusLocation"), IfdId::sony1Id, SectionId::makerTags,
1627
     undefined, -1, printFocusFrameSize},
1628
    {0x2039, "JPEGHEIFSwitch", N_("JPEG/HEIF switch"), N_("JPEG/HEIF switch"), IfdId::sony1Id, SectionId::makerTags,
1629
     unsignedShort, -1, EXV_PRINT_TAG(sonyJPEGHEIFSwitch)},
1630
    {0xb000, "FileFormat", N_("File Format"), N_("File Format"), IfdId::sony1Id, SectionId::makerTags, unsignedByte, -1,
1631
     EXV_PRINT_STRING_TAG_4(sonyFileFormat)},
1632
    {0xb001, "SonyModelID", N_("Sony Model ID"),
1633
     N_("Similar to Exif.Image.Model but can contain multiple entries or conditions"), IfdId::sony1Id,
1634
     SectionId::makerTags, unsignedShort, -1, EXV_PRINT_TAG(sonyModelId)},
1635
    {0xb020, "CreativeStyle", N_("Creative style"), N_("Creative style"), IfdId::sony1Id, SectionId::makerTags,
1636
     asciiString, -1, EXV_PRINT_STRING_TAG_1(sonyCreativeStyleStd)},
1637
    {0xb021, "ColorTemperature", N_("Color Temperature"), N_("Color Temperature"), IfdId::sony1Id, SectionId::makerTags,
1638
     unsignedLong, -1, printColorTemperature},
1639
    {0xb022, "ColorCompensationFilter", N_("Color Compensation Filter"),
1640
     N_("Color Compensation Filter, (green/magenta)"), IfdId::sony1Id, SectionId::makerTags, unsignedLong, -1,
1641
     printColorCompensationFilter},
1642
    {0xb023, "SceneMode", N_("Scene Mode"), N_("Scene Mode"), IfdId::sony1Id, SectionId::makerTags, unsignedLong, -1,
1643
     printMinoltaSonySceneMode},
1644
    {0xb024, "ZoneMatching", N_("Zone Matching"), N_("Zone Matching"), IfdId::sony1Id, SectionId::makerTags,
1645
     unsignedLong, -1, printMinoltaSonyZoneMatching},
1646
    {0xb025, "DynamicRangeOptimizer", N_("Dynamic Range Optimizer"), N_("Dynamic Range Optimizer"), IfdId::sony1Id,
1647
     SectionId::makerTags, unsignedLong, -1, EXV_PRINT_TAG(print0xb025)},
1648
    {0xb026, "ImageStabilization", N_("Image stabilization"), N_("Image stabilization"), IfdId::sony1Id,
1649
     SectionId::makerTags, unsignedLong, -1, EXV_PRINT_TAG(sonyOffOnNA2)},
1650
    {0xb027, "LensID", N_("Lens ID"), N_("Lens ID"), IfdId::sony1Id, SectionId::makerTags, unsignedLong, -1,
1651
     printMinoltaSonyLensID},
1652
    {0xb029, "ColorMode", N_("Color Mode"), N_("Color Mode"), IfdId::sony1Id, SectionId::makerTags, unsignedLong, -1,
1653
     EXV_PRINT_TAG(sonyColorMode)},
1654
    {0xb02a, "LensSpec", N_("Lens specification"),
1655
     N_("Similar to Exif.Photo.LensModel but includes optional additional flags before and after (e.g., DT, Macro). "
1656
        "Works with most Sony cameras"),
1657
     IfdId::sony1Id, SectionId::makerTags, unsignedByte, -1, printLensSpec},
1658
    {0xb02b, "FullImageSize", N_("Full Image Size"), N_("Full image Size (width x height)"), IfdId::sony1Id,
1659
     SectionId::makerTags, unsignedLong, -1, printImageSize},
1660
    {0xb02c, "PreviewImageSize", N_("Preview image Size"), N_("Preview image size (width x height)"), IfdId::sony1Id,
1661
     SectionId::makerTags, unsignedLong, -1, printImageSize},
1662
    {0xb040, "Macro", N_("Macro"), N_("Macro"), IfdId::sony1Id, SectionId::makerTags, unsignedShort, -1,
1663
     EXV_PRINT_TAG(sonyMacro)},
1664
    {0xb041, "ExposureMode", N_("Exposure Mode"), N_("Exposure Mode"), IfdId::sony1Id, SectionId::makerTags,
1665
     unsignedShort, -1, EXV_PRINT_TAG(sonyExposureMode)},
1666
    {0xb042, "FocusMode", N_("Focus Mode"), N_("Focus Mode"), IfdId::sony1Id, SectionId::makerTags, unsignedShort, -1,
1667
     printFocusMode},
1668
    {0xb043, "AFMode", N_("Auto focus area mode"), N_("Auto focus area mode"), IfdId::sony1Id, SectionId::makerTags,
1669
     unsignedShort, -1, printAFMode},
1670
    {0xb044, "AFIlluminator", N_("Auto focus illuminator"), N_("Auto focus illuminator"), IfdId::sony1Id,
1671
     SectionId::makerTags, unsignedShort, -1, EXV_PRINT_TAG(sonyAFIlluminator)},
1672
    {0xb047, "JPEGQuality", N_("JPEG Quality"), N_("JPEG Quality"), IfdId::sony1Id, SectionId::makerTags, unsignedShort,
1673
     -1, EXV_PRINT_TAG(sonyJPEGQuality)},
1674
    {0xb048, "FlashLevel", N_("Flash Level"), N_("Flash Level"), IfdId::sony1Id, SectionId::makerTags, signedShort, -1,
1675
     EXV_PRINT_TAG(sonyFlashLevel)},
1676
    {0xb049, "ReleaseMode", N_("Release Mode"), N_("Release Mode"), IfdId::sony1Id, SectionId::makerTags, unsignedShort,
1677
     -1, EXV_PRINT_TAG(sonyReleaseMode)},
1678
    {0xb04a, "SequenceNumber", N_("Sequence Number"), N_("Shot number in continuous burst mode"), IfdId::sony1Id,
1679
     SectionId::makerTags, unsignedShort, -1, EXV_PRINT_TAG_NO_ERROR(sonySequenceNumber)},
1680
    {0xb04b, "AntiBlur", N_("Anti-Blur"), N_("Anti-Blur"), IfdId::sony1Id, SectionId::makerTags, unsignedShort, -1,
1681
     EXV_PRINT_TAG(sonyAntiBlur)},
1682
    {0xb04e, "FocusMode3", N_("Focus mode 3"), N_("Focus mode 3"), IfdId::sony1Id, SectionId::makerTags, unsignedShort,
1683
     -1, printFocusMode3},
1684
    {0xb04f, "DynamicRangeOptimizer2", N_("Dynamic Range Optimizer 2"), N_("Dynamic Range Optimizer 2"), IfdId::sony1Id,
1685
     SectionId::makerTags, unsignedShort, -1, EXV_PRINT_TAG(print0xb04f)},
1686
    {0xb050, "HighISONoiseReduction2", N_("High ISO noise reduction 2"), N_("High ISO noise reduction 2"),
1687
     IfdId::sony1Id, SectionId::makerTags, unsignedShort, -1, printHighISONoiseReduction2},
1688
    {0xb052, "IntelligentAuto", N_("Intelligent Auto"), N_("Intelligent Auto"), IfdId::sony1Id, SectionId::makerTags,
1689
     unsignedShort, -1, EXV_PRINT_TAG(sonyIntelligentAuto)},
1690
    {0xb054, "WhiteBalance2", N_("White balance 2"),
1691
     N_("White balance 2. Decoding the Fluorescent settings matches the EXIF standard, which is different from "
1692
        "the names used by Sony for some models"),
1693
     IfdId::sony1Id, SectionId::makerTags, unsignedShort, -1, EXV_PRINT_TAG(sonyWhiteBalance2)},
1694
    // End of list marker
1695
    {0xffff, "(UnknownSony1MakerNoteTag)", "(UnknownSony1MakerNoteTag)", N_("Unknown Sony1MakerNote tag"),
1696
     IfdId::sony1Id, SectionId::makerTags, asciiString, -1, printValue},
1697
};
1698
1699
14.1k
const TagInfo* SonyMakerNote::tagList() {
1700
14.1k
  return tagInfo_;
1701
14.1k
}
1702
1703
// -- Sony camera settings ---------------------------------------------------------------
1704
1705
//! Lookup table to translate Sony camera settings drive mode values to readable labels
1706
constexpr TagDetails sonyDriveModeStd[] = {
1707
    {0x01, N_("Single Frame")},
1708
    {0x02, N_("Continuous High")},
1709
    {0x04, N_("Self-timer 10 sec")},
1710
    {0x05, N_("Self-timer 2 sec, Mirror Lock-up")},
1711
    {0x06, N_("Single-frame Bracketing")},
1712
    {0x07, N_("Continuous Bracketing")},
1713
    {0x0a, N_("Remote Commander")},
1714
    {0x0b, N_("Mirror Lock-up")},
1715
    {0x12, N_("Continuous Low")},
1716
    {0x18, N_("White Balance Bracketing Low")},
1717
    {0x19, N_("D-Range Optimizer Bracketing Low")},
1718
    {0x28, N_("White Balance Bracketing High")},
1719
    {0x29, N_("D-Range Optimizer Bracketing High")},
1720
};
1721
1722
//! Lookup table to translate Sony camera settings focus mode values to readable labels
1723
constexpr TagDetails sonyCSFocusMode[] = {
1724
    {0, N_("Manual")},
1725
    {1, "AF-S"},
1726
    {2, "AF-C"},
1727
    {3, "AF-A"},
1728
};
1729
1730
//! Lookup table to translate Sony camera settings metering mode values to readable labels
1731
constexpr TagDetails sonyMeteringMode[] = {
1732
    {1, N_("Multi-segment")},
1733
    {2, N_("Center weighted average")},
1734
    {4, N_("Spot")},
1735
};
1736
1737
//! Lookup table to translate Sony camera settings creative style values to readable labels
1738
constexpr TagDetails sonyCreativeStyle[] = {
1739
    {1, N_("Standard")},      {2, N_("Vivid")},     {3, N_("Portrait")},
1740
    {4, N_("Landscape")},     {5, N_("Sunset")},    {6, N_("Night View/Portrait")},
1741
    {8, N_("Black & White")}, {9, N_("Adobe RGB")}, {11, N_("Neutral")},
1742
    {12, N_("Clear")},        {13, N_("Deep")},     {14, N_("Light")},
1743
    {15, N_("Autumn")},       {16, N_("Sepia")},
1744
};
1745
1746
//! Lookup table to translate Sony camera settings flash mode values to readable labels
1747
constexpr TagDetails sonyFlashMode[] = {
1748
    {0, N_("ADI")},
1749
    {1, N_("TTL")},
1750
};
1751
1752
//! Lookup table to translate Sony AF illuminator values to readable labels
1753
constexpr TagDetails sonyAFIlluminatorCS[] = {
1754
    {0, N_("Auto")},
1755
    {1, N_("Off")},
1756
    {0xffff, N_("n/a")},
1757
};
1758
1759
//! Lookup table to translate Sony camera settings image style values to readable labels
1760
constexpr TagDetails sonyImageStyle[] = {
1761
    {1, N_("Standard")},    {2, N_("Vivid")},       {3, N_("Portrait")},
1762
    {4, N_("Landscape")},   {5, N_("Sunset")},      {7, N_("Night View/Portrait")},
1763
    {8, N_("B&W")},         {9, N_("Adobe RGB")},   {11, N_("Neutral")},
1764
    {129, N_("StyleBox1")}, {130, N_("StyleBox2")}, {131, N_("StyleBox3")},
1765
    {132, N_("StyleBox4")}, {133, N_("StyleBox5")}, {134, N_("StyleBox6")},
1766
};
1767
1768
//! Lookup table to translate Sony camera settings exposure program values to readable labels
1769
constexpr TagDetails sonyExposureProgram[] = {
1770
    {0, N_("Auto")},
1771
    {1, N_("Manual")},
1772
    {2, N_("Program AE")},
1773
    {3, N_("Aperture-priority AE")},
1774
    {4, N_("Shutter speed priority AE")},
1775
    {8, N_("Program Shift A")},
1776
    {9, N_("Program Shift S")},
1777
    {16, N_("Portrait")},
1778
    {17, N_("Sports")},
1779
    {18, N_("Sunset")},
1780
    {19, N_("Night Portrait")},
1781
    {20, N_("Landscape")},
1782
    {21, N_("Macro")},
1783
    {35, N_("Auto No Flash")},
1784
};
1785
1786
//! Lookup table to translate Sony camera settings image size values to readable labels
1787
constexpr TagDetails sonyImageSize[] = {
1788
    {1, N_("Large")},
1789
    {2, N_("Medium")},
1790
    {3, N_("Small")},
1791
};
1792
1793
//! Lookup table to translate Sony aspect ratio values to readable labels
1794
constexpr TagDetails sonyAspectRatio[] = {
1795
    {1, "3:2"},
1796
    {2, "16:9"},
1797
};
1798
1799
//! Lookup table to translate Sony exposure level increments values to readable labels
1800
constexpr TagDetails sonyExposureLevelIncrements[] = {
1801
    {33, "1/3 EV"},
1802
    {50, "1/2 EV"},
1803
};
1804
1805
// Sony Camera Settings Tag Info
1806
// NOTE: all are for A200, A230, A300, A350, A700, A850 and A900 Sony model excepted
1807
// some entries which are only relevant with A700.
1808
1809
// Warnings: Exiftool database give a list of tags shorted in decimal mode, not hexadecimal.
1810
1811
constexpr TagInfo SonyMakerNote::tagInfoCs_[] = {
1812
    // NOTE: A700 only
1813
    {0x0004, "DriveMode", N_("Drive Mode"), N_("Drive Mode"), IfdId::sony1CsId, SectionId::makerTags, unsignedShort, 1,
1814
     EXV_PRINT_TAG(sonyDriveModeStd)},
1815
    // NOTE: A700 only
1816
    {0x0006, "WhiteBalanceFineTune", N_("White Balance Fine Tune"), N_("White Balance Fine Tune"), IfdId::sony1CsId,
1817
     SectionId::makerTags, signedShort, 1, printValue},
1818
    {0x0010, "FocusMode", N_("Focus Mode"), N_("Focus Mode"), IfdId::sony1CsId, SectionId::makerTags, unsignedShort, 1,
1819
     EXV_PRINT_TAG(sonyCSFocusMode)},
1820
    {0x0011, "AFAreaMode", N_("AF Area Mode"), N_("AF Area Mode"), IfdId::sony1CsId, SectionId::makerTags,
1821
     unsignedShort, 1, printMinoltaSonyAFAreaMode},
1822
    {0x0012, "LocalAFAreaPoint", N_("Local AF Area Point"), N_("Local AF Area Point"), IfdId::sony1CsId,
1823
     SectionId::makerTags, unsignedShort, 1, printMinoltaSonyLocalAFAreaPoint},
1824
    {0x0015, "MeteringMode", N_("Metering Mode"), N_("Metering Mode"), IfdId::sony1CsId, SectionId::makerTags,
1825
     unsignedShort, 1, EXV_PRINT_TAG(sonyMeteringMode)},
1826
    {0x0016, "ISOSetting", N_("ISO Setting"), N_("ISO Setting"), IfdId::sony1CsId, SectionId::makerTags, unsignedShort,
1827
     1, printValue},
1828
    {0x0018, "DynamicRangeOptimizerMode", N_("Dynamic Range Optimizer Mode"), N_("Dynamic Range Optimizer Mode"),
1829
     IfdId::sony1CsId, SectionId::makerTags, unsignedShort, 1, printMinoltaSonyDynamicRangeOptimizerMode},
1830
    {0x0019, "DynamicRangeOptimizerLevel", N_("Dynamic Range Optimizer Level"), N_("Dynamic Range Optimizer Level"),
1831
     IfdId::sony1CsId, SectionId::makerTags, unsignedShort, 1, printValue},
1832
    {0x001A, "CreativeStyle", N_("Creative Style"), N_("Creative Style"), IfdId::sony1CsId, SectionId::makerTags,
1833
     unsignedShort, 1, EXV_PRINT_TAG(sonyCreativeStyle)},
1834
    {0x001C, "Sharpness", N_("Sharpness"), N_("Sharpness"), IfdId::sony1CsId, SectionId::makerTags, unsignedShort, 1,
1835
     printValue},
1836
    {0x001D, "Contrast", N_("Contrast"), N_("Contrast"), IfdId::sony1CsId, SectionId::makerTags, unsignedShort, 1,
1837
     printValue},
1838
    {0x001E, "Saturation", N_("Saturation"), N_("Saturation"), IfdId::sony1CsId, SectionId::makerTags, unsignedShort, 1,
1839
     printValue},
1840
    {0x001F, "ZoneMatchingValue", N_("Zone Matching Value"), N_("Zone Matching Value"), IfdId::sony1CsId,
1841
     SectionId::makerTags, unsignedShort, 1, printValue},
1842
    {0x0022, "Brightness", N_("Brightness"), N_("Brightness"), IfdId::sony1CsId, SectionId::makerTags, unsignedShort, 1,
1843
     printValue},
1844
    {0x0023, "FlashMode", N_("FlashMode"), N_("FlashMode"), IfdId::sony1CsId, SectionId::makerTags, unsignedShort, 1,
1845
     EXV_PRINT_TAG(sonyFlashMode)},
1846
    // NOTE: A700 only
1847
    {0x0028, "PrioritySetupShutterRelease", N_("Priority Setup Shutter Release"), N_("Priority Setup Shutter Release"),
1848
     IfdId::sony1CsId, SectionId::makerTags, unsignedShort, 1, printMinoltaSonyPrioritySetupShutterRelease},
1849
    // NOTE: A700 only
1850
    {0x0029, "AFIlluminator", N_("AF Illuminator"), N_("AF Illuminator"), IfdId::sony1CsId, SectionId::makerTags,
1851
     unsignedShort, 1, EXV_PRINT_TAG(sonyAFIlluminatorCS)},
1852
    // NOTE: A700 only
1853
    {0x002A, "AFWithShutter", N_("AF With Shutter"), N_("AF With Shutter"), IfdId::sony1CsId, SectionId::makerTags,
1854
     unsignedShort, 1, printMinoltaSonyBoolInverseValue},
1855
    // NOTE: A700 only
1856
    {0x002B, "LongExposureNoiseReduction", N_("Long Exposure Noise Reduction"), N_("Long Exposure Noise Reduction"),
1857
     IfdId::sony1CsId, SectionId::makerTags, unsignedShort, 1, printMinoltaSonyBoolValue},
1858
    // NOTE: A700 only
1859
    {0x002C, "HighISONoiseReduction", N_("High ISO Noise Reduction"), N_("High ISO Noise Reduction"), IfdId::sony1CsId,
1860
     SectionId::makerTags, unsignedShort, 1, printValue},
1861
    // NOTE: A700 only
1862
    {0x002D, "ImageStyle", N_("Image Style"), N_("Image Style"), IfdId::sony1CsId, SectionId::makerTags, unsignedShort,
1863
     1, EXV_PRINT_TAG(sonyImageStyle)},
1864
    {0x003C, "ExposureProgram", N_("Exposure Program"), N_("Exposure Program"), IfdId::sony1CsId, SectionId::makerTags,
1865
     unsignedShort, 1, EXV_PRINT_TAG(sonyExposureProgram)},
1866
    {0x003D, "ImageStabilization", N_("Image Stabilization"), N_("Image Stabilization"), IfdId::sony1CsId,
1867
     SectionId::makerTags, unsignedShort, 1, printMinoltaSonyBoolValue},
1868
    {0x003F, "Rotation", N_("Rotation"), N_("Rotation"), IfdId::sony1CsId, SectionId::makerTags, unsignedShort, 1,
1869
     printMinoltaSonyRotation},
1870
    {0x0054, "SonyImageSize", N_("Sony Image Size"), N_("Sony Image Size"), IfdId::sony1CsId, SectionId::makerTags,
1871
     unsignedShort, 1, EXV_PRINT_TAG(sonyImageSize)},
1872
    {0x0055, "AspectRatio", N_("Aspect Ratio"), N_("Aspect Ratio"), IfdId::sony1CsId, SectionId::makerTags,
1873
     unsignedShort, 1, EXV_PRINT_TAG(sonyAspectRatio)},
1874
    {0x0056, "Quality", N_("Quality"), N_("Quality"), IfdId::sony1CsId, SectionId::makerTags, unsignedShort, 1,
1875
     printMinoltaSonyQualityCs},
1876
    {0x0058, "ExposureLevelIncrements", N_("Exposure Level Increments"), N_("Exposure Level Increments"),
1877
     IfdId::sony1CsId, SectionId::makerTags, unsignedShort, 1, EXV_PRINT_TAG(sonyExposureLevelIncrements)},
1878
    // End of list marker
1879
    {0xffff, "(UnknownSony1CsTag)", "(UnknownSony1CsTag)", N_("Unknown Sony1 Camera Settings tag"), IfdId::sony1CsId,
1880
     SectionId::makerTags, unsignedShort, 1, printValue},
1881
};
1882
1883
1.21k
const TagInfo* SonyMakerNote::tagListCs() {
1884
1.21k
  return tagInfoCs_;
1885
1.21k
}
1886
1887
// -- Sony camera settings 2 ---------------------------------------------------------------
1888
1889
// Sony Camera Settings Tag Version 2 Info
1890
// NOTE: for A330, A380, A450, A500, A550 Sony model
1891
1892
// Warnings: Exiftool database give a list of tags shorted in decimal mode, not hexadecimal.
1893
1894
constexpr TagInfo SonyMakerNote::tagInfoCs2_[] = {
1895
    {0x0010, "FocusMode", N_("Focus Mode"), N_("Focus Mode"), IfdId::sony1Cs2Id, SectionId::makerTags, unsignedShort, 1,
1896
     EXV_PRINT_TAG(sonyCSFocusMode)},
1897
    {0x0011, "AFAreaMode", N_("AF Area Mode"), N_("AF Area Mode"), IfdId::sony1Cs2Id, SectionId::makerTags,
1898
     unsignedShort, 1, printMinoltaSonyAFAreaMode},
1899
    {0x0012, "LocalAFAreaPoint", N_("Local AF Area Point"), N_("Local AF Area Point"), IfdId::sony1Cs2Id,
1900
     SectionId::makerTags, unsignedShort, 1, printMinoltaSonyLocalAFAreaPoint},
1901
    {0x0013, "MeteringMode", N_("Metering Mode"), N_("Metering Mode"), IfdId::sony1Cs2Id, SectionId::makerTags,
1902
     unsignedShort, 1, EXV_PRINT_TAG(sonyMeteringMode)},
1903
    {0x0014, "ISOSetting", N_("ISO Setting"), N_("ISO Setting"), IfdId::sony1Cs2Id, SectionId::makerTags, unsignedShort,
1904
     1, printValue},
1905
    {0x0016, "DynamicRangeOptimizerMode", N_("Dynamic Range Optimizer Mode"), N_("Dynamic Range Optimizer Mode"),
1906
     IfdId::sony1Cs2Id, SectionId::makerTags, unsignedShort, 1, printMinoltaSonyDynamicRangeOptimizerMode},
1907
    {0x0017, "DynamicRangeOptimizerLevel", N_("Dynamic Range Optimizer Level"), N_("Dynamic Range Optimizer Level"),
1908
     IfdId::sony1Cs2Id, SectionId::makerTags, unsignedShort, 1, printValue},
1909
    {0x0018, "CreativeStyle", N_("Creative Style"), N_("Creative Style"), IfdId::sony1Cs2Id, SectionId::makerTags,
1910
     unsignedShort, 1, EXV_PRINT_TAG(sonyCreativeStyle)},
1911
    {0x0019, "Sharpness", N_("Sharpness"), N_("Sharpness"), IfdId::sony1Cs2Id, SectionId::makerTags, unsignedShort, 1,
1912
     printValue},
1913
    {0x001A, "Contrast", N_("Contrast"), N_("Contrast"), IfdId::sony1Cs2Id, SectionId::makerTags, unsignedShort, 1,
1914
     printValue},
1915
    {0x001B, "Saturation", N_("Saturation"), N_("Saturation"), IfdId::sony1Cs2Id, SectionId::makerTags, unsignedShort,
1916
     1, printValue},
1917
    {0x0023, "FlashMode", N_("FlashMode"), N_("FlashMode"), IfdId::sony1Cs2Id, SectionId::makerTags, unsignedShort, 1,
1918
     EXV_PRINT_TAG(sonyFlashMode)},
1919
    {0x003C, "ExposureProgram", N_("Exposure Program"), N_("Exposure Program"), IfdId::sony1Cs2Id, SectionId::makerTags,
1920
     unsignedShort, 1, EXV_PRINT_TAG(sonyExposureProgram)},
1921
    {0x003F, "Rotation", N_("Rotation"), N_("Rotation"), IfdId::sony1Cs2Id, SectionId::makerTags, unsignedShort, 1,
1922
     printMinoltaSonyRotation},
1923
    {0x0054, "SonyImageSize", N_("Sony Image Size"), N_("Sony Image Size"), IfdId::sony1Cs2Id, SectionId::makerTags,
1924
     unsignedShort, 1, EXV_PRINT_TAG(sonyImageSize)},
1925
    // End of list marker
1926
    {0xffff, "(UnknownSony1Cs2Tag)", "(UnknownSony1Cs2Tag)", N_("Unknown Sony1 Camera Settings 2 tag"),
1927
     IfdId::sony1Cs2Id, SectionId::makerTags, unsignedShort, 1, printValue},
1928
};
1929
1930
457
const TagInfo* SonyMakerNote::tagListCs2() {
1931
457
  return tagInfoCs2_;
1932
457
}
1933
1934
//! Lookup table to translate Sony2Fp AF Area Mode values to readable labels
1935
constexpr TagDetails sony2FpAFAreaMode[] = {
1936
    {0, N_("Multi")},
1937
    {1, N_("Center")},
1938
    {2, N_("Spot")},
1939
    {3, N_("Flexible Spot")},
1940
    {10, N_("Selective (for Miniature effect)")},
1941
    {11, N_("Zone")},
1942
    {12, N_("Expanded Flexible Spot")},
1943
    {14, N_("Tracking")},
1944
    {15, N_("Face Tracking")},
1945
    {20, N_("Animal Eye Tracking")},
1946
    {255, N_("Manual")},
1947
};
1948
1949
//! Sony Tag 9402 Sony2Fp (FocusPosition)
1950
constexpr TagInfo SonyMakerNote::tagInfoFp_[] = {
1951
    {0x04, "AmbientTemperature", N_("Ambient temperature"), N_("Temperature of the surroundings (in degrees Celsius)"),
1952
     IfdId::sony2FpId, SectionId::makerTags, signedByte, 1, printSony2FpAmbientTemperature},
1953
    {0x16, "FocusMode", N_("Focus mode"), N_("Focus mode"), IfdId::sony2FpId, SectionId::makerTags, unsignedByte, 1,
1954
     printSony2FpFocusMode},
1955
    {0x17, "AFAreaMode", N_("AF area mode"), N_("Auto focus area mode"), IfdId::sony2FpId, SectionId::makerTags,
1956
     unsignedByte, 1, EXV_PRINT_TAG(sony2FpAFAreaMode)},
1957
    {0x2d, "FocusPosition2", N_("Focus position 2"), N_("Focus position 2"), IfdId::sony2FpId, SectionId::makerTags,
1958
     unsignedByte, 1, printSony2FpFocusPosition2},
1959
    // End of list marker
1960
    {0xffff, "(UnknownSony2FpTag)", "(Unknown Sony2Fp tag)", "(Unknown Sony2Fp tag)", IfdId::sony2FpId,
1961
     SectionId::makerTags, unsignedByte, 1, printValue},
1962
};
1963
1964
15.2k
const TagInfo* SonyMakerNote::tagListFp() {
1965
15.2k
  return tagInfoFp_;
1966
15.2k
}
1967
1968
std::ostream& SonyMakerNote::printSony2FpAmbientTemperature(std::ostream& os, const Value& value,
1969
0
                                                            const ExifData* metadata) {
1970
0
  if (value.count() != 1 || !metadata)
1971
0
    return os << "(" << value << ")";
1972
1973
0
  auto pos = metadata->findKey(ExifKey("Exif.Sony2Fp.0x0002"));
1974
0
  if (pos != metadata->end() && pos->count() == 1 && pos->toInt64() == 255)
1975
0
    return os << value << " °C";
1976
1977
0
  return os << N_("n/a");
1978
0
}
1979
1980
0
std::ostream& SonyMakerNote::printSony2FpFocusMode(std::ostream& os, const Value& value, const ExifData*) {
1981
0
  if (value.count() != 1)
1982
0
    os << value;
1983
0
  else {
1984
0
    const auto val = (value.toInt64() & 0x7F);
1985
0
    switch (val) {
1986
0
      case 0:
1987
0
        os << N_("Manual");
1988
0
        break;
1989
0
      case 2:
1990
0
        os << N_("AF-S");
1991
0
        break;
1992
0
      case 3:
1993
0
        os << N_("AF-C");
1994
0
        break;
1995
0
      case 4:
1996
0
        os << N_("AF-A");
1997
0
        break;
1998
0
      case 6:
1999
0
        os << N_("DMF");
2000
0
        break;
2001
0
      default:
2002
0
        os << "(" << val << ")";
2003
0
    }
2004
0
  }
2005
2006
0
  return os;
2007
0
}
2008
2009
std::ostream& SonyMakerNote::printSony2FpFocusPosition2(std::ostream& os, const Value& value,
2010
0
                                                        const ExifData* metadata) {
2011
0
  if (value.count() != 1 || !metadata)
2012
0
    os << "(" << value << ")";
2013
0
  else {
2014
0
    std::string model;
2015
0
    if (!getModel(metadata, model)) {
2016
0
      os << "(" << value << ")";
2017
0
      return os;
2018
0
    }
2019
2020
    // Ranges of models that do not support this tag
2021
0
    for (const auto& m : {"DSC-", "Stellar"}) {
2022
0
      if (model.starts_with(m)) {
2023
0
        os << N_("n/a");
2024
0
        return os;
2025
0
      }
2026
0
    }
2027
0
    const auto val = value.toInt64();
2028
0
    if (val == 255)
2029
0
      os << N_("Infinity");
2030
0
    else
2031
0
      os << val;
2032
0
  }
2033
0
  return os;
2034
0
}
2035
2036
//! Sony Tag 9403 SonyMisc1
2037
constexpr TagInfo SonyMakerNote::tagInfoSonyMisc1_[] = {
2038
    {0x05, "CameraTemperature", N_("Camera temperature"), N_("Internal camera temperature (in degrees Celsius)"),
2039
     IfdId::sonyMisc1Id, SectionId::makerTags, signedByte, -1, printSonyMisc1CameraTemperature},
2040
    // End of list marker
2041
    {0xffff, "(UnknownSonyMisc1Tag)", "(UnknownSonyMisc1Tag)", "(UnknownSonyMisc1Tag)", IfdId::sonyMisc1Id,
2042
     SectionId::makerTags, unsignedByte, -1, printValue},
2043
};
2044
2045
2.91k
const TagInfo* SonyMakerNote::tagListSonyMisc1() {
2046
2.91k
  return tagInfoSonyMisc1_;
2047
2.91k
}
2048
2049
std::ostream& SonyMakerNote::printSonyMisc1CameraTemperature(std::ostream& os, const Value& value,
2050
0
                                                             const ExifData* metadata) {
2051
0
  if (value.count() != 1 || !metadata)
2052
0
    return os << "(" << value << ")";
2053
2054
0
  auto pos = metadata->findKey(ExifKey("Exif.SonyMisc1.0x0004"));
2055
0
  if (pos != metadata->end() && pos->count() == 1 && pos->toInt64() != 0 && pos->toInt64() < 100)
2056
0
    return os << value << " °C";
2057
2058
0
  return os << N_("n/a");
2059
0
}
2060
2061
//! Lookup table to translate Sony Exposure Program 3 values to readable labels
2062
constexpr TagDetails sonyExposureProgram3[] = {
2063
    {0, N_("Program AE")},
2064
    {1, N_("Aperture-priority AE")},
2065
    {2, N_("Shutter speed priority AE")},
2066
    {3, N_("Manual")},
2067
    {4, N_("Auto")},
2068
    {5, N_("iAuto")},
2069
    {6, N_("Superior Auto")},
2070
    {7, N_("iAuto+")},
2071
    {8, N_("Portrait")},
2072
    {9, N_("Landscape")},
2073
    {10, N_("Twilight")},
2074
    {11, N_("Twilight Portrait")},
2075
    {12, N_("Sunset")},
2076
    {14, N_("Action (High speed)")},
2077
    {16, N_("Sports")},
2078
    {17, N_("Handheld Night Shot")},
2079
    {18, N_("Anti Motion Blur")},
2080
    {19, N_("High Sensitivity")},
2081
    {21, N_("Beach")},
2082
    {22, N_("Snow")},
2083
    {23, N_("Fireworks")},
2084
    {26, N_("Underwater")},
2085
    {27, N_("Gourmet")},
2086
    {28, N_("Pet")},
2087
    {29, N_("Macro")},
2088
    {30, N_("Backlight Correction HDR")},
2089
    {33, N_("Sweep Panorama")},
2090
    {36, N_("Background Defocus")},
2091
    {37, N_("Soft Skin")},
2092
    {42, N_("3D Image")},
2093
    {43, N_("Cont. Priority AE")},
2094
    {45, N_("Document")},
2095
    {46, N_("Party")},
2096
};
2097
2098
//! Sony Tag 9404b SonyMisc2b tags
2099
constexpr TagInfo SonyMakerNote::tagInfoSonyMisc2b_[] = {
2100
    {12, "ExposureProgram", N_("Exposure program"), N_("Exposure program"), IfdId::sonyMisc2bId, SectionId::makerTags,
2101
     unsignedByte, -1, EXV_PRINT_TAG(sonyExposureProgram3)},
2102
    {14, "IntelligentAuto", N_("Intelligent auto"), N_("Whether intelligent auto was used"), IfdId::sonyMisc2bId,
2103
     SectionId::makerTags, unsignedByte, -1, printMinoltaSonyBoolValue},
2104
    {30, "LensZoomPosition", N_("Lens zoom position"), N_("Lens zoom position (in %)"), IfdId::sonyMisc2bId,
2105
     SectionId::makerTags, unsignedShort, -1, printSonyMisc2bLensZoomPosition},
2106
    {32, "FocusPosition2", N_("Focus position 2"), N_("Focus position 2"), IfdId::sonyMisc2bId, SectionId::makerTags,
2107
     unsignedByte, -1, printSonyMisc2bFocusPosition2},
2108
    // End of list marker
2109
    {0xffff, "(UnknownSonyMisc2bTag)", "(Unknown SonyMisc2b tag)", "(Unknown SonyMisc2b tag)", IfdId::sonyMisc2bId,
2110
     SectionId::makerTags, unsignedByte, -1, printValue},
2111
};
2112
2113
201
const TagInfo* SonyMakerNote::tagListSonyMisc2b() {
2114
201
  return tagInfoSonyMisc2b_;
2115
201
}
2116
2117
std::ostream& SonyMakerNote::printSonyMisc2bLensZoomPosition(std::ostream& os, const Value& value,
2118
0
                                                             const ExifData* metadata) {
2119
0
  if (value.count() != 1 || !metadata)
2120
0
    return os << "(" << value << ")";
2121
2122
0
  std::string model;
2123
0
  if (!getModel(metadata, model))
2124
0
    return os << "(" << value << ")";
2125
2126
  // Models that do not support this tag
2127
0
  for (auto m : {"SLT-", "HV", "ILCA-"})
2128
0
    if (Internal::contains(model, m))
2129
0
      return os << N_("n/a");
2130
2131
0
  return os << stringFormat("{}%", std::lround(value.toInt64() / 10.24));
2132
0
}
2133
2134
std::ostream& SonyMakerNote::printSonyMisc2bFocusPosition2(std::ostream& os, const Value& value,
2135
0
                                                           const ExifData* metadata) {
2136
0
  if (value.count() != 1 || !metadata)
2137
0
    return os << "(" << value << ")";
2138
2139
0
  std::string model;
2140
0
  if (!getModel(metadata, model))
2141
0
    return os << "(" << value << ")";
2142
2143
  // Models that do not support this tag
2144
0
  for (auto m : {"SLT-", "HV", "ILCA-"})
2145
0
    if (Internal::contains(model, m))
2146
0
      return os << N_("n/a");
2147
2148
0
  return os << value;
2149
0
}
2150
2151
//! Lookup table to translate Sony camera SonyMisc3c sequence length 1 values to readable labels
2152
constexpr TagDetails sonyMisc3cSequenceLength1[] = {
2153
    {0, N_("Continuous")},
2154
    {1, N_("1 shot")},
2155
    {2, N_("2 shots")},
2156
    {3, N_("3 shots")},
2157
    {4, N_("4 shots")},
2158
    {5, N_("5 shots")},
2159
    {6, N_("6 shots")},
2160
    {7, N_("7 shots")},
2161
    {9, N_("9 shots")},
2162
    {10, N_("10 shots")},
2163
    {12, N_("12 shots")},
2164
    {16, N_("16 shots")},
2165
    {100, N_("Continuous - iSweep Panorama")},
2166
    {200, N_("Continuous - Sweep Panorama")},
2167
};
2168
2169
//! Lookup table to translate Sony camera SonyMisc3c sequence length 2 values to readable labels
2170
constexpr TagDetails sonyMisc3cSequenceLength2[] = {
2171
    {0, N_("Continuous")}, {1, N_("1 file")},  {2, N_("2 files")}, {3, N_("3 files")},
2172
    {5, N_("5 files")},    {7, N_("7 files")}, {9, N_("9 files")}, {10, N_("10 files")},
2173
};
2174
2175
//! Lookup table to translate Sony camera SonyMisc3c, camera orientation values to readable labels
2176
constexpr TagDetails sonyMisc3cCameraOrientation[] = {
2177
    {1, N_("Horizontal (normal)")},
2178
    {3, N_("Rotate 180°")},
2179
    {6, N_("Rotate 90° CW")},
2180
    {8, N_("Rotate 270° CW")},
2181
};
2182
2183
//! Lookup table to translate SonyMisc3c Quality2 (a) values to readable labels
2184
constexpr TagDetails sonyMisc3cQuality2a[] = {
2185
    {1, "JPEG"}, {2, "Raw"}, {3, "Raw + JPEG"}, {4, "HEIF"}, {6, "Raw + HEIF"},
2186
};
2187
2188
//! Lookup table to translate SonyMisc3c Quality2 (b) values to readable labels
2189
constexpr TagDetails sonyMisc3cQuality2b[] = {
2190
    {0, "JPEG"},
2191
    {1, "Raw"},
2192
    {2, "Raw + JPEG"},
2193
    {3, "Raw + MPO"},
2194
};
2195
2196
//! SonyMisc3c tags (Tag 9400c)
2197
constexpr TagInfo SonyMakerNote::tagInfoSonyMisc3c_[] = {
2198
    {9, "ReleaseMode2", N_("Release mode 2"), N_("Release mode 2"), IfdId::sonyMisc3cId, SectionId::makerTags,
2199
     unsignedByte, -1, EXV_PRINT_TAG(sonyReleaseMode2)},
2200
    {10, "ShotNumberSincePowerUp", N_("Shot number since power up"),
2201
     N_("Number of photos taken since the camera was powered up"), IfdId::sonyMisc3cId, SectionId::makerTags,
2202
     unsignedLong, -1, printSonyMisc3cShotNumberSincePowerUp},
2203
    {18, "SequenceImageNumber", N_("Sequence image number"), N_("Number of images captured in burst sequence"),
2204
     IfdId::sonyMisc3cId, SectionId::makerTags, unsignedLong, -1, printSonyMisc3cSequenceNumber},
2205
    // In Exiftool, "SequenceLength1" is called "SequenceLength (22). Renamed due to clash of names."
2206
    {22, "SequenceLength1", N_("Sequence length 1"), N_("Length of the sequence of photos taken"), IfdId::sonyMisc3cId,
2207
     SectionId::makerTags, unsignedByte, -1, EXV_PRINT_TAG(sonyMisc3cSequenceLength1)},
2208
    {26, "SequenceFileNumber", N_("Sequence file number"), N_("File number in burst sequence"), IfdId::sonyMisc3cId,
2209
     SectionId::makerTags, unsignedLong, -1, printSonyMisc3cSequenceNumber},
2210
    // In Exiftool, "SequenceLength2" is called "SequenceLength" (30). Renamed due to clash of names."
2211
    {30, "SequenceLength2", N_("Sequence length 2"), N_("Length of the sequence of photos taken"), IfdId::sonyMisc3cId,
2212
     SectionId::makerTags, unsignedByte, -1, EXV_PRINT_TAG(sonyMisc3cSequenceLength2)},
2213
    {41, "CameraOrientation", N_("Camera orientation"), N_("Orientation of the camera when the photo was taken"),
2214
     IfdId::sonyMisc3cId, SectionId::makerTags, unsignedByte, -1, EXV_PRINT_TAG(sonyMisc3cCameraOrientation)},
2215
    {42, "Quality2", N_("Quality 2"), N_("Quality 2"), IfdId::sonyMisc3cId, SectionId::makerTags, unsignedByte, -1,
2216
     printSonyMisc3cQuality2},
2217
    {71, "SonyImageHeight", N_("Sony image height"), N_("Height of the image"), IfdId::sonyMisc3cId,
2218
     SectionId::makerTags, unsignedShort, -1, printSonyMisc3cSonyImageHeight},
2219
    {83, "ModelReleaseYear", N_("Model release year"), N_("Year that the model of camera was released"),
2220
     IfdId::sonyMisc3cId, SectionId::makerTags, unsignedByte, -1, printSonyMisc3cModelReleaseYear},
2221
    // End of list marker
2222
    {0xffff, "(UnknownSonyMisc3c)", "(Unknown SonyMisc3c Tag)", N_("Unknown SonyMisc23 tag"), IfdId::sonyMisc3cId,
2223
     SectionId::makerTags, asciiString, -1, printValue},
2224
};
2225
2226
1.22k
const TagInfo* SonyMakerNote::tagListSonyMisc3c() {
2227
1.22k
  return tagInfoSonyMisc3c_;
2228
1.22k
}
2229
2230
std::ostream& SonyMakerNote::printSonyMisc3cShotNumberSincePowerUp(std::ostream& os, const Value& value,
2231
0
                                                                   const ExifData* metadata) {
2232
0
  if (value.count() != 1 || value.typeId() != unsignedLong || !metadata)
2233
0
    return os << "(" << value << ")";
2234
2235
0
  std::string model;
2236
0
  if (!getModel(metadata, model)) {
2237
0
    os << "(" << value << ")";
2238
0
    return os;
2239
0
  }
2240
2241
  // Tag only valid for certain camera models. See
2242
  // https://github.com/exiftool/exiftool/blob/7368629751669ba170511419b3d1e05bf0076d0e/lib/Image/ExifTool/Sony.pm#L8170
2243
0
  static constexpr const char* models[] = {
2244
0
      "ILCA-68",     "ILCA-77M2",   "ILCA-99M2",   "ILCE-5000",  "ILCE-5100", "ILCE-6000",  "ILCE-6300",
2245
0
      "ILCE-6500",   "ILCE-7",      "ILCE-7M2",    "ILCE-7R",    "ILCE-7RM2", "ILCE-7S",    "ILCE-7SM2",
2246
0
      "ILCE-7SM5",   "ILCE-QX1",    "DSC-HX350",   "DSC-HX400V", "DSC-HX60V", "DSC-HX80",   "DSC-HX90",
2247
0
      "DSC-HX90V",   "DSC-QX30",    "DSC-RX0",     "DSC-RX1RM2", "DSC-RX10",  "DSC-RX10M2", "DSC-RX10M3",
2248
0
      "DSC-RX100M3", "DSC-RX100M4", "DSC-RX100M5", "DSC-WX220",  "DSC-WX350", "DSC-WX500",
2249
0
  };
2250
2251
0
  if (Exiv2::find(models, model)) {
2252
0
    return os << value.toInt64();
2253
0
  }
2254
0
  return os << N_("n/a");
2255
0
}
2256
2257
0
std::ostream& SonyMakerNote::printSonyMisc3cSequenceNumber(std::ostream& os, const Value& value, const ExifData*) {
2258
0
  return (value.count() != 1 || value.typeId() != unsignedLong) ? os << "(" << value << ")"
2259
0
                                                                : os << (value.toInt64() + 1);
2260
0
}
2261
2262
0
std::ostream& SonyMakerNote::printSonyMisc3cQuality2(std::ostream& os, const Value& value, const ExifData* metadata) {
2263
0
  if (value.count() != 1 || value.typeId() != unsignedByte || !metadata)
2264
0
    return os << "(" << value << ")";
2265
2266
0
  std::string model;
2267
0
  if (!getModel(metadata, model)) {
2268
0
    os << "(" << value << ")";
2269
0
    return os;
2270
0
  }
2271
2272
0
  const auto val = value.toInt64();
2273
2274
  // Tag only valid for certain camera models. See
2275
  // https://github.com/exiftool/exiftool/blob/7368629751669ba170511419b3d1e05bf0076d0e/lib/Image/ExifTool/Sony.pm#L8219
2276
0
  constexpr const char* models[] = {"ILCE-1", "ILCE-7M4", "ILCE-7RM5", "ILCE-7SM3", "ILME-FX3"};
2277
2278
0
  if (Exiv2::find(models, model)) {
2279
0
    EXV_PRINT_TAG(sonyMisc3cQuality2a)(os, val, metadata);
2280
0
    return os;
2281
0
  }
2282
2283
0
  return EXV_PRINT_TAG(sonyMisc3cQuality2b)(os, val, metadata);
2284
0
}
2285
2286
std::ostream& SonyMakerNote::printSonyMisc3cSonyImageHeight(std::ostream& os, const Value& value,
2287
0
                                                            const ExifData* metadata) {
2288
0
  if (value.count() != 1 || value.typeId() != unsignedShort || !metadata)
2289
0
    return os << "(" << value << ")";
2290
2291
0
  std::string model;
2292
0
  if (!getModel(metadata, model)) {
2293
0
    os << "(" << value << ")";
2294
0
    return os;
2295
0
  }
2296
2297
  // Tag only valid for certain camera models. See
2298
  // https://github.com/exiftool/exiftool/blob/7368629751669ba170511419b3d1e05bf0076d0e/lib/Image/ExifTool/Sony.pm#L8239
2299
0
  constexpr const char* models[] = {"ILCE-1", "ILCE-7M4", "ILCE-7RM5", "ILCE-7SM3", "ILME-FX3"};
2300
2301
0
  if (Exiv2::find(models, model)) {
2302
0
    return os << N_("n/a");
2303
0
  }
2304
0
  const auto val = value.toInt64();
2305
2306
0
  return val > 0 ? os << (8 * val) : os << N_("n/a");
2307
0
}
2308
2309
std::ostream& SonyMakerNote::printSonyMisc3cModelReleaseYear(std::ostream& os, const Value& value,
2310
0
                                                             const ExifData* metadata) {
2311
0
  if (value.count() != 1 || value.typeId() != unsignedByte || !metadata)
2312
0
    return os << "(" << value << ")";
2313
2314
0
  std::string model;
2315
0
  if (!getModel(metadata, model)) {
2316
0
    os << "(" << value << ")";
2317
0
    return os;
2318
0
  }
2319
2320
  // Tag only valid for certain camera models. See
2321
  // https://github.com/exiftool/exiftool/blob/7368629751669ba170511419b3d1e05bf0076d0e/lib/Image/ExifTool/Sony.pm#L8245
2322
0
  constexpr const char* models[] = {"ILCE-1", "ILCE-7M4", "ILCE-7RM5", "ILCE-7SM3", "ILME-FX3"};
2323
2324
0
  if (Exiv2::find(models, model)) {
2325
0
    return os << N_("n/a");
2326
0
  }
2327
2328
0
  const auto val = value.toInt64();
2329
0
  if (val > 99)
2330
0
    return os << "(" << val << ")";
2331
2332
0
  if (val == 0)
2333
0
    return os << "2000";
2334
2335
0
  return os << "20" << val;
2336
0
}
2337
2338
//! Sony SInfo1 tags (ShotInfo - Tag 3000)
2339
constexpr TagInfo SonyMakerNote::tagInfoSonySInfo1_[] = {
2340
    // TODO: As "FaceInfo1" (72) and "FaceInfo2" (94) are not added, including
2341
    //       "FaceInfoOffset" (2) and "FaceInfoLength" (50) does not make sense.
2342
    //       The values are all connected and changing one without the rest will
2343
    //       corrupt the data.
2344
    {6, "SonyDateTime", N_("Sony date/time"), N_("Date and time when the photo was captured"), IfdId::sonySInfo1Id,
2345
     SectionId::makerTags, asciiString, -1, printValue},
2346
    {26, "SonyImageHeight", N_("Sony image height"), N_("Height of the image"), IfdId::sonySInfo1Id,
2347
     SectionId::makerTags, unsignedShort, -1, printValue},
2348
    {28, "SonyImageWidth", N_("Sony image width"), N_("Width of the image"), IfdId::sonySInfo1Id, SectionId::makerTags,
2349
     unsignedShort, -1, printValue},
2350
    {48, "FacesDetected", N_("Faces detected"), N_("Number of faces detected in the image"), IfdId::sonySInfo1Id,
2351
     SectionId::makerTags, unsignedShort, -1, printValue},
2352
    {52, "MetaVersion", N_("Meta version"), N_("Sony meta version"), IfdId::sonySInfo1Id, SectionId::makerTags,
2353
     asciiString, -1, printValue},
2354
    // TODO: Add FaceInfo1 (72) and FaceInfo2 (94) which are sub-groups of tags.
2355
    // End of list marker
2356
    {0xffff, "(UnknownsonySInfo1Tag)", "(Unknown SonySInfo1 Tag)", "(Unknown SonySInfo1 Tag)", IfdId::sonySInfo1Id,
2357
     SectionId::makerTags, unsignedByte, -1, printValue},
2358
};
2359
2360
1.50M
const TagInfo* SonyMakerNote::tagListSonySInfo1() {
2361
1.50M
  return tagInfoSonySInfo1_;
2362
1.50M
}
2363
2364
//! Sony Tag 2010 Sony2010 (Miscellaneous)
2365
constexpr TagInfo SonyMakerNote::tagInfo2010e_[] = {
2366
    {0, "SequenceImageNumber", N_("Sequence Image Number"), N_("Sequence Image Number"), IfdId::sony2010eId,
2367
     SectionId::makerTags, unsignedLong, 1, printValue},
2368
    {4, "SequenceFileNumber", N_("SequenceFileNumber"), N_("SequenceFileNumber"), IfdId::sony2010eId,
2369
     SectionId::makerTags, unsignedLong, 1, printValue},
2370
    {8, "ReleaseMode2", N_("ReleaseMode2"), N_("ReleaseMode2"), IfdId::sony2010eId, SectionId::makerTags, unsignedLong,
2371
     1, printValue},
2372
    {540, "DigitalZoomRatio", N_("DigitalZoomRatio"), N_("DigitalZoomRatio"), IfdId::sony2010eId, SectionId::makerTags,
2373
     unsignedByte, 1, printValue},
2374
    {556, "SonyDateTime", N_("SonyDateTime"), N_("SonyDateTime"), IfdId::sony2010eId, SectionId::makerTags, undefined,
2375
     1, printValue},
2376
    {808, "DynamicRangeOptimizer", N_("DynamicRangeOptimizer"), N_("DynamicRangeOptimizer"), IfdId::sony2010eId,
2377
     SectionId::makerTags, unsignedByte, 1, printValue},
2378
    {1208, "MeterInfo", N_("MeterInfo"), N_("MeterInfo"), IfdId::sony2010eId, SectionId::makerTags, undefined, 1,
2379
     printValue},
2380
    {4444, "ReleaseMode3", N_("ReleaseMode3"), N_("ReleaseMode3"), IfdId::sony2010eId, SectionId::makerTags,
2381
     unsignedByte, 1, printValue},
2382
    {4448, "ReleaseMode4", N_("ReleaseMode4"), N_("ReleaseMode4"), IfdId::sony2010eId, SectionId::makerTags,
2383
     unsignedByte, 1, printValue},
2384
    {4456, "SelfTimer", N_("SelfTimer"), N_("SelfTimer"), IfdId::sony2010eId, SectionId::makerTags, unsignedByte, 1,
2385
     printValue},
2386
    {4460, "FlashMode", N_("FlashMode"), N_("FlashMode"), IfdId::sony2010eId, SectionId::makerTags, unsignedByte, 1,
2387
     printValue},
2388
    {4466, "StopsAboveBaseISO", N_("StopsAboveBaseISO"), N_("StopsAboveBaseISO"), IfdId::sony2010eId,
2389
     SectionId::makerTags, unsignedShort, 1, printValue},
2390
    {4468, "BrightnessValue", N_("BrightnessValue"), N_("BrightnessValue"), IfdId::sony2010eId, SectionId::makerTags,
2391
     unsignedShort, 1, printValue},
2392
    {4472, "DynamicRangeOptimizer2", N_("DynamicRangeOptimizer 2"), N_("DynamicRangeOptimizer 2"), IfdId::sony2010eId,
2393
     SectionId::makerTags, unsignedByte, 1, printValue},
2394
    {4476, "HDRSetting", N_("HDRSetting"), N_("HDRSetting"), IfdId::sony2010eId, SectionId::makerTags, unsignedByte, 1,
2395
     printValue},
2396
    {4480, "ExposureCompensation", N_("ExposureCompensation"), N_("ExposureCompensation"), IfdId::sony2010eId,
2397
     SectionId::makerTags, signedShort, 1, printValue},
2398
    {4502, "PictureProfile", N_("PictureProfile"), N_("PictureProfile"), IfdId::sony2010eId, SectionId::makerTags,
2399
     unsignedByte, 1, printValue},
2400
    {4503, "PictureProfile2", N_("PictureProfile2"), N_("PictureProfile2"), IfdId::sony2010eId, SectionId::makerTags,
2401
     unsignedByte, 1, printValue},
2402
    {4507, "PictureEffect2", N_("PictureEffect2"), N_("PictureEffect2"), IfdId::sony2010eId, SectionId::makerTags,
2403
     unsignedByte, 1, printValue},
2404
    {4520, "Quality2", N_("Quality2"), N_("Quality2"), IfdId::sony2010eId, SectionId::makerTags, unsignedByte, 1,
2405
     printValue},
2406
    {4524, "MeteringMode", N_("MeteringMode"), N_("MeteringMode"), IfdId::sony2010eId, SectionId::makerTags,
2407
     unsignedByte, 1, printValue},
2408
    {4525, "ExposureProgram", N_("ExposureProgram"), N_("ExposureProgram"), IfdId::sony2010eId, SectionId::makerTags,
2409
     unsignedByte, 1, printValue},
2410
    {4532, "WB_RGBLevels", N_("WB_RGBLevels"), N_("WB_RGBLevels"), IfdId::sony2010eId, SectionId::makerTags,
2411
     unsignedShort, 3, printValue},
2412
    {4692, "SonyISO", N_("SonyISO"), N_("SonyISO"), IfdId::sony2010eId, SectionId::makerTags, unsignedShort, 1,
2413
     printValue},
2414
    {4696, "SonyISO2", N_("SonyISO2"), N_("SonyISO2"), IfdId::sony2010eId, SectionId::makerTags, unsignedShort, 1,
2415
     printValue},
2416
    {4728, "FocalLength", N_("FocalLength"), N_("FocalLength"), IfdId::sony2010eId, SectionId::makerTags, unsignedShort,
2417
     1, printValue},
2418
    {4730, "MinFocalLength", N_("MinFocalLength"), N_("MinFocalLength"), IfdId::sony2010eId, SectionId::makerTags,
2419
     unsignedShort, 1, printValue},
2420
    {4732, "MaxFocalLength", N_("MaxFocalLength"), N_("MaxFocalLength"), IfdId::sony2010eId, SectionId::makerTags,
2421
     unsignedShort, 1, printValue},
2422
    {4736, "SonyISO3", N_("SonyISO3"), N_("SonyISO3"), IfdId::sony2010eId, SectionId::makerTags, unsignedShort, 1,
2423
     printValue},
2424
    {6256, "DistortionCorrParams", N_("DistortionCorrParams"), N_("DistortionCorrParams"), IfdId::sony2010eId,
2425
     SectionId::makerTags, signedShort, 16, printValue},
2426
    {6289, "LensFormat", N_("LensFormat"), N_("LensFormat"), IfdId::sony2010eId, SectionId::makerTags, unsignedByte, 1,
2427
     printValue},
2428
    {6290, "LensMount", N_("LensMount"), N_("LensMount"), IfdId::sony2010eId, SectionId::makerTags, unsignedByte, 1,
2429
     printValue},
2430
    {6291, "LensType2", N_("LensType2"), N_("LensType2"), IfdId::sony2010eId, SectionId::makerTags, unsignedShort, 1,
2431
     printValue},
2432
    {6294, "LensType", N_("LensType"), N_("LensType"), IfdId::sony2010eId, SectionId::makerTags, unsignedShort, 1,
2433
     printValue},
2434
    {6296, "DistortionCorrParamsPresent", N_("DistortionCorrParamsPresent"), N_("DistortionCorrParamsPresent"),
2435
     IfdId::sony2010eId, SectionId::makerTags, unsignedByte, 1, printValue},
2436
    {6297, "DistortionCorrParamsNumber", N_("DistortionCorrParamsNumber"), N_("DistortionCorrParamsNumber"),
2437
     IfdId::sony2010eId, SectionId::makerTags, unsignedByte, 1, printValue},
2438
    // End of list marker
2439
    {0xffff, "(UnknownSony2010eTag)", "(UnknownSony2010eTag)", "(UnknownSony2010eTag)", IfdId::sony2010eId,
2440
     SectionId::makerTags, unsignedByte, 1, printValue},
2441
};
2442
2443
0
const TagInfo* SonyMakerNote::tagList2010e() {
2444
0
  return tagInfo2010e_;
2445
0
}
2446
2447
// https://github.com/Exiv2/exiv2/pull/906#issuecomment-504338797
2448
static DataBuf sonyTagCipher(uint16_t /* tag */, const byte* bytes, size_t size, const TiffComponent* /*object*/,
2449
388
                             bool bDecipher) {
2450
388
  DataBuf b(bytes, size);  // copy the data
2451
2452
  // initialize the code table
2453
388
  byte code[256];
2454
97.0k
  for (uint32_t i = 0; i < 249; i++) {
2455
96.6k
    if (bDecipher) {
2456
69.4k
      code[(i * i * i) % 249] = static_cast<byte>(i);
2457
69.4k
    } else {
2458
27.1k
      code[i] = (i * i * i) % 249;
2459
27.1k
    }
2460
96.6k
  }
2461
3.10k
  for (uint32_t i = 249; i < 256; i++) {
2462
2.71k
    code[i] = static_cast<byte>(i);
2463
2.71k
  }
2464
2465
  // code byte-by-byte
2466
57.1k
  for (uint32_t i = 0; i < size; i++) {
2467
56.7k
    b.write_uint8(i, code[bytes[i]]);
2468
56.7k
  }
2469
2470
388
  return b;
2471
388
}
2472
2473
279
DataBuf sonyTagDecipher(uint16_t tag, const byte* bytes, size_t size, TiffComponent* object) {
2474
279
  return sonyTagCipher(tag, bytes, size, object, true);
2475
279
}
2476
109
DataBuf sonyTagEncipher(uint16_t tag, const byte* bytes, size_t size, TiffComponent* object) {
2477
109
  return sonyTagCipher(tag, bytes, size, object, false);
2478
109
}
2479
2480
}  // namespace Exiv2::Internal