Coverage Report

Created: 2025-09-08 07:52

/src/LibRaw/src/decoders/load_mfbacks.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- C++ -*-
2
 * Copyright 2019-2024 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
22.2k
{
23
  // Branchless version.
24
22.2k
  uint32_t sm = x >> 31;
25
22.2k
  return (uint32_t) ((x + sm) ^ sm);
26
22.2k
}
27
28
inline uint32_t min32(uint32_t x, uint32_t y)
29
4.23k
{
30
4.23k
  return x < y ? x : y;
31
4.23k
}
32
33
inline uint32_t max32(uint32_t x, uint32_t y)
34
529
{
35
529
  return x > y ? x : y;
36
529
}
37
38
inline uint32_t constain32(uint32_t x, uint32_t l, uint32_t u)
39
529
{
40
529
  return x < l ? l : (x > u ? u : x);
41
529
}
42
43
int unsigned_cmp(const void *a, const void *b)
44
89
{
45
89
  if (!a || !b)
46
0
    return 0;
47
48
89
  return *(unsigned *)a > *(unsigned *)b ? 1 : (*(unsigned *)a < *(unsigned *)b ? -1 : 0);
49
89
}
50
51
int LibRaw::p1rawc(unsigned row, unsigned col, unsigned& count)
52
4.59k
{
53
4.59k
  return (row < raw_height && col < raw_width) ? (++count, RAW(row, col)) : 0;
54
4.59k
}
55
56
int LibRaw::p1raw(unsigned row, unsigned col)
57
53.9k
{
58
53.9k
  return (row < raw_height && col < raw_width) ? RAW(row, col) : 0;
59
53.9k
}
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
1.08k
{
66
1.08k
  static const int8_t dir[3][8][2] = {
67
1.08k
  { {-2,-2}, {-2, 2}, {2,-2}, {2, 2}, { 0, 0}, { 0, 0}, {0, 0}, {0, 0} },
68
1.08k
  { {-2,-4}, {-4,-2}, {2,-4}, {4,-2}, {-2, 4}, {-4, 2}, {2, 4}, {4, 2} },
69
1.08k
  { {-4,-4}, {-4, 4}, {4,-4}, {4, 4}, { 0, 0}, { 0, 0}, {0, 0}, {0, 0} } };
70
71
1.08k
  for (int set=0; set < 3; ++set)
72
1.08k
  {
73
1.08k
    uint32_t total = 0;
74
1.08k
    uint32_t count = 0;
75
5.40k
    for (int i = 0; i < 8; ++i)
76
5.40k
    {
77
5.40k
      if (!dir[set][i][0] && !dir[set][i][1])
78
1.08k
        break;
79
80
4.32k
      total += p1rawc(row+dir[set][i][0], col+dir[set][i][1], count);
81
4.32k
    }
82
83
1.08k
    if (count)
84
1.08k
    {
85
1.08k
      RAW(row,col) = (uint16_t)((total + (count >> 1)) / count);
86
1.08k
      break;
87
1.08k
    }
88
1.08k
  }
89
1.08k
}
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
529
{
94
529
  static const int8_t grad_sets[7][12][2] = {
95
529
    { {-4,-2}, { 4, 2}, {-3,-1}, { 1, 1}, {-1,-1}, { 3, 1}, 
96
529
      {-4,-1}, { 0, 1}, {-2,-1}, { 2, 1}, { 0,-1}, { 4, 1} },
97
529
    { {-2,-2}, { 2, 2}, {-3,-1}, {-1, 1}, {-1,-1}, { 1, 1}, 
98
529
      { 1,-1}, { 3, 1}, {-2,-1}, { 0, 1}, { 0,-1}, { 2, 1} },
99
529
    { {-2,-4}, { 2, 4}, {-1,-3}, { 1, 1}, {-1,-1}, { 1, 3}, 
100
529
      {-2,-1}, { 0, 3}, {-1,-2}, { 1, 2}, { 0,-3}, { 2, 1} },
101
529
    { { 0,-2}, { 0, 2}, {-1,-1}, {-1, 1}, { 1,-1}, { 1, 1}, 
102
529
      {-1,-2}, {-1, 2}, { 0,-1}, { 0,-1}, { 1,-2}, { 1, 2} },
103
529
    { {-2, 4}, { 2,-4}, {-1, 3}, { 1,-1}, {-1, 1}, { 1,-3}, 
104
529
      {-2, 1}, { 0,-3}, {-1, 2}, { 1,-2}, { 0, 3}, { 2,-1} },
105
529
    { {-2, 2}, { 2,-2}, {-3, 1}, {-1,-1}, {-1, 1}, { 1,-1}, 
106
529
      { 1, 1}, { 3,-1}, {-2, 1}, { 0,-1}, { 0, 1}, { 2,-1} },
107
529
    { {-4, 2}, { 4,-2}, {-3, 1}, { 1,-1}, {-1, 1}, { 3,-1}, 
108
529
      {-4, 1}, { 0,-1}, {-2, 1}, { 2,-1}, { 0, 1}, { 4,-1} } };
109
110
529
  uint32_t est[7], grad[7];
111
529
  uint32_t lower = min32(p1raw(row,col-2), p1raw(row, col+2));
112
529
  uint32_t upper = max32(p1raw(row,col-2), p1raw(row, col+2));
113
529
  uint32_t minGrad = 0xFFFFFFFF;
114
4.23k
  for (int i = 0; i<7; ++i)
115
3.70k
  {
116
3.70k
    est[i] = p1raw(row+grad_sets[i][0][0], col+grad_sets[i][0][1]) +
117
3.70k
             p1raw(row+grad_sets[i][1][0], col+grad_sets[i][1][1]);
118
3.70k
    grad[i] = 0;
119
25.9k
    for (int j=0; j<12; j+=2)
120
22.2k
      grad[i] += abs32(p1raw(row+grad_sets[i][j][0], col+grad_sets[i][j][1]) -
121
22.2k
                       p1raw(row+grad_sets[i][j+1][0], col+grad_sets[i][j+1][1]));
122
3.70k
    minGrad = min32(minGrad, grad[i]);
123
3.70k
  }
124
125
529
  uint32_t limit = (minGrad * 3) >> 1;
126
529
  uint32_t total = 0;
127
529
  uint32_t count = 0;
128
4.23k
  for (int i = 0; i<7; ++i)
129
3.70k
    if (grad[i] <= limit)
130
958
    {
131
958
      total += est[i];
132
958
      count += 2;
133
958
    }
134
529
  RAW(row, col) = constain32((total + (count >> 1)) / count, lower, upper);
135
529
}
136
137
void LibRaw::phase_one_flat_field(int is_float, int nc)
138
365
{
139
365
  ushort head[8];
140
365
  unsigned wide, high, y, x, c, rend, cend, row, col;
141
365
  float *mrow, num, mult[4];
142
143
365
  read_shorts(head, 8);
144
365
  if (head[2] == 0 || head[3] == 0 || head[4] == 0 || head[5] == 0)
145
248
    return;
146
117
  wide = head[2] / head[4] + (head[2] % head[4] != 0);
147
117
  high = head[3] / head[5] + (head[3] % head[5] != 0);
148
117
  mrow = (float *)calloc(nc * wide, sizeof *mrow);
149
89.4k
  for (y = 0; y < high; y++)
150
89.3k
  {
151
89.3k
    checkCancel();
152
219k
    for (x = 0; x < wide; x++)
153
259k
      for (c = 0; c < (unsigned)nc; c += 2)
154
129k
      {
155
129k
        num = is_float ? getrealf(LIBRAW_EXIFTAG_TYPE_FLOAT) : float(get2()) / 32768.f;
156
129k
        if (y == 0)
157
2.85k
          mrow[c * wide + x] = num;
158
127k
        else
159
127k
          mrow[(c + 1) * wide + x] = (num - mrow[c * wide + x]) / head[5];
160
129k
      }
161
89.3k
    if (y == 0)
162
117
      continue;
163
89.2k
    rend = head[1] + y * head[5];
164
89.2k
    for (row = rend - head[5];
165
89.7k
         row < raw_height && row < rend && row < unsigned(head[1] + head[3] - head[5]);
166
89.2k
         row++)
167
517
    {
168
36.5k
      for (x = 1; x < wide; x++)
169
35.9k
      {
170
71.9k
        for (c = 0; c < (unsigned)nc; c += 2)
171
35.9k
        {
172
35.9k
          mult[c] = mrow[c * wide + x - 1];
173
35.9k
          mult[c + 1] = (mrow[c * wide + x] - mult[c]) / head[4];
174
35.9k
        }
175
35.9k
        cend = head[0] + x * head[4];
176
35.9k
        for (col = cend - head[4];
177
36.9k
             col < raw_width && col < cend && col < unsigned(head[0] + head[2] - head[4]);
178
35.9k
             col++)
179
952
        {
180
952
          c = nc > 2 ? FC(row - top_margin, col - left_margin) : 0;
181
952
          if (!(c & 1))
182
952
          {
183
952
            c = unsigned(RAW(row, col) * mult[c]);
184
952
            RAW(row, col) = LIM(c, 0, 65535);
185
952
          }
186
1.90k
          for (c = 0; c < (unsigned)nc; c += 2)
187
952
            mult[c] += mult[c + 1];
188
952
        }
189
35.9k
      }
190
37.0k
      for (x = 0; x < wide; x++)
191
73.0k
        for (c = 0; c < (unsigned)nc; c += 2)
192
36.5k
          mrow[c * wide + x] += mrow[(c + 1) * wide + x];
193
517
    }
194
89.2k
  }
195
117
  free(mrow);
196
117
}
197
198
int LibRaw::phase_one_correct()
199
214
{
200
214
  unsigned entries, tag, data, col, row, type;
201
214
  INT64 save;
202
214
  int len, i, j, k, cip, sum;
203
#if 0
204
  int val[4], dev[4], max;
205
#endif
206
214
  int head[9], diff, mindiff = INT_MAX;
207
214
  INT64 off_412 = 0;
208
214
  /* static */ const signed char dir[12][2] = {
209
214
      {-1, -1}, {-1, 1}, {1, -1},  {1, 1},  {-2, 0}, {0, -2},
210
214
      {0, 2},   {2, 0},  {-2, -2}, {-2, 2}, {2, -2}, {2, 2}};
211
214
  float poly[8], num, cfrac, frac, mult[2], *yval[2] = {NULL, NULL};
212
214
  ushort *xval[2];
213
214
  int qmult_applied = 0, qlin_applied = 0;
214
214
  std::vector<unsigned> badCols;
215
216
214
  if (!meta_length)
217
38
    return 0;
218
176
  fseek(ifp, meta_offset, SEEK_SET);
219
176
  order = get2();
220
176
  fseek(ifp, 6, SEEK_CUR);
221
176
  fseek(ifp, meta_offset + get4(), SEEK_SET);
222
176
  entries = get4();
223
176
  get4();
224
176
  INT64 fsize = ifp->size();
225
226
176
  try
227
176
  {
228
588k
    while (entries--)
229
587k
    {
230
587k
      checkCancel();
231
587k
      tag = get4();
232
587k
      len = get4();
233
587k
      data = get4();
234
587k
      save = ftell(ifp);
235
587k
      fseek(ifp, meta_offset + data, SEEK_SET);
236
587k
#if 1
237
587k
    if (ifp->eof())
238
80
    {
239
      // skip bad or unknown tag
240
80
      fseek(ifp, save, SEEK_SET);
241
80
      continue;
242
80
    }
243
587k
#endif
244
587k
      INT64 savepos = ftell(ifp);
245
587k
    if (len < 0 || (len > 8 && savepos + (INT64)len > 2 * fsize))
246
416k
    {
247
416k
        fseek(ifp, save, SEEK_SET); // Recover tiff-read position!!
248
416k
        continue;
249
416k
    }
250
170k
      if (tag == 0x0400)
251
666
      { /* Sensor defects */
252
838k
        while ((len -= 8) >= 0)
253
838k
        {
254
838k
          col = get2();
255
838k
          row = get2();
256
838k
          type = get2();
257
838k
          get2();
258
838k
          if (col >= raw_width)
259
510k
            continue;
260
327k
          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
245
            badCols.push_back(col);
293
327k
#endif
294
327k
          else if (type == 129)
295
69
          { /* Bad pixel */
296
69
            if (row >= raw_height)
297
35
              continue;
298
34
            j = (FC(row - top_margin, col - left_margin) != 1) * 4;
299
34
            unsigned count = 0;
300
306
            for (sum = 0, i = j; i < j + 8; i++)
301
272
              sum += p1rawc(row + dir[i][0], col + dir[i][1], count);
302
34
            if (count)
303
34
              RAW(row, col) = (sum + (count >> 1)) / count;
304
34
          }
305
327k
        }
306
666
      }
307
170k
      else if (tag == 0x0419)
308
0
      { /* Polynomial curve - output calibraion */
309
0
        for (get4(), i = 0; i < 8; i++)
310
0
          poly[i] = getrealf(LIBRAW_EXIFTAG_TYPE_FLOAT);
311
0
        poly[3] += (ph1.tag_210 - poly[7]) * poly[6] + 1;
312
0
        for (i = 0; i < 0x10000; i++)
313
0
        {
314
0
          num = (poly[5] * i + poly[3]) * i + poly[1];
315
0
          curve[i] = ushort(LIM(num, 0, 65535));
316
0
        }
317
0
        goto apply; /* apply to right half */
318
0
      }
319
170k
      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
0
      apply: /* apply to whole image */
330
0
        for (row = 0; row < raw_height; row++)
331
0
        {
332
0
          checkCancel();
333
0
          for (col = (tag & 1) * ph1.split_col; col < raw_width; col++)
334
0
            RAW(row, col) = curve[RAW(row, col)];
335
0
        }
336
0
      }
337
170k
      else if (tag == 0x0401)
338
178
      { /* All-color flat fields - luma calibration*/
339
178
        phase_one_flat_field(1, 2);
340
178
      }
341
170k
      else if (tag == 0x0416 || tag == 0x0410)
342
187
      {
343
        // 0x410 - luma calibration
344
187
        phase_one_flat_field(0, 2);
345
187
      }
346
169k
      else if (tag == 0x040b)
347
0
      { /* Red+blue flat field - croma calibration */
348
0
        phase_one_flat_field(0, 4);
349
0
      }
350
169k
      else if (tag == 0x0412)
351
126
      {
352
126
        fseek(ifp, 36, SEEK_CUR);
353
126
        diff = abs(get2() - ph1.tag_21a);
354
126
        if (mindiff > diff)
355
35
        {
356
35
          mindiff = diff;
357
35
          off_412 = ftell(ifp) - 38;
358
35
        }
359
126
      }
360
169k
      else if (tag == 0x041f && !qlin_applied && ph1.split_col > 0 && ph1.split_col < raw_width
361
169k
    && 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
169k
      else if (tag == 0x041e && !qmult_applied)
412
1
      { /* Quadrant multipliers - output calibraion */
413
1
        float qmult[2][2] = {{1, 1}, {1, 1}};
414
1
        get4();
415
1
        get4();
416
1
        get4();
417
1
        get4();
418
1
        qmult[0][0] = 1.0f + getrealf(LIBRAW_EXIFTAG_TYPE_FLOAT);
419
1
        get4();
420
1
        get4();
421
1
        get4();
422
1
        get4();
423
1
        get4();
424
1
        qmult[0][1] = 1.0f + getrealf(LIBRAW_EXIFTAG_TYPE_FLOAT);
425
1
        get4();
426
1
        get4();
427
1
        get4();
428
1
        qmult[1][0] = 1.0f + getrealf(LIBRAW_EXIFTAG_TYPE_FLOAT);
429
1
        get4();
430
1
        get4();
431
1
        get4();
432
1
        qmult[1][1] = 1.0f + getrealf(LIBRAW_EXIFTAG_TYPE_FLOAT);
433
24
        for (row = 0; row < raw_height; row++)
434
23
        {
435
23
          checkCancel();
436
5.12k
          for (col = 0; col < raw_width; col++)
437
5.10k
          {
438
5.10k
            i = int(qmult[row >= (unsigned)ph1.split_row][col >= (unsigned)ph1.split_col] *
439
5.10k
                RAW(row, col));
440
5.10k
            RAW(row, col) = LIM(i, 0, 65535);
441
5.10k
          }
442
23
        }
443
1
        qmult_applied = 1;
444
1
      }
445
169k
      else if (tag == 0x0431 && !qmult_applied && ph1.split_col > 0 && ph1.split_col < raw_width 
446
169k
    && 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
170k
      fseek(ifp, save, SEEK_SET);
483
170k
    }
484
176
    if (!badCols.empty())
485
24
    {
486
24
      qsort(badCols.data(), badCols.size(), sizeof(unsigned), unsigned_cmp);
487
24
      bool prevIsolated = true;
488
94
      for (i = 0; i < (int)badCols.size(); ++i)
489
70
      {
490
70
        bool nextIsolated = i == ((int)(badCols.size()-1)) || badCols[i+1]>badCols[i]+4;
491
1.68k
        for (row = 0; row < raw_height; ++row)
492
1.61k
          if (prevIsolated && nextIsolated)
493
529
            phase_one_fix_pixel_grad(row,badCols[i]);
494
1.08k
          else
495
1.08k
            phase_one_fix_col_pixel_avg(row,badCols[i]);
496
70
        prevIsolated = nextIsolated;
497
70
      }
498
24
    }
499
176
    if (off_412)
500
7
    {
501
7
      fseek(ifp, off_412, SEEK_SET);
502
70
      for (i = 0; i < 9; i++)
503
63
        head[i] = get4() & 0x7fff;
504
7
    unsigned w0 = head[1] * head[3], w1 = head[2] * head[4];
505
7
    if (w0 > 10240000 || w1 > 10240000)
506
2
      throw LIBRAW_EXCEPTION_ALLOC;
507
5
    if (w0 < 1 || w1 < 1)
508
0
      throw LIBRAW_EXCEPTION_IO_CORRUPT;
509
5
      yval[0] = (float *)calloc(head[1] * head[3] + head[2] * head[4], 6);
510
5
      yval[1] = (float *)(yval[0] + head[1] * head[3]);
511
5
      xval[0] = (ushort *)(yval[1] + head[2] * head[4]);
512
5
      xval[1] = (ushort *)(xval[0] + head[1] * head[3]);
513
5
      get2();
514
14
      for (i = 0; i < 2; i++)
515
58.2k
        for (j = 0; j < head[i + 1] * head[i + 3]; j++)
516
58.2k
          yval[i][j] = getrealf(LIBRAW_EXIFTAG_TYPE_FLOAT);
517
5
      for (i = 0; i < 2; i++)
518
0
        for (j = 0; j < head[i + 1] * head[i + 3]; j++)
519
0
          xval[i][j] = get2();
520
5
      for (row = 0; row < raw_height; row++)
521
0
      {
522
0
        checkCancel();
523
0
        for (col = 0; col < raw_width; col++)
524
0
        {
525
0
          cfrac = (float)col * head[3] / raw_width;
526
0
      cip = (int)cfrac;
527
0
          cfrac -= cip;
528
0
          num = RAW(row, col) * 0.5f;
529
0
          for (i = cip; i < cip + 2; i++)
530
0
          {
531
0
            for (k = j = 0; j < head[1]; j++)
532
0
              if (num < xval[0][k = head[1] * i + j])
533
0
                break;
534
0
      if (j == 0 || j == head[1] || k < 1 || k >= w0+w1)
535
0
        frac = 0;
536
0
      else
537
0
      {
538
0
        int xdiv = (xval[0][k] - xval[0][k - 1]);
539
0
        frac = xdiv ? (xval[0][k] - num) / (xval[0][k] - xval[0][k - 1]) : 0;
540
0
      }
541
0
      if (k < w0 + w1)
542
0
        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
0
          }
546
0
          i = int(((mult[0] * (1.f - cfrac) + mult[1] * cfrac) * row + num) * 2.f);
547
0
          RAW(row, col) = LIM(i, 0, 65535);
548
0
        }
549
0
      }
550
5
      free(yval[0]);
551
5
    }
552
176
  }
553
176
  catch (...)
554
176
  {
555
148
    if (yval[0])
556
5
      free(yval[0]);
557
148
    return LIBRAW_CANCELLED_BY_CALLBACK;
558
148
  }
559
28
  return 0;
560
176
}
561
562
void LibRaw::phase_one_load_raw()
563
188
{
564
188
  int a, b, i;
565
188
  ushort akey, bkey, t_mask;
566
567
188
  fseek(ifp, ph1.key_off, SEEK_SET);
568
188
  akey = get2();
569
188
  bkey = get2();
570
188
  t_mask = ph1.format == 1 ? 0x5555 : 0x1354;
571
188
  if (ph1.black_col || ph1.black_row)
572
10
  {
573
10
    imgdata.rawdata.ph1_cblack =
574
10
        (short(*)[2])calloc(raw_height * 2, sizeof(ushort));
575
10
    imgdata.rawdata.ph1_rblack =
576
10
        (short(*)[2])calloc(raw_width * 2, sizeof(ushort));
577
10
    if (ph1.black_col)
578
10
    {
579
10
      fseek(ifp, ph1.black_col, SEEK_SET);
580
10
      read_shorts((ushort *)imgdata.rawdata.ph1_cblack[0], raw_height * 2);
581
10
    }
582
10
    if (ph1.black_row)
583
0
    {
584
0
      fseek(ifp, ph1.black_row, SEEK_SET);
585
0
      read_shorts((ushort *)imgdata.rawdata.ph1_rblack[0], raw_width * 2);
586
0
    }
587
10
  }
588
188
  fseek(ifp, data_offset, SEEK_SET);
589
188
  read_shorts(raw_image, raw_width * raw_height);
590
188
  if (ph1.format)
591
5.10k
    for (i = 0; i < raw_width * raw_height; i += 2)
592
5.10k
    {
593
5.10k
      a = raw_image[i + 0] ^ akey;
594
5.10k
      b = raw_image[i + 1] ^ bkey;
595
5.10k
      raw_image[i + 0] = (a & t_mask) | (b & ~t_mask);
596
5.10k
      raw_image[i + 1] = (b & t_mask) | (a & ~t_mask);
597
5.10k
    }
598
188
}
599
600
unsigned LibRaw::ph1_bithuff(int nbits, ushort *huff)
601
46.9M
{
602
46.9M
#ifndef LIBRAW_NOTHREADS
603
65.7M
#define bitbuf tls->ph1_bits.bitbuf
604
149M
#define vbits tls->ph1_bits.vbits
605
#else
606
  static UINT64 bitbuf = 0;
607
  static int vbits = 0;
608
#endif
609
46.9M
  unsigned c;
610
611
46.9M
  if (nbits == -1)
612
156k
  {
613
156k
    bitbuf = vbits = 0;
614
156k
    return 0;
615
156k
  }
616
46.7M
  if (nbits == 0)
617
17.0k
    return 0;
618
46.7M
  if (vbits < nbits)
619
9.42M
  {
620
9.42M
    bitbuf = bitbuf << 32 | get4();
621
9.42M
    vbits += 32;
622
9.42M
  }
623
46.7M
  c = unsigned ((bitbuf << (64 - vbits) >> (64 - nbits)) & 0xffffffff);
624
46.7M
  if (huff)
625
0
  {
626
0
    vbits -= huff[c] >> 8;
627
0
    return (uchar)huff[c];
628
0
  }
629
46.7M
  vbits -= nbits;
630
46.7M
  return c;
631
46.7M
#ifndef LIBRAW_NOTHREADS
632
46.7M
#undef bitbuf
633
46.7M
#undef vbits
634
46.7M
#endif
635
46.7M
}
636
637
void LibRaw::phase_one_load_raw_c()
638
127
{
639
127
  static const int length[] = {8, 7, 6, 9, 11, 10, 5, 12, 14, 13};
640
127
  int *offset, len[2], pred[2], row, col, i, j;
641
127
  ushort *pixel;
642
127
  short(*c_black)[2], (*r_black)[2];
643
127
  if (ph1.format == 6)
644
0
    throw LIBRAW_EXCEPTION_IO_CORRUPT;
645
646
127
  pixel = (ushort *)calloc(raw_width * 3 + raw_height * 4, 2);
647
127
  offset = (int *)(pixel + raw_width);
648
127
  fseek(ifp, strip_offset, SEEK_SET);
649
182k
  for (row = 0; row < raw_height; row++)
650
182k
    offset[row] = get4();
651
127
  c_black = (short(*)[2])(offset + raw_height);
652
127
  fseek(ifp, ph1.black_col, SEEK_SET);
653
127
  if (ph1.black_col)
654
7
    read_shorts((ushort *)c_black[0], raw_height * 2);
655
127
  r_black = c_black + raw_height;
656
127
  fseek(ifp, ph1.black_row, SEEK_SET);
657
127
  if (ph1.black_row)
658
0
    read_shorts((ushort *)r_black[0], raw_width * 2);
659
660
  // Copy data to internal copy (ever if not read)
661
127
  if (ph1.black_col || ph1.black_row)
662
7
  {
663
7
    imgdata.rawdata.ph1_cblack =
664
7
        (short(*)[2])calloc(raw_height * 2, sizeof(ushort));
665
7
    memmove(imgdata.rawdata.ph1_cblack, (ushort *)c_black[0],
666
7
            raw_height * 2 * sizeof(ushort));
667
7
    imgdata.rawdata.ph1_rblack =
668
7
        (short(*)[2])calloc(raw_width * 2, sizeof(ushort));
669
7
    memmove(imgdata.rawdata.ph1_rblack, (ushort *)r_black[0],
670
7
            raw_width * 2 * sizeof(ushort));
671
7
  }
672
673
31.3k
  for (i = 0; i < 256; i++)
674
31.2k
    curve[i] = ushort(float(i * i) / 3.969f + 0.5f);
675
127
  try
676
127
  {
677
69.7k
    for (row = 0; row < raw_height; row++)
678
69.6k
    {
679
69.6k
      checkCancel();
680
69.6k
      fseek(ifp, data_offset + offset[row], SEEK_SET);
681
69.6k
      ph1_bits(-1);
682
69.6k
      pred[0] = pred[1] = 0;
683
15.5M
      for (col = 0; col < raw_width; col++)
684
15.4M
      {
685
15.4M
        if (col >= (raw_width & -8))
686
248k
          len[0] = len[1] = 14;
687
15.2M
        else if ((col & 7) == 0)
688
5.70M
          for (i = 0; i < 2; i++)
689
3.80M
          {
690
12.9M
            for (j = 0; j < 5 && !ph1_bits(1); j++)
691
9.18M
              ;
692
3.80M
            if (j--)
693
2.58M
              len[i] = length[j * 2 + ph1_bits(1)];
694
3.80M
          }
695
15.4M
        if ((i = len[col & 1]) == 14)
696
7.66M
          pixel[col] = pred[col & 1] = ph1_bits(16);
697
7.79M
        else
698
7.79M
          pixel[col] = pred[col & 1] += ph1_bits(i) + 1 - (1 << (i - 1));
699
15.4M
        if (pred[col & 1] >> 16)
700
2.60M
          derror();
701
15.4M
        if (ph1.format == 5 && pixel[col] < 256)
702
0
          pixel[col] = curve[pixel[col]];
703
15.4M
      }
704
69.6k
      if (ph1.format == 8)
705
0
        memmove(&RAW(row, 0), &pixel[0], raw_width * 2);
706
69.6k
      else
707
15.4M
        for (col = 0; col < raw_width; col++)
708
15.4M
          RAW(row, col) = pixel[col] << 2;
709
69.6k
    }
710
127
  }
711
127
  catch (...)
712
127
  {
713
92
    free(pixel);
714
92
    throw;
715
92
  }
716
30
  free(pixel);
717
30
  maximum = 0xfffc - ph1.t_black;
718
30
}
719
720
void LibRaw::hasselblad_load_raw()
721
1
{
722
1
  struct jhead jh;
723
1
  int shot, row, col, *back[5]={0,0,0,0,0},
724
1
   len[2], diff[12], pred, sh, f, c;
725
1
  unsigned s;
726
1
  unsigned upix, urow, ucol;
727
1
  ushort *ip;
728
729
1
  if (!ljpeg_start(&jh, 0))
730
1
    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
138
{
806
138
  ushort *pixel = 0;
807
138
  unsigned tile = 0, r, c, row, col;
808
809
138
  if (!filters || !raw_image)
810
25
  {
811
25
    if (!image)
812
0
      throw LIBRAW_EXCEPTION_IO_CORRUPT;
813
25
    pixel = (ushort *)calloc(raw_width, sizeof *pixel);
814
25
  }
815
138
  try
816
138
  {
817
138
    FORC(tiff_samples)
818
12.1k
    for (r = 0; r < raw_height; r++)
819
12.1k
    {
820
12.1k
      checkCancel();
821
12.1k
      if (r % tile_length == 0)
822
4.03k
      {
823
4.03k
        fseek(ifp, data_offset + 4 * tile++, SEEK_SET);
824
4.03k
        fseek(ifp, get4(), SEEK_SET);
825
4.03k
      }
826
12.1k
      if (filters && c != shot_select)
827
0
        continue;
828
12.1k
      if (filters && raw_image)
829
826
        pixel = raw_image + r * raw_width;
830
12.1k
      read_shorts(pixel, raw_width);
831
12.1k
      if (!filters && image && (row = r - top_margin) < height)
832
510k
        for (col = 0; col < width && col + left_margin < raw_width; col++)
833
501k
          image[row * width + col][c] = pixel[col + left_margin];
834
12.1k
    }
835
138
  }
836
138
  catch (...)
837
138
  {
838
32
    if (!filters)
839
22
      free(pixel);
840
32
    throw;
841
32
  }
842
106
  if (!filters)
843
3
  {
844
3
    maximum = 0xffff;
845
3
    raw_color = 1;
846
3
    free(pixel);
847
3
  }
848
106
}
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
5
{
858
5
  int scan_line, tile_n;
859
5
  int nTiles;
860
861
5
  nTiles = 8;
862
5
  tile_width = raw_width / nTiles;
863
864
5
  ushort *tile;
865
5
  tile = (ushort *)calloc(raw_height, tile_width * 2);
866
867
20
  for (tile_n = 0; tile_n < nTiles; tile_n++)
868
15
  {
869
15
    read_shorts(tile, tile_width * raw_height);
870
1.29k
    for (scan_line = 0; scan_line < raw_height; scan_line++)
871
1.28k
    {
872
1.28k
      memcpy(&raw_image[scan_line * raw_width + tile_n * tile_width],
873
1.28k
             &tile[scan_line * tile_width], tile_width * 2);
874
1.28k
    }
875
15
  }
876
5
  free(tile);
877
5
  fseek(ifp, -2, SEEK_CUR); // avoid EOF error
878
5
}
879
880
void LibRaw::sinar_4shot_load_raw()
881
143
{
882
143
  ushort *pixel;
883
143
  unsigned shot, row, col, r, c;
884
885
143
  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
143
  if (!image)
894
0
    throw LIBRAW_EXCEPTION_IO_CORRUPT;
895
143
  pixel = (ushort *)calloc(raw_width, sizeof *pixel);
896
143
  try
897
143
  {
898
620
    for (shot = 0; shot < 4; shot++)
899
477
    {
900
477
      checkCancel();
901
477
      fseek(ifp, data_offset + shot * 4, SEEK_SET);
902
477
      fseek(ifp, get4(), SEEK_SET);
903
16.6k
      for (row = 0; row < raw_height; row++)
904
16.1k
      {
905
16.1k
        read_shorts(pixel, raw_width);
906
16.1k
        if ((r = row - top_margin - (shot >> 1 & 1)) >= height)
907
2.32k
          continue;
908
482k
        for (col = 0; col < raw_width; col++)
909
468k
        {
910
468k
          if ((c = col - left_margin - (shot & 1)) >= width)
911
81.0k
            continue;
912
387k
          image[r * width + c][(row & 1) * 3 ^ (~col & 1)] = pixel[col];
913
387k
        }
914
13.8k
      }
915
477
    }
916
143
  }
917
143
  catch (...)
918
143
  {
919
34
    free(pixel);
920
34
    throw;
921
34
  }
922
109
  free(pixel);
923
109
  mix_green = 1;
924
109
}
925
926
void LibRaw::imacon_full_load_raw()
927
20
{
928
20
  if (!image)
929
3
    throw LIBRAW_EXCEPTION_IO_CORRUPT;
930
17
  int row, col;
931
932
17
  unsigned short *buf =
933
17
      (unsigned short *)malloc(width * 3 * sizeof(unsigned short));
934
935
592
  for (row = 0; row < height; row++)
936
575
  {
937
575
    checkCancel();
938
575
    read_shorts(buf, width * 3);
939
575
    unsigned short(*rowp)[4] = &image[row * width];
940
38.1k
    for (col = 0; col < width; col++)
941
37.5k
    {
942
37.5k
      rowp[col][0] = buf[col * 3];
943
37.5k
      rowp[col][1] = buf[col * 3 + 1];
944
37.5k
      rowp[col][2] = buf[col * 3 + 2];
945
37.5k
      rowp[col][3] = 0;
946
37.5k
    }
947
575
  }
948
17
  free(buf);
949
17
}