Coverage Report

Created: 2026-02-14 07:11

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libraw/src/decoders/decoders_libraw_dcrdefs.cpp
Line
Count
Source
1
/* -*- C++ -*-
2
 * Copyright 2019-2025 LibRaw LLC (info@libraw.org)
3
 *
4
 LibRaw is free software; you can redistribute it and/or modify
5
 it under the terms of the one of two licenses as you choose:
6
7
1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
8
   (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
9
10
2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
11
   (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
12
13
 */
14
15
#include "../../internal/dcraw_defs.h"
16
17
18
void LibRaw::nikon_he_load_raw()
19
0
{
20
0
    if(dng_version)
21
0
      throw LIBRAW_EXCEPTION_UNSUPPORTED_FORMAT; // Never reached
22
0
    throw LIBRAW_EXCEPTION_UNSUPPORTED_FORMAT;
23
0
}
24
25
void LibRaw::packed_tiled_dng_load_raw()
26
32
{
27
32
  ushort *rp;
28
32
  unsigned row, col;
29
30
32
  int ss = shot_select;
31
32
  shot_select = libraw_internal_data.unpacker_data.dng_frames[LIM(ss, 0, (LIBRAW_IFD_MAXCOUNT * 2 - 1))] & 0xff;
32
32
  std::vector<ushort> pixel;
33
34
32
  try
35
32
  {
36
32
    int ntiles = 1 + (raw_width) / tile_width;
37
32
    if ((unsigned)ntiles * tile_width > raw_width * 2u) throw LIBRAW_EXCEPTION_ALLOC;
38
32
    pixel.resize(tile_width * ntiles * tiff_samples);
39
32
  }
40
32
  catch (...)
41
32
  {
42
0
    throw LIBRAW_EXCEPTION_ALLOC; // rethrow
43
0
  }
44
32
  try
45
32
  {
46
32
      unsigned trow = 0, tcol = 0;
47
32
      INT64 save;
48
459
      while (trow < raw_height)
49
427
      {
50
427
        checkCancel();
51
427
        save = ftell(ifp);
52
427
        if (tile_length < INT_MAX)
53
427
          fseek(ifp, get4(), SEEK_SET);
54
55
6.46k
        for (row = 0; row < tile_length && (row + trow) < raw_height; row++)
56
6.04k
        {
57
6.04k
          if (tiff_bps == 16)
58
679
            read_shorts(pixel.data(), tile_width * tiff_samples);
59
5.36k
          else
60
5.36k
          {
61
5.36k
            getbits(-1);
62
34.4k
            for (col = 0; col < tile_width * tiff_samples; col++)
63
29.0k
              pixel[col] = getbits(tiff_bps);
64
5.36k
          }
65
41.4k
          for (rp = pixel.data(), col = 0; col < tile_width; col++)
66
35.4k
            adobe_copy_pixel(trow+row, tcol+col, &rp);
67
6.04k
        }
68
427
        fseek(ifp, save + 4, SEEK_SET);
69
427
        if ((tcol += tile_width) >= raw_width)
70
75
          trow += tile_length + (tcol = 0);
71
427
      }
72
32
  }
73
32
  catch (...)
74
32
  {
75
31
    shot_select = ss;
76
31
    throw;
77
31
  }
78
1
  shot_select = ss;
79
1
}
80
81
82
void LibRaw::sony_ljpeg_load_raw()
83
5
{
84
5
  unsigned trow = 0, tcol = 0, jrow, jcol, row, col;
85
5
  INT64 save;
86
5
  struct jhead jh;
87
88
5
  while (trow < raw_height)
89
5
  {
90
5
    checkCancel();
91
5
    save = ftell(ifp); // We're at
92
5
    if (tile_length < INT_MAX)
93
0
      fseek(ifp, get4(), SEEK_SET);
94
5
    if (!ljpeg_start(&jh, 0))
95
5
      break;
96
0
    try
97
0
    {
98
0
      for (row = jrow = 0; jrow < (unsigned)jh.high && trow+row < raw_height-1; jrow++, row += 2)
99
0
      {
100
0
        checkCancel();
101
0
        ushort(*rowp)[4] = (ushort(*)[4])ljpeg_row(jrow, &jh);
102
0
        for (col = jcol = 0; jcol < (unsigned)jh.wide && tcol+col < raw_width-1; jcol++, col += 2)
103
0
        {
104
0
          RAW(trow + row, tcol + col) = rowp[jcol][0];
105
0
          RAW(trow + row, tcol + col + 1) = rowp[jcol][1];
106
0
          RAW(trow + row + 1, tcol + col) = rowp[jcol][2];
107
0
          RAW(trow + row + 1, tcol + col + 1) = rowp[jcol][3];
108
0
        }
109
0
      }
110
0
    }
111
0
    catch (...)
112
0
    {
113
0
      ljpeg_end(&jh);
114
0
      throw;
115
0
    }
116
0
    fseek(ifp, save + 4, SEEK_SET);
117
0
    if ((tcol += tile_width) >= raw_width)
118
0
      trow += tile_length + (tcol = 0);
119
0
    ljpeg_end(&jh);
120
0
  }
121
5
}
122
123
void LibRaw::nikon_coolscan_load_raw()
124
63
{
125
63
  int clrs = colors == 3 ? 3 : 1;
126
127
63
  if (clrs == 3 && !image)
128
1
    throw LIBRAW_EXCEPTION_IO_CORRUPT;
129
130
62
  if(clrs == 1 && !raw_image)
131
0
    throw LIBRAW_EXCEPTION_IO_CORRUPT;
132
133
62
  int bypp = tiff_bps <= 8 ? 1 : 2;
134
62
  int bufsize = width * clrs * bypp;
135
62
  unsigned char *buf = (unsigned char *)calloc(bufsize,1);
136
62
  unsigned short *ubuf = (unsigned short *)buf;
137
138
62
  if (tiff_bps <= 8)
139
41
    gamma_curve(1.0 / imgdata.rawparams.coolscan_nef_gamma, 0., 1, 255);
140
21
  else
141
21
    gamma_curve(1.0 / imgdata.rawparams.coolscan_nef_gamma, 0., 1, 65535);
142
62
  fseek(ifp, data_offset, SEEK_SET);
143
9.68k
  for (int row = 0; row < raw_height; row++)
144
9.61k
  {
145
9.61k
      if(tiff_bps <=8)
146
9.19k
        fread(buf, 1, bufsize, ifp);
147
425
      else
148
425
          read_shorts(ubuf,width*clrs);
149
150
9.61k
    unsigned short(*ip)[4] = (unsigned short(*)[4])image + row * width;
151
9.61k
    unsigned short *rp =  raw_image + row * raw_width;
152
153
9.61k
    if (is_NikonTransfer == 2)
154
1.50k
    { // it is also (tiff_bps == 8)
155
1.50k
        if (clrs == 3)
156
915
        {
157
326k
          for (int col = 0; col < width; col++)
158
325k
          {
159
325k
            ip[col][0] = ushort(((float)curve[buf[col * 3]]) / 255.0f);
160
325k
            ip[col][1] = ushort(((float)curve[buf[col * 3 + 1]]) / 255.0f);
161
325k
            ip[col][2] = ushort(((float)curve[buf[col * 3 + 2]]) / 255.0f);
162
325k
            ip[col][3] = 0;
163
325k
          }
164
915
        }
165
587
        else
166
587
        {
167
27.6k
          for (int col = 0; col < width; col++)
168
27.0k
            rp[col] = ushort(((float)curve[buf[col]]) / 255.0f);
169
587
        }
170
1.50k
    }
171
8.11k
    else if (tiff_bps <= 8)
172
7.69k
    {
173
7.69k
        if (clrs == 3)
174
6.22k
        {
175
413k
          for (int col = 0; col < width; col++)
176
407k
          {
177
407k
            ip[col][0] = curve[buf[col * 3]];
178
407k
            ip[col][1] = curve[buf[col * 3 + 1]];
179
407k
            ip[col][2] = curve[buf[col * 3 + 2]];
180
407k
            ip[col][3] = 0;
181
407k
          }
182
6.22k
        }
183
1.46k
        else
184
1.46k
        {
185
239k
          for (int col = 0; col < width; col++)
186
237k
            rp[col] = curve[buf[col]];
187
1.46k
        }
188
7.69k
    }
189
425
    else
190
425
    {
191
425
        if (clrs == 3)
192
148
        {
193
4.45k
          for (int col = 0; col < width; col++)
194
4.31k
          {
195
4.31k
            ip[col][0] = curve[ubuf[col * 3]];
196
4.31k
            ip[col][1] = curve[ubuf[col * 3 + 1]];
197
4.31k
            ip[col][2] = curve[ubuf[col * 3 + 2]];
198
4.31k
            ip[col][3] = 0;
199
4.31k
          }
200
148
        }
201
277
        else
202
277
        {
203
6.81k
          for (int col = 0; col < width; col++)
204
6.54k
            rp[col] = curve[ubuf[col]];
205
277
        }
206
425
    }
207
9.61k
  }
208
62
  free(buf);
209
62
}
210
211
void LibRaw::broadcom_load_raw()
212
0
{
213
0
  uchar *dp;
214
0
  int rev, row, col, c;
215
0
  rev = 3 * (order == 0x4949);
216
0
  std::vector<uchar> data(raw_stride * 2);
217
218
0
  for (row = 0; row < raw_height; row++)
219
0
  {
220
0
    if (fread(data.data() + raw_stride, 1, raw_stride, ifp) < raw_stride)
221
0
      derror();
222
0
    FORC(raw_stride) data[c] = data[raw_stride + (c ^ rev)];
223
0
    for (dp = data.data(), col = 0; col < raw_width; dp += 5, col += 4)
224
0
      FORC4 RAW(row, col + c) = (dp[c] << 2) | (dp[4] >> (c << 1) & 3);
225
0
  }
226
0
}
227
228
void LibRaw::android_tight_load_raw()
229
0
{
230
0
  uchar *data, *dp;
231
0
  int bwide, row, col, c;
232
233
0
  bwide = -(-5 * raw_width >> 5) << 3;
234
0
  data = (uchar *)calloc(bwide,1);
235
0
  for (row = 0; row < raw_height; row++)
236
0
  {
237
0
    if (fread(data, 1, bwide, ifp) < bwide)
238
0
      derror();
239
0
    for (dp = data, col = 0; col < raw_width; dp += 5, col += 4)
240
0
      FORC4 RAW(row, col + c) = (dp[c] << 2) | (dp[4] >> (c << 1) & 3);
241
0
  }
242
0
  free(data);
243
0
}
244
245
void LibRaw::android_loose_load_raw()
246
0
{
247
0
  uchar *data, *dp;
248
0
  int bwide, row, col, c;
249
0
  UINT64 bitbuf = 0;
250
251
0
  bwide = (raw_width + 5) / 6 << 3;
252
0
  data = (uchar *)calloc(bwide,1);
253
0
  for (row = 0; row < raw_height; row++)
254
0
  {
255
0
    if (fread(data, 1, bwide, ifp) < bwide)
256
0
      derror();
257
0
    for (dp = data, col = 0; col < raw_width; dp += 8, col += 6)
258
0
    {
259
0
      FORC(8) bitbuf = (bitbuf << 8) | dp[c ^ 7];
260
0
      FORC(6) RAW(row, col + c) = (bitbuf >> c * 10) & 0x3ff;
261
0
    }
262
0
  }
263
0
  free(data);
264
0
}
265
266
void LibRaw::unpacked_load_raw_reversed()
267
0
{
268
0
  int row, col, bits = 0;
269
0
  while (1 << ++bits < (int)maximum)
270
0
    ;
271
0
  for (row = raw_height - 1; row >= 0; row--)
272
0
  {
273
0
    checkCancel();
274
0
    read_shorts(&raw_image[row * raw_width], raw_width);
275
0
    for (col = 0; col < raw_width; col++)
276
0
      if ((RAW(row, col) >>= load_flags) >> bits &&
277
0
          (unsigned)(row - top_margin) < height &&
278
0
          (unsigned)(col - left_margin) < width)
279
0
        derror();
280
0
  }
281
0
}
282
283
#ifdef USE_6BY9RPI
284
285
void LibRaw::rpi_load_raw8()
286
{
287
  uchar  *data, *dp;
288
  int rev, dwide, row, col, c;
289
  double sum[] = { 0,0 };
290
  rev = 3 * (order == 0x4949);
291
  if (raw_stride == 0)
292
    dwide = raw_width;
293
  else
294
    dwide = raw_stride;
295
    data = (uchar *)calloc(dwide, 2);
296
  for (row = 0; row < raw_height; row++) {
297
    if (fread(data + dwide, 1, dwide, ifp) < dwide) derror();
298
    FORC(dwide) data[c] = data[dwide + (c ^ rev)];
299
    for (dp = data, col = 0; col < raw_width; dp++, col++)
300
      RAW(row, col + c) = dp[c];
301
  }
302
  free(data);
303
  maximum = 0xff;
304
  if (!strcmp(make, "OmniVision") ||
305
    !strcmp(make, "Sony") ||
306
    !strcmp(make, "RaspberryPi")) return;
307
308
  row = raw_height / 2;
309
  FORC(width - 1) {
310
    sum[c & 1] += SQR(RAW(row, c) - RAW(row + 1, c + 1));
311
    sum[~c & 1] += SQR(RAW(row + 1, c) - RAW(row, c + 1));
312
  }
313
  if (sum[1] > sum[0]) filters = 0x4b4b4b4b;
314
}
315
316
void LibRaw::rpi_load_raw12()
317
{
318
  uchar  *data, *dp;
319
  int rev, dwide, row, col, c;
320
  double sum[] = { 0,0 };
321
  rev = 3 * (order == 0x4949);
322
  if (raw_stride == 0)
323
    dwide = (raw_width * 3 + 1) / 2;
324
  else
325
    dwide = raw_stride;
326
    data = (uchar *)calloc(dwide, 2);
327
  for (row = 0; row < raw_height; row++) {
328
    if (fread(data + dwide, 1, dwide, ifp) < dwide) derror();
329
    FORC(dwide) data[c] = data[dwide + (c ^ rev)];
330
    for (dp = data, col = 0; col < raw_width; dp += 3, col += 2)
331
      FORC(2) RAW(row, col + c) = (dp[c] << 4) | (dp[2] >> (c << 2) & 0xF);
332
  }
333
  free(data);
334
  maximum = 0xfff;
335
  if (!strcmp(make, "OmniVision") ||
336
    !strcmp(make, "Sony") ||
337
    !strcmp(make, "RaspberryPi")) return;
338
339
  row = raw_height / 2;
340
  FORC(width - 1) {
341
    sum[c & 1] += SQR(RAW(row, c) - RAW(row + 1, c + 1));
342
    sum[~c & 1] += SQR(RAW(row + 1, c) - RAW(row, c + 1));
343
  }
344
  if (sum[1] > sum[0]) filters = 0x4b4b4b4b;
345
}
346
347
void LibRaw::rpi_load_raw14()
348
{
349
  uchar  *data, *dp;
350
  int rev, dwide, row, col, c;
351
  double sum[] = { 0,0 };
352
  rev = 3 * (order == 0x4949);
353
  if (raw_stride == 0)
354
    dwide = ((raw_width * 7) + 3) >> 2;
355
  else
356
    dwide = raw_stride;
357
    data = (uchar *)calloc(dwide, 2);
358
  for (row = 0; row < raw_height; row++) {
359
    if (fread(data + dwide, 1, dwide, ifp) < dwide) derror();
360
    FORC(dwide) data[c] = data[dwide + (c ^ rev)];
361
    for (dp = data, col = 0; col < raw_width; dp += 7, col += 4) {
362
      RAW(row, col + 0) = (dp[0] << 6) | (dp[4] >> 2);
363
      RAW(row, col + 1) = (dp[1] << 6) | ((dp[4] & 0x3) << 4) | ((dp[5] & 0xf0) >> 4);
364
      RAW(row, col + 2) = (dp[2] << 6) | ((dp[5] & 0xf) << 2) | ((dp[6] & 0xc0) >> 6);
365
      RAW(row, col + 3) = (dp[3] << 6) | ((dp[6] & 0x3f) << 2);
366
    }
367
  }
368
  free(data);
369
  maximum = 0x3fff;
370
  if (!strcmp(make, "OmniVision") ||
371
    !strcmp(make, "Sony") ||
372
    !strcmp(make, "RaspberryPi")) return;
373
374
  row = raw_height / 2;
375
  FORC(width - 1) {
376
    sum[c & 1] += SQR(RAW(row, c) - RAW(row + 1, c + 1));
377
    sum[~c & 1] += SQR(RAW(row + 1, c) - RAW(row, c + 1));
378
  }
379
  if (sum[1] > sum[0]) filters = 0x4b4b4b4b;
380
}
381
382
void LibRaw::rpi_load_raw16()
383
{
384
  uchar  *data, *dp;
385
  int rev, dwide, row, col, c;
386
  double sum[] = { 0,0 };
387
  rev = 3 * (order == 0x4949);
388
  if (raw_stride == 0)
389
    dwide = (raw_width * 2);
390
  else
391
    dwide = raw_stride;
392
    data = (uchar *)calloc(dwide, 2);
393
  for (row = 0; row < raw_height; row++) {
394
    if (fread(data + dwide, 1, dwide, ifp) < dwide) derror();
395
    FORC(dwide) data[c] = data[dwide + (c ^ rev)];
396
    for (dp = data, col = 0; col < raw_width; dp += 2, col++)
397
      RAW(row, col + c) = (dp[1] << 8) | dp[0];
398
  }
399
  free(data);
400
  maximum = 0xffff;
401
  if (!strcmp(make, "OmniVision") ||
402
    !strcmp(make, "Sony") ||
403
    !strcmp(make, "RaspberryPi")) return;
404
405
  row = raw_height / 2;
406
  FORC(width - 1) {
407
    sum[c & 1] += SQR(RAW(row, c) - RAW(row + 1, c + 1));
408
    sum[~c & 1] += SQR(RAW(row + 1, c) - RAW(row, c + 1));
409
  }
410
  if (sum[1] > sum[0]) filters = 0x4b4b4b4b;
411
}
412
413
#endif