Coverage Report

Created: 2026-06-30 07:12

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libraw/src/decoders/load_mfbacks.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
21
inline uint32_t abs32(int32_t x)
22
291k
{
23
  // Branchless version.
24
291k
  uint32_t sm = x >> 31;
25
291k
  return (uint32_t) ((x + sm) ^ sm);
26
291k
}
27
28
inline uint32_t min32(uint32_t x, uint32_t y)
29
55.5k
{
30
55.5k
  return x < y ? x : y;
31
55.5k
}
32
33
inline uint32_t max32(uint32_t x, uint32_t y)
34
6.94k
{
35
6.94k
  return x > y ? x : y;
36
6.94k
}
37
38
inline uint32_t constain32(uint32_t x, uint32_t l, uint32_t u)
39
6.94k
{
40
6.94k
  return x < l ? l : (x > u ? u : x);
41
6.94k
}
42
43
int unsigned_cmp(const void *a, const void *b)
44
420
{
45
420
  if (!a || !b)
46
0
    return 0;
47
48
420
  return *(unsigned *)a > *(unsigned *)b ? 1 : (*(unsigned *)a < *(unsigned *)b ? -1 : 0);
49
420
}
50
51
int LibRaw::p1rawc(unsigned row, unsigned col, unsigned& count)
52
43.6k
{
53
43.6k
  return (row < raw_height && col < raw_width) ? (++count, RAW(row, col)) : 0;
54
43.6k
}
55
56
int LibRaw::p1raw(unsigned row, unsigned col)
57
708k
{
58
708k
  return (row < raw_height && col < raw_width) ? RAW(row, col) : 0;
59
708k
}
60
61
62
// DNG SDK version of fixing pixels in bad column using averages sets
63
// corrected not to use pixels in the same column
64
void LibRaw::phase_one_fix_col_pixel_avg(unsigned row, unsigned col)
65
10.6k
{
66
10.6k
  static const int8_t dir[3][8][2] = {
67
10.6k
  { {-2,-2}, {-2, 2}, {2,-2}, {2, 2}, { 0, 0}, { 0, 0}, {0, 0}, {0, 0} },
68
10.6k
  { {-2,-4}, {-4,-2}, {2,-4}, {4,-2}, {-2, 4}, {-4, 2}, {2, 4}, {4, 2} },
69
10.6k
  { {-4,-4}, {-4, 4}, {4,-4}, {4, 4}, { 0, 0}, { 0, 0}, {0, 0}, {0, 0} } };
70
71
10.6k
  for (int set=0; set < 3; ++set)
72
10.6k
  {
73
10.6k
    uint32_t total = 0;
74
10.6k
    uint32_t count = 0;
75
53.4k
    for (int i = 0; i < 8; ++i)
76
53.4k
    {
77
53.4k
      if (!dir[set][i][0] && !dir[set][i][1])
78
10.6k
        break;
79
80
42.7k
      total += p1rawc(row+dir[set][i][0], col+dir[set][i][1], count);
81
42.7k
    }
82
83
10.6k
    if (count)
84
10.6k
    {
85
10.6k
      RAW(row,col) = (uint16_t)((total + (count >> 1)) / count);
86
10.6k
      break;
87
10.6k
    }
88
10.6k
  }
89
10.6k
}
90
91
// DNG SDK version of fixing pixels in bad column using gradient prediction
92
void LibRaw::phase_one_fix_pixel_grad(unsigned row, unsigned col)
93
6.94k
{
94
6.94k
  static const int8_t grad_sets[7][12][2] = {
95
6.94k
    { {-4,-2}, { 4, 2}, {-3,-1}, { 1, 1}, {-1,-1}, { 3, 1}, 
96
6.94k
      {-4,-1}, { 0, 1}, {-2,-1}, { 2, 1}, { 0,-1}, { 4, 1} },
97
6.94k
    { {-2,-2}, { 2, 2}, {-3,-1}, {-1, 1}, {-1,-1}, { 1, 1}, 
98
6.94k
      { 1,-1}, { 3, 1}, {-2,-1}, { 0, 1}, { 0,-1}, { 2, 1} },
99
6.94k
    { {-2,-4}, { 2, 4}, {-1,-3}, { 1, 1}, {-1,-1}, { 1, 3}, 
100
6.94k
      {-2,-1}, { 0, 3}, {-1,-2}, { 1, 2}, { 0,-3}, { 2, 1} },
101
6.94k
    { { 0,-2}, { 0, 2}, {-1,-1}, {-1, 1}, { 1,-1}, { 1, 1}, 
102
6.94k
      {-1,-2}, {-1, 2}, { 0,-1}, { 0,-1}, { 1,-2}, { 1, 2} },
103
6.94k
    { {-2, 4}, { 2,-4}, {-1, 3}, { 1,-1}, {-1, 1}, { 1,-3}, 
104
6.94k
      {-2, 1}, { 0,-3}, {-1, 2}, { 1,-2}, { 0, 3}, { 2,-1} },
105
6.94k
    { {-2, 2}, { 2,-2}, {-3, 1}, {-1,-1}, {-1, 1}, { 1,-1}, 
106
6.94k
      { 1, 1}, { 3,-1}, {-2, 1}, { 0,-1}, { 0, 1}, { 2,-1} },
107
6.94k
    { {-4, 2}, { 4,-2}, {-3, 1}, { 1,-1}, {-1, 1}, { 3,-1}, 
108
6.94k
      {-4, 1}, { 0,-1}, {-2, 1}, { 2,-1}, { 0, 1}, { 4,-1} } };
109
110
6.94k
  uint32_t est[7], grad[7];
111
6.94k
  uint32_t lower = min32(p1raw(row,col-2), p1raw(row, col+2));
112
6.94k
  uint32_t upper = max32(p1raw(row,col-2), p1raw(row, col+2));
113
6.94k
  uint32_t minGrad = 0xFFFFFFFF;
114
55.5k
  for (int i = 0; i<7; ++i)
115
48.6k
  {
116
48.6k
    est[i] = p1raw(row+grad_sets[i][0][0], col+grad_sets[i][0][1]) +
117
48.6k
             p1raw(row+grad_sets[i][1][0], col+grad_sets[i][1][1]);
118
48.6k
    grad[i] = 0;
119
340k
    for (int j=0; j<12; j+=2)
120
291k
      grad[i] += abs32(p1raw(row+grad_sets[i][j][0], col+grad_sets[i][j][1]) -
121
291k
                       p1raw(row+grad_sets[i][j+1][0], col+grad_sets[i][j+1][1]));
122
48.6k
    minGrad = min32(minGrad, grad[i]);
123
48.6k
  }
124
125
6.94k
  uint32_t limit = (minGrad * 3) >> 1;
126
6.94k
  uint32_t total = 0;
127
6.94k
  uint32_t count = 0;
128
55.5k
  for (int i = 0; i<7; ++i)
129
48.6k
    if (grad[i] <= limit)
130
20.2k
    {
131
20.2k
      total += est[i];
132
20.2k
      count += 2;
133
20.2k
    }
134
6.94k
  RAW(row, col) = constain32((total + (count >> 1)) / count, lower, upper);
135
6.94k
}
136
137
void LibRaw::phase_one_flat_field(int is_float, int nc)
138
175
{
139
175
  ushort head[8];
140
175
  unsigned wide, high, y, x, c, rend, cend, row, col;
141
175
  float *mrow, num, mult[4];
142
143
175
  read_shorts(head, 8);
144
175
  if (head[2] == 0 || head[3] == 0 || head[4] == 0 || head[5] == 0)
145
77
    return;
146
98
  wide = head[2] / head[4] + (head[2] % head[4] != 0);
147
98
  high = head[3] / head[5] + (head[3] % head[5] != 0);
148
98
  mrow = (float *)calloc(nc * wide, sizeof *mrow);
149
700k
  for (y = 0; y < high; y++)
150
700k
  {
151
700k
    checkCancel();
152
43.1M
    for (x = 0; x < wide; x++)
153
84.9M
      for (c = 0; c < (unsigned)nc; c += 2)
154
42.4M
      {
155
42.4M
        num = is_float ? getrealf(LIBRAW_EXIFTAG_TYPE_FLOAT) : float(get2()) / 32768.f;
156
42.4M
        if (y == 0)
157
42.2k
          mrow[c * wide + x] = num;
158
42.4M
        else
159
42.4M
          mrow[(c + 1) * wide + x] = (num - mrow[c * wide + x]) / head[5];
160
42.4M
      }
161
700k
    if (y == 0)
162
81
      continue;
163
700k
    rend = head[1] + y * head[5];
164
700k
    for (row = rend - head[5];
165
702k
         row < raw_height && row < rend && row < unsigned(head[1] + head[3] - head[5]);
166
700k
         row++)
167
2.08k
    {
168
99.3k
      for (x = 1; x < wide; x++)
169
97.2k
      {
170
194k
        for (c = 0; c < (unsigned)nc; c += 2)
171
97.2k
        {
172
97.2k
          mult[c] = mrow[c * wide + x - 1];
173
97.2k
          mult[c + 1] = (mrow[c * wide + x] - mult[c]) / head[4];
174
97.2k
        }
175
97.2k
        cend = head[0] + x * head[4];
176
97.2k
        for (col = cend - head[4];
177
129k
             col < raw_width && col < cend && col < unsigned(head[0] + head[2] - head[4]);
178
97.2k
             col++)
179
31.7k
        {
180
31.7k
          c = nc > 2 ? FC(row - top_margin, col - left_margin) : 0;
181
31.7k
          if (!(c & 1))
182
31.7k
          {
183
31.7k
            c = unsigned(RAW(row, col) * mult[c]);
184
31.7k
            RAW(row, col) = LIM(c, 0, 65535);
185
31.7k
          }
186
63.5k
          for (c = 0; c < (unsigned)nc; c += 2)
187
31.7k
            mult[c] += mult[c + 1];
188
31.7k
        }
189
97.2k
      }
190
101k
      for (x = 0; x < wide; x++)
191
199k
        for (c = 0; c < (unsigned)nc; c += 2)
192
99.9k
          mrow[c * wide + x] += mrow[(c + 1) * wide + x];
193
2.08k
    }
194
700k
  }
195
98
  free(mrow);
196
98
}
197
198
int LibRaw::phase_one_correct()
199
343
{
200
343
  unsigned entries, tag, data, col, row, type;
201
343
  INT64 save;
202
343
  int len, i, j, k, cip, sum;
203
#if 0
204
  int val[4], dev[4], max;
205
#endif
206
343
  int head[9], diff, mindiff = INT_MAX;
207
343
  INT64 off_412 = 0;
208
343
  /* static */ const signed char dir[12][2] = {
209
343
      {-1, -1}, {-1, 1}, {1, -1},  {1, 1},  {-2, 0}, {0, -2},
210
343
      {0, 2},   {2, 0},  {-2, -2}, {-2, 2}, {2, -2}, {2, 2}};
211
343
  float poly[8], num, cfrac, frac, mult[2], *yval[2] = {NULL, NULL};
212
343
  ushort *xval[2];
213
343
  int qmult_applied = 0, qlin_applied = 0;
214
343
  std::vector<unsigned> badCols;
215
216
343
  if (!meta_length)
217
22
    return 0;
218
321
  fseek(ifp, meta_offset, SEEK_SET);
219
321
  order = get2();
220
321
  fseek(ifp, 6, SEEK_CUR);
221
321
  fseek(ifp, meta_offset + get4(), SEEK_SET);
222
321
  entries = get4();
223
321
  get4();
224
321
  INT64 fsize = ifp->size();
225
226
321
  try
227
321
  {
228
1.51M
    while (entries--)
229
1.51M
    {
230
1.51M
      checkCancel();
231
1.51M
      tag = get4();
232
1.51M
      len = get4();
233
1.51M
      data = get4();
234
1.51M
      save = ftell(ifp);
235
1.51M
      fseek(ifp, meta_offset + data, SEEK_SET);
236
1.51M
#if 1
237
1.51M
    if (ifp->eof())
238
0
    {
239
      // skip bad or unknown tag
240
0
      fseek(ifp, save, SEEK_SET);
241
0
      continue;
242
0
    }
243
1.51M
#endif
244
1.51M
      INT64 savepos = ftell(ifp);
245
1.51M
    if (len < 0 || (len > 8 && savepos + (INT64)len > 2 * fsize))
246
1.50M
    {
247
1.50M
        fseek(ifp, save, SEEK_SET); // Recover tiff-read position!!
248
1.50M
        continue;
249
1.50M
    }
250
14.5k
      if (tag == 0x0400)
251
262
      { /* Sensor defects */
252
59.8k
        while ((len -= 8) >= 0)
253
59.5k
        {
254
59.5k
          col = get2();
255
59.5k
          row = get2();
256
59.5k
          type = get2();
257
59.5k
          get2();
258
59.5k
          if (col >= raw_width)
259
41.9k
            continue;
260
17.6k
          if (type == 131 || type == 137) /* Bad column */
261
#if 0
262
            // Original code by Dave Coffin - it works better by
263
            // not employing special logic for G1 channel below.
264
            // Alternatively this column remap (including G1 channel
265
            // logic) should be called prior to black subtraction
266
            // unlike other corrections
267
            for (row = 0; row < raw_height; row++)
268
            {
269
              if (FC(row - top_margin, col - left_margin)==1)
270
              {
271
                for (sum = i = 0; i < 4; i++)
272
                  sum += val[i] = p1raw(row + dir[i][0], col + dir[i][1]);
273
                for (max = i = 0; i < 4; i++)
274
                {
275
                  dev[i] = abs((val[i] << 2) - sum);
276
                  if (dev[max] < dev[i])
277
                    max = i;
278
                }
279
                RAW(row, col) = (sum - val[max]) / 3.0 + 0.5;
280
              }
281
              else
282
              {
283
                for (sum = 0, i = 8; i < 12; i++)
284
                  sum += p1raw(row + dir[i][0], col + dir[i][1]);
285
                RAW(row, col) =
286
                  0.5 + sum * 0.0732233 +
287
                  (p1raw(row, col - 2) + p1raw(row, col + 2)) * 0.3535534;
288
              }
289
            }
290
#else
291
            // accumulae bad columns to be sorted later
292
275
            badCols.push_back(col);
293
17.3k
#endif
294
17.3k
          else if (type == 129)
295
136
          { /* Bad pixel */
296
136
            if (row >= raw_height)
297
16
              continue;
298
120
            j = (FC(row - top_margin, col - left_margin) != 1) * 4;
299
120
            unsigned count = 0;
300
1.08k
            for (sum = 0, i = j; i < j + 8; i++)
301
960
              sum += p1rawc(row + dir[i][0], col + dir[i][1], count);
302
120
            if (count)
303
120
              RAW(row, col) = (sum + (count >> 1)) / count;
304
120
          }
305
17.6k
        }
306
262
      }
307
14.2k
      else if (tag == 0x0419)
308
35
      { /* Polynomial curve - output calibraion */
309
315
        for (get4(), i = 0; i < 8; i++)
310
280
          poly[i] = getrealf(LIBRAW_EXIFTAG_TYPE_FLOAT);
311
35
        poly[3] += (ph1.tag_210 - poly[7]) * poly[6] + 1;
312
2.29M
        for (i = 0; i < 0x10000; i++)
313
2.29M
        {
314
2.29M
          num = (poly[5] * i + poly[3]) * i + poly[1];
315
2.29M
          curve[i] = ushort(LIM(num, 0, 65535));
316
2.29M
        }
317
35
        goto apply; /* apply to right half */
318
35
      }
319
14.2k
      else if (tag == 0x041a)
320
0
      { /* Polynomial curve */
321
0
        for (i = 0; i < 4; i++)
322
0
          poly[i] = getrealf(LIBRAW_EXIFTAG_TYPE_FLOAT);
323
0
        for (i = 0; i < 0x10000; i++)
324
0
        {
325
0
          for (num = 0, j = 4; j--;)
326
0
            num = num * i + poly[j];
327
0
          curve[i] = ushort(LIM(num + i, 0, 65535));
328
0
        }
329
35
      apply: /* apply to whole image */
330
1.26k
        for (row = 0; row < raw_height; row++)
331
1.22k
        {
332
1.22k
          checkCancel();
333
42.3k
          for (col = (tag & 1) * ph1.split_col; col < raw_width; col++)
334
41.1k
            RAW(row, col) = curve[RAW(row, col)];
335
1.22k
        }
336
35
      }
337
14.2k
      else if (tag == 0x0401)
338
13
      { /* All-color flat fields - luma calibration*/
339
13
        phase_one_flat_field(1, 2);
340
13
      }
341
14.2k
      else if (tag == 0x0416 || tag == 0x0410)
342
155
      {
343
        // 0x410 - luma calibration
344
155
        phase_one_flat_field(0, 2);
345
155
      }
346
14.0k
      else if (tag == 0x040b)
347
7
      { /* Red+blue flat field - croma calibration */
348
7
        phase_one_flat_field(0, 4);
349
7
      }
350
14.0k
      else if (tag == 0x0412)
351
48
      {
352
48
        fseek(ifp, 36, SEEK_CUR);
353
48
        diff = abs(get2() - ph1.tag_21a);
354
48
        if (mindiff > diff)
355
42
        {
356
42
          mindiff = diff;
357
42
          off_412 = ftell(ifp) - 38;
358
42
        }
359
48
      }
360
14.0k
      else if (tag == 0x041f && !qlin_applied && ph1.split_col > 0 && ph1.split_col < raw_width
361
0
    && ph1.split_row > 0 && ph1.split_row < raw_height)
362
0
      { /* Quadrant linearization */
363
0
        ushort lc[2][2][16], ref[16];
364
0
        int qr, qc;
365
0
    bool baddiv = false;
366
0
        for (qr = 0; qr < 2; qr++)
367
0
      for (qc = 0; qc < 2; qc++)
368
0
      {
369
0
        for (i = 0; i < 16; i++)
370
0
          lc[qr][qc][i] = get4();
371
0
        if (lc[qr][qc][15] == 0)
372
0
          baddiv = true;
373
0
      }
374
0
    if(baddiv)
375
0
      continue;
376
0
        for (i = 0; i < 16; i++)
377
0
        {
378
0
          int v = 0;
379
0
          for (qr = 0; qr < 2; qr++)
380
0
            for (qc = 0; qc < 2; qc++)
381
0
              v += lc[qr][qc][i];
382
0
          ref[i] = (v + 2) >> 2;
383
0
        }
384
0
        for (qr = 0; qr < 2; qr++)
385
0
        {
386
0
          for (qc = 0; qc < 2; qc++)
387
0
          {
388
0
            int cx[19], cf[19];
389
0
            for (i = 0; i < 16; i++)
390
0
            {
391
0
              cx[1 + i] = lc[qr][qc][i];
392
0
              cf[1 + i] = ref[i];
393
0
            }
394
0
            cx[0] = cf[0] = 0;
395
0
            cx[17] = cf[17] = ((unsigned int)ref[15] * 65535) / lc[qr][qc][15];
396
0
            cf[18] = cx[18] = 65535;
397
0
            cubic_spline(cx, cf, 19);
398
399
0
            for (row = (qr ? ph1.split_row : 0);
400
0
                 row < unsigned(qr ? raw_height : ph1.split_row); row++)
401
0
            {
402
0
              checkCancel();
403
0
              for (col = (qc ? ph1.split_col : 0);
404
0
                   col < unsigned(qc ? raw_width : ph1.split_col); col++)
405
0
                RAW(row, col) = curve[RAW(row, col)];
406
0
            }
407
0
          }
408
0
        }
409
0
        qlin_applied = 1;
410
0
      }
411
14.0k
      else if (tag == 0x041e && !qmult_applied)
412
25
      { /* Quadrant multipliers - output calibraion */
413
25
        float qmult[2][2] = {{1, 1}, {1, 1}};
414
25
        get4();
415
25
        get4();
416
25
        get4();
417
25
        get4();
418
25
        qmult[0][0] = 1.0f + getrealf(LIBRAW_EXIFTAG_TYPE_FLOAT);
419
25
        get4();
420
25
        get4();
421
25
        get4();
422
25
        get4();
423
25
        get4();
424
25
        qmult[0][1] = 1.0f + getrealf(LIBRAW_EXIFTAG_TYPE_FLOAT);
425
25
        get4();
426
25
        get4();
427
25
        get4();
428
25
        qmult[1][0] = 1.0f + getrealf(LIBRAW_EXIFTAG_TYPE_FLOAT);
429
25
        get4();
430
25
        get4();
431
25
        get4();
432
25
        qmult[1][1] = 1.0f + getrealf(LIBRAW_EXIFTAG_TYPE_FLOAT);
433
1.04k
        for (row = 0; row < raw_height; row++)
434
1.02k
        {
435
1.02k
          checkCancel();
436
33.7k
          for (col = 0; col < raw_width; col++)
437
32.7k
          {
438
32.7k
            i = int(qmult[row >= (unsigned)ph1.split_row][col >= (unsigned)ph1.split_col] *
439
32.7k
                RAW(row, col));
440
32.7k
            RAW(row, col) = LIM(i, 0, 65535);
441
32.7k
          }
442
1.02k
        }
443
25
        qmult_applied = 1;
444
25
      }
445
13.9k
      else if (tag == 0x0431 && !qmult_applied && ph1.split_col > 0 && ph1.split_col < raw_width 
446
0
    && ph1.split_row > 0 && ph1.split_row < raw_height)
447
0
      { /* Quadrant combined - four tile gain calibration */
448
0
        ushort lc[2][2][7], ref[7];
449
0
        int qr, qc;
450
0
        for (i = 0; i < 7; i++)
451
0
          ref[i] = get4();
452
0
        for (qr = 0; qr < 2; qr++)
453
0
          for (qc = 0; qc < 2; qc++)
454
0
            for (i = 0; i < 7; i++)
455
0
              lc[qr][qc][i] = get4();
456
0
        for (qr = 0; qr < 2; qr++)
457
0
        {
458
0
          for (qc = 0; qc < 2; qc++)
459
0
          {
460
0
            int cx[9], cf[9];
461
0
            for (i = 0; i < 7; i++)
462
0
            {
463
0
              cx[1 + i] = ref[i];
464
0
              cf[1 + i] = ((unsigned)ref[i] * lc[qr][qc][i]) / 10000;
465
0
            }
466
0
            cx[0] = cf[0] = 0;
467
0
            cx[8] = cf[8] = 65535;
468
0
            cubic_spline(cx, cf, 9);
469
0
            for (row = (qr ? ph1.split_row : 0);
470
0
                 row < unsigned(qr ? raw_height : ph1.split_row); row++)
471
0
            {
472
0
              checkCancel();
473
0
              for (col = (qc ? ph1.split_col : 0);
474
0
                   col < unsigned(qc ? raw_width : ph1.split_col); col++)
475
0
                RAW(row, col) = curve[RAW(row, col)];
476
0
            }
477
0
          }
478
0
        }
479
0
        qmult_applied = 1;
480
0
        qlin_applied = 1;
481
0
      }
482
14.5k
      fseek(ifp, save, SEEK_SET);
483
14.5k
    }
484
321
    if (!badCols.empty())
485
56
    {
486
56
      qsort(badCols.data(), badCols.size(), sizeof(unsigned), unsigned_cmp);
487
56
      bool prevIsolated = true;
488
318
      for (i = 0; i < (int)badCols.size(); ++i)
489
262
      {
490
262
        bool nextIsolated = i == ((int)(badCols.size()-1)) || badCols[i+1]>badCols[i]+4;
491
17.8k
        for (row = 0; row < raw_height; ++row)
492
17.6k
          if (prevIsolated && nextIsolated)
493
6.94k
            phase_one_fix_pixel_grad(row,badCols[i]);
494
10.6k
          else
495
10.6k
            phase_one_fix_col_pixel_avg(row,badCols[i]);
496
262
        prevIsolated = nextIsolated;
497
262
      }
498
56
    }
499
321
    if (off_412)
500
42
    {
501
42
      fseek(ifp, off_412, SEEK_SET);
502
420
      for (i = 0; i < 9; i++)
503
378
        head[i] = get4() & 0x7fff;
504
42
    unsigned w0 = head[1] * head[3], w1 = head[2] * head[4];
505
42
    if (w0 > 10240000 || w1 > 10240000)
506
5
      throw LIBRAW_EXCEPTION_ALLOC;
507
37
    if (w0 < 1 || w1 < 1)
508
3
      throw LIBRAW_EXCEPTION_IO_CORRUPT;
509
34
      yval[0] = (float *)calloc(head[1] * head[3] + head[2] * head[4], 6);
510
34
      yval[1] = (float *)(yval[0] + head[1] * head[3]);
511
34
      xval[0] = (ushort *)(yval[1] + head[2] * head[4]);
512
34
      xval[1] = (ushort *)(xval[0] + head[1] * head[3]);
513
34
      get2();
514
102
      for (i = 0; i < 2; i++)
515
41.9M
        for (j = 0; j < head[i + 1] * head[i + 3]; j++)
516
41.9M
          yval[i][j] = getrealf(LIBRAW_EXIFTAG_TYPE_FLOAT);
517
102
      for (i = 0; i < 2; i++)
518
41.9M
        for (j = 0; j < head[i + 1] * head[i + 3]; j++)
519
41.9M
          xval[i][j] = get2();
520
1.15k
      for (row = 0; row < raw_height; row++)
521
1.12k
      {
522
1.12k
        checkCancel();
523
37.1k
        for (col = 0; col < raw_width; col++)
524
36.0k
        {
525
36.0k
          cfrac = (float)col * head[3] / raw_width;
526
36.0k
      cip = (int)cfrac;
527
36.0k
          cfrac -= cip;
528
36.0k
          num = RAW(row, col) * 0.5f;
529
99.6k
          for (i = cip; i < cip + 2 && i < head[3]; i++)
530
63.6k
          {
531
94.2k
            for (k = j = 0; j < head[1]; j++)
532
89.5k
              if (num < xval[0][k = head[1] * i + j])
533
58.9k
                break;
534
63.6k
      if (j == 0 || j == head[1] || k < 1 || k >= w0+w1)
535
57.7k
        frac = 0;
536
5.93k
      else
537
5.93k
      {
538
5.93k
        int xdiv = (xval[0][k] - xval[0][k - 1]);
539
5.93k
        frac = xdiv ? (xval[0][k] - num) / (xval[0][k] - xval[0][k - 1]) : 0;
540
5.93k
      }
541
63.6k
      if (k < w0 + w1)
542
63.6k
        mult[i - cip] = yval[0][k > 0 ? k - 1 : 0] * frac + yval[0][k] * (1 - frac);
543
0
      else
544
0
        mult[i - cip] = 0;
545
63.6k
          }
546
36.0k
          i = int(((mult[0] * (1.f - cfrac) + mult[1] * cfrac) * row + num) * 2.f);
547
36.0k
          RAW(row, col) = LIM(i, 0, 65535);
548
36.0k
        }
549
1.12k
      }
550
34
      free(yval[0]);
551
34
    }
552
321
  }
553
321
  catch (...)
554
321
  {
555
25
    if (yval[0])
556
0
      free(yval[0]);
557
25
    return LIBRAW_CANCELLED_BY_CALLBACK;
558
25
  }
559
296
  return 0;
560
321
}
561
562
void LibRaw::phase_one_load_raw()
563
273
{
564
273
  int a, b, i;
565
273
  ushort akey, bkey, t_mask;
566
567
273
  fseek(ifp, ph1.key_off, SEEK_SET);
568
273
  akey = get2();
569
273
  bkey = get2();
570
273
  t_mask = ph1.format == 1 ? 0x5555 : 0x1354;
571
273
  if (ph1.black_col || ph1.black_row)
572
13
  {
573
13
    imgdata.rawdata.ph1_cblack =
574
13
        (short(*)[2])calloc(raw_height * 2, sizeof(ushort));
575
13
    imgdata.rawdata.ph1_rblack =
576
13
        (short(*)[2])calloc(raw_width * 2, sizeof(ushort));
577
13
    if (ph1.black_col)
578
6
    {
579
6
      fseek(ifp, ph1.black_col, SEEK_SET);
580
6
      read_shorts((ushort *)imgdata.rawdata.ph1_cblack[0], raw_height * 2);
581
6
    }
582
13
    if (ph1.black_row)
583
7
    {
584
7
      fseek(ifp, ph1.black_row, SEEK_SET);
585
7
      read_shorts((ushort *)imgdata.rawdata.ph1_rblack[0], raw_width * 2);
586
7
    }
587
13
  }
588
273
  fseek(ifp, data_offset, SEEK_SET);
589
273
  read_shorts(raw_image, raw_width * raw_height);
590
273
  if (ph1.format)
591
529
    for (i = 0; i < raw_width * raw_height; i += 2)
592
528
    {
593
528
      a = raw_image[i + 0] ^ akey;
594
528
      b = raw_image[i + 1] ^ bkey;
595
528
      raw_image[i + 0] = (a & t_mask) | (b & ~t_mask);
596
528
      raw_image[i + 1] = (b & t_mask) | (a & ~t_mask);
597
528
    }
598
273
}
599
600
unsigned LibRaw::ph1_bithuff(int nbits, ushort *huff)
601
31.4M
{
602
31.4M
#ifndef LIBRAW_NOTHREADS
603
49.9M
#define bitbuf tls->ph1_bits.bitbuf
604
103M
#define vbits tls->ph1_bits.vbits
605
#else
606
  static UINT64 bitbuf = 0;
607
  static int vbits = 0;
608
#endif
609
31.4M
  unsigned c;
610
611
31.4M
  if (nbits == -1)
612
35.6k
  {
613
35.6k
    bitbuf = vbits = 0;
614
35.6k
    return 0;
615
35.6k
  }
616
31.3M
  if (nbits == 0)
617
8.56k
    return 0;
618
31.3M
  if (vbits < nbits)
619
9.28M
  {
620
9.28M
    bitbuf = bitbuf << 32 | get4();
621
9.28M
    vbits += 32;
622
9.28M
  }
623
31.3M
  c = unsigned ((bitbuf << (64 - vbits) >> (64 - nbits)) & 0xffffffff);
624
31.3M
  if (huff)
625
0
  {
626
0
    vbits -= huff[c] >> 8;
627
0
    return (uchar)huff[c];
628
0
  }
629
31.3M
  vbits -= nbits;
630
31.3M
  return c;
631
31.3M
#ifndef LIBRAW_NOTHREADS
632
31.3M
#undef bitbuf
633
31.3M
#undef vbits
634
31.3M
#endif
635
31.3M
}
636
637
void LibRaw::phase_one_load_raw_c()
638
76
{
639
76
  static const int length[] = {8, 7, 6, 9, 11, 10, 5, 12, 14, 13};
640
76
  int *offset, len[2], pred[2], row, col, i, j;
641
76
  ushort *pixel;
642
76
  short(*c_black)[2], (*r_black)[2];
643
76
  if (ph1.format == 6)
644
0
    throw LIBRAW_EXCEPTION_IO_CORRUPT;
645
646
76
  pixel = (ushort *)calloc(raw_width * 3 + raw_height * 4, 2);
647
76
  offset = (int *)(pixel + raw_width);
648
76
  fseek(ifp, strip_offset, SEEK_SET);
649
18.2k
  for (row = 0; row < raw_height; row++)
650
18.1k
    offset[row] = get4();
651
76
  c_black = (short(*)[2])(offset + raw_height);
652
76
  fseek(ifp, ph1.black_col, SEEK_SET);
653
76
  if (ph1.black_col)
654
2
    read_shorts((ushort *)c_black[0], raw_height * 2);
655
76
  r_black = c_black + raw_height;
656
76
  fseek(ifp, ph1.black_row, SEEK_SET);
657
76
  if (ph1.black_row)
658
4
    read_shorts((ushort *)r_black[0], raw_width * 2);
659
660
  // Copy data to internal copy (ever if not read)
661
76
  if (ph1.black_col || ph1.black_row)
662
6
  {
663
6
    imgdata.rawdata.ph1_cblack =
664
6
        (short(*)[2])calloc(raw_height * 2, sizeof(ushort));
665
6
    memmove(imgdata.rawdata.ph1_cblack, (ushort *)c_black[0],
666
6
            raw_height * 2 * sizeof(ushort));
667
6
    imgdata.rawdata.ph1_rblack =
668
6
        (short(*)[2])calloc(raw_width * 2, sizeof(ushort));
669
6
    memmove(imgdata.rawdata.ph1_rblack, (ushort *)r_black[0],
670
6
            raw_width * 2 * sizeof(ushort));
671
6
  }
672
673
19.5k
  for (i = 0; i < 256; i++)
674
19.4k
    curve[i] = ushort(float(i * i) / 3.969f + 0.5f);
675
76
  try
676
76
  {
677
17.5k
    for (row = 0; row < raw_height; row++)
678
17.4k
    {
679
17.4k
      checkCancel();
680
17.4k
      fseek(ifp, data_offset + offset[row], SEEK_SET);
681
17.4k
      ph1_bits(-1);
682
17.4k
      pred[0] = pred[1] = 0;
683
8.91M
      for (col = 0; col < raw_width; col++)
684
8.90M
      {
685
8.90M
        if (col >= (raw_width & -8))
686
23.5k
          len[0] = len[1] = 14;
687
8.87M
        else if ((col & 7) == 0)
688
3.32M
          for (i = 0; i < 2; i++)
689
2.21M
          {
690
4.09M
            for (j = 0; j < 5 && !ph1_bits(1); j++)
691
1.87M
              ;
692
2.21M
            if (j--)
693
541k
              len[i] = length[j * 2 + ph1_bits(1)];
694
2.21M
          }
695
8.90M
        if ((i = len[col & 1]) == 14)
696
3.76M
          pixel[col] = pred[col & 1] = ph1_bits(16);
697
5.13M
        else
698
5.13M
          pixel[col] = pred[col & 1] += ph1_bits(i) + 1 - (1 << (i - 1));
699
8.90M
        if (pred[col & 1] >> 16)
700
1.98M
          derror();
701
8.90M
        if (ph1.format == 5 && pixel[col] < 256)
702
19.1k
          pixel[col] = curve[pixel[col]];
703
8.90M
      }
704
17.4k
      if (ph1.format == 8)
705
1.60k
        memmove(&RAW(row, 0), &pixel[0], raw_width * 2);
706
15.8k
      else
707
8.62M
        for (col = 0; col < raw_width; col++)
708
8.60M
          RAW(row, col) = pixel[col] << 2;
709
17.4k
    }
710
76
  }
711
76
  catch (...)
712
76
  {
713
3
    free(pixel);
714
3
    throw;
715
3
  }
716
73
  free(pixel);
717
73
  maximum = 0xfffc - ph1.t_black;
718
73
}
719
720
void LibRaw::hasselblad_load_raw()
721
0
{
722
0
  struct jhead jh;
723
0
  int shot, row, col, *back[5]={0,0,0,0,0},
724
0
   len[2], diff[12], pred, sh, f, c;
725
0
  unsigned s;
726
0
  unsigned upix, urow, ucol;
727
0
  ushort *ip;
728
729
0
  if (!ljpeg_start(&jh, 0))
730
0
    return;
731
0
  order = 0x4949;
732
0
  ph1_bits(-1);
733
0
  try
734
0
  {
735
0
    back[4] = (int *)calloc(raw_width, 3 * sizeof **back);
736
0
    FORC3 back[c] = back[4] + c * raw_width;
737
0
    cblack[6] >>= sh = tiff_samples > 1;
738
0
    shot = LIM(shot_select, 1, tiff_samples) - 1;
739
0
    for (row = 0; row < raw_height; row++)
740
0
    {
741
0
      checkCancel();
742
0
      FORC4 back[(c + 3) & 3] = back[c];
743
0
      for (col = 0; col < raw_width; col += 2)
744
0
      {
745
0
        for (s = 0; s < tiff_samples * 2; s += 2)
746
0
        {
747
0
          FORC(2) len[c] = ph1_huff(jh.huff[0]);
748
0
          FORC(2)
749
0
          {
750
0
            diff[s + c] = ph1_bits(len[c]);
751
0
            if (len[c] > 0 && (diff[s + c] & (1 << (len[c] - 1))) == 0)
752
0
              diff[s + c] -= (1 << len[c]) - 1;
753
0
            if (diff[s + c] == 65535)
754
0
              diff[s + c] = -32768;
755
0
          }
756
0
        }
757
0
        for (s = col; s < unsigned(col + 2); s++)
758
0
        {
759
0
          pred = 0x8000 + load_flags;
760
0
          if (col)
761
0
            pred = back[2][s - 2];
762
0
          if (col && row > 1)
763
0
            switch (jh.psv)
764
0
            {
765
0
            case 11:
766
0
              pred += back[0][s] / 2 - back[0][s - 2] / 2;
767
0
              break;
768
0
            }
769
0
          f = (row & 1) * 3 ^ ((col + s) & 1);
770
0
          FORC(int(tiff_samples))
771
0
          {
772
0
            pred += diff[(s & 1) * tiff_samples + c];
773
0
            upix = pred >> sh & 0xffff;
774
0
            if (raw_image && c == shot)
775
0
              RAW(row, s) = upix;
776
0
            if (image)
777
0
            {
778
0
              urow = row - top_margin + (c & 1);
779
0
              ucol = col - left_margin - ((c >> 1) & 1);
780
0
              ip = &image[urow * width + ucol][f];
781
0
              if (urow < height && ucol < width)
782
0
                *ip = c < 4 ? upix : (*ip + upix) >> 1;
783
0
            }
784
0
          }
785
0
          back[2][s] = pred;
786
0
        }
787
0
      }
788
0
    }
789
0
  }
790
0
  catch (...)
791
0
  {
792
0
    if(back[4])
793
0
      free(back[4]);
794
0
    ljpeg_end(&jh);
795
0
    throw;
796
0
  }
797
0
  if(back[4])
798
0
    free(back[4]);
799
0
  ljpeg_end(&jh);
800
0
  if (image)
801
0
    mix_green = 1;
802
0
}
803
804
void LibRaw::leaf_hdr_load_raw()
805
67
{
806
67
  ushort *pixel = 0;
807
67
  unsigned tile = 0, r, c, row, col;
808
809
67
  if (!filters || !raw_image)
810
18
  {
811
18
    if (!image)
812
0
      throw LIBRAW_EXCEPTION_IO_CORRUPT;
813
18
    pixel = (ushort *)calloc(raw_width, sizeof *pixel);
814
18
  }
815
67
  try
816
67
  {
817
67
    FORC(tiff_samples)
818
975
    for (r = 0; r < raw_height; r++)
819
936
    {
820
936
      checkCancel();
821
936
      if (r % tile_length == 0)
822
196
      {
823
196
        fseek(ifp, data_offset + 4 * tile++, SEEK_SET);
824
196
        fseek(ifp, get4(), SEEK_SET);
825
196
      }
826
936
      if (filters && c != shot_select)
827
0
        continue;
828
936
      if (filters && raw_image)
829
454
        pixel = raw_image + r * raw_width;
830
936
      read_shorts(pixel, raw_width);
831
936
      if (!filters && image && (row = r - top_margin) < height)
832
17.2k
        for (col = 0; col < width && col + left_margin < raw_width; col++)
833
16.7k
          image[row * width + col][c] = pixel[col + left_margin];
834
936
    }
835
67
  }
836
67
  catch (...)
837
67
  {
838
23
    if (!filters)
839
15
      free(pixel);
840
23
    throw;
841
23
  }
842
44
  if (!filters)
843
3
  {
844
3
    maximum = 0xffff;
845
3
    raw_color = 1;
846
3
    free(pixel);
847
3
  }
848
44
}
849
850
void LibRaw::unpacked_load_raw_FujiDBP()
851
/*
852
for Fuji DBP for GX680, aka DX-2000
853
  DBP_tile_width = 688;
854
  DBP_tile_height = 3856;
855
  DBP_n_tiles = 8;
856
*/
857
0
{
858
0
  int scan_line, tile_n;
859
0
  int nTiles;
860
861
0
  nTiles = 8;
862
0
  tile_width = raw_width / nTiles;
863
864
0
  ushort *tile;
865
0
  tile = (ushort *)calloc(raw_height, tile_width * 2);
866
867
0
  for (tile_n = 0; tile_n < nTiles; tile_n++)
868
0
  {
869
0
    read_shorts(tile, tile_width * raw_height);
870
0
    for (scan_line = 0; scan_line < raw_height; scan_line++)
871
0
    {
872
0
      memcpy(&raw_image[scan_line * raw_width + tile_n * tile_width],
873
0
             &tile[scan_line * tile_width], tile_width * 2);
874
0
    }
875
0
  }
876
0
  free(tile);
877
0
  fseek(ifp, -2, SEEK_CUR); // avoid EOF error
878
0
}
879
880
void LibRaw::sinar_4shot_load_raw()
881
50
{
882
50
  ushort *pixel;
883
50
  unsigned shot, row, col, r, c;
884
885
50
  if (raw_image)
886
0
  {
887
0
    shot = LIM(shot_select, 1, 4) - 1;
888
0
    fseek(ifp, data_offset + shot * 4, SEEK_SET);
889
0
    fseek(ifp, get4(), SEEK_SET);
890
0
    unpacked_load_raw();
891
0
    return;
892
0
  }
893
50
  if (!image)
894
0
    throw LIBRAW_EXCEPTION_IO_CORRUPT;
895
50
  pixel = (ushort *)calloc(raw_width, sizeof *pixel);
896
50
  try
897
50
  {
898
137
    for (shot = 0; shot < 4; shot++)
899
87
    {
900
87
      checkCancel();
901
87
      fseek(ifp, data_offset + shot * 4, SEEK_SET);
902
87
      fseek(ifp, get4(), SEEK_SET);
903
2.04k
      for (row = 0; row < raw_height; row++)
904
1.95k
      {
905
1.95k
        read_shorts(pixel, raw_width);
906
1.95k
        if ((r = row - top_margin - (shot >> 1 & 1)) >= height)
907
66
          continue;
908
78.4k
        for (col = 0; col < raw_width; col++)
909
76.5k
        {
910
76.5k
          if ((c = col - left_margin - (shot & 1)) >= width)
911
2.08k
            continue;
912
74.4k
          image[r * width + c][(row & 1) * 3 ^ (~col & 1)] = pixel[col];
913
74.4k
        }
914
1.88k
      }
915
87
    }
916
50
  }
917
50
  catch (...)
918
50
  {
919
43
    free(pixel);
920
43
    throw;
921
43
  }
922
7
  free(pixel);
923
7
  mix_green = 1;
924
7
}
925
926
void LibRaw::imacon_full_load_raw()
927
11
{
928
11
  if (!image)
929
1
    throw LIBRAW_EXCEPTION_IO_CORRUPT;
930
10
  int row, col;
931
932
10
  unsigned short *buf =
933
10
      (unsigned short *)malloc(width * 3 * sizeof(unsigned short));
934
935
130
  for (row = 0; row < height; row++)
936
120
  {
937
120
    checkCancel();
938
120
    read_shorts(buf, width * 3);
939
120
    unsigned short(*rowp)[4] = &image[row * width];
940
4.26k
    for (col = 0; col < width; col++)
941
4.14k
    {
942
4.14k
      rowp[col][0] = buf[col * 3];
943
4.14k
      rowp[col][1] = buf[col * 3 + 1];
944
4.14k
      rowp[col][2] = buf[col * 3 + 2];
945
4.14k
      rowp[col][3] = 0;
946
4.14k
    }
947
120
  }
948
10
  free(buf);
949
10
}