Coverage Report

Created: 2026-05-16 07:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libraw/src/metadata/nikon.cpp
Line
Count
Source
1
/* -*- C++ -*-
2
 * Copyright 2019-2025 LibRaw LLC (info@libraw.org)
3
 *
4
 LibRaw is free software; you can redistribute it and/or modify
5
 it under the terms of the one of two licenses as you choose:
6
7
1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
8
   (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
9
10
2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
11
   (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
12
13
 */
14
15
#include "../../internal/dcraw_defs.h"
16
17
// void hexDump(char *title, void *addr, int len);
18
19
unsigned sget4_order (short _order, uchar *s);
20
double sget_fixed32u (short _order, uchar *s);
21
double AngleConversion_a (short _order, uchar *s);
22
double AngleConversion (short _order, uchar *s);
23
24
static const uchar xlat[2][256] = {
25
    {0xc1, 0xbf, 0x6d, 0x0d, 0x59, 0xc5, 0x13, 0x9d, 0x83, 0x61, 0x6b, 0x4f,
26
     0xc7, 0x7f, 0x3d, 0x3d, 0x53, 0x59, 0xe3, 0xc7, 0xe9, 0x2f, 0x95, 0xa7,
27
     0x95, 0x1f, 0xdf, 0x7f, 0x2b, 0x29, 0xc7, 0x0d, 0xdf, 0x07, 0xef, 0x71,
28
     0x89, 0x3d, 0x13, 0x3d, 0x3b, 0x13, 0xfb, 0x0d, 0x89, 0xc1, 0x65, 0x1f,
29
     0xb3, 0x0d, 0x6b, 0x29, 0xe3, 0xfb, 0xef, 0xa3, 0x6b, 0x47, 0x7f, 0x95,
30
     0x35, 0xa7, 0x47, 0x4f, 0xc7, 0xf1, 0x59, 0x95, 0x35, 0x11, 0x29, 0x61,
31
     0xf1, 0x3d, 0xb3, 0x2b, 0x0d, 0x43, 0x89, 0xc1, 0x9d, 0x9d, 0x89, 0x65,
32
     0xf1, 0xe9, 0xdf, 0xbf, 0x3d, 0x7f, 0x53, 0x97, 0xe5, 0xe9, 0x95, 0x17,
33
     0x1d, 0x3d, 0x8b, 0xfb, 0xc7, 0xe3, 0x67, 0xa7, 0x07, 0xf1, 0x71, 0xa7,
34
     0x53, 0xb5, 0x29, 0x89, 0xe5, 0x2b, 0xa7, 0x17, 0x29, 0xe9, 0x4f, 0xc5,
35
     0x65, 0x6d, 0x6b, 0xef, 0x0d, 0x89, 0x49, 0x2f, 0xb3, 0x43, 0x53, 0x65,
36
     0x1d, 0x49, 0xa3, 0x13, 0x89, 0x59, 0xef, 0x6b, 0xef, 0x65, 0x1d, 0x0b,
37
     0x59, 0x13, 0xe3, 0x4f, 0x9d, 0xb3, 0x29, 0x43, 0x2b, 0x07, 0x1d, 0x95,
38
     0x59, 0x59, 0x47, 0xfb, 0xe5, 0xe9, 0x61, 0x47, 0x2f, 0x35, 0x7f, 0x17,
39
     0x7f, 0xef, 0x7f, 0x95, 0x95, 0x71, 0xd3, 0xa3, 0x0b, 0x71, 0xa3, 0xad,
40
     0x0b, 0x3b, 0xb5, 0xfb, 0xa3, 0xbf, 0x4f, 0x83, 0x1d, 0xad, 0xe9, 0x2f,
41
     0x71, 0x65, 0xa3, 0xe5, 0x07, 0x35, 0x3d, 0x0d, 0xb5, 0xe9, 0xe5, 0x47,
42
     0x3b, 0x9d, 0xef, 0x35, 0xa3, 0xbf, 0xb3, 0xdf, 0x53, 0xd3, 0x97, 0x53,
43
     0x49, 0x71, 0x07, 0x35, 0x61, 0x71, 0x2f, 0x43, 0x2f, 0x11, 0xdf, 0x17,
44
     0x97, 0xfb, 0x95, 0x3b, 0x7f, 0x6b, 0xd3, 0x25, 0xbf, 0xad, 0xc7, 0xc5,
45
     0xc5, 0xb5, 0x8b, 0xef, 0x2f, 0xd3, 0x07, 0x6b, 0x25, 0x49, 0x95, 0x25,
46
     0x49, 0x6d, 0x71, 0xc7},
47
    {0xa7, 0xbc, 0xc9, 0xad, 0x91, 0xdf, 0x85, 0xe5, 0xd4, 0x78, 0xd5, 0x17,
48
     0x46, 0x7c, 0x29, 0x4c, 0x4d, 0x03, 0xe9, 0x25, 0x68, 0x11, 0x86, 0xb3,
49
     0xbd, 0xf7, 0x6f, 0x61, 0x22, 0xa2, 0x26, 0x34, 0x2a, 0xbe, 0x1e, 0x46,
50
     0x14, 0x68, 0x9d, 0x44, 0x18, 0xc2, 0x40, 0xf4, 0x7e, 0x5f, 0x1b, 0xad,
51
     0x0b, 0x94, 0xb6, 0x67, 0xb4, 0x0b, 0xe1, 0xea, 0x95, 0x9c, 0x66, 0xdc,
52
     0xe7, 0x5d, 0x6c, 0x05, 0xda, 0xd5, 0xdf, 0x7a, 0xef, 0xf6, 0xdb, 0x1f,
53
     0x82, 0x4c, 0xc0, 0x68, 0x47, 0xa1, 0xbd, 0xee, 0x39, 0x50, 0x56, 0x4a,
54
     0xdd, 0xdf, 0xa5, 0xf8, 0xc6, 0xda, 0xca, 0x90, 0xca, 0x01, 0x42, 0x9d,
55
     0x8b, 0x0c, 0x73, 0x43, 0x75, 0x05, 0x94, 0xde, 0x24, 0xb3, 0x80, 0x34,
56
     0xe5, 0x2c, 0xdc, 0x9b, 0x3f, 0xca, 0x33, 0x45, 0xd0, 0xdb, 0x5f, 0xf5,
57
     0x52, 0xc3, 0x21, 0xda, 0xe2, 0x22, 0x72, 0x6b, 0x3e, 0xd0, 0x5b, 0xa8,
58
     0x87, 0x8c, 0x06, 0x5d, 0x0f, 0xdd, 0x09, 0x19, 0x93, 0xd0, 0xb9, 0xfc,
59
     0x8b, 0x0f, 0x84, 0x60, 0x33, 0x1c, 0x9b, 0x45, 0xf1, 0xf0, 0xa3, 0x94,
60
     0x3a, 0x12, 0x77, 0x33, 0x4d, 0x44, 0x78, 0x28, 0x3c, 0x9e, 0xfd, 0x65,
61
     0x57, 0x16, 0x94, 0x6b, 0xfb, 0x59, 0xd0, 0xc8, 0x22, 0x36, 0xdb, 0xd2,
62
     0x63, 0x98, 0x43, 0xa1, 0x04, 0x87, 0x86, 0xf7, 0xa6, 0x26, 0xbb, 0xd6,
63
     0x59, 0x4d, 0xbf, 0x6a, 0x2e, 0xaa, 0x2b, 0xef, 0xe6, 0x78, 0xb6, 0x4e,
64
     0xe0, 0x2f, 0xdc, 0x7c, 0xbe, 0x57, 0x19, 0x32, 0x7e, 0x2a, 0xd0, 0xb8,
65
     0xba, 0x29, 0x00, 0x3c, 0x52, 0x7d, 0xa8, 0x49, 0x3b, 0x2d, 0xeb, 0x25,
66
     0x49, 0xfa, 0xa3, 0xaa, 0x39, 0xa7, 0xc5, 0xa7, 0x50, 0x11, 0x36, 0xfb,
67
     0xc6, 0x67, 0x4a, 0xf5, 0xa5, 0x12, 0x65, 0x7e, 0xb0, 0xdf, 0xaf, 0x4e,
68
     0xb3, 0x61, 0x7f, 0x2f} };
69
70
void LibRaw::processNikonLensData(uchar *LensData, unsigned len)
71
19
{
72
73
19
  ushort i=0;
74
19
  if (imgdata.lens.nikon.LensType & 0x80) {
75
2
    strcpy (ilm.LensFeatures_pre, "AF-P");
76
17
  } else if (!(imgdata.lens.nikon.LensType & 0x01)) {
77
14
    ilm.LensFeatures_pre[0] = 'A';
78
14
    ilm.LensFeatures_pre[1] = 'F';
79
14
  } else {
80
3
    ilm.LensFeatures_pre[0] = 'M';
81
3
    ilm.LensFeatures_pre[1] = 'F';
82
3
  }
83
84
19
  if (imgdata.lens.nikon.LensType & 0x40) {
85
1
    ilm.LensFeatures_suf[0] = 'E';
86
18
  } else if (imgdata.lens.nikon.LensType & 0x04) {
87
2
    ilm.LensFeatures_suf[0] = 'G';
88
16
  } else if (imgdata.lens.nikon.LensType & 0x02) {
89
1
    ilm.LensFeatures_suf[0] = 'D';
90
1
  }
91
92
19
  if (imgdata.lens.nikon.LensType & 0x08)
93
1
  {
94
1
    ilm.LensFeatures_suf[1] = ' ';
95
1
    ilm.LensFeatures_suf[2] = 'V';
96
1
    ilm.LensFeatures_suf[3] = 'R';
97
1
  }
98
99
19
  if (imgdata.lens.nikon.LensType & 0x10)
100
2
  {
101
2
    ilm.LensMount = ilm.CameraMount = LIBRAW_MOUNT_Nikon_CX;
102
2
    ilm.CameraFormat = ilm.LensFormat = LIBRAW_FORMAT_1INCH;
103
2
  }
104
17
  else
105
17
    ilm.LensMount = ilm.CameraMount = LIBRAW_MOUNT_Nikon_F;
106
107
19
  if (imgdata.lens.nikon.LensType & 0x20)
108
2
  {
109
2
    strcpy(ilm.Adapter, "FT-1");
110
2
    ilm.LensMount = LIBRAW_MOUNT_Nikon_F;
111
2
    ilm.CameraMount = LIBRAW_MOUNT_Nikon_CX;
112
2
    ilm.CameraFormat = LIBRAW_FORMAT_1INCH;
113
2
  }
114
115
19
  imgdata.lens.nikon.LensType = imgdata.lens.nikon.LensType & 0xdf;
116
117
19
  if ((len < 20) || (len == 58) || (len == 108))
118
14
  {
119
14
    switch (len)
120
14
    {
121
1
    case 9:
122
1
      i = 2;
123
1
      break;
124
6
    case 15:
125
6
      i = 7;
126
6
      break;
127
0
    case 16:
128
0
      i = 8;
129
0
      break;
130
1
    case  58: // "Z 6", "Z 6 II", "Z 7", "Z 7 II", "Z 50", D780, "Z 5", "Z fc"
131
7
    case 108: // "Z 9", "Z 30", "Z 8", "Z6_2"
132
7
      if (model[6] == 'Z')
133
2
        ilm.CameraMount = LIBRAW_MOUNT_Nikon_Z;
134
7
      if (imNikon.HighSpeedCropFormat != 12)
135
7
        ilm.CameraFormat = LIBRAW_FORMAT_FF;
136
7
      i = 1;
137
8
      while ((LensData[i] == LensData[0]) && (i < 17))
138
1
        i++;
139
7
      if (i == 17)
140
0
      {
141
0
        ilm.LensMount = LIBRAW_MOUNT_Nikon_Z;
142
0
        ilm.LensID = sget2(LensData + 0x2c);
143
0
        if (
144
0
               (ilm.LensID == 11)
145
0
            || (ilm.LensID == 12)
146
0
            || (ilm.LensID == 26)
147
0
            || (ilm.LensID == 41)
148
0
            || (ilm.LensID == 43)
149
0
            || (ilm.LensID == 0xd003)
150
0
           ) ilm.LensFormat = LIBRAW_FORMAT_APSC;
151
0
        else ilm.LensFormat = LIBRAW_FORMAT_FF;
152
0
        if (ilm.MaxAp4CurFocal < 0.7f)
153
0
          ilm.MaxAp4CurFocal = libraw_powf64l(
154
0
              2.0f, (float)sget2(LensData + 0x32) / 384.0f - 1.0f);
155
0
        if (ilm.CurAp < 0.7f)
156
0
          ilm.CurAp = libraw_powf64l(
157
0
              2.0f, (float)sget2(LensData + 0x34) / 384.0f - 1.0f);
158
0
        if (fabsf(ilm.CurFocal) < 1.1f)
159
0
          ilm.CurFocal = sget2(LensData + 0x38);
160
0
        return;
161
0
      }
162
7
      i = 9;
163
7
      ilm.LensMount = LIBRAW_MOUNT_Nikon_F;
164
7
      if (ilm.CameraMount == LIBRAW_MOUNT_Nikon_Z)
165
2
        strcpy(ilm.Adapter, "FTZ");
166
7
      break;
167
14
    }
168
14
    imgdata.lens.nikon.LensIDNumber = LensData[i];
169
14
    imgdata.lens.nikon.LensFStops = LensData[i + 1];
170
14
    ilm.LensFStops = (float)imgdata.lens.nikon.LensFStops / 12.0f;
171
14
    if (fabsf(ilm.MinFocal) < 1.1f)
172
11
    {
173
11
      if ((imgdata.lens.nikon.LensType ^ (uchar)0x01) || LensData[i + 2])
174
10
        ilm.MinFocal =
175
10
            5.0f * libraw_powf64l(2.0f, (float)LensData[i + 2] / 24.0f);
176
11
      if ((imgdata.lens.nikon.LensType ^ (uchar)0x01) || LensData[i + 3])
177
10
        ilm.MaxFocal =
178
10
            5.0f * libraw_powf64l(2.0f, (float)LensData[i + 3] / 24.0f);
179
11
      if ((imgdata.lens.nikon.LensType ^ (uchar)0x01) || LensData[i + 4])
180
10
        ilm.MaxAp4MinFocal =
181
10
            libraw_powf64l(2.0f, (float)LensData[i + 4] / 24.0f);
182
11
      if ((imgdata.lens.nikon.LensType ^ (uchar)0x01) || LensData[i + 5])
183
11
        ilm.MaxAp4MaxFocal =
184
11
            libraw_powf64l(2.0f, (float)LensData[i + 5] / 24.0f);
185
11
    }
186
14
    imgdata.lens.nikon.MCUVersion = LensData[i + 6];
187
14
    if (i != 2)
188
13
    {
189
13
      if ((LensData[i - 1]) && (fabsf(ilm.CurFocal) < 1.1f))
190
9
        ilm.CurFocal =
191
9
            5.0f * libraw_powf64l(2.0f, (float)LensData[i - 1] / 24.0f);
192
13
      if (LensData[i + 7])
193
9
        imgdata.lens.nikon.EffectiveMaxAp =
194
9
            libraw_powf64l(2.0f, (float)LensData[i + 7] / 24.0f);
195
13
    }
196
14
    ilm.LensID = (unsigned long long)LensData[i] << 56 |
197
14
                 (unsigned long long)LensData[i + 1] << 48 |
198
14
                 (unsigned long long)LensData[i + 2] << 40 |
199
14
                 (unsigned long long)LensData[i + 3] << 32 |
200
14
                 (unsigned long long)LensData[i + 4] << 24 |
201
14
                 (unsigned long long)LensData[i + 5] << 16 |
202
14
                 (unsigned long long)LensData[i + 6] << 8 |
203
14
                 (unsigned long long)imgdata.lens.nikon.LensType;
204
14
  }
205
5
  else if ((len == 459) || (len == 590))
206
4
  {
207
4
    memcpy(ilm.Lens, LensData + 390, 64);
208
4
  }
209
1
  else if (len == 509)
210
0
  {
211
0
    memcpy(ilm.Lens, LensData + 391, 64);
212
0
  }
213
1
  else if (len == 879)
214
1
  {
215
1
    memcpy(ilm.Lens, LensData + 680, 64);
216
1
  }
217
218
19
  return;
219
19
}
220
221
void LibRaw::Nikon_NRW_WBtag(int wb, int skip)
222
23.4k
{
223
224
23.4k
  int r, g0, g1, b;
225
23.4k
  if (skip)
226
18.8k
    get4(); // skip wb "CCT", it is not unique
227
23.4k
  r = get4();
228
23.4k
  g0 = get4();
229
23.4k
  g1 = get4();
230
23.4k
  b = get4();
231
23.4k
  if (r && g0 && g1 && b)
232
16.2k
  {
233
16.2k
    icWBC[wb][0] = r << 1;
234
16.2k
    icWBC[wb][1] = g0;
235
16.2k
    icWBC[wb][2] = b << 1;
236
16.2k
    icWBC[wb][3] = g1;
237
16.2k
  }
238
23.4k
  return;
239
23.4k
}
240
241
void LibRaw::parseNikonMakernote(INT64 base, int uptag, unsigned /*dng_writer */)
242
32.6k
{
243
244
32.6k
  unsigned offset = 0, entries, tag, type, len;
245
32.6k
  INT64 save;
246
247
32.6k
  unsigned c, i;
248
32.6k
  unsigned LensData_len = 0;
249
32.6k
  uchar *LensData_buf=0;
250
32.6k
  uchar ColorBalanceData_buf[324];
251
32.6k
  int ColorBalanceData_ready = 0;
252
32.6k
  uchar ci, cj, ck;
253
32.6k
  unsigned serial = 0;
254
32.6k
  unsigned custom_serial = 0;
255
256
32.6k
  unsigned ShotInfo_len = 0;
257
32.6k
  uchar *ShotInfo_buf=0;
258
259
/* for dump:
260
uchar *cj_block, *ck_block;
261
*/
262
263
32.6k
  short morder, sorder = order;
264
32.6k
  char buf[10] = {0,0,0,0,0,0,0,0,0,0};
265
32.6k
  INT64 fsize = ifp->size();
266
267
32.6k
  fread(buf, 1, 10, ifp);
268
32.6k
  buf[9] = 0;
269
270
32.6k
  if (!strcmp(buf, "Nikon"))
271
460
  {
272
460
    if (buf[6] != '\2')
273
322
      return;
274
138
    base = ftell(ifp);
275
138
    order = get2();
276
138
    if (get2() != 42)
277
65
      goto quit;
278
73
    offset = get4();
279
73
    fseek(ifp, INT64(offset) - 8LL, SEEK_CUR);
280
73
  }
281
32.1k
  else
282
32.1k
  {
283
32.1k
    fseek(ifp, -10, SEEK_CUR);
284
32.1k
  }
285
286
32.2k
  entries = get2();
287
32.2k
  if (entries > 1000)
288
7.52k
    return;
289
24.6k
  morder = order;
290
291
2.35M
  while (entries--)
292
2.33M
  {
293
2.33M
    order = morder;
294
2.33M
    tiff_get(base, &tag, &type, &len, &save);
295
296
2.33M
    INT64 pos = ifp->tell();
297
2.33M
    if (len > 8 && pos + len > 2 * fsize)
298
1.91M
    {
299
1.91M
      fseek(ifp, save, SEEK_SET); // Recover tiff-read position!!
300
1.91M
      continue;
301
1.91M
    }
302
413k
    tag |= uptag << 16;
303
413k
    if (len > 100 * 1024 * 1024)
304
0
      goto next; // 100Mb tag? No!
305
306
413k
  if (callbacks.makernotes_cb)
307
0
    {
308
0
      INT64 _savepos = ifp->tell();
309
0
      callbacks.makernotes_cb(callbacks.makernotesparser_data, tag, type, len, order, ifp, base);
310
0
      fseek(ifp, _savepos, SEEK_SET);
311
0
    }
312
313
413k
    if (tag == 0x0002)
314
4.55k
    {
315
4.55k
      if (!iso_speed)
316
776
        iso_speed = (get2(), get2());
317
4.55k
    }
318
408k
    else if (tag == 0x000a)
319
855
    {
320
855
      ilm.LensMount = ilm.CameraMount = LIBRAW_MOUNT_FixedLens;
321
855
      ilm.FocalType = LIBRAW_FT_ZOOM_LENS;
322
855
    }
323
407k
    else if ((tag == 0x000c) && (len == 4) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_RATIONAL))
324
36
    {
325
36
      cam_mul[0] = getrealf(type);
326
36
      cam_mul[2] = getrealf(type);
327
36
      cam_mul[1] = getrealf(type);
328
36
      cam_mul[3] = getrealf(type);
329
36
    }
330
407k
    else if (tag == 0x0011)
331
317
    {
332
317
      if (is_raw)
333
260
      {
334
260
        fseek(ifp, get4() + base, SEEK_SET);
335
260
        parse_tiff_ifd(base);
336
260
      }
337
317
    }
338
407k
    else if (tag == 0x0012)
339
847
    {
340
847
      uchar uc1 = fgetc(ifp);
341
847
      uchar uc2 = fgetc(ifp);
342
847
      uchar uc3 = fgetc(ifp);
343
847
      if (uc3)
344
494
        imCommon.FlashEC = (float)(uc1 * uc2) / (float)uc3;
345
847
    }
346
406k
    else if (tag == 0x0014)
347
6.37k
    {
348
6.37k
      if (tagtypeIs(LIBRAW_EXIFTOOLTAGTYPE_binary))
349
5.54k
      {
350
5.54k
        if (len == 2560)
351
49
        { // E5400, E8400, E8700, E8800
352
49
          fseek(ifp, 0x4e0L, SEEK_CUR);
353
49
          order = 0x4d4d;
354
49
          cam_mul[0] = float(get2()) / 256.f;
355
49
          cam_mul[2] = float(get2()) / 256.f;
356
49
          cam_mul[1] = cam_mul[3] = 1.0;
357
49
          icWBC[LIBRAW_WBI_Auto][0] = get2();
358
49
          icWBC[LIBRAW_WBI_Auto][2] = get2();
359
49
          icWBC[LIBRAW_WBI_Daylight][0] = get2();
360
49
          icWBC[LIBRAW_WBI_Daylight][2] = get2();
361
49
          fseek(ifp, 0x18L, SEEK_CUR);
362
49
          icWBC[LIBRAW_WBI_Tungsten][0] = get2();
363
49
          icWBC[LIBRAW_WBI_Tungsten][2] = get2();
364
49
          fseek(ifp, 0x18L, SEEK_CUR);
365
49
          icWBC[LIBRAW_WBI_FL_W][0] = get2();
366
49
          icWBC[LIBRAW_WBI_FL_W][2] = get2();
367
49
          icWBC[LIBRAW_WBI_FL_N][0] = get2();
368
49
          icWBC[LIBRAW_WBI_FL_N][2] = get2();
369
49
          icWBC[LIBRAW_WBI_FL_D][0] = get2();
370
49
          icWBC[LIBRAW_WBI_FL_D][2] = get2();
371
49
          icWBC[LIBRAW_WBI_Cloudy][0] = get2();
372
49
          icWBC[LIBRAW_WBI_Cloudy][2] = get2();
373
49
          fseek(ifp, 0x18L, SEEK_CUR);
374
49
          icWBC[LIBRAW_WBI_Flash][0] = get2();
375
49
          icWBC[LIBRAW_WBI_Flash][2] = get2();
376
377
49
          icWBC[LIBRAW_WBI_Auto][1] = icWBC[LIBRAW_WBI_Auto][3] =
378
49
            icWBC[LIBRAW_WBI_Daylight][1] = icWBC[LIBRAW_WBI_Daylight][3] =
379
49
            icWBC[LIBRAW_WBI_Tungsten][1] = icWBC[LIBRAW_WBI_Tungsten][3] =
380
49
            icWBC[LIBRAW_WBI_FL_W][1] = icWBC[LIBRAW_WBI_FL_W][3] =
381
49
            icWBC[LIBRAW_WBI_FL_N][1] = icWBC[LIBRAW_WBI_FL_N][3] =
382
49
            icWBC[LIBRAW_WBI_FL_D][1] = icWBC[LIBRAW_WBI_FL_D][3] =
383
49
            icWBC[LIBRAW_WBI_Cloudy][1] = icWBC[LIBRAW_WBI_Cloudy][3] =
384
49
            icWBC[LIBRAW_WBI_Flash][1] = icWBC[LIBRAW_WBI_Flash][3] = 256;
385
386
49
          if (strncmp(model, "E8700", 5))
387
49
          {
388
49
            fseek(ifp, 0x18L, SEEK_CUR);
389
49
            icWBC[LIBRAW_WBI_Shade][0] = get2();
390
49
            icWBC[LIBRAW_WBI_Shade][2] = get2();
391
49
            icWBC[LIBRAW_WBI_Shade][1] = icWBC[LIBRAW_WBI_Shade][3] = 256;
392
49
          }
393
49
        }
394
5.49k
        else if (len == 1280)
395
327
        { // E5000, E5700
396
327
          cam_mul[0] = cam_mul[1] = cam_mul[2] = cam_mul[3] = 1.0;
397
327
        }
398
5.17k
        else
399
5.17k
        {
400
5.17k
          memset(buf,0,sizeof(buf));
401
5.17k
          fread(buf, 1, 10, ifp);
402
5.17k
          buf[9] = 0;
403
5.17k
          if (!strncmp(buf, "NRW ", 4))
404
2.54k
          { // P6000, P7000, P7100, B700, P1000
405
2.54k
            if (!strcmp(buf + 4, "0100"))
406
658
            { // P6000
407
658
              fseek(ifp, 0x13deL, SEEK_CUR);
408
658
              cam_mul[0] = float(get4() << 1);
409
658
              cam_mul[1] = float(get4());
410
658
              cam_mul[3] = float(get4());
411
658
              cam_mul[2] = float(get4() << 1);
412
658
              Nikon_NRW_WBtag(LIBRAW_WBI_Daylight, 0);
413
658
              Nikon_NRW_WBtag(LIBRAW_WBI_Cloudy, 0);
414
658
              fseek(ifp, 0x10L, SEEK_CUR);
415
658
              Nikon_NRW_WBtag(LIBRAW_WBI_Tungsten, 0);
416
658
              Nikon_NRW_WBtag(LIBRAW_WBI_FL_W, 0);
417
658
              Nikon_NRW_WBtag(LIBRAW_WBI_Flash, 0);
418
658
              fseek(ifp, 0x10L, SEEK_CUR);
419
658
              Nikon_NRW_WBtag(LIBRAW_WBI_Custom, 0);
420
658
              Nikon_NRW_WBtag(LIBRAW_WBI_Auto, 0);
421
658
            }
422
1.88k
            else
423
1.88k
            { // P7000, P7100, B700, P1000
424
1.88k
              fseek(ifp, 0x16L, SEEK_CUR);
425
1.88k
              black = get2();
426
1.88k
              if (cam_mul[0] < 0.1f)
427
579
              {
428
579
                fseek(ifp, 0x16L, SEEK_CUR);
429
579
                cam_mul[0] = float(get4() << 1);
430
579
                cam_mul[1] = float(get4());
431
579
                cam_mul[3] = float(get4());
432
579
                cam_mul[2] = float(get4() << 1);
433
579
              }
434
1.30k
              else
435
1.30k
              {
436
1.30k
                fseek(ifp, 0x26L, SEEK_CUR);
437
1.30k
              }
438
1.88k
              if (len != 332)
439
1.88k
              { // not A1000
440
1.88k
                Nikon_NRW_WBtag(LIBRAW_WBI_Daylight, 1);
441
1.88k
                Nikon_NRW_WBtag(LIBRAW_WBI_Cloudy, 1);
442
1.88k
                Nikon_NRW_WBtag(LIBRAW_WBI_Shade, 1);
443
1.88k
                Nikon_NRW_WBtag(LIBRAW_WBI_Tungsten, 1);
444
1.88k
                Nikon_NRW_WBtag(LIBRAW_WBI_FL_W, 1);
445
1.88k
                Nikon_NRW_WBtag(LIBRAW_WBI_FL_N, 1);
446
1.88k
                Nikon_NRW_WBtag(LIBRAW_WBI_FL_D, 1);
447
1.88k
                Nikon_NRW_WBtag(LIBRAW_WBI_HT_Mercury, 1);
448
1.88k
                fseek(ifp, 0x14L, SEEK_CUR);
449
1.88k
                Nikon_NRW_WBtag(LIBRAW_WBI_Custom, 1);
450
1.88k
                Nikon_NRW_WBtag(LIBRAW_WBI_Auto, 1);
451
1.88k
              }
452
0
              else
453
0
              {
454
0
                fseek(ifp, 0xc8L, SEEK_CUR);
455
0
                Nikon_NRW_WBtag(LIBRAW_WBI_Auto, 1);
456
0
              }
457
1.88k
            }
458
2.54k
          }
459
5.17k
        }
460
5.54k
      }
461
6.37k
    }
462
400k
    else if (tag == 0x001b)
463
4.52k
    {
464
4.52k
      imNikon.HighSpeedCropFormat = get2();
465
4.52k
      imNikon.SensorHighSpeedCrop.cwidth = get2();
466
4.52k
      imNikon.SensorHighSpeedCrop.cheight = get2();
467
4.52k
      imNikon.SensorWidth = get2();
468
4.52k
      imNikon.SensorHeight = get2();
469
4.52k
      imNikon.SensorHighSpeedCrop.cleft = get2();
470
4.52k
      imNikon.SensorHighSpeedCrop.ctop = get2();
471
4.52k
      switch (imNikon.HighSpeedCropFormat)
472
4.52k
      {
473
287
      case 0:
474
664
      case 1:
475
1.36k
      case 2:
476
1.46k
      case 4:
477
1.46k
        imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_3to2;
478
1.46k
        break;
479
398
      case 11:
480
398
        ilm.CameraFormat = LIBRAW_FORMAT_FF;
481
398
        imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_3to2;
482
398
        break;
483
926
      case 12:
484
926
        ilm.CameraFormat = LIBRAW_FORMAT_APSC;
485
926
        imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_3to2;
486
926
        break;
487
477
      case 3:
488
477
        imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_5to4;
489
477
        break;
490
230
      case 6:
491
230
        imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_16to9;
492
230
        break;
493
138
      case 17:
494
138
        imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_1to1;
495
138
        break;
496
895
      default:
497
895
        imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_OTHER;
498
895
        break;
499
4.52k
      }
500
4.52k
    }
501
395k
    else if (tag == 0x001d)
502
5.89k
    { // serial number
503
5.89k
      if (len > 0)
504
5.27k
      {
505
5.27k
        int model_len = (int)strbuflen(model);
506
12.8k
        while ((c = fgetc(ifp)) && (len-- > 0) && (c != (unsigned)EOF))
507
10.1k
        {
508
10.1k
          if ((!custom_serial) && (!isdigit(c)))
509
2.55k
          {
510
2.55k
            if (((model_len == 3) && !strcmp(model, "D50")) ||
511
2.51k
                ((model_len >= 4) && !isalnum(model[model_len - 4]) &&
512
520
                 !strncmp(&model[model_len - 3], "D50", 3)))
513
299
            {
514
299
              custom_serial = 34;
515
299
            }
516
2.25k
            else
517
2.25k
            {
518
2.25k
              custom_serial = 96;
519
2.25k
            }
520
2.55k
            break;
521
2.55k
          }
522
7.56k
          serial = serial * 10 + (isdigit(c) ? c - '0' : c % 10);
523
7.56k
        }
524
5.27k
        if (!imgdata.shootinginfo.BodySerial[0])
525
215
          sprintf(imgdata.shootinginfo.BodySerial, "%d", serial);
526
5.27k
      }
527
5.89k
    }
528
389k
    else if (tag == 0x001e) {
529
2.35k
      switch (get2()) {
530
155
      case 1:
531
155
        imCommon.ColorSpace = LIBRAW_COLORSPACE_sRGB;
532
155
        break;
533
200
      case 2:
534
200
        imCommon.ColorSpace = LIBRAW_COLORSPACE_AdobeRGB;
535
200
        break;
536
1.55k
      case 4:
537
1.55k
        imCommon.ColorSpace = LIBRAW_COLORSPACE_Rec2020;
538
1.55k
        break;
539
442
      default:
540
442
        imCommon.ColorSpace = LIBRAW_COLORSPACE_Unknown;
541
442
        break;
542
2.35k
      }
543
387k
    } else if (tag == 0x0025)
544
674
    {
545
674
      imCommon.real_ISO = float(100.f * float(libraw_powf64l(2.f, float((uchar)fgetc(ifp)) / 12.f - 5.f)));
546
674
      if (!iso_speed || (iso_speed == 65535))
547
90
      {
548
90
        iso_speed = imCommon.real_ISO;
549
90
      }
550
674
    }
551
386k
    else if (tag == 0x0022)
552
559
    {
553
559
      imNikon.Active_D_Lighting = get2();
554
559
    }
555
386k
    else if (tag == 0x0023)
556
885
    {
557
3.54k
      FORC4 imNikon.PictureControlVersion =
558
3.54k
          imNikon.PictureControlVersion * 10 + fgetc(ifp) - '0';
559
885
      if ((imNikon.PictureControlVersion >= 300) &&
560
848
          (imNikon.PictureControlVersion <= 399))
561
1
      {
562
1
        fseek(ifp, 4, SEEK_CUR);
563
1
      }
564
885
      stmread (imNikon.PictureControlName, 20, ifp);
565
885
      stmread (imNikon.PictureControlBase, 20, ifp);
566
885
      if (!strncmp(imNikon.PictureControlBase, "STANDARD(HLG)", 13))
567
74
      {
568
74
        imCommon.ExposureCalibrationShift -= 2;
569
74
      }
570
885
    }
571
385k
    else if (tag == 0x003b)
572
1.38k
    { // WB for multi-exposure (ME); all 1s for regular exposures
573
1.38k
      imNikon.ME_WB[0] = getreal(type);
574
1.38k
      imNikon.ME_WB[2] = getreal(type);
575
1.38k
      imNikon.ME_WB[1] = getreal(type);
576
1.38k
      imNikon.ME_WB[3] = getreal(type);
577
1.38k
    }
578
384k
    else if (tag == 0x003d)
579
1.95k
    { // not corrected for file bitcount, to be patched in open_datastream
580
7.82k
      FORC4 cblack[RGGB_2_RGBG(c)] = get2();
581
1.95k
      i = cblack[3];
582
5.86k
      FORC3 if (i > cblack[c]) i = cblack[c];
583
7.82k
      FORC4 cblack[c] -= i;
584
1.95k
      black += i;
585
1.95k
    }
586
382k
    else if (tag == 0x0045)
587
114
    { /* upper left pixel (x,y), size (width,height) */
588
114
      imgdata.sizes.raw_inset_crops[0].cleft = get2();
589
114
      imgdata.sizes.raw_inset_crops[0].ctop = get2();
590
114
      imgdata.sizes.raw_inset_crops[0].cwidth = get2();
591
114
      imgdata.sizes.raw_inset_crops[0].cheight = get2();
592
114
    }
593
382k
    else if (tag == 0x0051)
594
234
    {
595
234
      fseek(ifp, 10LL, SEEK_CUR);
596
234
      imNikon.NEFCompression = get2();
597
234
    }
598
599
// BurstTable_0x0056
600
/*
601
photo shooting menu -> [Pixel shift shooting] :
602
  [Pixel shift shooting mode] : On(series) | On(single photo) | Off (default is Off)
603
  [Number of shots]           : 4 | 8 | 16 | 32 (default is 16)
604
  [Delay]                     : (default is 2 s)
605
  [Interval until next shot]  : (default is 0)
606
*/
607
381k
    else if ((tag == 0x0056) && !strncmp(model+6, "Z ", 2))
608
50
    {
609
50
        imNikon.BurstTable_0x0056_len = len;
610
50
        if (imNikon.BurstTable_0x0056_len == 16) {
611
0
          imNikon.BurstTable_0x0056 = (uchar *)calloc(imNikon.BurstTable_0x0056_len+1,1);
612
0
          fread(imNikon.BurstTable_0x0056, imNikon.BurstTable_0x0056_len, 1, ifp);
613
0
          FORC4 imNikon.BurstTable_0x0056_ver = imNikon.BurstTable_0x0056_ver * 10 + (imNikon.BurstTable_0x0056[c] - '0');
614
0
          imNikon.BurstTable_0x0056_gid = (imNikon.BurstTable_0x0056[5]<<8) | imNikon.BurstTable_0x0056[4];
615
0
          imNikon.BurstTable_0x0056_fnum = imNikon.BurstTable_0x0056[8];
616
/*
617
          printf (">> camera: %s; BurstTable_0x0056: len %d, ver %d, gid 0x%04x, fnum %d\n",
618
              model, imNikon.BurstTable_0x0056_len, imNikon.BurstTable_0x0056_ver, imNikon.BurstTable_0x0056_gid, imNikon.BurstTable_0x0056_fnum);
619
          printf ("  0x6: 0x%02x 0x7: 0x%02x\n   0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
620
               imNikon.BurstTable_0x0056[0x6], imNikon.BurstTable_0x0056[0x7],
621
               imNikon.BurstTable_0x0056[0x9], imNikon.BurstTable_0x0056[0xa],
622
               imNikon.BurstTable_0x0056[0xb], imNikon.BurstTable_0x0056[0xc],
623
               imNikon.BurstTable_0x0056[0xd], imNikon.BurstTable_0x0056[0xe],
624
               imNikon.BurstTable_0x0056[0xf]);
625
626
          printf ("BurstTable_0x0056[5 .. 4]: ");
627
          for (c = 1 << 7; c > 0; c = c / 2)
628
            (imNikon.BurstTable_0x0056[5] & c) ? printf("1") : printf("0");
629
          printf (" ");
630
          for (c = 1 << 7; c > 0; c = c / 2)
631
            (imNikon.BurstTable_0x0056[4] & c) ? printf("1") : printf("0");
632
          printf ("\n");
633
          printf ("BurstTable_0x0056[7 .. 6]: ");
634
          for (c = 1 << 7; c > 0; c = c / 2)
635
            (imNikon.BurstTable_0x0056[7] & c) ? printf("1") : printf("0");
636
          printf (" ");
637
          for (c = 1 << 7; c > 0; c = c / 2)
638
            (imNikon.BurstTable_0x0056[6] & c) ? printf("1") : printf("0");
639
          printf ("\n");
640
*/
641
0
        }
642
/*
643
        else {
644
          printf (">> camera: =%s=; table 0x0056 len!=16, len %d\n", model, len);
645
        }
646
*/
647
50
    }
648
649
381k
    else if (tag == 0x0082)
650
811
    { // lens attachment
651
811
      stmread(ilm.Attachment, len, ifp);
652
811
    }
653
380k
    else if (tag == 0x0083)
654
1.27k
    { // lens type
655
1.27k
      imgdata.lens.nikon.LensType = fgetc(ifp);
656
1.27k
    }
657
379k
    else if (tag == 0x0084)
658
364
    { // lens
659
364
      ilm.MinFocal = getrealf(type);
660
364
      ilm.MaxFocal = getrealf(type);
661
364
      ilm.MaxAp4MinFocal = getrealf(type);
662
364
      ilm.MaxAp4MaxFocal = getrealf(type);
663
364
    }
664
379k
    else if (tag == 0x0088) // AFInfo
665
359
    {
666
359
      if (!imCommon.afcount)
667
20
      {
668
20
        imCommon.afdata[imCommon.afcount].AFInfoData_tag = tag;
669
20
        imCommon.afdata[imCommon.afcount].AFInfoData_order = order;
670
20
        imCommon.afdata[imCommon.afcount].AFInfoData_length = len;
671
20
        imCommon.afdata[imCommon.afcount].AFInfoData = (uchar *)calloc(imCommon.afdata[imCommon.afcount].AFInfoData_length+1,1);
672
20
        fread(imCommon.afdata[imCommon.afcount].AFInfoData, imCommon.afdata[imCommon.afcount].AFInfoData_length, 1, ifp);
673
20
        imCommon.afcount = 1;
674
20
      }
675
359
    }
676
378k
    else if (tag == 0x008b) // lens f-stops
677
2.08k
    {
678
2.08k
      uchar uc1 = fgetc(ifp);
679
2.08k
      uchar uc2 = fgetc(ifp);
680
2.08k
      uchar uc3 = fgetc(ifp);
681
2.08k
      if (uc3)
682
1.16k
      {
683
1.16k
        imgdata.lens.nikon.LensFStops = uc1 * uc2 * (12 / uc3);
684
1.16k
        ilm.LensFStops = (float)imgdata.lens.nikon.LensFStops / 12.0f;
685
1.16k
      }
686
2.08k
    }
687
376k
    else if ((tag == 0x008c) || (tag == 0x0096))
688
491
    {
689
491
      meta_offset = ftell(ifp);
690
491
    }
691
376k
    else if ((tag == 0x0091) && (len > 4))
692
815
    {
693
815
      ShotInfo_len = len;
694
815
      ShotInfo_buf = (uchar *)calloc(ShotInfo_len+1,1);
695
696
/* for dump:
697
cj_block = (uchar *)malloc(ShotInfo_len);
698
ck_block = (uchar *)malloc(ShotInfo_len);
699
*/
700
701
815
      fread(ShotInfo_buf, ShotInfo_len, 1, ifp);
702
3.26k
      FORC4 imNikon.ShotInfoVersion =
703
3.26k
          imNikon.ShotInfoVersion * 10 + ShotInfo_buf[c] - '0';
704
815
    }
705
375k
    else if (tag == 0x0093)
706
1.19k
    {
707
1.19k
      imNikon.NEFCompression = i = get2();
708
1.19k
      if ((i == 7) || (i == 9))
709
279
      {
710
279
        ilm.LensMount = LIBRAW_MOUNT_FixedLens;
711
279
        ilm.CameraMount = LIBRAW_MOUNT_FixedLens;
712
279
      }
713
1.19k
    }
714
374k
    else if (tag == 0x0097)
715
2.64k
    { // ver97
716
10.5k
      FORC4 imNikon.ColorBalanceVersion =
717
10.5k
          imNikon.ColorBalanceVersion * 10 + fgetc(ifp) - '0';
718
2.64k
      switch (imNikon.ColorBalanceVersion)
719
2.64k
      {
720
1
      case 100: // NIKON D100
721
1
        fseek(ifp, 0x44L, SEEK_CUR);
722
4
        FORC4 cam_mul[RBGG_2_RGBG(c)] = get2();
723
1
        break;
724
1
      case 102: // NIKON D2H
725
1
        fseek(ifp, 0x6L, SEEK_CUR);
726
4
        FORC4 cam_mul[RGGB_2_RGBG(c)] = get2();
727
1
        break;
728
1
      case 103: // NIKON D70, D70s
729
1
        fseek(ifp, 0x10L, SEEK_CUR);
730
4
        FORC4 cam_mul[c] = get2();
731
2.64k
      }
732
2.64k
      if (imNikon.ColorBalanceVersion >= 200)
733
2.57k
      {
734
        /*
735
        204: NIKON D2X, D2Xs
736
        205: NIKON D50
737
        206: NIKON D2Hs
738
        207: NIKON D200
739
        208: NIKON D40, D40X, D80
740
        209: NIKON D3, D3X, D300, D700
741
        210: NIKON D60
742
        211: NIKON D90, D5000
743
        212: NIKON D300S
744
        213: NIKON D3000
745
        214: NIKON D3S
746
        215: NIKON D3100
747
        216: NIKON D5100, D7000
748
        217: NIKON D4, D600, D800, D800E, D3200
749
        -= unknown =-
750
        218: NIKON D5200, D7100
751
        219: NIKON D5300
752
        220: NIKON D610, Df
753
        221: NIKON D3300
754
        222: NIKON D4S
755
        223: NIKON D750, D810
756
        224: NIKON D3400, D3500, D5500, D5600, D7200
757
        225: NIKON D5, D500
758
        226: NIKON D7500
759
        227: NIKON D850
760
         */
761
2.57k
        if (imNikon.ColorBalanceVersion != 205)
762
2.56k
        {
763
2.56k
          fseek(ifp, 0x118L, SEEK_CUR);
764
2.56k
        }
765
2.57k
        ColorBalanceData_ready =
766
2.57k
            (fread(ColorBalanceData_buf, 324, 1, ifp) == 1);
767
2.57k
      }
768
2.64k
      if ((imNikon.ColorBalanceVersion >= 400) &&
769
2.56k
          (imNikon.ColorBalanceVersion <= 405))
770
1
      { // 1 J1, 1 V1, 1 J2, 1 V2, 1 J3, 1 S1, 1 AW1, 1 S2, 1 J4, 1 V3, 1 J5
771
1
        ilm.CameraFormat = LIBRAW_FORMAT_1INCH;
772
1
        ilm.CameraMount = LIBRAW_MOUNT_Nikon_CX;
773
1
      }
774
2.64k
      else if ((imNikon.ColorBalanceVersion >= 500) &&
775
2.56k
               (imNikon.ColorBalanceVersion <= 502))
776
2
      { // P7700, P7800, P330, P340
777
2
        ilm.CameraMount = ilm.LensMount = LIBRAW_MOUNT_FixedLens;
778
2
        ilm.FocalType = LIBRAW_FT_ZOOM_LENS;
779
2
      }
780
2.64k
      else if (imNikon.ColorBalanceVersion == 601)
781
1
      { // Coolpix A
782
1
        ilm.CameraFormat = ilm.LensFormat = LIBRAW_FORMAT_APSC;
783
1
        ilm.CameraMount = ilm.LensMount = LIBRAW_MOUNT_FixedLens;
784
1
        ilm.FocalType = LIBRAW_FT_PRIME_LENS;
785
1
      }
786
2.64k
    }
787
371k
    else if (tag == 0x0098) // contains lens data
788
2.43k
    {
789
9.72k
      FORC4 imNikon.LensDataVersion =
790
9.72k
          imNikon.LensDataVersion * 10 + fgetc(ifp) - '0';
791
2.43k
      switch (imNikon.LensDataVersion)
792
2.43k
      {
793
1
      case 100:
794
1
        LensData_len = 9;
795
1
        break;
796
5
      case 101:
797
6
      case 201: // encrypted, starting from v.201
798
6
      case 202:
799
6
      case 203:
800
6
        LensData_len = 15;
801
6
        break;
802
0
      case 204:
803
0
        LensData_len = 16;
804
0
        break;
805
4
      case 400:
806
4
        LensData_len = 459;
807
4
        break;
808
1
      case 401:
809
1
        LensData_len = 590;
810
1
        break;
811
1
      case 402:
812
1
        LensData_len = 509;
813
1
        break;
814
1
      case 403:
815
1
        LensData_len = 879;
816
1
        break;
817
1
      case 800:
818
2
      case 801:
819
2
        LensData_len = 58;
820
2
        break;
821
8
      case 802:
822
8
        LensData_len = 108;
823
8
        break;
824
2.43k
      }
825
2.43k
      if (LensData_len)
826
33
      {
827
33
        LensData_buf = (uchar *)calloc(LensData_len+1,1);
828
33
        fread(LensData_buf, LensData_len, 1, ifp);
829
33
      }
830
2.43k
    }
831
369k
    else if (tag == 0x00a0)
832
961
    {
833
961
      stmread(imgdata.shootinginfo.BodySerial, len, ifp);
834
961
    }
835
368k
    else if (tag == 0x00a7) // shutter count
836
1.32k
    {
837
1.32k
      imNikon.key = fgetc(ifp) ^ fgetc(ifp) ^ fgetc(ifp) ^ fgetc(ifp);
838
1.32k
      if (custom_serial)
839
324
      {
840
324
        ci = xlat[0][custom_serial];
841
324
      }
842
1.00k
      else
843
1.00k
      {
844
1.00k
        ci = xlat[0][serial & 0xff];
845
1.00k
      }
846
1.32k
      cj = xlat[1][imNikon.key];
847
1.32k
      ck = 0x60;
848
1.32k
      if (((unsigned)(imNikon.ColorBalanceVersion - 200) < 18) &&
849
94
          ColorBalanceData_ready)
850
58
      {
851
18.8k
        for (i = 0; i < 324; i++)
852
18.7k
          ColorBalanceData_buf[i] ^= (cj += ci * ck++);
853
58
        i = "66666>666;6A;:;555"[imNikon.ColorBalanceVersion - 200] - '0';
854
232
        FORC4 cam_mul[c ^ (c >> 1) ^ (i & 1)] =
855
232
            sget2(ColorBalanceData_buf + (i & -2) + c * 2);
856
58
      }
857
858
1.32k
      if (LensData_len)
859
19
      {
860
19
        if (imNikon.LensDataVersion > 200)
861
13
        {
862
13
          cj = xlat[1][imNikon.key];
863
13
          ck = 0x60;
864
3.58k
          for (i = 0; i < LensData_len; i++)
865
3.56k
          {
866
3.56k
            LensData_buf[i] ^= (cj += ci * ck++);
867
3.56k
          }
868
13
        }
869
19
        processNikonLensData(LensData_buf, LensData_len);
870
19
        LensData_len = 0;
871
19
        free(LensData_buf);
872
19
      }
873
1.32k
      if (ShotInfo_len && (imNikon.ShotInfoVersion >= 208)) {
874
528
        unsigned RotationOffset = 0,
875
528
                 OrientationOffset = 0;
876
877
528
        cj = xlat[1][imNikon.key];
878
528
        ck = 0x60;
879
12.1k
        for (i = 4; i < ShotInfo_len; i++) {
880
11.6k
          ShotInfo_buf[i] ^= (cj += ci * ck++);
881
882
/* for dump:
883
cj_block[i-4] = cj;
884
ck_block[i-4] = ck-1;
885
*/
886
11.6k
        }
887
/* for dump:
888
printf ("==>> ci: 0x%02x, cj at start: 0x%02x\n",
889
ci, xlat[1][imNikon.key]);
890
hexDump("ck array:", ck_block, ShotInfo_len-4);
891
hexDump("cj array:", cj_block, ShotInfo_len-4);
892
free(cj_block);
893
free(ck_block);
894
*/
895
896
528
        switch (imNikon.ShotInfoVersion) {
897
2
        case 208: // ShotInfoD80, Rotation
898
2
          RotationOffset = 590;
899
2
          if (RotationOffset<ShotInfo_len) {
900
1
            imNikon.MakernotesFlip = *(ShotInfo_buf+RotationOffset) & 0x07;
901
1
          }
902
2
          break;
903
904
1
        case 231: // ShotInfoD4S, Rotation, Roll/Pitch/Yaw
905
1
          OrientationOffset  = 0x350b;
906
1
          RotationOffset     = 0x3693;
907
1
          if (RotationOffset<ShotInfo_len) {
908
0
            imNikon.MakernotesFlip = (*(ShotInfo_buf+RotationOffset)>>4) & 0x03;
909
0
          }
910
1
          break;
911
912
0
        case 233: // ShotInfoD810, Roll/Pitch/Yaw
913
0
          OrientationOffset = sget4_order(morder, ShotInfo_buf+0x84);
914
0
          break;
915
916
0
        case 238: // D5,   ShotInfoD500, Rotation, Roll/Pitch/Yaw
917
0
        case 239: // D500, ShotInfoD500, Rotation, Roll/Pitch/Yaw
918
0
          RotationOffset = sget4_order(morder, ShotInfo_buf+0x10) + 0xca;
919
0
          if (RotationOffset > 0xca) {
920
0
            RotationOffset -= 0xb0;
921
0
          }
922
0
          if (RotationOffset<ShotInfo_len) {
923
0
            imNikon.MakernotesFlip = *(ShotInfo_buf+RotationOffset) & 0x03;
924
0
          }
925
0
          OrientationOffset = sget4_order(morder, ShotInfo_buf+0xa0);
926
0
          break;
927
928
1
        case 243: // ShotInfoD850, Roll/Pitch/Yaw
929
1
          OrientationOffset = sget4_order(morder, ShotInfo_buf+0xa0);
930
1
          break;
931
932
1
        case 246: // ShotInfoD6, Roll/Pitch/Yaw
933
1
          OrientationOffset = sget4_order(morder, ShotInfo_buf+0x9c);
934
1
          break;
935
936
1
        case 800: // "Z 6", "Z 7",     ShotInfoZ7II, Roll/Pitch/Yaw
937
3
        case 801: // "Z 50",           ShotInfoZ7II, Roll/Pitch/Yaw
938
4
        case 802: // "Z 5",            ShotInfoZ7II, Roll/Pitch/Yaw
939
5
        case 803: // "Z 6_2", "Z 7_2", ShotInfoZ7II, Roll/Pitch/Yaw
940
5
        case 804: // "Z fc"            ShotInfoZ7II, Roll/Pitch/Yaw
941
5
          OrientationOffset = sget4_order(morder, ShotInfo_buf+0x98);
942
5
          break;
943
944
0
        case 805: // "Z 9",            ShotInfoZ9, Roll/Pitch/Yaw
945
0
          OrientationOffset = sget4_order(morder, ShotInfo_buf+0x84);
946
0
          break;
947
1
        case 806: // "Z 8"
948
1
          if (ShotInfo_len >= 12) {
949
0
            memcpy (imNikon.ShotInfoFirmware, ShotInfo_buf+4, 8*sizeof(char));
950
0
            imNikon.ShotInfoFirmware[8] = '\0';
951
            // printf (">> camera: =%s= exifSW: =%s= ShotInfo: Version %d, Firmware =%s=\n",
952
            //  model, software, imNikon.ShotInfoVersion, imNikon.ShotInfoFirmware);
953
0
          }
954
1
          break;
955
0
        case 807: // "Z 30"
956
0
          break;
957
1
        case 808: // "Z f"
958
1
          if (ShotInfo_len >= 12) {
959
1
            memcpy (imNikon.ShotInfoFirmware, ShotInfo_buf+4, 8*sizeof(char));
960
1
            imNikon.ShotInfoFirmware[8] = '\0';
961
            // printf (">> camera: =%s= exifSW: =%s= ShotInfo: Version %d, Firmware =%s=\n",
962
            //  model, software, imNikon.ShotInfoVersion, imNikon.ShotInfoFirmware);
963
1
          }
964
1
          break;
965
528
        }
966
967
528
        if (OrientationOffset && ((OrientationOffset+12)<ShotInfo_len) && OrientationOffset < 0xffff) {
968
0
          if (imNikon.ShotInfoVersion == 231) // ShotInfoD4S
969
0
            imNikon.RollAngle = AngleConversion_a(morder, ShotInfo_buf+OrientationOffset);
970
0
          else
971
0
            imNikon.RollAngle = AngleConversion(morder, ShotInfo_buf+OrientationOffset);
972
0
          imNikon.PitchAngle  = AngleConversion (morder, ShotInfo_buf+OrientationOffset+4);
973
0
          imNikon.YawAngle    = AngleConversion (morder, ShotInfo_buf+OrientationOffset+8);
974
0
        }
975
528
        if ((RotationOffset) && (imNikon.MakernotesFlip < 4) && (imNikon.MakernotesFlip >= 0))
976
2
          imNikon.MakernotesFlip = "0863"[imNikon.MakernotesFlip] - '0';
977
528
        ShotInfo_len = 0;
978
528
        free(ShotInfo_buf);
979
528
      }
980
1.32k
    }
981
366k
    else if (tag == 0x00a8)
982
561
    { // contains flash data
983
2.24k
      FORC4 imNikon.FlashInfoVersion =
984
2.24k
          imNikon.FlashInfoVersion * 10 + fgetc(ifp) - '0';
985
561
    }
986
366k
    else if (tag == 0x00b0)
987
1.26k
    {
988
1.26k
      get4(); // ME (multi-exposure) tag version, 4 symbols
989
1.26k
      imNikon.ExposureMode = get4();
990
1.26k
      imNikon.nMEshots = get4();
991
1.26k
      imNikon.MEgainOn = get4();
992
1.26k
    }
993
365k
    else if (tag == 0x00b7) // AFInfo2
994
748
    {
995
748
      if (!imCommon.afcount && len > 4)
996
14
      {
997
14
        imCommon.afdata[imCommon.afcount].AFInfoData_tag = tag;
998
14
        imCommon.afdata[imCommon.afcount].AFInfoData_order = order;
999
14
        int ver = 0;
1000
56
        FORC4  ver = ver * 10 + (fgetc(ifp) - '0');
1001
14
        imCommon.afdata[imCommon.afcount].AFInfoData_version = ver;
1002
14
        imCommon.afdata[imCommon.afcount].AFInfoData_length = len-4;
1003
14
        imCommon.afdata[imCommon.afcount].AFInfoData = (uchar *)calloc(imCommon.afdata[imCommon.afcount].AFInfoData_length+1,1);
1004
14
        fread(imCommon.afdata[imCommon.afcount].AFInfoData, imCommon.afdata[imCommon.afcount].AFInfoData_length, 1, ifp);
1005
14
        imCommon.afcount = 1;
1006
14
      }
1007
748
    }
1008
364k
    else if (tag == 0x00b9)
1009
617
    {
1010
617
      imNikon.AFFineTune = fgetc(ifp);
1011
617
      imNikon.AFFineTuneIndex = fgetc(ifp);
1012
617
      imNikon.AFFineTuneAdj = (int8_t)fgetc(ifp);
1013
617
    }
1014
363k
    else if ((tag == 0x0100) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_UNDEFINED))
1015
627
    {
1016
627
      thumb_offset = ftell(ifp);
1017
627
      thumb_length = len;
1018
627
    }
1019
363k
    else if (tag == 0x0e01)
1020
1.03k
    { /* Nikon Software / in-camera edit Note */
1021
1.03k
      int loopc = 0;
1022
1.03k
      int WhiteBalanceAdj_active = 0;
1023
1.03k
      order = 0x4949;
1024
1.03k
      fseek(ifp, 22, SEEK_CUR);
1025
4.48k
      for (offset = 22; offset + 22 < len; offset += 22 + i)
1026
3.45k
      {
1027
3.45k
        if (loopc++ > 1024)
1028
0
          throw LIBRAW_EXCEPTION_IO_CORRUPT;
1029
3.45k
        tag = get4();
1030
3.45k
        fseek(ifp, 14, SEEK_CUR);
1031
3.45k
        i = get4() - 4;
1032
1033
3.45k
        if (tag == 0x76a43204)
1034
36
        {
1035
36
          WhiteBalanceAdj_active = fgetc(ifp);
1036
36
        }
1037
3.41k
        else if (tag == 0xbf3c6c20)
1038
0
        {
1039
0
          if (WhiteBalanceAdj_active)
1040
0
          {
1041
0
            union {
1042
0
              double dbl;
1043
0
              unsigned long long lng;
1044
0
            } un;
1045
0
            un.dbl = getreal(LIBRAW_EXIFTAG_TYPE_DOUBLE);
1046
0
            if ((un.lng != 0x3FF0000000000000ULL) &&
1047
0
                (un.lng != 0x000000000000F03FULL))
1048
0
            {
1049
0
              cam_mul[0] = float(un.dbl);
1050
0
              cam_mul[2] = getrealf(LIBRAW_EXIFTAG_TYPE_DOUBLE);
1051
0
              cam_mul[1] = cam_mul[3] = 1.f;
1052
0
              i -= 16;
1053
0
            }
1054
0
            else
1055
0
              i -= 8;
1056
0
          }
1057
0
          fseek(ifp, i, SEEK_CUR);
1058
0
        }
1059
3.41k
        else if (tag == 0x76a43207)
1060
39
        {
1061
39
          flip = get2();
1062
39
        }
1063
3.37k
        else
1064
3.37k
        {
1065
3.37k
          fseek(ifp, i, SEEK_CUR);
1066
3.37k
        }
1067
3.45k
      }
1068
1.03k
    }
1069
362k
    else if (tag == 0x0e22)
1070
212
    {
1071
848
      FORC4 imNikon.NEFBitDepth[c] = get2();
1072
212
    }
1073
413k
  next:
1074
413k
    fseek(ifp, save, SEEK_SET);
1075
413k
  }
1076
24.4k
quit:
1077
24.4k
  order = sorder;
1078
24.4k
}
1079
1080
7
unsigned sget4_order (short _order, uchar *s) {
1081
7
  unsigned v;
1082
7
  if (_order == 0x4949)
1083
7
    v= s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24;
1084
0
  else
1085
0
    v= s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3];
1086
7
  return v;
1087
7
}
1088
1089
0
double sget_fixed32u (short _order, uchar *s) {
1090
0
  unsigned v = sget4_order (_order, s);
1091
0
  return ((double)v / 6.5536 + 0.5) / 10000.0;
1092
0
}
1093
1094
0
double AngleConversion_a (short _order, uchar *s) {
1095
0
  double v = sget_fixed32u(_order, s);
1096
0
  if (v < 180.0) return -v;
1097
0
  return 360.0-v;
1098
0
}
1099
1100
0
double AngleConversion (short _order, uchar *s) {
1101
0
  double v = sget_fixed32u(_order, s);
1102
0
  if (v <= 180.0) return v;
1103
0
  return v-360.0;
1104
0
}
1105
1106
/* ========= */
1107
/*
1108
void hexDump(char *title, void *addr, int len)
1109
{
1110
    int i;
1111
    unsigned char buff[17];
1112
    unsigned char *pc = (unsigned char*)addr;
1113
1114
    // Output description if given.
1115
    if (title != NULL)
1116
        printf ("%s:\n", title);
1117
1118
    // Process every byte in the data.
1119
    for (i = 0; i < len; i++) {
1120
        // Multiple of 16 means new line (with line offset).
1121
1122
        if ((i % 16) == 0) {
1123
            // Just don't print ASCII for the zeroth line.
1124
            if (i != 0)
1125
                printf("  %s\n", buff);
1126
1127
            // Output the offset.
1128
            printf("  %04x ", i);
1129
        }
1130
1131
        // Now the hex code for the specific character.
1132
        printf(" %02x", pc[i]);
1133
1134
        // And store a printable ASCII character for later.
1135
        if ((pc[i] < 0x20) || (pc[i] > 0x7e)) {
1136
            buff[i % 16] = '.';
1137
        } else {
1138
            buff[i % 16] = pc[i];
1139
        }
1140
1141
        buff[(i % 16) + 1] = '\0';
1142
    }
1143
1144
    // Pad out last line if not exactly 16 characters.
1145
    while ((i % 16) != 0) {
1146
        printf("   ");
1147
        i++;
1148
    }
1149
1150
    // And print the final ASCII bit.
1151
    printf("  %s\n", buff);
1152
}
1153
*/