Coverage Report

Created: 2026-07-20 07:19

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libraw/src/metadata/fuji.cpp
Line
Count
Source
1
/* -*- C++ -*-
2
 * Copyright 2019-2025 LibRaw LLC (info@libraw.org)
3
 *
4
 LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder,
5
 dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net.
6
 LibRaw do not use RESTRICTED code from dcraw.c
7
8
 LibRaw is free software; you can redistribute it and/or modify
9
 it under the terms of the one of two licenses as you choose:
10
11
1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
12
   (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
13
14
2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
15
   (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
16
17
 */
18
19
#include "../../internal/dcraw_defs.h"
20
#include "../../internal/libraw_checked_buffer.h"
21
22
23
int LibRaw::guess_RAFDataGeneration (uchar *RAFData_start) // returns offset to first valid width/height pair
24
12.2k
{
25
26
/* RAFDataGeneration codes, values are 4 bytes, little endian
27
28
   RAFData gen. 0: no RAFData
29
     DBP for GX680 / DX-2000
30
     E550, E900, (F500 / F505?) F550, F600 / F605, F700, F770 / F775, F800, F810, F900
31
     HS10 HS11, HS20 / HS22, HS30 / HS33 / HS35, HS50
32
     S1, SL1000, S100, S200 / S205, S20Pro, S2Pro, S3Pro, S5Pro
33
     S5000, S5100 / S5500, S5200 / S5600, S6000 / S6500, S7000, S9000 / S9500, S9100 / S9600
34
35
   RAFData gen. 1, offset to WH pair (offsetWH_inRAFData) = 0:
36
   - number in bytes 0..1 is less than 10000
37
   - contains WH pair, recommended image size WH pair, 16 bytes unknown, 2*13 values (for crops, scales?)
38
     X100, X-Pro1, X-S1, X10, XF1
39
40
   RAFData gen. 2, offset to WH pair = 4:
41
   - bytes 0..1 contain a number greater than 10000; bytes 2..3 contain zero;
42
     version is in bytes 0..1, possibly big endian
43
     - contains WH pair, recommended image size WH pair, 16 bytes unknown, 2*13 values
44
     X-E1
45
46
   RAFData gen. 3, offset to WH pair = 4:
47
   - bytes 0..1 contain zero; bytes 2..3 contain version;
48
   - contains a table of 3+2*13 values; first 3 values look like WHW
49
     X-A1, X-A2, X-E2, X-M1
50
     X-T1, X-T10
51
     X100S, X100T
52
     X20, X30, X70, XQ1, XQ2
53
54
   RAFData gen. 4, offset to WH pair = 8:
55
   - same conditions as for RAFData gen. 3, but also adds WRTS in bytes 4..7
56
   - contains a table of 3+2*13 values; first 3 values look like WHW
57
   - H in WHW group has a different meaning if the shot is taken in crop 2 mode
58
     GFX 100, GFX 100S, GFX 100 II
59
     GFX 50R, GFX 50S, GFX 50S II
60
     X-E2S, X-E3, X-H1, X-S10, X-H2
61
     X-T2, X-T3, X-T4, X-T20, X-T30
62
     X-Pro2, X-Pro3
63
     X100F, X100V, X100VI
64
65
   RAFData gen. set to 4096:
66
   - RAFData length is exactly 4096
67
     X-A3, X-A5, X-A7, X-A10, X-A20
68
     X-T100, X-T200,
69
     XF10
70
*/
71
72
12.2k
  int offsetWH_inRAFData=0; /* clang warns about not initialized value */
73
12.2k
  ushort b01  = sget2(RAFData_start);   // bytes 0..1
74
12.2k
  ushort b23  = sget2(RAFData_start+2); // bytes 2..3
75
12.2k
  int is_WRTS = (sget4(RAFData_start + 4) == 0x53545257); // STRW
76
12.2k
  if (b01 && !b23 && (b01<10000))
77
475
  {
78
475
    imFuji.RAFDataGeneration = 1;
79
475
    offsetWH_inRAFData = 0;
80
475
  }
81
11.7k
  else if ((b01>10000) && !b23)
82
302
  {
83
302
    imFuji.RAFDataGeneration = 2;
84
302
    imFuji.RAFDataVersion = b01;
85
302
    offsetWH_inRAFData = 4;
86
302
  }
87
11.4k
  else if (!b01)
88
5.64k
  {
89
5.64k
    if (!is_WRTS)
90
5.64k
    {
91
5.64k
      imFuji.RAFDataGeneration = 3;
92
5.64k
      offsetWH_inRAFData = 4;
93
5.64k
    }
94
0
    else
95
0
    {
96
0
      imFuji.RAFDataGeneration = 4;
97
0
      offsetWH_inRAFData = 8;
98
0
    }
99
5.64k
    imFuji.RAFDataVersion = b23;
100
5.64k
  }
101
102
// printf (">> ID: 0x%llx, RAFDataVersion: 0x%04x, RAFDataGeneration: %d\n",
103
// ilm.CamID, imFuji.RAFDataVersion, imFuji.RAFDataGeneration);
104
105
12.2k
  return offsetWH_inRAFData;
106
12.2k
}
107
108
class fuji_wb_checked_buffer_t : public checked_buffer_t
109
{
110
public:
111
  bool isWB(unsigned offset)
112
13.9k
  {
113
13.9k
    return sget2(offset) != 0 && sget2(offset + 2) != 0 && sget2(offset + 4) != 0 && sget2(offset + 6) != 0 &&
114
4.40k
      sget2(offset + 8) != 0 && sget2(offset + 10) != 0 && sget2(offset) != 0xff && sget2(offset + 2) != 0xff &&
115
3.65k
      sget2(offset + 4) != 0xff && sget2(offset + 6) != 0xff && sget2(offset + 8) != 0xff &&
116
3.07k
      sget2(offset + 10) != 0xff && sget2(offset) == sget2(offset + 6) && sget2(offset) < sget2(offset + 2) &&
117
2.21k
      sget2(offset) < sget2(offset + 4) && sget2(offset) < sget2(offset + 8) && sget2(offset) < sget2(offset + 10)
118
13.9k
      ;
119
13.9k
  }
120
14.6k
  fuji_wb_checked_buffer_t(short ord, int size) : checked_buffer_t(ord, size) {}
121
3.56M
  void set_order(short o) { _order = o; }
122
};
123
124
struct tag2wb_t
125
{
126
  unsigned tag;
127
  int wb;
128
} tag2wbtable[] =
129
{
130
  {0x2000, LIBRAW_WBI_Auto },
131
  {0x2100, LIBRAW_WBI_FineWeather },
132
  {0x2200, LIBRAW_WBI_Shade},
133
  {0x2300, LIBRAW_WBI_FL_D },
134
  {0x2301, LIBRAW_WBI_FL_N},
135
  {0x2302, LIBRAW_WBI_FL_W },
136
  {0x2310, LIBRAW_WBI_FL_WW},
137
  {0x2311, LIBRAW_WBI_FL_L},
138
  {0x2400, LIBRAW_WBI_Tungsten},
139
  {0x2410, LIBRAW_WBI_Flash}
140
};
141
const int tag2wbtable_size = sizeof(tag2wbtable) / sizeof(tag2wbtable[0]);
142
143
144
void LibRaw::parseAdobeRAFMakernote()
145
14.8k
{
146
147
14.8k
  unsigned posPrivateMknBuf=0; /* clang warns about not inited value */
148
14.8k
  unsigned PrivateMknLength;
149
14.8k
  unsigned PrivateOrder;
150
14.8k
  unsigned ifd_start, ifd_len;
151
14.8k
  unsigned PrivateEntries, PrivateTagID;
152
14.8k
  unsigned PrivateTagBytes;
153
14.8k
  int FujiShotSelect;
154
14.8k
  unsigned wb_section_offset = 0;
155
14.8k
  int posWB;
156
14.8k
  int c;
157
158
#if 0
159
#define isWB(posWB)                                                            \
160
  sget2(posWB) != 0 && sget2(posWB + 2) != 0 && sget2(posWB + 4) != 0 &&       \
161
      sget2(posWB + 6) != 0 && sget2(posWB + 8) != 0 &&                        \
162
      sget2(posWB + 10) != 0 && sget2(posWB) != 0xff &&                        \
163
      sget2(posWB + 2) != 0xff && sget2(posWB + 4) != 0xff &&                  \
164
      sget2(posWB + 6) != 0xff && sget2(posWB + 8) != 0xff &&                  \
165
      sget2(posWB + 10) != 0xff && sget2(posWB) == sget2(posWB + 6) &&         \
166
      sget2(posWB) < sget2(posWB + 2) && sget2(posWB) < sget2(posWB + 4) &&    \
167
      sget2(posWB) < sget2(posWB + 8) && sget2(posWB) < sget2(posWB + 10)
168
#endif
169
170
14.8k
#define get_average_WB(wb_index)                                               \
171
14.8k
  do {                                                                         \
172
20.5k
    FORC4 icWBC[wb_index][GRGB_2_RGBG(c)] =                                      \
173
20.5k
      PrivateMknBuf.sget2(posPrivateMknBuf + (c << 1));                        \
174
5.13k
    if ((PrivateTagBytes == 16) && average_WBData) {                             \
175
4.02k
    FORC4 icWBC[wb_index][GRGB_2_RGBG(c)] =                                    \
176
4.02k
         (icWBC[wb_index][GRGB_2_RGBG(c)] +                                \
177
4.02k
          PrivateMknBuf.sget2(posPrivateMknBuf + (c << 1)+8)) /2;          \
178
1.00k
    }                                                                            \
179
5.13k
    if (use_WBcorr_coeffs) {                                                     \
180
1.26k
    icWBC[wb_index][0] = int(icWBC[wb_index][0]*wbR_corr);                     \
181
1.26k
    icWBC[wb_index][2] = int(icWBC[wb_index][2]*wbB_corr);                     \
182
1.26k
    }                                                                            \
183
5.13k
  } while(0)
184
185
14.8k
  ushort use_WBcorr_coeffs = 0;
186
14.8k
  double wbR_corr = 1.0;
187
14.8k
  double wbB_corr = 1.0;
188
189
14.8k
  if (strstr(model, "S2Pro")
190
14.8k
      || strstr(model, "S20Pro")
191
14.6k
      || strstr(model, "F700")
192
14.4k
      || strstr(model, "S5000")
193
14.4k
      || strstr(model, "S7000")
194
14.8k
      ) {
195
546
    use_WBcorr_coeffs = 1;
196
546
    wbR_corr = 10.0 / 17.0 / 0.652941;
197
546
    wbB_corr = 2.0 /3.0 / (3.0 / 4.0 + 1.0 / 300.0);
198
14.3k
  } else if (strstr(model, "DBP") || strstr(model, "DX-2000")) {
199
236
    use_WBcorr_coeffs = 1;
200
236
    wbR_corr = 0.7632653061;
201
236
    wbB_corr = 0.8591549296;
202
236
  }
203
204
14.8k
  FujiShotSelect = LIM(shot_select, 0, 1);
205
14.8k
  int average_WBData = 1;
206
207
14.8k
  order = 0x4d4d;
208
14.8k
  PrivateMknLength = get4();
209
210
  // At least 0x36 bytes because of memcpy(imFuji.RAFVersion, PrivateMknBuf + 0x32, 4);
211
14.8k
  if ((PrivateMknLength >= 0x36) && (PrivateMknLength < 10240000)) // 1024b for safety
212
14.6k
  {
213
14.6k
  fuji_wb_checked_buffer_t PrivateMknBuf(order, PrivateMknLength+1024);
214
14.6k
    fread(PrivateMknBuf.data(), PrivateMknLength, 1, ifp);
215
14.6k
    memcpy(imFuji.SerialSignature, PrivateMknBuf.data() + 6, 0x0c);
216
14.6k
    imFuji.SerialSignature[0x0c] = 0;
217
14.6k
    memcpy(imFuji.SensorID, imFuji.SerialSignature + 0x06, 0x04);
218
14.6k
    imFuji.SensorID[0x04] = 0;
219
14.6k
    c = 11;
220
15.8k
    while (isdigit(imFuji.SerialSignature[c]) && (c>0))
221
1.11k
      c--;
222
14.6k
    ilm.CamID = unique_id = (unsigned long long)atoi(imFuji.SerialSignature+c+1);
223
14.6k
    memcpy(model, PrivateMknBuf.data() + 0x12, 0x20);
224
14.6k
    model[0x20] = 0;
225
14.6k
    memcpy(imFuji.RAFVersion, PrivateMknBuf.data() + 0x32, 4);
226
14.6k
    imFuji.RAFVersion[4] = 0;
227
228
14.6k
    PrivateOrder = PrivateMknBuf.sget2(0);
229
14.6k
    unsigned s, l;
230
14.6k
    s = ifd_start = PrivateMknBuf.sget4(2)+6;
231
14.6k
    l = ifd_len = PrivateMknBuf.sget4(ifd_start);
232
233
14.6k
  if (!PrivateMknBuf.sget4(ifd_start+ifd_len+4))
234
2.06k
      FujiShotSelect = 0;
235
236
14.6k
    if ((FujiShotSelect == 1) && (PrivateMknLength > ifd_len*2)) {
237
0
      ifd_start += (ifd_len+4);
238
0
      ifd_len = PrivateMknBuf.sget4(ifd_start);
239
0
      if ((ifd_start+ifd_len) > PrivateMknLength) {
240
0
        ifd_start = s;
241
0
        ifd_len = l;
242
0
        FujiShotSelect = 0;
243
0
      }
244
14.6k
    } else FujiShotSelect = 0;
245
246
14.6k
    PrivateEntries = PrivateMknBuf.sget4(ifd_start + 4);
247
14.6k
    if ((PrivateEntries > 1000) ||
248
13.1k
        ((PrivateOrder != 0x4d4d) && (PrivateOrder != 0x4949)))
249
685
    {
250
685
      return;
251
685
    }
252
14.0k
    posPrivateMknBuf = (ifd_start+8);
253
254
    /*
255
     * because Adobe DNG converter strips or misplaces 0xfnnn tags,
256
     * for now, Auto WB is missing for the following cameras:
257
     * - F550EXR / F600EXR / F770EXR / F800EXR / F900EXR
258
     * - HS10 / HS11 / HS20EXR / HS30EXR / HS33EXR / HS35EXR / HS50EXR
259
     * - S1 / SL1000
260
     **/
261
1.78M
    while (PrivateEntries--)
262
1.77M
    {
263
1.77M
    PrivateMknBuf.set_order(0x4d4d);
264
1.77M
    order = 0x4d4d;
265
1.77M
      PrivateTagID = PrivateMknBuf.sget2(posPrivateMknBuf);
266
1.77M
      PrivateTagBytes = PrivateMknBuf.sget2(posPrivateMknBuf + 2);
267
1.77M
      posPrivateMknBuf += 4;
268
1.77M
    PrivateMknBuf.set_order(PrivateOrder);
269
1.77M
    order = PrivateOrder;
270
271
1.77M
    if (PrivateTagID >= 0x2000 && PrivateTagID <= 0x2410)
272
4.39k
    {
273
35.0k
      for(int q = 0; q < tag2wbtable_size; q++)
274
33.3k
        if (tag2wbtable[q].tag == PrivateTagID)
275
2.73k
        {
276
2.73k
          get_average_WB(tag2wbtable[q].wb);
277
2.73k
          break;
278
2.73k
        }
279
4.39k
    }
280
1.77M
      else if (PrivateTagID == 0x2f00)
281
3.71k
      {
282
3.71k
        int nWBs = MIN(PrivateMknBuf.sget4(posPrivateMknBuf), 6);
283
3.71k
        posWB = posPrivateMknBuf + 4;
284
24.8k
        for (int wb_ind = LIBRAW_WBI_Custom1; wb_ind < LIBRAW_WBI_Custom1+nWBs; wb_ind++) {
285
84.6k
          FORC4 icWBC[wb_ind][GRGB_2_RGBG(c)] =
286
84.6k
        PrivateMknBuf.sget2(posWB + (c << 1));
287
21.1k
          if ((PrivateTagBytes >= unsigned(4+16*nWBs)) && average_WBData) {
288
96
            posWB += 8;
289
384
            FORC4 icWBC[wb_ind][GRGB_2_RGBG(c)] =
290
384
                    (icWBC[wb_ind][GRGB_2_RGBG(c)] +
291
384
            PrivateMknBuf.sget2(posWB + (c << 1))) /2;
292
96
          }
293
21.1k
          if (use_WBcorr_coeffs) {
294
4.43k
             icWBC[wb_ind][0] = int(icWBC[wb_ind][0]*wbR_corr);
295
4.43k
             icWBC[wb_ind][2] = int(icWBC[wb_ind][2]*wbB_corr);
296
4.43k
          }
297
21.1k
          posWB += 8;
298
21.1k
        }
299
3.71k
      }
300
1.76M
      else if (PrivateTagID == 0x2ff0)
301
2.40k
      {
302
2.40k
        get_average_WB(LIBRAW_WBI_AsShot);
303
9.60k
        FORC4 cam_mul[c] = float(icWBC[LIBRAW_WBI_AsShot][c]);
304
2.40k
      }
305
1.76M
      else if ((PrivateTagID == 0x4000) &&
306
780
               ((PrivateTagBytes == 8) || (PrivateTagBytes == 16)))
307
433
      {
308
433
        imFuji.BlackLevel[0] = PrivateTagBytes / 2;
309
1.73k
        FORC4 imFuji.BlackLevel[GRGB_2_RGBG(c)+1] =
310
1.73k
      PrivateMknBuf.sget2(posPrivateMknBuf + (c << 1));
311
433
        if (imFuji.BlackLevel[0] == 8) {
312
1.24k
          FORC4 imFuji.BlackLevel[GRGB_2_RGBG(c) + 5] =
313
1.24k
        PrivateMknBuf.sget2(posPrivateMknBuf + (c << 1) + 8);
314
311
        }
315
433
      }
316
1.76M
      else if (PrivateTagID == 0x9650)
317
97
      {
318
97
        short a = (short)PrivateMknBuf.sget2(posPrivateMknBuf);
319
97
        float b = fMAX(1.0f, PrivateMknBuf.sget2(posPrivateMknBuf + 2));
320
97
        imFuji.ExpoMidPointShift = a / b;
321
97
        imCommon.ExposureCalibrationShift += imFuji.ExpoMidPointShift;
322
97
      }
323
1.76M
      else if ((PrivateTagID == 0xc000) && (PrivateTagBytes > 3) &&
324
12.6k
               (PrivateTagBytes < 10240000))
325
12.6k
      {
326
12.6k
    PrivateMknBuf.set_order(0x4949);
327
12.6k
    order = 0x4949;
328
12.6k
        if (PrivateTagBytes != 4096) // not one of Fuji X-A3, X-A5, X-A7, X-A10, X-A20, X-T100, X-T200, XF10
329
12.0k
        {
330
12.0k
          int is34 = 0;
331
12.0k
      PrivateMknBuf.checkoffset(posPrivateMknBuf + 8); // will raise exception if no space
332
12.0k
          guess_RAFDataGeneration (PrivateMknBuf.data() + posPrivateMknBuf);
333
334
// printf (">> ID: 0x%llx, RAFDataVersion: 0x%04x, RAFDataGeneration: %d\n",
335
// ilm.CamID, imFuji.RAFDataVersion, imFuji.RAFDataGeneration);
336
337
22.8M
          for (posWB = 0; posWB < (int)PrivateTagBytes - 16; posWB++)
338
22.7M
          {
339
22.7M
            PrivateMknBuf.checkoffset(posWB + 12); // will raise exception if no space
340
22.7M
            if ((!memcmp(PrivateMknBuf.data() + posWB, "TSNERDTS", 8) &&
341
391
                 (PrivateMknBuf.sget2( posWB + 10) > 125)))
342
338
            {
343
338
              posWB += 10;
344
338
              icWBC[LIBRAW_WBI_Auto][1] =
345
338
                  icWBC[LIBRAW_WBI_Auto][3] =
346
338
          PrivateMknBuf.sget2(posWB);
347
338
              icWBC[LIBRAW_WBI_Auto][0] =
348
338
          PrivateMknBuf.sget2(posWB + 2);
349
338
              icWBC[LIBRAW_WBI_Auto][2] =
350
338
          PrivateMknBuf.sget2(posWB + 4);
351
338
              break;
352
338
            }
353
22.7M
          }
354
355
12.0k
          if ((imFuji.RAFDataVersion == 0x0260) || // X-Pro3, GFX 100S
356
11.7k
              (imFuji.RAFDataVersion == 0x0261) || // X100V, GFX 50S II
357
11.7k
              (imFuji.RAFDataVersion == 0x0262) || // X-T4
358
11.6k
              (imFuji.RAFDataVersion == 0x0263) || // X-H2s
359
11.6k
              (imFuji.RAFDataVersion == 0x0264) || // X-S10, X-H2
360
11.5k
              (imFuji.RAFDataVersion == 0x0265) || // X-E4, X-T5
361
11.4k
              (imFuji.RAFDataVersion == 0x0266) || // X-T30 II
362
11.1k
              (imFuji.RAFDataVersion == 0x0267) || // GFX 100 II
363
11.0k
              (imFuji.RAFDataVersion == 0x0368) || // GFX 100S II
364
11.0k
              (imFuji.RAFDataVersion == 0x0369) || // X100VI
365
10.4k
              (imFuji.RAFDataVersion == 0x036a) || // X-T50
366
10.4k
              (imFuji.RAFDataVersion == 0x036b) || // X-M5
367
10.4k
                !strcmp(model, "X-Pro3")      ||
368
10.3k
                !strcmp(model, "GFX 100S II") || !strcmp(model, "GFX100S II") ||
369
10.2k
                !strcmp(model, "GFX 100S")    || !strcmp(model, "GFX100S")    ||
370
10.2k
                !strcmp(model, "GFX 100 II")  || !strcmp(model, "GFX100 II")  ||
371
10.1k
                !strcmp(model, "GFX 50S II")  || !strcmp(model, "GFX50S II")  ||
372
10.0k
                !strcmp(model, "X100VI")      ||
373
9.95k
                !strcmp(model, "X100V")       ||
374
9.90k
                !strcmp(model, "X-H2")        ||
375
9.67k
                !strcmp(model, "X-H2S")       ||
376
9.53k
                !strcmp(model, "X-T4")        ||
377
9.45k
                !strcmp(model, "X-T50")       ||
378
9.32k
                !strcmp(model, "X-T5")        ||
379
9.16k
                !strcmp(model, "X-M5")        ||
380
9.11k
                !strcmp(model, "X-E4")        ||
381
9.09k
                !strcmp(model, "X-T30 II")    ||
382
8.96k
                !strcmp(model, "X-S10"))
383
2.92k
            is34 = 1;
384
385
12.0k
          if (imFuji.RAFDataVersion == 0x4500) // X-E1, RAFData gen. 3
386
66
          {
387
66
            wb_section_offset = 0x13ac;
388
66
          }
389
11.9k
          else if (imFuji.RAFDataVersion == 0x0146 || // X20
390
11.6k
                   imFuji.RAFDataVersion == 0x0149 || // X100S
391
11.5k
                   imFuji.RAFDataVersion == 0x0249)   // X100S
392
168
          {
393
168
            wb_section_offset = 0x1410;
394
168
          }
395
11.8k
          else if (imFuji.RAFDataVersion == 0x014d || // X-M1
396
11.5k
                   imFuji.RAFDataVersion == 0x014e)   // X-A1, X-A2
397
129
          {
398
129
            wb_section_offset = 0x1474;
399
129
          }
400
11.6k
          else if (imFuji.RAFDataVersion == 0x014f || // X-E2
401
11.3k
                   imFuji.RAFDataVersion == 0x024f || // X-E2
402
10.6k
                   imFuji.RAFDataVersion == 0x025d || // X-H1
403
10.6k
                   imFuji.RAFDataVersion == 0x035d)   // X-H1
404
914
          {
405
914
            wb_section_offset = 0x1480;
406
914
          }
407
10.7k
          else if (imFuji.RAFDataVersion == 0x0150) // XQ1, XQ2
408
79
          {
409
79
            wb_section_offset = 0x1414;
410
79
          }
411
10.6k
          else if (imFuji.RAFDataVersion == 0x0151 || // X-T1 w/diff. fws
412
10.4k
                   imFuji.RAFDataVersion == 0x0251 || imFuji.RAFDataVersion == 0x0351 ||
413
10.3k
                   imFuji.RAFDataVersion == 0x0451 || imFuji.RAFDataVersion == 0x0551)
414
120
          {
415
120
            wb_section_offset = 0x14b0;
416
120
          }
417
10.5k
          else if (imFuji.RAFDataVersion == 0x0152 || // X30
418
10.2k
                   imFuji.RAFDataVersion == 0x0153)   // X100T
419
89
          {
420
89
            wb_section_offset = 0x1444;
421
89
          }
422
10.4k
          else if (imFuji.RAFDataVersion == 0x0154) // X-T10
423
19
          {
424
19
            wb_section_offset = 0x1824;
425
19
          }
426
10.4k
          else if (imFuji.RAFDataVersion == 0x0155) // X70
427
18
          {
428
18
            wb_section_offset = 0x17b4;
429
18
          }
430
10.4k
          else if (imFuji.RAFDataVersion == 0x0255 || // X-Pro2
431
10.1k
                   imFuji.RAFDataVersion == 0x0455)
432
53
          {
433
53
            wb_section_offset = 0x135c;
434
53
          }
435
10.3k
          else if (imFuji.RAFDataVersion == 0x0258 || // X-T2
436
9.93k
                   imFuji.RAFDataVersion == 0x025b)   // X-T20
437
217
          {
438
217
            wb_section_offset = 0x13dc;
439
217
          }
440
10.1k
          else if (imFuji.RAFDataVersion == 0x0259) // X100F
441
83
          {
442
83
            wb_section_offset = 0x1370;
443
83
          }
444
10.0k
          else if (imFuji.RAFDataVersion == 0x025a || // GFX 50S
445
9.82k
                   imFuji.RAFDataVersion == 0x045a)
446
59
          {
447
59
            wb_section_offset = 0x1424;
448
59
         }
449
10.0k
          else if (imFuji.RAFDataVersion == 0x025c) // X-E3
450
48
          {
451
48
            wb_section_offset = 0x141c;
452
48
          }
453
9.98k
          else if (imFuji.RAFDataVersion == 0x025e) // X-T3
454
33
          {
455
33
            wb_section_offset = 0x2014;
456
33
          }
457
9.94k
          else if (imFuji.RAFDataVersion == 0x025f) // X-T30, GFX 50R, GFX 100 (? RAFDataVersion 0x045f)
458
368
          {
459
368
            if (!strcmp(model, "X-T30")) {
460
238
              if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x20b8))
461
0
                wb_section_offset = 0x20b8;
462
238
              else if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x20c8))
463
0
            wb_section_offset = 0x20c8;
464
238
            }
465
130
            else if (!strcmp(model, "GFX 50R"))
466
13
              wb_section_offset = 0x1424;
467
117
            else if (!strcmp(model, "GFX 100"))
468
26
              wb_section_offset = 0x20e4;
469
368
          }
470
9.58k
          else if (imFuji.RAFDataVersion == 0x0260) // X-Pro3, GFX 100S
471
40
          {
472
40
           if (!strcmp(model, "X-Pro3"))
473
0
              wb_section_offset = 0x20e8;
474
40
            else if (!strcmp(model, "GFX 100S") || !strcmp(model, "GFX100S"))
475
0
              wb_section_offset = 0x2108;
476
40
          }
477
9.54k
          else if (imFuji.RAFDataVersion == 0x0261) // X100V, GFX 50S II
478
40
          {
479
40
            if (!strcmp(model, "X100V"))
480
0
              wb_section_offset = 0x2078;
481
40
            else if (!strcmp(model, "GFX 50S II") || !strcmp(model, "GFX50S II"))
482
0
              wb_section_offset = 0x214c;
483
40
          }
484
9.50k
          else if (imFuji.RAFDataVersion == 0x0262) // X-T4
485
68
          {
486
68
            if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x21c8))
487
0
              wb_section_offset = 0x21c8;
488
68
            else if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x21cc))
489
0
              wb_section_offset = 0x21cc;
490
68
          }
491
9.43k
          else if (imFuji.RAFDataVersion == 0x0263) // X-H2S
492
11
          {
493
11
            wb_section_offset = 0x0b40;
494
11
          }
495
9.42k
          else if (imFuji.RAFDataVersion == 0x0264) // X-S10, X-H2
496
103
          {
497
103
            if (!strcmp(model, "X-S10"))
498
51
              wb_section_offset = 0x21de;
499
52
            else if (!strcmp(model, "X-H2"))
500
20
              wb_section_offset = 0x0b3e;
501
103
          }
502
9.31k
          else if ((imFuji.RAFDataVersion == 0x0265)  || // X-E4, X-T5
503
8.96k
                   (imFuji.RAFDataVersion == 0x0266))    // X-T30 II, X-S20
504
373
          {
505
373
            if (!strcmp(model, "X-T5") ||
506
334
                !strcmp(model, "X-S20"))
507
50
              wb_section_offset = 0x0c72;
508
323
            else
509
323
              wb_section_offset = 0x21cc;
510
373
          }
511
8.94k
          else if (imFuji.RAFDataVersion == 0x0267) // GFX 100 II
512
85
          {
513
85
            wb_section_offset = 0x0cae;
514
85
          }
515
8.86k
          else if (imFuji.RAFDataVersion == 0x0355) // X-E2S
516
69
          {
517
69
            wb_section_offset = 0x1840;
518
69
          }
519
8.79k
          else if (imFuji.RAFDataVersion == 0x0368) // GFX 100S II
520
62
          {
521
62
            wb_section_offset = 0x0cba;
522
62
          }
523
8.72k
          else if (imFuji.RAFDataVersion == 0x0369) // X100VI
524
584
          {
525
584
            wb_section_offset = 0x0c5a;
526
584
          }
527
8.14k
          else if (imFuji.RAFDataVersion == 0x036a) // X-T50
528
0
          {
529
0
            wb_section_offset = 0x0cca;
530
0
          }
531
8.14k
          else if (imFuji.RAFDataVersion == 0x036b) // X-M5
532
23
          {
533
23
            wb_section_offset = 0x0cea;
534
23
          }
535
536
/* try for unknown RAF Data versions */
537
8.12k
          else if (!strcmp(model, "X-Pro2"))
538
184
          {
539
184
            if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x135c))
540
84
              wb_section_offset = 0x135c;
541
184
          }
542
7.93k
          else if (!strcmp(model, "X100F"))
543
58
          {
544
58
            if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x1370))
545
9
              wb_section_offset = 0x1370;
546
58
          }
547
7.88k
          else if (!strcmp(model, "X-E1"))
548
109
          {
549
109
            if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x13ac))
550
22
              wb_section_offset = 0x13ac;
551
109
          }
552
7.77k
          else if (!strcmp(model, "X-T2") ||
553
7.40k
                   !strcmp(model, "X-T20"))
554
213
          {
555
213
            if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x13dc))
556
1
              wb_section_offset = 0x13dc;
557
213
          }
558
7.55k
          else if (!strcmp(model, "X20") ||
559
6.58k
                   !strcmp(model, "X100S"))
560
808
          {
561
808
            if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x1410))
562
95
              wb_section_offset = 0x1410;
563
808
          }
564
6.75k
          else if (!strcmp(model, "XQ1") ||
565
6.34k
                   !strcmp(model, "XQ2"))
566
254
          {
567
254
            if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x1414))
568
78
              wb_section_offset = 0x1414;
569
254
          }
570
6.49k
          else if (!strcmp(model, "X-E3"))
571
100
          {
572
100
            if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x141c))
573
11
              wb_section_offset = 0x141c;
574
100
          }
575
6.39k
          else if (!strcmp(model, "GFX 50S") ||
576
6.08k
                   !strcmp(model, "GFX 50R"))
577
264
          {
578
264
            if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x1424))
579
62
              wb_section_offset = 0x1424;
580
264
          }
581
6.13k
          else if (!strcmp(model, "GFX 50S II") ||
582
5.84k
                   !strcmp(model, "GFX50S II")) {
583
40
            if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x214c))
584
0
              wb_section_offset = 0x214c;
585
40
          }
586
6.09k
          else if (!strcmp(model, "X30") ||
587
5.79k
                   !strcmp(model, "X100T"))
588
143
          {
589
143
            if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x1444))
590
0
              wb_section_offset = 0x1444;
591
143
          }
592
5.94k
          else if (!strcmp(model, "X-M1") ||
593
5.57k
                   !strcmp(model, "X-A1") ||
594
5.30k
                   !strcmp(model, "X-A2"))
595
512
          {
596
512
            if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x1474))
597
37
              wb_section_offset = 0x1474;
598
512
          }
599
5.43k
          else if (!strcmp(model, "X-E2") ||
600
5.17k
                   !strcmp(model, "X-H1"))
601
89
          {
602
89
            if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x1480))
603
0
              wb_section_offset = 0x1480;
604
89
          }
605
5.34k
          else if (!strcmp(model, "X-T1"))
606
116
          {
607
116
            if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x14b0))
608
3
              wb_section_offset = 0x14b0;
609
116
          }
610
5.23k
          else if (!strcmp(model, "X70"))
611
153
          {
612
153
            if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x17b4))
613
61
              wb_section_offset = 0x17b4;
614
153
          }
615
5.07k
          else if (!strcmp(model, "X-T10"))
616
60
          {
617
60
            if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x1824))
618
21
              wb_section_offset = 0x1824;
619
60
          }
620
5.01k
          else if (!strcmp(model, "X-E2S"))
621
61
          {
622
61
            if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x1840))
623
11
              wb_section_offset = 0x1840;
624
61
          }
625
4.95k
          else if (!strcmp(model, "X-T3"))
626
77
          {
627
77
            if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x2014))
628
0
              wb_section_offset = 0x2014;
629
77
          }
630
4.88k
          else if (!strcmp(model, "X100VI"))
631
113
          {
632
113
            if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x0c5a))
633
33
              wb_section_offset = 0x0c5a;
634
113
          }
635
4.76k
          else if (!strcmp(model, "X100V"))
636
46
          {
637
46
            if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x2078))
638
0
              wb_section_offset = 0x2078;
639
46
          }
640
4.72k
          else if (!strcmp(model, "X-T30"))
641
195
          {
642
195
            if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x20b8))
643
0
              wb_section_offset = 0x20b8;
644
195
            else if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x20c8))
645
0
              wb_section_offset = 0x20c8;
646
195
          }
647
4.52k
          else if (!strcmp(model, "GFX 100"))
648
148
          {
649
148
            if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x20e4))
650
0
              wb_section_offset = 0x20e4;
651
148
          }
652
4.37k
          else if (!strcmp(model, "X-Pro3"))
653
87
          {
654
87
            if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x20e8))
655
0
              wb_section_offset = 0x20e8;
656
87
          }
657
4.29k
          else if (!strcmp(model, "GFX100S") ||
658
4.02k
                   !strcmp(model, "GFX 100S"))
659
82
          {
660
82
            if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x2108))
661
0
              wb_section_offset = 0x2108;
662
82
          }
663
4.21k
          else if (!strcmp(model, "X-T4"))
664
83
          {
665
83
            if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x21c8))
666
0
              wb_section_offset = 0x21c8;
667
83
            else if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x21cc))
668
0
              wb_section_offset = 0x21cc;
669
83
          }
670
4.12k
          else if ((!strcmp(model, "X-E4"))       ||
671
3.86k
                   (!strcmp(model, "X-T30 II")))
672
113
          {
673
113
            if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x21cc))
674
0
              wb_section_offset = 0x21cc;
675
113
          }
676
4.01k
          else if (!strcmp(model, "X-S10"))
677
62
          {
678
62
            if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x21de))
679
0
              wb_section_offset = 0x21de;
680
62
          }
681
3.95k
          else if (!strcmp(model, "X-H2"))
682
238
          {
683
238
            if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x0b3e))
684
18
              wb_section_offset = 0x0b3e;
685
238
          }
686
3.71k
          else if (!strcmp(model, "X-H2S"))
687
134
          {
688
134
            if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x0b40))
689
6
              wb_section_offset = 0x0b40;
690
134
          }
691
3.58k
          else if (!strcmp(model, "X-T5") ||
692
3.16k
                   !strcmp(model, "X-S20"))
693
235
          {
694
235
            if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x0c72))
695
101
              wb_section_offset = 0x0c72;
696
235
          }
697
3.34k
          else if (!strcmp(model, "GFX 100 II") ||
698
3.00k
                   !strcmp(model, "GFX100 II"))
699
99
          {
700
99
            if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x0cae))
701
4
              wb_section_offset = 0x0cae;
702
99
          }
703
3.24k
          else if (!strcmp(model, "GFX 100S II") ||
704
3.00k
                   !strcmp(model, "GFX100S II"))
705
34
          {
706
34
            if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x0cba))
707
0
              wb_section_offset = 0x0cba;
708
34
          }
709
3.21k
          else if (!strcmp(model, "X-T50"))
710
40
          {
711
40
            if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x0cca))
712
0
              wb_section_offset = 0x0cca;
713
40
          }
714
3.17k
          else if (!strcmp(model, "X-M5"))
715
49
          {
716
49
            if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x0cea))
717
6
              wb_section_offset = 0x0cea;
718
49
          }
719
720
/* no RAF Data version for the models below */
721
3.12k
          else if (!strcmp(model, "FinePix X100")) // X100 0 0x19f0 0x19e8
722
341
          {
723
341
            if (!strcmp(imFuji.RAFVersion, "0069"))
724
89
              wb_section_offset = 0x19e8;
725
252
            else if (!strcmp(imFuji.RAFVersion, "0100") ||
726
173
                     !strcmp(imFuji.RAFVersion, "0110"))
727
140
              wb_section_offset = 0x19f0;
728
112
      else
729
112
      {
730
112
        if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x19e8))
731
31
          wb_section_offset = 0x19e8;
732
81
                else if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x19f0))
733
15
                  wb_section_offset = 0x19f0;
734
112
      }
735
341
          }
736
2.78k
          else if (!strcmp(model, "X-Pro1")) // X-Pro1 0 0x13a4
737
459
          {
738
459
            if (!strcmp(imFuji.RAFVersion, "0100") ||
739
377
                !strcmp(imFuji.RAFVersion, "0101") ||
740
288
                !strcmp(imFuji.RAFVersion, "0204"))
741
190
              wb_section_offset = 0x13a4;
742
269
            else if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x13a4))
743
86
              wb_section_offset = 0x13a4;
744
459
          }
745
2.32k
          else if (!strcmp(model, "XF1")) // XF1 0 0x138c
746
286
          {
747
286
            if (!strcmp(imFuji.RAFVersion, "0100"))
748
87
              wb_section_offset = 0x138c;
749
199
            else if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x138c))
750
79
              wb_section_offset = 0x138c;
751
286
          }
752
2.03k
          else if (!strcmp(model, "X-S1")) // X-S1 0 0x1284
753
72
          {
754
72
            if (!strcmp(imFuji.RAFVersion, "0100"))
755
18
              wb_section_offset = 0x1284;
756
54
            else if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x1284))
757
18
              wb_section_offset = 0x1284;
758
72
          }
759
1.96k
          else if (!strcmp(model, "X10")) // X10 0 0x1280 0x12d4
760
1.27k
          {
761
1.27k
            if (!strcmp(imFuji.RAFVersion, "0100") ||
762
1.21k
                !strcmp(imFuji.RAFVersion, "0102"))
763
104
              wb_section_offset = 0x1280;
764
1.17k
            else if (!strcmp(imFuji.RAFVersion, "0103"))
765
88
              wb_section_offset = 0x12d4;
766
1.08k
            else if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x1280))
767
58
          wb_section_offset = 0x1280;
768
1.02k
            else if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x12d4))
769
72
              wb_section_offset = 0x12d4;
770
1.27k
          }
771
690
          else if (!strcmp(model, "XF1")) // XF1 0 0x138c
772
0
          {
773
0
            if (!strcmp(imFuji.RAFVersion, "0100"))
774
0
              wb_section_offset = 0x138c;
775
0
            else if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x138c))
776
0
              wb_section_offset = 0x138c;
777
0
          }
778
779
12.0k
          if (wb_section_offset && PrivateMknBuf.isWB(posPrivateMknBuf + wb_section_offset))
780
1.02k
          {
781
782
1.02k
            if (!imFuji.RAFDataVersion)
783
789
            {
784
789
              posWB = posPrivateMknBuf + wb_section_offset - 6;
785
789
              icWBC[LIBRAW_WBI_Auto][1] = icWBC[LIBRAW_WBI_Auto][3] = PrivateMknBuf.sget2(posWB);
786
789
              icWBC[LIBRAW_WBI_Auto][0] = PrivateMknBuf.sget2(posWB + 2);
787
789
              icWBC[LIBRAW_WBI_Auto][2] = PrivateMknBuf.sget2(posWB + 4);
788
789
            }
789
790
1.02k
            posWB = posPrivateMknBuf + wb_section_offset;
791
7.16k
            for (int wb_ind = 0; wb_ind < (int)Fuji_wb_list1.size(); posWB += 6, wb_ind++)
792
6.13k
            {
793
6.13k
              icWBC[Fuji_wb_list1[wb_ind]][1] = icWBC[Fuji_wb_list1[wb_ind]][3] = PrivateMknBuf.sget2(posWB);
794
6.13k
              icWBC[Fuji_wb_list1[wb_ind]][0] = PrivateMknBuf.sget2(posWB + 2);
795
6.13k
              icWBC[Fuji_wb_list1[wb_ind]][2] = PrivateMknBuf.sget2(posWB + 4);
796
6.13k
            }
797
1.02k
            int found = 0;
798
1.02k
            if (is34)
799
146
              posWB += 0x30;
800
1.02k
            posWB += 0xc0;
801
1.02k
            ushort Gval = PrivateMknBuf.sget2(posWB);
802
4.34k
            for (int posEndCCTsection = posWB; posEndCCTsection < (posWB + 30);
803
3.32k
                 posEndCCTsection += 6)
804
3.78k
            {
805
3.78k
              if (PrivateMknBuf.sget2(posEndCCTsection) != Gval)
806
463
              {
807
463
                if (is34)
808
125
                  wb_section_offset = posEndCCTsection - 34*3*2; // 34 records, 3 2-byte values in a record
809
338
                else
810
338
                  wb_section_offset = posEndCCTsection - 31*3*2; // 31 records, 3 2-byte values in a record
811
463
                found = 1;
812
463
                break;
813
463
              }
814
3.78k
            }
815
816
1.02k
            if (found)
817
463
            {
818
14.8k
              for (int iCCT = 0; iCCT < 31; iCCT++)
819
14.3k
              {
820
14.3k
                icWBCCTC[iCCT][0] = float(FujiCCT_K[iCCT]);
821
14.3k
                icWBCCTC[iCCT][1] = PrivateMknBuf.sget2(wb_section_offset + iCCT * 6 + 2);
822
14.3k
                icWBCCTC[iCCT][2] = icWBCCTC[iCCT][4] = PrivateMknBuf.sget2(wb_section_offset + iCCT * 6);
823
14.3k
                icWBCCTC[iCCT][3] = PrivateMknBuf.sget2(wb_section_offset + iCCT * 6 + 4);
824
14.3k
              }
825
463
            }
826
1.02k
          }
827
12.0k
        }
828
584
        else // process 4K raf data
829
584
        {
830
584
          int wb[4];
831
584
          int nWB, tWB, pWB;
832
584
          int iCCT = 0;
833
584
          imFuji.RAFDataGeneration = 4096; // X-A3, X-A5, X-A7, X-A10, X-A20, X-T100, X-T200, XF10
834
584
          posWB = posPrivateMknBuf + 0x200;
835
24.0k
          for (int wb_ind = 0; wb_ind < 42; wb_ind++)
836
23.4k
          {
837
23.4k
            nWB = PrivateMknBuf.sget4(posWB);
838
23.4k
            posWB += 4;
839
23.4k
            tWB = PrivateMknBuf.sget4(posWB);
840
23.4k
            posWB += 4;
841
23.4k
            wb[0] = PrivateMknBuf.sget4(posWB) << 1;
842
23.4k
            posWB += 4;
843
23.4k
            wb[1] = PrivateMknBuf.sget4(posWB);
844
23.4k
            posWB += 4;
845
23.4k
            wb[3] = PrivateMknBuf.sget4(posWB);
846
23.4k
            posWB += 4;
847
23.4k
            wb[2] = PrivateMknBuf.sget4(posWB) << 1;
848
23.4k
            posWB += 4;
849
850
23.4k
            if (tWB && (iCCT < 64))
851
14.0k
            {
852
14.0k
              icWBCCTC[iCCT][0] = float(tWB);
853
56.3k
              FORC4 icWBCCTC[iCCT][c + 1] = float(wb[c]);
854
14.0k
              iCCT++;
855
14.0k
            }
856
23.4k
            if (nWB != 0x46)
857
23.2k
            {
858
167k
              for (pWB = 1; pWB < (int)Fuji_wb_list2.size(); pWB += 2)
859
154k
              {
860
154k
                if (Fuji_wb_list2[pWB] == nWB)
861
10.1k
                {
862
40.6k
                  FORC4 icWBC[Fuji_wb_list2[pWB - 1]][c] = wb[c];
863
10.1k
                  break;
864
10.1k
                }
865
154k
              }
866
23.2k
            }
867
23.4k
          }
868
584
        }
869
12.6k
      }
870
1.77M
      posPrivateMknBuf += PrivateTagBytes;
871
1.77M
    }
872
14.0k
  }
873
14.8k
#undef get_average_WB
874
14.8k
}
875
876
void LibRaw::parseFujiMakernotes(unsigned tag, unsigned type, unsigned len,
877
                                 unsigned /*dng_writer*/)
878
215k
{
879
215k
  if (tag == 0x0010)
880
7.99k
  {
881
7.99k
    char FujiSerial[sizeof(imgdata.shootinginfo.InternalBodySerial)];
882
7.99k
  char *words[4] = { 0,0,0,0 };
883
7.99k
    char yy[2], mm[3], dd[3], ystr[16], ynum[16];
884
7.99k
    int year, nwords, ynum_len;
885
7.99k
    unsigned c;
886
7.99k
    memset(FujiSerial, 0, sizeof(imgdata.shootinginfo.InternalBodySerial));
887
7.99k
    ifp->read(FujiSerial, MIN(len,sizeof(FujiSerial)), 1);
888
7.99k
    nwords = getwords(FujiSerial, words, 4,
889
7.99k
                      sizeof(imgdata.shootinginfo.InternalBodySerial));
890
15.3k
    for (int i = 0; i < nwords; i++)
891
7.30k
    {
892
7.30k
    if (!words[i]) break;  // probably damaged input
893
7.30k
      mm[2] = dd[2] = 0;
894
7.30k
      if (strnlen(words[i],
895
7.30k
                  sizeof(imgdata.shootinginfo.InternalBodySerial) - 1) < 18)
896
4.29k
      {
897
4.29k
        if (i == 0)
898
2.67k
        {
899
2.67k
          strncpy(imgdata.shootinginfo.InternalBodySerial, words[0],
900
2.67k
                  sizeof(imgdata.shootinginfo.InternalBodySerial) - 1);
901
2.67k
        }
902
1.62k
        else
903
1.62k
        {
904
1.62k
          char tbuf[sizeof(imgdata.shootinginfo.InternalBodySerial)];
905
1.62k
          snprintf(tbuf, sizeof(tbuf)-1, "%s %s",
906
1.62k
                   imgdata.shootinginfo.InternalBodySerial, words[i]);
907
1.62k
          strncpy(imgdata.shootinginfo.InternalBodySerial, tbuf,
908
1.62k
                  sizeof(imgdata.shootinginfo.InternalBodySerial) - 1);
909
1.62k
        }
910
4.29k
      }
911
3.01k
      else
912
3.01k
      {
913
3.01k
        strncpy(
914
3.01k
            dd,
915
3.01k
            words[i] +
916
3.01k
                strnlen(words[i],
917
3.01k
                        sizeof(imgdata.shootinginfo.InternalBodySerial) - 1) -
918
3.01k
                14,
919
3.01k
            2);
920
3.01k
        strncpy(
921
3.01k
            mm,
922
3.01k
            words[i] +
923
3.01k
                strnlen(words[i],
924
3.01k
                        sizeof(imgdata.shootinginfo.InternalBodySerial) - 1) -
925
3.01k
                16,
926
3.01k
            2);
927
3.01k
        strncpy(
928
3.01k
            yy,
929
3.01k
            words[i] +
930
3.01k
                strnlen(words[i],
931
3.01k
                        sizeof(imgdata.shootinginfo.InternalBodySerial) - 1) -
932
3.01k
                18,
933
3.01k
            2);
934
3.01k
        year = (yy[0] - '0') * 10 + (yy[1] - '0');
935
3.01k
        if (year < 70)
936
2.34k
          year += 2000;
937
670
        else
938
670
          year += 1900;
939
940
3.01k
        ynum_len = MIN(
941
3.01k
            int(sizeof(ynum) - 1),
942
3.01k
            (int)strnlen(words[i],
943
3.01k
                         sizeof(imgdata.shootinginfo.InternalBodySerial) - 1) -
944
3.01k
                18);
945
3.01k
        strncpy(ynum, words[i], ynum_len);
946
3.01k
        ynum[ynum_len] = 0;
947
5.83k
        for (int j = 0; ynum[j] && ynum[j + 1] && sscanf(ynum + j, "%2x", &c);
948
3.01k
             j += 2)
949
2.81k
          ystr[j / 2] = c;
950
3.01k
        ynum_len /= 2;
951
3.01k
        ystr[ynum_len + 1] = 0;
952
3.01k
        strcpy(model2, ystr);
953
954
3.01k
        if (i == 0)
955
1.89k
        {
956
1.89k
          char tbuf[sizeof(imgdata.shootinginfo.InternalBodySerial)];
957
958
1.89k
          if (nwords == 1)
959
1.41k
          {
960
1.41k
            snprintf(
961
1.41k
              tbuf, sizeof(tbuf), "%s %d:%s:%s %s",
962
1.41k
              ystr, year, mm, dd,
963
1.41k
              words[0] +
964
1.41k
                strnlen(words[0], sizeof(imgdata.shootinginfo.InternalBodySerial)-1)-12);
965
1.41k
          }
966
483
          else
967
483
          {
968
483
            snprintf(
969
483
                tbuf, sizeof(tbuf), "%s %d:%s:%s %s", ystr, year, mm, dd,
970
483
                words[0] +
971
483
                    strnlen(words[0],
972
483
                            sizeof(imgdata.shootinginfo.InternalBodySerial) -
973
483
                                1) -
974
483
                    12);
975
483
          }
976
1.89k
          strncpy(imgdata.shootinginfo.InternalBodySerial, tbuf,
977
1.89k
                  sizeof(imgdata.shootinginfo.InternalBodySerial) - 1);
978
1.89k
        }
979
1.11k
        else
980
1.11k
        {
981
1.11k
          char tbuf[sizeof(imgdata.shootinginfo.InternalBodySerial)];
982
1.11k
          snprintf(
983
1.11k
              tbuf, sizeof(tbuf), "%s %s %d:%s:%s %s",
984
1.11k
              imgdata.shootinginfo.InternalBodySerial, ystr, year, mm, dd,
985
1.11k
              words[i] +
986
1.11k
                  strnlen(words[i],
987
1.11k
                          sizeof(imgdata.shootinginfo.InternalBodySerial) - 1) -
988
1.11k
                  12);
989
1.11k
          strncpy(imgdata.shootinginfo.InternalBodySerial, tbuf,
990
1.11k
                  sizeof(imgdata.shootinginfo.InternalBodySerial) - 1);
991
1.11k
        }
992
3.01k
      }
993
7.30k
    }
994
7.99k
  }
995
207k
  else
996
207k
    switch (tag)
997
207k
    {
998
228
    case 0x1002:
999
228
      imFuji.WB_Preset = get2();
1000
228
      break;
1001
197
    case 0x1011:
1002
197
      imCommon.FlashEC = getrealf(type);
1003
197
      break;
1004
398
    case 0x1020:
1005
398
      imFuji.Macro = get2();
1006
398
      break;
1007
236
    case 0x1021:
1008
236
      imFuji.FocusMode = imgdata.shootinginfo.FocusMode = get2();
1009
236
      break;
1010
796
    case 0x1022:
1011
796
      imFuji.AFMode = get2();
1012
796
      break;
1013
529
    case 0x1023:
1014
529
      imFuji.FocusPixel[0] = get2();
1015
529
      imFuji.FocusPixel[1] = get2();
1016
529
      break;
1017
417
    case 0x102b:
1018
417
      imFuji.PrioritySettings = get2();
1019
417
      break;
1020
315
    case 0x102d:
1021
315
      imFuji.FocusSettings = get4();
1022
315
      break;
1023
57
    case 0x102e:
1024
57
      imFuji.AF_C_Settings = get4();
1025
57
      break;
1026
311
    case 0x1034:
1027
311
      imFuji.ExrMode = get2();
1028
311
      break;
1029
229
    case 0x104d:
1030
229
      FujiCropMode = get2(); // odd: one of raw dimensions here can be lost
1031
229
      break;
1032
244
    case 0x1050:
1033
244
      imFuji.ShutterType = get2();
1034
244
      break;
1035
624
    case 0x1100:
1036
624
      imFuji.AutoBracketing = get2(); // AutoBracketing = 6 for pixel shift mode
1037
624
      break;
1038
802
    case 0x1101:
1039
802
      imFuji.SequenceNumber = get2();
1040
802
      break;
1041
118
    case 0x1103:
1042
118
      imgdata.shootinginfo.DriveMode = get2();
1043
118
      imFuji.DriveMode = imgdata.shootinginfo.DriveMode & 0xff;
1044
118
      break;
1045
94
    case 0x1105:
1046
94
      imFuji.SeriesLength = get2();
1047
94
      break;
1048
315
    case 0x1106:
1049
315
      imFuji.PixelShiftOffset[0] = getrealf(type);
1050
315
      imFuji.PixelShiftOffset[1] = getrealf(type);
1051
315
      break;
1052
401
    case 0x1301:
1053
401
      imFuji.FocusWarning = get2();
1054
401
      break;
1055
586
    case 0x1400:
1056
586
      imFuji.DynamicRange = get2();
1057
586
      break;
1058
493
    case 0x1401:
1059
493
      imFuji.FilmMode = get2();
1060
493
      break;
1061
798
    case 0x1402:
1062
798
      imFuji.DynamicRangeSetting = get2();
1063
798
      break;
1064
107
    case 0x1403:
1065
107
      imFuji.DevelopmentDynamicRange = get2();
1066
107
      break;
1067
855
    case 0x1404:
1068
855
      ilm.MinFocal = getrealf(type);
1069
855
      break;
1070
373
    case 0x1405:
1071
373
      ilm.MaxFocal = getrealf(type);
1072
373
      break;
1073
190
    case 0x1406:
1074
190
      ilm.MaxAp4MinFocal = getrealf(type);
1075
190
      break;
1076
51
    case 0x1407:
1077
51
      ilm.MaxAp4MaxFocal = getrealf(type);
1078
51
      break;
1079
290
    case 0x140b:
1080
290
      imFuji.AutoDynamicRange = get2();
1081
290
      break;
1082
273
    case 0x1422:
1083
273
      imFuji.ImageStabilization[0] = get2();
1084
273
      imFuji.ImageStabilization[1] = get2();
1085
273
      imFuji.ImageStabilization[2] = get2();
1086
273
      imgdata.shootinginfo.ImageStabilization =
1087
273
          (imFuji.ImageStabilization[0] << 9) + imFuji.ImageStabilization[1];
1088
273
      break;
1089
102
    case 0x1438:
1090
102
      imFuji.ImageCount = get2();
1091
102
      break;
1092
185
    case 0x1431:
1093
185
      imFuji.Rating = get4();
1094
185
      break;
1095
385
    case 0x1443:
1096
385
      imFuji.DRangePriority = get2();
1097
385
      break;
1098
141
    case 0x1444:
1099
141
      imFuji.DRangePriorityAuto = get2();
1100
141
      break;
1101
472
    case 0x1445:
1102
472
      imFuji.DRangePriorityFixed = get2();
1103
472
      break;
1104
309
    case 0x1447:
1105
309
      stmread(imFuji.FujiModel, len, ifp);
1106
309
      break;
1107
758
    case 0x1448:
1108
758
      stmread(imFuji.FujiModel2, len, ifp);
1109
758
      break;
1110
207k
    }
1111
215k
  return;
1112
215k
}
1113
1114
void LibRaw::parse_fuji_thumbnail(INT64 offset)
1115
2.21k
{
1116
2.21k
    uchar xmpmarker[] = "http://ns.adobe.com/xap/1.0/";
1117
2.21k
    uchar buf[sizeof(xmpmarker)+1];
1118
2.21k
    int xmpsz = sizeof(xmpmarker); // we do not
1119
1120
2.21k
    INT64 pos = ftell(ifp);
1121
2.21k
    fseek(ifp, offset, SEEK_SET);
1122
2.21k
    ushort s_order = order;
1123
2.21k
    order = 0x4a4a; // JPEG is always in MM order
1124
1125
2.21k
    if (get2() == 0xFFD8)
1126
268
    {
1127
533
        while (1)
1128
533
        {
1129
533
          ushort tag = get2();
1130
533
          if (tag != 0xFFE1 && tag != 0xFFE2) // allow APP1/APP2 only
1131
267
            break;
1132
266
          INT64 tpos = ftell(ifp);
1133
266
          int len = get2();
1134
266
          if (len > xmpsz + 2)
1135
262
          {
1136
262
              if ((fread(buf, 1, xmpsz, ifp) == xmpsz) && !memcmp(buf, xmpmarker, xmpsz)) // got it
1137
1
              {
1138
1
                  xmplen = len - xmpsz - 2;
1139
1
                  xmpdata = (char*) calloc(xmplen+1,1);
1140
1
                  unsigned br = fread(xmpdata, 1, xmplen, ifp);
1141
1
                  xmpdata[br] = 0;
1142
1
                  break;
1143
1
              }
1144
262
          }
1145
265
          fseek(ifp, tpos + len, SEEK_SET);
1146
265
        }
1147
268
    }
1148
1149
2.21k
    order = s_order;
1150
2.21k
    fseek(ifp, pos, SEEK_SET);
1151
2.21k
}
1152
1153
void LibRaw::parse_fuji(INT64 offset)
1154
3.56k
{
1155
3.56k
  unsigned entries, tag, len, c;
1156
3.56k
  INT64 save;
1157
1158
3.56k
#define get_average_WB(wb_index)                                               \
1159
3.56k
  do {                                                                         \
1160
8.59k
    FORC4 icWBC[wb_index][GRGB_2_RGBG(c)] = get2();                              \
1161
2.14k
    if ((len == 16) && average_WBData) {                                         \
1162
1.96k
    FORC4 icWBC[wb_index][GRGB_2_RGBG(c)] =                                    \
1163
1.96k
         (icWBC[wb_index][GRGB_2_RGBG(c)] + get2())/2;                     \
1164
492
    }                                                                            \
1165
2.14k
    if (use_WBcorr_coeffs) {                                                     \
1166
334
    icWBC[wb_index][0] = int(icWBC[wb_index][0] * wbR_corr);                   \
1167
334
    icWBC[wb_index][2] = int( icWBC[wb_index][2] * wbB_corr);                  \
1168
334
    }                                                                            \
1169
2.14k
  } while(0)
1170
1171
3.56k
  ushort raw_inset_present = 0;
1172
3.56k
  ushort use_WBcorr_coeffs = 0;
1173
3.56k
  double wbR_corr = 1.0;
1174
3.56k
  double wbB_corr = 1.0;
1175
3.56k
  ilm.CamID = unique_id;
1176
3.56k
  int average_WBData = 1;
1177
1178
3.56k
  fseek(ifp, offset, SEEK_SET);
1179
3.56k
  entries = get4();
1180
3.56k
  if (entries > 255)
1181
2.02k
    return;
1182
1.54k
  imgdata.process_warnings |= LIBRAW_WARN_PARSEFUJI_PROCESSED;
1183
1184
1.54k
  if (strstr(model, "S2Pro")
1185
1.53k
      || strstr(model, "S20Pro")
1186
1.51k
      || strstr(model, "F700")
1187
1.50k
      || strstr(model, "S5000")
1188
1.49k
      || strstr(model, "S7000")
1189
1.54k
      ) {
1190
64
    use_WBcorr_coeffs = 1;
1191
64
    wbR_corr = 10.0 / 17.0 / 0.652941;
1192
64
    wbB_corr = 2.0 /3.0 / (3.0 / 4.0 + 1.0 / 300.0);
1193
1.47k
  } else if (strstr(model, "DBP") || strstr(model, "DX-2000")) {
1194
22
    use_WBcorr_coeffs = 1;
1195
22
    wbR_corr = 0.7632653061;
1196
22
    wbB_corr = 0.8591549296;
1197
22
  }
1198
1199
79.1k
  while (entries--)
1200
77.5k
  {
1201
77.5k
    tag = get2();
1202
77.5k
    len = get2();
1203
77.5k
    save = ftell(ifp);
1204
77.5k
    if (tag == 0x0100) // RawImageFullSize
1205
1.16k
    {
1206
1.16k
      raw_height = get2();
1207
1.16k
      raw_width = get2();
1208
1.16k
      raw_inset_present = 1;
1209
1.16k
    }
1210
76.4k
    else if ((tag == 0x0110) && raw_inset_present) // RawImageCropTopLeft
1211
154
    {
1212
154
      imgdata.sizes.raw_inset_crops[0].ctop = get2();
1213
154
      imgdata.sizes.raw_inset_crops[0].cleft = get2();
1214
154
    }
1215
76.2k
    else if ((tag == 0x0111) && raw_inset_present) // RawImageCroppedSize
1216
182
    {
1217
182
      imgdata.sizes.raw_inset_crops[0].cheight = get2();
1218
182
      imgdata.sizes.raw_inset_crops[0].cwidth = get2();
1219
182
    }
1220
76.0k
    else if ((tag == 0x0115) && raw_inset_present) // RawImageAspectRatio
1221
216
    {
1222
216
      int a = get2();
1223
216
      int b = get2();
1224
216
      if (a * b == 6)
1225
54
        imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_3to2;
1226
162
      else if (a * b == 12)
1227
58
        imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_4to3;
1228
104
      else if (a * b == 144)
1229
24
        imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_16to9;
1230
80
      else if (a * b == 1)
1231
18
        imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_1to1;
1232
216
    }
1233
75.8k
    else if (tag == 0x0121) // RawImageSize
1234
154
    {
1235
154
      height = get2();
1236
154
      if ((width = get2()) == 4284)
1237
1
        width += 3;
1238
154
    }
1239
75.7k
    else if (tag == 0x0130) // FujiLayout,
1240
167
    {
1241
167
      fuji_layout = fgetc(ifp) >> 7;
1242
167
      fuji_width  = !(fgetc(ifp) & 8);
1243
167
    }
1244
75.5k
    else if (tag == 0x0131) // XTransLayout
1245
55
    {
1246
55
      filters = 9;
1247
55
      char *xtrans_abs_alias = &xtrans_abs[0][0];
1248
55
      FORC(36)
1249
1.98k
      {
1250
1.98k
        int q = fgetc(ifp);
1251
1.98k
        xtrans_abs_alias[35 - c] = MAX(0, MIN(q, 2)); /* & 3;*/
1252
1.98k
      }
1253
55
    }
1254
75.4k
    else if (tag == 0x2ff0) // WB_GRGBLevels
1255
793
    {
1256
793
      get_average_WB(LIBRAW_WBI_AsShot);
1257
3.17k
      FORC4 cam_mul[c] = float(icWBC[LIBRAW_WBI_AsShot][c]);
1258
793
    }
1259
74.6k
    else if ((tag == 0x4000) &&
1260
222
             ((len == 8) || (len == 16)))
1261
151
    {
1262
151
      imFuji.BlackLevel[0] = len / 2;
1263
604
      FORC4 imFuji.BlackLevel[GRGB_2_RGBG(c)+1] = get2();
1264
151
      if (imFuji.BlackLevel[0] == 8)
1265
384
        FORC4 imFuji.BlackLevel[GRGB_2_RGBG(c)+5] = get2();
1266
151
      if (imFuji.BlackLevel[0] == 4)
1267
220
        FORC4 cblack[c] = imFuji.BlackLevel[c+1];
1268
96
      else if (imFuji.BlackLevel[0] == 8)
1269
384
        FORC4 cblack[c] = (imFuji.BlackLevel[c+1]+imFuji.BlackLevel[c+5]) /2;
1270
151
    }
1271
74.5k
    else if (tag == 0x9200) // RelativeExposure
1272
580
    {
1273
580
      int s1 = get2();
1274
580
      int s2 = get2();
1275
580
      if ((s1 == s2) || !s1)
1276
48
        imFuji.BrightnessCompensation = 0.0f;
1277
532
      else if ((s1*4) == s2)
1278
14
        imFuji.BrightnessCompensation = 2.0f;
1279
518
      else if ((s1*16) == s2)
1280
76
        imFuji.BrightnessCompensation = 4.0f;
1281
442
      else
1282
442
        imFuji.BrightnessCompensation = logf(float(s2)/float(s1))/logf(2.f);
1283
580
    }
1284
73.9k
    else if (tag == 0x9650) // RawExposureBias
1285
66
    {
1286
66
      short a = (short)get2();
1287
66
      float b = fMAX(1.0f, get2());
1288
66
      imFuji.ExpoMidPointShift = a / b;
1289
66
      imCommon.ExposureCalibrationShift += imFuji.ExpoMidPointShift;
1290
66
    }
1291
77.5k
    if (tag >= 0x2000 && tag <= 0x2410)
1292
1.70k
    {
1293
9.73k
      for (int q = 0; q < tag2wbtable_size; q++)
1294
9.38k
        if (tag2wbtable[q].tag == tag)
1295
1.35k
        {
1296
1.35k
          get_average_WB(tag2wbtable[q].wb);
1297
1.35k
          break;
1298
1.35k
        }
1299
1.70k
    }
1300
75.8k
    else if (tag == 0x2f00) // WB_GRGBLevels
1301
428
    {
1302
428
      int nWBs = get4();
1303
428
      nWBs = MIN(nWBs, 6);
1304
1.91k
      for (int wb_ind = LIBRAW_WBI_Custom1; wb_ind < LIBRAW_WBI_Custom1+nWBs; wb_ind++) {
1305
5.96k
        FORC4 icWBC[wb_ind][GRGB_2_RGBG(c)] = get2();
1306
1.49k
        if ((len >= unsigned(4+16*nWBs)) && average_WBData) {
1307
468
          FORC4 icWBC[wb_ind][GRGB_2_RGBG(c)] =
1308
468
                  (icWBC[wb_ind][GRGB_2_RGBG(c)] +get2()) /2;
1309
117
        }
1310
1.49k
        if (use_WBcorr_coeffs) {
1311
663
          icWBC[LIBRAW_WBI_Custom1 + wb_ind][0] = int(icWBC[LIBRAW_WBI_Custom1 + wb_ind][0] * wbR_corr);
1312
663
          icWBC[LIBRAW_WBI_Custom1 + wb_ind][2] = int(icWBC[LIBRAW_WBI_Custom1 + wb_ind][2] * wbB_corr);
1313
663
        }
1314
1.49k
      }
1315
428
    }
1316
1317
75.4k
    else if (tag == 0xc000) // RAFData
1318
328
    {
1319
328
      int offsetWH_inRAFData;
1320
328
      unsigned save_order = order;
1321
328
      order = 0x4949;
1322
328
      if (len > 20000)
1323
221
      {
1324
221
        uchar RAFDataHeader[16];
1325
221
        libraw_internal_data.unpacker_data.posRAFData = save;
1326
221
        libraw_internal_data.unpacker_data.lenRAFData = (len >> 1);
1327
221
    memset(RAFDataHeader, 0, sizeof(RAFDataHeader));
1328
221
        fread(RAFDataHeader, sizeof RAFDataHeader, 1, ifp);
1329
221
        offsetWH_inRAFData = guess_RAFDataGeneration(RAFDataHeader);
1330
221
        fseek(ifp, offsetWH_inRAFData-int(sizeof RAFDataHeader), SEEK_CUR);
1331
221
        for (int i=0;
1332
7.29k
             i< (int)((sizeof imFuji.RAFData_ImageSizeTable) / (sizeof imFuji.RAFData_ImageSizeTable[0]));
1333
7.07k
             i++) {
1334
7.07k
          imFuji.RAFData_ImageSizeTable[i] = get4();
1335
7.07k
        }
1336
1337
//         if ((width > raw_width)
1338
//             || (raw_inset_present && (width < imgdata.sizes.raw_inset_crops[0].cwidth))
1339
//         )
1340
//           width = raw_width;
1341
//         if ((height > raw_height)
1342
//             || (raw_inset_present && (height < imgdata.sizes.raw_inset_crops[0].cheight))
1343
//         )
1344
//           height = raw_height;
1345
//
1346
1347
221
      }
1348
107
      else if (len == 4096) // X-A3, X-A5, X-A7, X-A10, X-A20, X-T100, X-T200, XF10
1349
92
      {                     // Ill.A aligned to CCT 2850
1350
92
        int wb[4];
1351
92
        int nWB, tWB;
1352
92
        int iCCT = 0;
1353
92
        imFuji.RAFDataGeneration = 4096;
1354
92
        fseek(ifp, save + 0x200, SEEK_SET);
1355
3.95k
        for (int wb_ind = 0; wb_ind < 42; wb_ind++)
1356
3.86k
        {
1357
3.86k
          nWB = get4();
1358
3.86k
          tWB = get4();
1359
3.86k
          wb[0] = get4() << 1;
1360
3.86k
          wb[1] = get4();
1361
3.86k
          wb[3] = get4();
1362
3.86k
          wb[2] = get4() << 1;
1363
3.86k
          if (tWB && (iCCT < 64))
1364
2.58k
          {
1365
2.58k
            icWBCCTC[iCCT][0] = float(tWB);
1366
10.3k
            FORC4 icWBCCTC[iCCT][c + 1] = float(wb[c]);
1367
2.58k
            iCCT++;
1368
2.58k
          }
1369
3.86k
          if (nWB != 70)
1370
3.85k
          {
1371
31.8k
            for (int pWB = 1; pWB < (int)Fuji_wb_list2.size(); pWB += 2)
1372
29.3k
            {
1373
29.3k
              if (Fuji_wb_list2[pWB] == nWB)
1374
1.31k
              {
1375
5.26k
                FORC4 icWBC[Fuji_wb_list2[pWB - 1]][c] = wb[c];
1376
1.31k
                break;
1377
1.31k
              }
1378
29.3k
            }
1379
3.85k
          }
1380
3.86k
        }
1381
92
      }
1382
328
      order = save_order;
1383
328
    }
1384
77.5k
    fseek(ifp, save + len, SEEK_SET);
1385
77.5k
  }
1386
1387
1.54k
  if (!imFuji.RAFDataGeneration) {
1388
1.38k
    height <<= fuji_layout;
1389
1.38k
    width >>= fuji_layout;
1390
1.38k
  }
1391
1.54k
#undef get_average_WB
1392
1.54k
}
1393