Coverage Report

Created: 2025-11-24 06:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libexif/libexif/pentax/mnote-pentax-entry.c
Line
Count
Source
1
/* mnote-pentax-entry.c
2
 *
3
 * Copyright (c) 2002 Lutz Mueller <lutz@users.sourceforge.net>
4
 *
5
 * This library is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU Lesser General Public
7
 * License as published by the Free Software Foundation; either
8
 * version 2 of the License, or (at your option) any later version.
9
 *
10
 * This library is distributed in the hope that it will be useful, 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 * Lesser General Public License for more details. 
14
 *
15
 * You should have received a copy of the GNU Lesser General Public
16
 * License along with this library; if not, write to the
17
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18
 * Boston, MA  02110-1301  USA.
19
 *
20
 * SPDX-License-Identifier: LGPL-2.0-or-later
21
 */
22
23
#include <config.h>
24
#include "mnote-pentax-entry.h"
25
26
#include <libexif/i18n.h>
27
28
#include <stdio.h>
29
#include <stdlib.h>
30
#include <string.h>
31
32
#include <libexif/exif-format.h>
33
#include <libexif/exif-utils.h>
34
#include <libexif/exif-entry.h>
35
36
37
10.3k
#define CF(format,target,v,maxlen)                              \
38
10.3k
{                                                               \
39
10.3k
  if (format != target) {                                 \
40
4.84k
    snprintf (v, maxlen,                          \
41
4.84k
      _("Invalid format '%s', "               \
42
4.84k
      "expected '%s'."),                      \
43
4.84k
      exif_format_get_name (format),          \
44
4.84k
      exif_format_get_name (target));         \
45
4.84k
    break;                                          \
46
4.84k
  }                                                       \
47
10.3k
}
48
49
1.02k
#define CC(number,target,v,maxlen)                                      \
50
1.02k
{                                                                       \
51
1.02k
  if (number != target) {                                         \
52
383
    snprintf (v, maxlen,                                    \
53
383
      _("Invalid number of components (%i, "          \
54
383
      "expected %i)."), (int) number, (int) target);  \
55
383
    break;                                                  \
56
383
  }                                                               \
57
1.02k
}
58
59
4.46k
#define CC2(number,t1,t2,v,maxlen)                                      \
60
4.46k
{                                                                       \
61
4.46k
  if ((number != t1) && (number != t2)) {                         \
62
358
    snprintf (v, maxlen,                                    \
63
358
      _("Invalid number of components (%i, "          \
64
358
      "expected %i or %i)."), (int) number,   \
65
358
      (int) t1, (int) t2);          \
66
358
    break;                                                  \
67
358
  }                                                               \
68
4.46k
}
69
70
static const struct {
71
  MnotePentaxTag tag;
72
  struct {
73
    int index;
74
    const char *string;
75
  } elem[33];
76
} items[] = {
77
#ifndef NO_VERBOSE_TAG_DATA
78
  { MNOTE_PENTAX_TAG_MODE,
79
    { {0, N_("Auto")},
80
      {1, N_("Night scene")},
81
      {2, N_("Manual")},
82
      {4, N_("Multi-exposure")},
83
      {0, NULL}}},
84
  { MNOTE_PENTAX_TAG_QUALITY,
85
    { {0, N_("Good")},
86
      {1, N_("Better")},
87
      {2, N_("Best")},{0,NULL}}},
88
  { MNOTE_PENTAX_TAG_FOCUS,
89
    { {2, N_("Custom")},
90
      {3, N_("Auto")},
91
      {0, NULL}}},
92
  { MNOTE_PENTAX_TAG_FLASH,
93
    { {1, N_("Auto")},
94
      {2, N_("Flash on")},
95
      {4, N_("Flash off")},
96
      {6, N_("Red-eye reduction")},
97
      {0, NULL}}},
98
  { MNOTE_PENTAX_TAG_WHITE_BALANCE,
99
    { {0, N_("Auto")},
100
      {1, N_("Daylight")},
101
      {2, N_("Shade")},
102
      {3, N_("Tungsten")},
103
      {4, N_("Fluorescent")},
104
      {5, N_("Manual")},
105
      {0, NULL}}},
106
  { MNOTE_PENTAX_TAG_SHARPNESS,
107
    { {0, N_("Normal")},
108
      {1, N_("Soft")},
109
      {2, N_("Hard")},
110
      {0, NULL}}},
111
  { MNOTE_PENTAX_TAG_CONTRAST,
112
    { {0, N_("Normal")},
113
      {1, N_("Low")},
114
      {2, N_("High")},
115
      {0, NULL}}},
116
  { MNOTE_PENTAX_TAG_SATURATION,
117
    { {0, N_("Normal")},
118
      {1, N_("Low")},
119
      {2, N_("High")},
120
      {0, NULL}}},
121
  { MNOTE_PENTAX_TAG_ISO_SPEED,
122
    { {10,  N_("100")},
123
      {16,  N_("200")},
124
      {100, N_("100")},
125
      {200, N_("200")},
126
      { 0,  NULL}}},
127
  { MNOTE_PENTAX_TAG_COLOR,
128
    { {1, N_("Full")},
129
      {2, N_("Black & white")},
130
      {3, N_("Sepia")},
131
      {0, NULL}}},
132
  { MNOTE_PENTAX2_TAG_MODE,
133
    { {0, N_("Auto")},
134
      {1, N_("Night scene")},
135
      {2, N_("Manual")},
136
      {4, N_("Multi-exposure")},
137
      {0, NULL}}},
138
  { MNOTE_PENTAX2_TAG_QUALITY,
139
    { {0, N_("Good")},
140
      {1, N_("Better")},
141
      {2, N_("Best")},
142
      {3, N_("TIFF")},
143
      {4, N_("RAW")},
144
      {0, NULL}}},
145
  { MNOTE_PENTAX2_TAG_IMAGE_SIZE,
146
    { {0, "640x480"},
147
      {1, N_("Full")},
148
      {2, "1024x768"},
149
      {3, "1280x960"},
150
      {4, "1600x1200"},
151
      {5, "2048x1536"},
152
      {8, N_("2560x1920 or 2304x1728")},
153
      {9, "3072x2304"},
154
      {10, "3264x2448"},
155
      {19, "320x240"},
156
      {20, "2288x1712"},
157
      {21, "2592x1944"},
158
      {22, N_("2304x1728 or 2592x1944")},
159
      {23, "3056x2296"},
160
      {25, N_("2816x2212 or 2816x2112")},
161
      {27, "3648x2736"},
162
      {36, "3008x2008"},
163
      {0, NULL}}},
164
  { MNOTE_PENTAX2_TAG_PICTURE_MODE,
165
    { {0, N_("Program")},
166
      {2, N_("Program AE")},
167
      {3, N_("Manual")},
168
      {5, N_("Portrait")},
169
      {6, N_("Landscape")},
170
      {8, N_("Sport")},
171
      {9, N_("Night scene")},
172
      {11, N_("Soft")},
173
      {12, N_("Surf & snow")},
174
      {13, N_("Sunset or candlelight")},
175
      {14, N_("Autumn")},
176
      {15, N_("Macro")},
177
      {17, N_("Fireworks")},
178
      {18, N_("Text")},
179
      {19, N_("Panorama")},
180
      {30, N_("Self portrait")},
181
      {31, N_("Illustrations")},
182
      {33, N_("Digital filter")},
183
      {37, N_("Museum")},
184
      {38, N_("Food")},
185
      {40, N_("Green mode")},
186
      {49, N_("Light pet")},
187
      {50, N_("Dark pet")},
188
      {51, N_("Medium pet")},
189
      {53, N_("Underwater")},
190
      {54, N_("Candlelight")},
191
      {55, N_("Natural skin tone")},
192
      {56, N_("Synchro sound record")},
193
      {58, N_("Frame composite")},
194
      {0, NULL}}},
195
  { MNOTE_PENTAX2_TAG_FLASH_MODE,
196
    { {0x0000, N_("Auto, did not fire")},
197
      {0x0001, N_("Off")},
198
      {0x0003, N_("Auto, did not fire, red-eye reduction")},
199
      {0x0100, N_("Auto, fired")},
200
      {0x0102, N_("On")},
201
      {0x0103, N_("Auto, fired, red-eye reduction")},
202
      {0x0104, N_("On, red-eye reduction")},
203
      {0x0105, N_("On, wireless")},
204
      {0x0108, N_("On, soft")},
205
      {0x0109, N_("On, slow-sync")},
206
      {0x010a, N_("On, slow-sync, red-eye reduction")},
207
      {0x010b, N_("On, trailing-curtain sync")},
208
      {0, NULL}}},
209
  { MNOTE_PENTAX2_TAG_FOCUS_MODE,
210
    { {0, N_("Normal")},
211
      {1, N_("Macro")},
212
      {2, N_("Infinity")},
213
      {3, N_("Manual")},
214
      {5, N_("Pan focus")},
215
      {16, N_("AF-S")},
216
      {17, N_("AF-C")},
217
      {0, NULL}}},
218
  { MNOTE_PENTAX2_TAG_AFPOINT_SELECTED,
219
    { {1, N_("Upper-left")},
220
      {2, N_("Top")},
221
      {3, N_("Upper-right")},
222
      {4, N_("Left")},
223
      {5, N_("Mid-left")},
224
      {6, N_("Center")},
225
      {7, N_("Mid-right")},
226
      {8, N_("Right")},
227
      {9, N_("Lower-left")},
228
      {10, N_("Bottom")},
229
      {11, N_("Lower-right")},
230
      {0xfffe, N_("Fixed center")},
231
      {0xffff, N_("Auto")},
232
      {0, NULL}}},
233
  { MNOTE_PENTAX2_TAG_AUTO_AFPOINT,
234
    { {0, N_("Multiple")},
235
      {1, N_("Top-left")},
236
      {2, N_("Top-center")},
237
      {3, N_("Top-right")},
238
      {4, N_("Left")},
239
      {5, N_("Center")},
240
      {6, N_("Right")},
241
      {7, N_("Bottom-left")},
242
      {8, N_("Bottom-center")},
243
      {9, N_("Bottom-right")},
244
      {0xffff, N_("None")},
245
      {0, NULL}}},
246
  { MNOTE_PENTAX2_TAG_WHITE_BALANCE,
247
    { {0, N_("Auto")},
248
      {1, N_("Daylight")},
249
      {2, N_("Shade")},
250
      {3, N_("Fluorescent")},
251
      {4, N_("Tungsten")},
252
      {5, N_("Manual")},
253
      {6, N_("Daylight fluorescent")},
254
      {7, N_("Day white fluorescent")},
255
      {8, N_("White fluorescent")},
256
      {9, N_("Flash")},
257
      {10, N_("Cloudy")},
258
      {0xfffe, N_("Unknown")},
259
      {0xffff, N_("User selected")},
260
      {0, NULL}}},
261
  {MNOTE_CASIO2_TAG_BESTSHOT_MODE, 
262
    { {0, N_("Off")},
263
      {1, N_("On")},
264
      {0, NULL}}},
265
#endif
266
  {0, {{0, NULL}}}
267
};
268
269
/* Two-component values */
270
static const struct {
271
  MnotePentaxTag tag;
272
  struct {
273
    int index1, index2;
274
    const char *string;
275
  } elem[39];
276
} items2[] = {
277
#ifndef NO_VERBOSE_TAG_DATA
278
  { MNOTE_PENTAX2_TAG_IMAGE_SIZE,
279
    { {0, 0, "2304x1728"},
280
      {4, 0, "1600x1200"},
281
      {5, 0, "2048x1536"},
282
      {8, 0, "2560x1920"},
283
      {34, 0, "1536x1024"},
284
      {36, 0, N_("3008x2008 or 3040x2024")},
285
      {37, 0, "3008x2000"},
286
      {35, 1, "2400x1600"},
287
      {32, 2, "960x480"},
288
      {33, 2, "1152x768"},
289
      {34, 2, "1536x1024"},
290
      {0,  0, NULL}}},
291
  { MNOTE_PENTAX2_TAG_PICTURE_MODE,
292
    { {0,   0, N_("Auto")},
293
      {5,   0, N_("Portrait")},
294
      {53,  0, N_("Underwater")},
295
      {255, 0, N_("Digital filter?")},
296
      {5,   1, N_("Portrait")},
297
      {9,   1, N_("Night scene")},
298
      {13,  1, N_("Candlelight")},
299
      {15,  1, N_("Macro")},
300
      {53,  1, N_("Underwater")},
301
      {0,   2, N_("Program AE")},
302
      {5,   2, N_("Portrait")},
303
      {6,   2, N_("Landscape")},
304
      {0,   0, NULL}}},
305
#endif
306
  {0, {{0, 0, NULL}}}
307
};
308
309
char *
310
mnote_pentax_entry_get_value (MnotePentaxEntry *entry,
311
            char *val, unsigned int maxlen)
312
12.2k
{
313
12.2k
  ExifLong vl;
314
12.2k
  ExifSLong vsl;
315
12.2k
  ExifShort vs, vs2;
316
12.2k
  ExifSShort vss;
317
12.2k
  int i = 0, j = 0;
318
319
12.2k
  if (!entry) return (NULL);
320
321
12.2k
  memset (val, 0, maxlen);
322
12.2k
  maxlen--;
323
324
12.2k
  switch (entry->tag) {
325
272
    case MNOTE_PENTAX_TAG_MODE:
326
491
    case MNOTE_PENTAX_TAG_QUALITY:
327
751
    case MNOTE_PENTAX_TAG_FOCUS:
328
1.15k
    case MNOTE_PENTAX_TAG_FLASH:
329
1.36k
    case MNOTE_PENTAX_TAG_WHITE_BALANCE:
330
1.58k
    case MNOTE_PENTAX_TAG_SHARPNESS:
331
1.95k
    case MNOTE_PENTAX_TAG_CONTRAST:
332
2.15k
    case MNOTE_PENTAX_TAG_SATURATION:
333
2.37k
    case MNOTE_PENTAX_TAG_ISO_SPEED:
334
2.57k
    case MNOTE_PENTAX_TAG_COLOR:
335
3.08k
    case MNOTE_PENTAX2_TAG_MODE:
336
3.62k
    case MNOTE_PENTAX2_TAG_QUALITY:
337
3.92k
    case MNOTE_PENTAX2_TAG_FLASH_MODE:
338
4.20k
    case MNOTE_PENTAX2_TAG_FOCUS_MODE:
339
4.42k
    case MNOTE_PENTAX2_TAG_AFPOINT_SELECTED:
340
4.82k
    case MNOTE_PENTAX2_TAG_AUTO_AFPOINT:
341
5.00k
    case MNOTE_PENTAX2_TAG_WHITE_BALANCE:
342
5.57k
    case MNOTE_PENTAX2_TAG_PICTURE_MODE:
343
6.35k
    case MNOTE_PENTAX2_TAG_IMAGE_SIZE:
344
6.56k
    case MNOTE_CASIO2_TAG_BESTSHOT_MODE:
345
6.56k
    CF (entry->format, EXIF_FORMAT_SHORT, val, maxlen)
346
3.15k
    CC2 (entry->components, 1, 2, val, maxlen)
347
2.87k
    if (entry->components == 1) {
348
1.85k
      vs = exif_get_short (entry->data, entry->order);
349
350
      /* search the tag */
351
23.2k
      for (i = 0; (items[i].tag && items[i].tag != entry->tag); i++);
352
1.85k
      if (!items[i].tag) {
353
0
        snprintf (val, maxlen,
354
0
            _("Internal error (unknown value %hu)"), vs);
355
0
          break;
356
0
      }
357
358
      /* find the value */
359
14.1k
      for (j = 0; items[i].elem[j].string &&
360
13.0k
          (items[i].elem[j].index < vs); j++);
361
1.85k
      if (items[i].elem[j].index != vs) {
362
1.36k
        snprintf (val, maxlen,
363
1.36k
            _("Internal error (unknown value %hu)"), vs);
364
1.36k
        break;
365
1.36k
      }
366
495
      strncpy (val, _(items[i].elem[j].string), maxlen);
367
1.02k
    } else {
368
      /* Two-component values */
369
1.02k
      CF (entry->format, EXIF_FORMAT_SHORT, val, maxlen)
370
1.02k
      CC2 (entry->components, 1, 2, val, maxlen)
371
1.02k
      vs = exif_get_short (entry->data, entry->order);
372
1.02k
      vs2 = ((unsigned int)exif_get_short (entry->data+2, entry->order)) << 16;
373
374
      /* search the tag */
375
1.90k
      for (i = 0; (items2[i].tag && items2[i].tag != entry->tag); i++);
376
1.02k
      if (!items2[i].tag) {
377
332
        snprintf (val, maxlen,
378
332
            _("Internal error (unknown value %hu %hu)"), vs, vs2);
379
332
          break;
380
332
      }
381
382
      /* find the value */
383
2.18k
      for (j = 0; items2[i].elem[j].string && ((items2[i].elem[j].index2 < vs2)
384
2.18k
        || ((items2[i].elem[j].index2 == vs2) && (items2[i].elem[j].index1 < vs))); j++);
385
689
      if ((items2[i].elem[j].index1 != vs) || (items2[i].elem[j].index2 != vs2)) {
386
280
        snprintf (val, maxlen,
387
280
            _("Internal error (unknown value %hi %hi)"), vs, vs2);
388
280
        break;
389
280
      }
390
409
      strncpy (val, _(items2[i].elem[j].string), maxlen);
391
409
    }
392
904
    break;
393
394
904
  case MNOTE_PENTAX_TAG_ZOOM:
395
606
    CF (entry->format, EXIF_FORMAT_LONG, val, maxlen)
396
264
    CC (entry->components, 1, val, maxlen)
397
103
    vl = exif_get_long (entry->data, entry->order);
398
103
    snprintf (val, maxlen, "%lu", (long unsigned) vl);
399
103
    break;
400
185
  case MNOTE_PENTAX_TAG_PRINTIM:
401
185
    CF (entry->format, EXIF_FORMAT_UNDEFINED, val, maxlen)
402
75
    CC (entry->components, 124, val, maxlen)
403
19
    snprintf (val, maxlen, _("%i bytes unknown data"),
404
19
      entry->size);
405
19
    break;
406
267
  case MNOTE_PENTAX_TAG_TZ_CITY:
407
844
  case MNOTE_PENTAX_TAG_TZ_DST:
408
844
    CF (entry->format, EXIF_FORMAT_UNDEFINED, val, maxlen)
409
553
    CC (entry->components, 4, val, maxlen)
410
455
    strncpy (val, (char*)entry->data, MIN(maxlen, entry->size));
411
455
    break;
412
521
  case MNOTE_PENTAX2_TAG_DATE:
413
521
    CF (entry->format, EXIF_FORMAT_UNDEFINED, val, maxlen)
414
137
    CC (entry->components, 4, val, maxlen)
415
    /* Note: format is UNDEFINED, not SHORT -> order is fixed: MOTOROLA */
416
69
    vs = exif_get_short (entry->data, EXIF_BYTE_ORDER_MOTOROLA);
417
69
    snprintf (val, maxlen, "%hi:%02i:%02i", vs, entry->data[2], entry->data[3]);
418
69
    break;
419
602
  case MNOTE_PENTAX2_TAG_TIME:
420
602
    CF (entry->format, EXIF_FORMAT_UNDEFINED, val, maxlen)
421
290
    CC2 (entry->components, 3, 4, val, maxlen)
422
208
    snprintf (val, maxlen, "%02i:%02i:%02i", entry->data[0], entry->data[1], entry->data[2]);
423
208
    break;
424
2.89k
  default:
425
2.89k
    switch (entry->format) {
426
375
    case EXIF_FORMAT_ASCII:
427
375
      strncpy (val, (char *)entry->data, MIN(maxlen, entry->size));
428
375
      break;
429
541
    case EXIF_FORMAT_SHORT:
430
541
      {
431
541
      const unsigned char *data = entry->data;
432
541
      size_t k, len = strlen(val), sizeleft;
433
434
541
      sizeleft = entry->size;
435
83.7k
      for(k=0; k<entry->components; k++) {
436
83.2k
        if (sizeleft < 2)
437
0
          break;
438
83.2k
        vs = exif_get_short (data, entry->order);
439
83.2k
        snprintf (val+len, maxlen-len, "%hu ", vs);
440
83.2k
        len = strlen(val);
441
83.2k
        data += 2;
442
83.2k
        sizeleft -= 2;
443
83.2k
      }
444
541
      }
445
541
      break;
446
436
    case EXIF_FORMAT_SSHORT:
447
436
      {
448
436
      const unsigned char *data = entry->data;
449
436
      size_t k, len = strlen(val), sizeleft;
450
451
436
      sizeleft = entry->size;
452
94.4k
      for(k=0; k<entry->components; k++) {
453
94.0k
        if (sizeleft < 2)
454
0
          break;
455
94.0k
        vss = exif_get_sshort (data, entry->order);
456
94.0k
        snprintf (val+len, maxlen-len, "%hi ", vss);
457
94.0k
        len = strlen(val);
458
94.0k
        data += 2;
459
94.0k
        sizeleft -= 2;
460
94.0k
      }
461
436
      }
462
436
      break;
463
472
    case EXIF_FORMAT_LONG:
464
472
      {
465
472
      const unsigned char *data = entry->data;
466
472
      size_t k, len = strlen(val), sizeleft;
467
468
472
      sizeleft = entry->size;
469
56.3k
      for(k=0; k<entry->components; k++) {
470
55.8k
        if (sizeleft < 4)
471
0
          break;
472
55.8k
        vl = exif_get_long (data, entry->order);
473
55.8k
        snprintf (val+len, maxlen-len, "%lu ", (long unsigned) vl);
474
55.8k
        len = strlen(val);
475
55.8k
        data += 4;
476
55.8k
        sizeleft -= 4;
477
55.8k
      }
478
472
      }
479
472
      break;
480
470
    case EXIF_FORMAT_SLONG:
481
470
      {
482
470
      const unsigned char *data = entry->data;
483
470
      size_t k, len = strlen(val), sizeleft;
484
485
470
      sizeleft = entry->size;
486
20.1k
      for(k=0; k<entry->components; k++) {
487
19.6k
        if (sizeleft < 4)
488
0
          break;
489
19.6k
        vsl = exif_get_slong (data, entry->order);
490
19.6k
        snprintf (val+len, maxlen-len, "%li ", (long int) vsl);
491
19.6k
        len = strlen(val);
492
19.6k
        data += 4;
493
19.6k
        sizeleft -= 4;
494
19.6k
      }
495
470
      }
496
470
      break;
497
3
    case EXIF_FORMAT_UNDEFINED:
498
596
    default:
499
596
      snprintf (val, maxlen, _("%i bytes unknown data"),
500
596
        entry->size);
501
596
      break;
502
2.89k
    }
503
2.89k
    break;
504
12.2k
  }
505
506
12.2k
  return val;
507
12.2k
}