Coverage Report

Created: 2026-03-12 07:14

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
0
{
23
  // Branchless version.
24
0
  uint32_t sm = x >> 31;
25
0
  return (uint32_t) ((x + sm) ^ sm);
26
0
}
27
28
inline uint32_t min32(uint32_t x, uint32_t y)
29
0
{
30
0
  return x < y ? x : y;
31
0
}
32
33
inline uint32_t max32(uint32_t x, uint32_t y)
34
0
{
35
0
  return x > y ? x : y;
36
0
}
37
38
inline uint32_t constain32(uint32_t x, uint32_t l, uint32_t u)
39
0
{
40
0
  return x < l ? l : (x > u ? u : x);
41
0
}
42
43
int unsigned_cmp(const void *a, const void *b)
44
0
{
45
0
  if (!a || !b)
46
0
    return 0;
47
48
0
  return *(unsigned *)a > *(unsigned *)b ? 1 : (*(unsigned *)a < *(unsigned *)b ? -1 : 0);
49
0
}
50
51
int LibRaw::p1rawc(unsigned row, unsigned col, unsigned& count)
52
0
{
53
0
  return (row < raw_height && col < raw_width) ? (++count, RAW(row, col)) : 0;
54
0
}
55
56
int LibRaw::p1raw(unsigned row, unsigned col)
57
0
{
58
0
  return (row < raw_height && col < raw_width) ? RAW(row, col) : 0;
59
0
}
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
0
{
66
0
  static const int8_t dir[3][8][2] = {
67
0
  { {-2,-2}, {-2, 2}, {2,-2}, {2, 2}, { 0, 0}, { 0, 0}, {0, 0}, {0, 0} },
68
0
  { {-2,-4}, {-4,-2}, {2,-4}, {4,-2}, {-2, 4}, {-4, 2}, {2, 4}, {4, 2} },
69
0
  { {-4,-4}, {-4, 4}, {4,-4}, {4, 4}, { 0, 0}, { 0, 0}, {0, 0}, {0, 0} } };
70
71
0
  for (int set=0; set < 3; ++set)
72
0
  {
73
0
    uint32_t total = 0;
74
0
    uint32_t count = 0;
75
0
    for (int i = 0; i < 8; ++i)
76
0
    {
77
0
      if (!dir[set][i][0] && !dir[set][i][1])
78
0
        break;
79
80
0
      total += p1rawc(row+dir[set][i][0], col+dir[set][i][1], count);
81
0
    }
82
83
0
    if (count)
84
0
    {
85
0
      RAW(row,col) = (uint16_t)((total + (count >> 1)) / count);
86
0
      break;
87
0
    }
88
0
  }
89
0
}
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
0
{
94
0
  static const int8_t grad_sets[7][12][2] = {
95
0
    { {-4,-2}, { 4, 2}, {-3,-1}, { 1, 1}, {-1,-1}, { 3, 1}, 
96
0
      {-4,-1}, { 0, 1}, {-2,-1}, { 2, 1}, { 0,-1}, { 4, 1} },
97
0
    { {-2,-2}, { 2, 2}, {-3,-1}, {-1, 1}, {-1,-1}, { 1, 1}, 
98
0
      { 1,-1}, { 3, 1}, {-2,-1}, { 0, 1}, { 0,-1}, { 2, 1} },
99
0
    { {-2,-4}, { 2, 4}, {-1,-3}, { 1, 1}, {-1,-1}, { 1, 3}, 
100
0
      {-2,-1}, { 0, 3}, {-1,-2}, { 1, 2}, { 0,-3}, { 2, 1} },
101
0
    { { 0,-2}, { 0, 2}, {-1,-1}, {-1, 1}, { 1,-1}, { 1, 1}, 
102
0
      {-1,-2}, {-1, 2}, { 0,-1}, { 0,-1}, { 1,-2}, { 1, 2} },
103
0
    { {-2, 4}, { 2,-4}, {-1, 3}, { 1,-1}, {-1, 1}, { 1,-3}, 
104
0
      {-2, 1}, { 0,-3}, {-1, 2}, { 1,-2}, { 0, 3}, { 2,-1} },
105
0
    { {-2, 2}, { 2,-2}, {-3, 1}, {-1,-1}, {-1, 1}, { 1,-1}, 
106
0
      { 1, 1}, { 3,-1}, {-2, 1}, { 0,-1}, { 0, 1}, { 2,-1} },
107
0
    { {-4, 2}, { 4,-2}, {-3, 1}, { 1,-1}, {-1, 1}, { 3,-1}, 
108
0
      {-4, 1}, { 0,-1}, {-2, 1}, { 2,-1}, { 0, 1}, { 4,-1} } };
109
110
0
  uint32_t est[7], grad[7];
111
0
  uint32_t lower = min32(p1raw(row,col-2), p1raw(row, col+2));
112
0
  uint32_t upper = max32(p1raw(row,col-2), p1raw(row, col+2));
113
0
  uint32_t minGrad = 0xFFFFFFFF;
114
0
  for (int i = 0; i<7; ++i)
115
0
  {
116
0
    est[i] = p1raw(row+grad_sets[i][0][0], col+grad_sets[i][0][1]) +
117
0
             p1raw(row+grad_sets[i][1][0], col+grad_sets[i][1][1]);
118
0
    grad[i] = 0;
119
0
    for (int j=0; j<12; j+=2)
120
0
      grad[i] += abs32(p1raw(row+grad_sets[i][j][0], col+grad_sets[i][j][1]) -
121
0
                       p1raw(row+grad_sets[i][j+1][0], col+grad_sets[i][j+1][1]));
122
0
    minGrad = min32(minGrad, grad[i]);
123
0
  }
124
125
0
  uint32_t limit = (minGrad * 3) >> 1;
126
0
  uint32_t total = 0;
127
0
  uint32_t count = 0;
128
0
  for (int i = 0; i<7; ++i)
129
0
    if (grad[i] <= limit)
130
0
    {
131
0
      total += est[i];
132
0
      count += 2;
133
0
    }
134
0
  RAW(row, col) = constain32((total + (count >> 1)) / count, lower, upper);
135
0
}
136
137
void LibRaw::phase_one_flat_field(int is_float, int nc)
138
0
{
139
0
  ushort head[8];
140
0
  unsigned wide, high, y, x, c, rend, cend, row, col;
141
0
  float *mrow, num, mult[4];
142
143
0
  read_shorts(head, 8);
144
0
  if (head[2] == 0 || head[3] == 0 || head[4] == 0 || head[5] == 0)
145
0
    return;
146
0
  wide = head[2] / head[4] + (head[2] % head[4] != 0);
147
0
  high = head[3] / head[5] + (head[3] % head[5] != 0);
148
0
  mrow = (float *)calloc(nc * wide, sizeof *mrow);
149
0
  for (y = 0; y < high; y++)
150
0
  {
151
0
    checkCancel();
152
0
    for (x = 0; x < wide; x++)
153
0
      for (c = 0; c < (unsigned)nc; c += 2)
154
0
      {
155
0
        num = is_float ? getrealf(LIBRAW_EXIFTAG_TYPE_FLOAT) : float(get2()) / 32768.f;
156
0
        if (y == 0)
157
0
          mrow[c * wide + x] = num;
158
0
        else
159
0
          mrow[(c + 1) * wide + x] = (num - mrow[c * wide + x]) / head[5];
160
0
      }
161
0
    if (y == 0)
162
0
      continue;
163
0
    rend = head[1] + y * head[5];
164
0
    for (row = rend - head[5];
165
0
         row < raw_height && row < rend && row < unsigned(head[1] + head[3] - head[5]);
166
0
         row++)
167
0
    {
168
0
      for (x = 1; x < wide; x++)
169
0
      {
170
0
        for (c = 0; c < (unsigned)nc; c += 2)
171
0
        {
172
0
          mult[c] = mrow[c * wide + x - 1];
173
0
          mult[c + 1] = (mrow[c * wide + x] - mult[c]) / head[4];
174
0
        }
175
0
        cend = head[0] + x * head[4];
176
0
        for (col = cend - head[4];
177
0
             col < raw_width && col < cend && col < unsigned(head[0] + head[2] - head[4]);
178
0
             col++)
179
0
        {
180
0
          c = nc > 2 ? FC(row - top_margin, col - left_margin) : 0;
181
0
          if (!(c & 1))
182
0
          {
183
0
            c = unsigned(RAW(row, col) * mult[c]);
184
0
            RAW(row, col) = LIM(c, 0, 65535);
185
0
          }
186
0
          for (c = 0; c < (unsigned)nc; c += 2)
187
0
            mult[c] += mult[c + 1];
188
0
        }
189
0
      }
190
0
      for (x = 0; x < wide; x++)
191
0
        for (c = 0; c < (unsigned)nc; c += 2)
192
0
          mrow[c * wide + x] += mrow[(c + 1) * wide + x];
193
0
    }
194
0
  }
195
0
  free(mrow);
196
0
}
197
198
int LibRaw::phase_one_correct()
199
0
{
200
0
  unsigned entries, tag, data, col, row, type;
201
0
  INT64 save;
202
0
  int len, i, j, k, cip, sum;
203
#if 0
204
  int val[4], dev[4], max;
205
#endif
206
0
  int head[9], diff, mindiff = INT_MAX;
207
0
  INT64 off_412 = 0;
208
0
  /* static */ const signed char dir[12][2] = {
209
0
      {-1, -1}, {-1, 1}, {1, -1},  {1, 1},  {-2, 0}, {0, -2},
210
0
      {0, 2},   {2, 0},  {-2, -2}, {-2, 2}, {2, -2}, {2, 2}};
211
0
  float poly[8], num, cfrac, frac, mult[2], *yval[2] = {NULL, NULL};
212
0
  ushort *xval[2];
213
0
  int qmult_applied = 0, qlin_applied = 0;
214
0
  std::vector<unsigned> badCols;
215
216
0
  if (!meta_length)
217
0
    return 0;
218
0
  fseek(ifp, meta_offset, SEEK_SET);
219
0
  order = get2();
220
0
  fseek(ifp, 6, SEEK_CUR);
221
0
  fseek(ifp, meta_offset + get4(), SEEK_SET);
222
0
  entries = get4();
223
0
  get4();
224
0
  INT64 fsize = ifp->size();
225
226
0
  try
227
0
  {
228
0
    while (entries--)
229
0
    {
230
0
      checkCancel();
231
0
      tag = get4();
232
0
      len = get4();
233
0
      data = get4();
234
0
      save = ftell(ifp);
235
0
      fseek(ifp, meta_offset + data, SEEK_SET);
236
0
#if 1
237
0
    if (ifp->eof())
238
0
    {
239
      // skip bad or unknown tag
240
0
      fseek(ifp, save, SEEK_SET);
241
0
      continue;
242
0
    }
243
0
#endif
244
0
      INT64 savepos = ftell(ifp);
245
0
    if (len < 0 || (len > 8 && savepos + (INT64)len > 2 * fsize))
246
0
    {
247
0
        fseek(ifp, save, SEEK_SET); // Recover tiff-read position!!
248
0
        continue;
249
0
    }
250
0
      if (tag == 0x0400)
251
0
      { /* Sensor defects */
252
0
        while ((len -= 8) >= 0)
253
0
        {
254
0
          col = get2();
255
0
          row = get2();
256
0
          type = get2();
257
0
          get2();
258
0
          if (col >= raw_width)
259
0
            continue;
260
0
          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
0
            badCols.push_back(col);
293
0
#endif
294
0
          else if (type == 129)
295
0
          { /* Bad pixel */
296
0
            if (row >= raw_height)
297
0
              continue;
298
0
            j = (FC(row - top_margin, col - left_margin) != 1) * 4;
299
0
            unsigned count = 0;
300
0
            for (sum = 0, i = j; i < j + 8; i++)
301
0
              sum += p1rawc(row + dir[i][0], col + dir[i][1], count);
302
0
            if (count)
303
0
              RAW(row, col) = (sum + (count >> 1)) / count;
304
0
          }
305
0
        }
306
0
      }
307
0
      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
0
      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
0
      else if (tag == 0x0401)
338
0
      { /* All-color flat fields - luma calibration*/
339
0
        phase_one_flat_field(1, 2);
340
0
      }
341
0
      else if (tag == 0x0416 || tag == 0x0410)
342
0
      {
343
        // 0x410 - luma calibration
344
0
        phase_one_flat_field(0, 2);
345
0
      }
346
0
      else if (tag == 0x040b)
347
0
      { /* Red+blue flat field - croma calibration */
348
0
        phase_one_flat_field(0, 4);
349
0
      }
350
0
      else if (tag == 0x0412)
351
0
      {
352
0
        fseek(ifp, 36, SEEK_CUR);
353
0
        diff = abs(get2() - ph1.tag_21a);
354
0
        if (mindiff > diff)
355
0
        {
356
0
          mindiff = diff;
357
0
          off_412 = ftell(ifp) - 38;
358
0
        }
359
0
      }
360
0
      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
0
      else if (tag == 0x041e && !qmult_applied)
412
0
      { /* Quadrant multipliers - output calibraion */
413
0
        float qmult[2][2] = {{1, 1}, {1, 1}};
414
0
        get4();
415
0
        get4();
416
0
        get4();
417
0
        get4();
418
0
        qmult[0][0] = 1.0f + getrealf(LIBRAW_EXIFTAG_TYPE_FLOAT);
419
0
        get4();
420
0
        get4();
421
0
        get4();
422
0
        get4();
423
0
        get4();
424
0
        qmult[0][1] = 1.0f + getrealf(LIBRAW_EXIFTAG_TYPE_FLOAT);
425
0
        get4();
426
0
        get4();
427
0
        get4();
428
0
        qmult[1][0] = 1.0f + getrealf(LIBRAW_EXIFTAG_TYPE_FLOAT);
429
0
        get4();
430
0
        get4();
431
0
        get4();
432
0
        qmult[1][1] = 1.0f + getrealf(LIBRAW_EXIFTAG_TYPE_FLOAT);
433
0
        for (row = 0; row < raw_height; row++)
434
0
        {
435
0
          checkCancel();
436
0
          for (col = 0; col < raw_width; col++)
437
0
          {
438
0
            i = int(qmult[row >= (unsigned)ph1.split_row][col >= (unsigned)ph1.split_col] *
439
0
                RAW(row, col));
440
0
            RAW(row, col) = LIM(i, 0, 65535);
441
0
          }
442
0
        }
443
0
        qmult_applied = 1;
444
0
      }
445
0
      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
0
      fseek(ifp, save, SEEK_SET);
483
0
    }
484
0
    if (!badCols.empty())
485
0
    {
486
0
      qsort(badCols.data(), badCols.size(), sizeof(unsigned), unsigned_cmp);
487
0
      bool prevIsolated = true;
488
0
      for (i = 0; i < (int)badCols.size(); ++i)
489
0
      {
490
0
        bool nextIsolated = i == ((int)(badCols.size()-1)) || badCols[i+1]>badCols[i]+4;
491
0
        for (row = 0; row < raw_height; ++row)
492
0
          if (prevIsolated && nextIsolated)
493
0
            phase_one_fix_pixel_grad(row,badCols[i]);
494
0
          else
495
0
            phase_one_fix_col_pixel_avg(row,badCols[i]);
496
0
        prevIsolated = nextIsolated;
497
0
      }
498
0
    }
499
0
    if (off_412)
500
0
    {
501
0
      fseek(ifp, off_412, SEEK_SET);
502
0
      for (i = 0; i < 9; i++)
503
0
        head[i] = get4() & 0x7fff;
504
0
    unsigned w0 = head[1] * head[3], w1 = head[2] * head[4];
505
0
    if (w0 > 10240000 || w1 > 10240000)
506
0
      throw LIBRAW_EXCEPTION_ALLOC;
507
0
    if (w0 < 1 || w1 < 1)
508
0
      throw LIBRAW_EXCEPTION_IO_CORRUPT;
509
0
      yval[0] = (float *)calloc(head[1] * head[3] + head[2] * head[4], 6);
510
0
      yval[1] = (float *)(yval[0] + head[1] * head[3]);
511
0
      xval[0] = (ushort *)(yval[1] + head[2] * head[4]);
512
0
      xval[1] = (ushort *)(xval[0] + head[1] * head[3]);
513
0
      get2();
514
0
      for (i = 0; i < 2; i++)
515
0
        for (j = 0; j < head[i + 1] * head[i + 3]; j++)
516
0
          yval[i][j] = getrealf(LIBRAW_EXIFTAG_TYPE_FLOAT);
517
0
      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
0
      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
0
      free(yval[0]);
551
0
    }
552
0
  }
553
0
  catch (...)
554
0
  {
555
0
    if (yval[0])
556
0
      free(yval[0]);
557
0
    return LIBRAW_CANCELLED_BY_CALLBACK;
558
0
  }
559
0
  return 0;
560
0
}
561
562
void LibRaw::phase_one_load_raw()
563
0
{
564
0
  int a, b, i;
565
0
  ushort akey, bkey, t_mask;
566
567
0
  fseek(ifp, ph1.key_off, SEEK_SET);
568
0
  akey = get2();
569
0
  bkey = get2();
570
0
  t_mask = ph1.format == 1 ? 0x5555 : 0x1354;
571
0
  if (ph1.black_col || ph1.black_row)
572
0
  {
573
0
    imgdata.rawdata.ph1_cblack =
574
0
        (short(*)[2])calloc(raw_height * 2, sizeof(ushort));
575
0
    imgdata.rawdata.ph1_rblack =
576
0
        (short(*)[2])calloc(raw_width * 2, sizeof(ushort));
577
0
    if (ph1.black_col)
578
0
    {
579
0
      fseek(ifp, ph1.black_col, SEEK_SET);
580
0
      read_shorts((ushort *)imgdata.rawdata.ph1_cblack[0], raw_height * 2);
581
0
    }
582
0
    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
0
  }
588
0
  fseek(ifp, data_offset, SEEK_SET);
589
0
  read_shorts(raw_image, raw_width * raw_height);
590
0
  if (ph1.format)
591
0
    for (i = 0; i < raw_width * raw_height; i += 2)
592
0
    {
593
0
      a = raw_image[i + 0] ^ akey;
594
0
      b = raw_image[i + 1] ^ bkey;
595
0
      raw_image[i + 0] = (a & t_mask) | (b & ~t_mask);
596
0
      raw_image[i + 1] = (b & t_mask) | (a & ~t_mask);
597
0
    }
598
0
}
599
600
unsigned LibRaw::ph1_bithuff(int nbits, ushort *huff)
601
0
{
602
0
#ifndef LIBRAW_NOTHREADS
603
0
#define bitbuf tls->ph1_bits.bitbuf
604
0
#define vbits tls->ph1_bits.vbits
605
#else
606
  static UINT64 bitbuf = 0;
607
  static int vbits = 0;
608
#endif
609
0
  unsigned c;
610
611
0
  if (nbits == -1)
612
0
  {
613
0
    bitbuf = vbits = 0;
614
0
    return 0;
615
0
  }
616
0
  if (nbits == 0)
617
0
    return 0;
618
0
  if (vbits < nbits)
619
0
  {
620
0
    bitbuf = bitbuf << 32 | get4();
621
0
    vbits += 32;
622
0
  }
623
0
  c = unsigned ((bitbuf << (64 - vbits) >> (64 - nbits)) & 0xffffffff);
624
0
  if (huff)
625
0
  {
626
0
    vbits -= huff[c] >> 8;
627
0
    return (uchar)huff[c];
628
0
  }
629
0
  vbits -= nbits;
630
0
  return c;
631
0
#ifndef LIBRAW_NOTHREADS
632
0
#undef bitbuf
633
0
#undef vbits
634
0
#endif
635
0
}
636
637
void LibRaw::phase_one_load_raw_c()
638
0
{
639
0
  static const int length[] = {8, 7, 6, 9, 11, 10, 5, 12, 14, 13};
640
0
  int *offset, len[2], pred[2], row, col, i, j;
641
0
  ushort *pixel;
642
0
  short(*c_black)[2], (*r_black)[2];
643
0
  if (ph1.format == 6)
644
0
    throw LIBRAW_EXCEPTION_IO_CORRUPT;
645
646
0
  pixel = (ushort *)calloc(raw_width * 3 + raw_height * 4, 2);
647
0
  offset = (int *)(pixel + raw_width);
648
0
  fseek(ifp, strip_offset, SEEK_SET);
649
0
  for (row = 0; row < raw_height; row++)
650
0
    offset[row] = get4();
651
0
  c_black = (short(*)[2])(offset + raw_height);
652
0
  fseek(ifp, ph1.black_col, SEEK_SET);
653
0
  if (ph1.black_col)
654
0
    read_shorts((ushort *)c_black[0], raw_height * 2);
655
0
  r_black = c_black + raw_height;
656
0
  fseek(ifp, ph1.black_row, SEEK_SET);
657
0
  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
0
  if (ph1.black_col || ph1.black_row)
662
0
  {
663
0
    imgdata.rawdata.ph1_cblack =
664
0
        (short(*)[2])calloc(raw_height * 2, sizeof(ushort));
665
0
    memmove(imgdata.rawdata.ph1_cblack, (ushort *)c_black[0],
666
0
            raw_height * 2 * sizeof(ushort));
667
0
    imgdata.rawdata.ph1_rblack =
668
0
        (short(*)[2])calloc(raw_width * 2, sizeof(ushort));
669
0
    memmove(imgdata.rawdata.ph1_rblack, (ushort *)r_black[0],
670
0
            raw_width * 2 * sizeof(ushort));
671
0
  }
672
673
0
  for (i = 0; i < 256; i++)
674
0
    curve[i] = ushort(float(i * i) / 3.969f + 0.5f);
675
0
  try
676
0
  {
677
0
    for (row = 0; row < raw_height; row++)
678
0
    {
679
0
      checkCancel();
680
0
      fseek(ifp, data_offset + offset[row], SEEK_SET);
681
0
      ph1_bits(-1);
682
0
      pred[0] = pred[1] = 0;
683
0
      for (col = 0; col < raw_width; col++)
684
0
      {
685
0
        if (col >= (raw_width & -8))
686
0
          len[0] = len[1] = 14;
687
0
        else if ((col & 7) == 0)
688
0
          for (i = 0; i < 2; i++)
689
0
          {
690
0
            for (j = 0; j < 5 && !ph1_bits(1); j++)
691
0
              ;
692
0
            if (j--)
693
0
              len[i] = length[j * 2 + ph1_bits(1)];
694
0
          }
695
0
        if ((i = len[col & 1]) == 14)
696
0
          pixel[col] = pred[col & 1] = ph1_bits(16);
697
0
        else
698
0
          pixel[col] = pred[col & 1] += ph1_bits(i) + 1 - (1 << (i - 1));
699
0
        if (pred[col & 1] >> 16)
700
0
          derror();
701
0
        if (ph1.format == 5 && pixel[col] < 256)
702
0
          pixel[col] = curve[pixel[col]];
703
0
      }
704
0
      if (ph1.format == 8)
705
0
        memmove(&RAW(row, 0), &pixel[0], raw_width * 2);
706
0
      else
707
0
        for (col = 0; col < raw_width; col++)
708
0
          RAW(row, col) = pixel[col] << 2;
709
0
    }
710
0
  }
711
0
  catch (...)
712
0
  {
713
0
    free(pixel);
714
0
    throw;
715
0
  }
716
0
  free(pixel);
717
0
  maximum = 0xfffc - ph1.t_black;
718
0
}
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
0
{
806
0
  ushort *pixel = 0;
807
0
  unsigned tile = 0, r, c, row, col;
808
809
0
  if (!filters || !raw_image)
810
0
  {
811
0
    if (!image)
812
0
      throw LIBRAW_EXCEPTION_IO_CORRUPT;
813
0
    pixel = (ushort *)calloc(raw_width, sizeof *pixel);
814
0
  }
815
0
  try
816
0
  {
817
0
    FORC(tiff_samples)
818
0
    for (r = 0; r < raw_height; r++)
819
0
    {
820
0
      checkCancel();
821
0
      if (r % tile_length == 0)
822
0
      {
823
0
        fseek(ifp, data_offset + 4 * tile++, SEEK_SET);
824
0
        fseek(ifp, get4(), SEEK_SET);
825
0
      }
826
0
      if (filters && c != shot_select)
827
0
        continue;
828
0
      if (filters && raw_image)
829
0
        pixel = raw_image + r * raw_width;
830
0
      read_shorts(pixel, raw_width);
831
0
      if (!filters && image && (row = r - top_margin) < height)
832
0
        for (col = 0; col < width && col + left_margin < raw_width; col++)
833
0
          image[row * width + col][c] = pixel[col + left_margin];
834
0
    }
835
0
  }
836
0
  catch (...)
837
0
  {
838
0
    if (!filters)
839
0
      free(pixel);
840
0
    throw;
841
0
  }
842
0
  if (!filters)
843
0
  {
844
0
    maximum = 0xffff;
845
0
    raw_color = 1;
846
0
    free(pixel);
847
0
  }
848
0
}
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
0
{
882
0
  ushort *pixel;
883
0
  unsigned shot, row, col, r, c;
884
885
0
  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
0
  if (!image)
894
0
    throw LIBRAW_EXCEPTION_IO_CORRUPT;
895
0
  pixel = (ushort *)calloc(raw_width, sizeof *pixel);
896
0
  try
897
0
  {
898
0
    for (shot = 0; shot < 4; shot++)
899
0
    {
900
0
      checkCancel();
901
0
      fseek(ifp, data_offset + shot * 4, SEEK_SET);
902
0
      fseek(ifp, get4(), SEEK_SET);
903
0
      for (row = 0; row < raw_height; row++)
904
0
      {
905
0
        read_shorts(pixel, raw_width);
906
0
        if ((r = row - top_margin - (shot >> 1 & 1)) >= height)
907
0
          continue;
908
0
        for (col = 0; col < raw_width; col++)
909
0
        {
910
0
          if ((c = col - left_margin - (shot & 1)) >= width)
911
0
            continue;
912
0
          image[r * width + c][(row & 1) * 3 ^ (~col & 1)] = pixel[col];
913
0
        }
914
0
      }
915
0
    }
916
0
  }
917
0
  catch (...)
918
0
  {
919
0
    free(pixel);
920
0
    throw;
921
0
  }
922
0
  free(pixel);
923
0
  mix_green = 1;
924
0
}
925
926
void LibRaw::imacon_full_load_raw()
927
0
{
928
0
  if (!image)
929
0
    throw LIBRAW_EXCEPTION_IO_CORRUPT;
930
0
  int row, col;
931
932
0
  unsigned short *buf =
933
0
      (unsigned short *)malloc(width * 3 * sizeof(unsigned short));
934
935
0
  for (row = 0; row < height; row++)
936
0
  {
937
0
    checkCancel();
938
0
    read_shorts(buf, width * 3);
939
0
    unsigned short(*rowp)[4] = &image[row * width];
940
0
    for (col = 0; col < width; col++)
941
0
    {
942
0
      rowp[col][0] = buf[col * 3];
943
0
      rowp[col][1] = buf[col * 3 + 1];
944
0
      rowp[col][2] = buf[col * 3 + 2];
945
0
      rowp[col][3] = 0;
946
0
    }
947
0
  }
948
0
  free(buf);
949
0
}