Coverage Report

Created: 2026-02-26 07:48

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
0
{
27
0
  ushort *rp;
28
0
  unsigned row, col;
29
30
0
  int ss = shot_select;
31
0
  shot_select = libraw_internal_data.unpacker_data.dng_frames[LIM(ss, 0, (LIBRAW_IFD_MAXCOUNT * 2 - 1))] & 0xff;
32
0
  std::vector<ushort> pixel;
33
34
0
  try
35
0
  {
36
0
    int ntiles = 1 + (raw_width) / tile_width;
37
0
    if ((unsigned)ntiles * tile_width > raw_width * 2u) throw LIBRAW_EXCEPTION_ALLOC;
38
0
    pixel.resize(tile_width * ntiles * tiff_samples);
39
0
  }
40
0
  catch (...)
41
0
  {
42
0
    throw LIBRAW_EXCEPTION_ALLOC; // rethrow
43
0
  }
44
0
  try
45
0
  {
46
0
      unsigned trow = 0, tcol = 0;
47
0
      INT64 save;
48
0
      while (trow < raw_height)
49
0
      {
50
0
        checkCancel();
51
0
        save = ftell(ifp);
52
0
        if (tile_length < INT_MAX)
53
0
          fseek(ifp, get4(), SEEK_SET);
54
55
0
        for (row = 0; row < tile_length && (row + trow) < raw_height; row++)
56
0
        {
57
0
          if (tiff_bps == 16)
58
0
            read_shorts(pixel.data(), tile_width * tiff_samples);
59
0
          else
60
0
          {
61
0
            getbits(-1);
62
0
            for (col = 0; col < tile_width * tiff_samples; col++)
63
0
              pixel[col] = getbits(tiff_bps);
64
0
          }
65
0
          for (rp = pixel.data(), col = 0; col < tile_width; col++)
66
0
            adobe_copy_pixel(trow+row, tcol+col, &rp);
67
0
        }
68
0
        fseek(ifp, save + 4, SEEK_SET);
69
0
        if ((tcol += tile_width) >= raw_width)
70
0
          trow += tile_length + (tcol = 0);
71
0
      }
72
0
  }
73
0
  catch (...)
74
0
  {
75
0
    shot_select = ss;
76
0
    throw;
77
0
  }
78
0
  shot_select = ss;
79
0
}
80
81
82
void LibRaw::sony_ljpeg_load_raw()
83
0
{
84
0
  unsigned trow = 0, tcol = 0, jrow, jcol, row, col;
85
0
  INT64 save;
86
0
  struct jhead jh;
87
88
0
  while (trow < raw_height)
89
0
  {
90
0
    checkCancel();
91
0
    save = ftell(ifp); // We're at
92
0
    if (tile_length < INT_MAX)
93
0
      fseek(ifp, get4(), SEEK_SET);
94
0
    if (!ljpeg_start(&jh, 0))
95
0
      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
0
}
122
123
void LibRaw::nikon_coolscan_load_raw()
124
0
{
125
0
  int clrs = colors == 3 ? 3 : 1;
126
127
0
  if (clrs == 3 && !image)
128
0
    throw LIBRAW_EXCEPTION_IO_CORRUPT;
129
130
0
  if(clrs == 1 && !raw_image)
131
0
    throw LIBRAW_EXCEPTION_IO_CORRUPT;
132
133
0
  int bypp = tiff_bps <= 8 ? 1 : 2;
134
0
  int bufsize = width * clrs * bypp;
135
0
  unsigned char *buf = (unsigned char *)calloc(bufsize,1);
136
0
  unsigned short *ubuf = (unsigned short *)buf;
137
138
0
  if (tiff_bps <= 8)
139
0
    gamma_curve(1.0 / imgdata.rawparams.coolscan_nef_gamma, 0., 1, 255);
140
0
  else
141
0
    gamma_curve(1.0 / imgdata.rawparams.coolscan_nef_gamma, 0., 1, 65535);
142
0
  fseek(ifp, data_offset, SEEK_SET);
143
0
  for (int row = 0; row < raw_height; row++)
144
0
  {
145
0
      if(tiff_bps <=8)
146
0
        fread(buf, 1, bufsize, ifp);
147
0
      else
148
0
          read_shorts(ubuf,width*clrs);
149
150
0
    unsigned short(*ip)[4] = (unsigned short(*)[4])image + row * width;
151
0
    unsigned short *rp =  raw_image + row * raw_width;
152
153
0
    if (is_NikonTransfer == 2)
154
0
    { // it is also (tiff_bps == 8)
155
0
        if (clrs == 3)
156
0
        {
157
0
          for (int col = 0; col < width; col++)
158
0
          {
159
0
            ip[col][0] = ushort(((float)curve[buf[col * 3]]) / 255.0f);
160
0
            ip[col][1] = ushort(((float)curve[buf[col * 3 + 1]]) / 255.0f);
161
0
            ip[col][2] = ushort(((float)curve[buf[col * 3 + 2]]) / 255.0f);
162
0
            ip[col][3] = 0;
163
0
          }
164
0
        }
165
0
        else
166
0
        {
167
0
          for (int col = 0; col < width; col++)
168
0
            rp[col] = ushort(((float)curve[buf[col]]) / 255.0f);
169
0
        }
170
0
    }
171
0
    else if (tiff_bps <= 8)
172
0
    {
173
0
        if (clrs == 3)
174
0
        {
175
0
          for (int col = 0; col < width; col++)
176
0
          {
177
0
            ip[col][0] = curve[buf[col * 3]];
178
0
            ip[col][1] = curve[buf[col * 3 + 1]];
179
0
            ip[col][2] = curve[buf[col * 3 + 2]];
180
0
            ip[col][3] = 0;
181
0
          }
182
0
        }
183
0
        else
184
0
        {
185
0
          for (int col = 0; col < width; col++)
186
0
            rp[col] = curve[buf[col]];
187
0
        }
188
0
    }
189
0
    else
190
0
    {
191
0
        if (clrs == 3)
192
0
        {
193
0
          for (int col = 0; col < width; col++)
194
0
          {
195
0
            ip[col][0] = curve[ubuf[col * 3]];
196
0
            ip[col][1] = curve[ubuf[col * 3 + 1]];
197
0
            ip[col][2] = curve[ubuf[col * 3 + 2]];
198
0
            ip[col][3] = 0;
199
0
          }
200
0
        }
201
0
        else
202
0
        {
203
0
          for (int col = 0; col < width; col++)
204
0
            rp[col] = curve[ubuf[col]];
205
0
        }
206
0
    }
207
0
  }
208
0
  free(buf);
209
0
}
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