Coverage Report

Created: 2026-02-26 06:08

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libraw/src/utils/utils_libraw.cpp
Line
Count
Source
1
/* -*- C++ -*-
2
 * Copyright 2019-2025 LibRaw LLC (info@libraw.org)
3
 *
4
5
 LibRaw is free software; you can redistribute it and/or modify
6
 it under the terms of the one of two licenses as you choose:
7
8
1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
9
   (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
10
11
2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
12
   (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
13
14
 */
15
16
#include "../../internal/libraw_cxx_defs.h"
17
#include "../../internal/libraw_checked_buffer.h"
18
19
#ifdef __cplusplus
20
extern "C"
21
{
22
#endif
23
24
  void default_data_callback(void *, const char *file, const INT64 offset)
25
2.72k
  {
26
2.72k
    if (offset < 0)
27
1.67k
      fprintf(stderr, "%s: Unexpected end of file\n",
28
1.67k
              file ? file : "unknown file");
29
1.04k
    else
30
1.04k
      fprintf(stderr, "%s: data corrupted at %lld\n",
31
1.04k
              file ? file : "unknown file", offset);
32
2.72k
  }
33
  const char *libraw_strerror(int e)
34
0
  {
35
0
    enum LibRaw_errors errorcode = (LibRaw_errors)e;
36
0
    switch (errorcode)
37
0
    {
38
0
    case LIBRAW_SUCCESS:
39
0
      return "No error";
40
0
    case LIBRAW_UNSPECIFIED_ERROR:
41
0
      return "Unspecified error";
42
0
    case LIBRAW_FILE_UNSUPPORTED:
43
0
      return "Unsupported file format or not RAW file";
44
0
    case LIBRAW_REQUEST_FOR_NONEXISTENT_IMAGE:
45
0
      return "Request for nonexisting image number";
46
0
    case LIBRAW_OUT_OF_ORDER_CALL:
47
0
      return "Out of order call of libraw function";
48
0
    case LIBRAW_NO_THUMBNAIL:
49
0
      return "No thumbnail in file";
50
0
    case LIBRAW_UNSUPPORTED_THUMBNAIL:
51
0
      return "Unsupported thumbnail format";
52
0
    case LIBRAW_INPUT_CLOSED:
53
0
      return "No input stream, or input stream closed";
54
0
    case LIBRAW_NOT_IMPLEMENTED:
55
0
      return "Decoder not implemented for this data format";
56
0
    case LIBRAW_REQUEST_FOR_NONEXISTENT_THUMBNAIL:
57
0
      return "Request for nonexisting thumbnail number";
58
0
    case LIBRAW_MEMPOOL_OVERFLOW:
59
0
      return "Libraw internal mempool overflowed";
60
0
    case LIBRAW_UNSUFFICIENT_MEMORY:
61
0
      return "Unsufficient memory";
62
0
    case LIBRAW_DATA_ERROR:
63
0
      return "Corrupted data or unexpected EOF";
64
0
    case LIBRAW_IO_ERROR:
65
0
      return "Input/output error";
66
0
    case LIBRAW_CANCELLED_BY_CALLBACK:
67
0
      return "Cancelled by user callback";
68
0
    case LIBRAW_BAD_CROP:
69
0
      return "Bad crop box";
70
0
    case LIBRAW_TOO_BIG:
71
0
      return "Image too big for processing";
72
0
    default:
73
0
      return "Unknown error code";
74
0
    }
75
0
  }
76
77
#ifdef __cplusplus
78
}
79
#endif
80
81
unsigned LibRaw::parse_custom_cameras(unsigned limit,
82
                                      libraw_custom_camera_t table[],
83
                                      char **list)
84
20.0k
{
85
20.0k
  if (!list)
86
20.0k
    return 0;
87
0
  unsigned index = 0;
88
0
  for (unsigned i = 0; i < limit; i++)
89
0
  {
90
0
    if (!list[i])
91
0
      break;
92
0
    if (strlen(list[i]) < 10)
93
0
      continue;
94
0
    char *string = (char *)malloc(strlen(list[i]) + 1);
95
0
    strcpy(string, list[i]);
96
0
    char *start = string;
97
0
    memset(&table[index], 0, sizeof(table[0]));
98
0
    for (int j = 0; start && j < 14; j++)
99
0
    {
100
0
      char *end = strchr(start, ',');
101
0
      if (end)
102
0
      {
103
0
        *end = 0;
104
0
        end++;
105
0
      } // move to next char
106
0
      while (isspace(*start) && *start)
107
0
        start++; // skip leading spaces?
108
0
      unsigned val = strtol(start, 0, 10);
109
0
      switch (j)
110
0
      {
111
0
      case 0:
112
0
        table[index].fsize = val;
113
0
        break;
114
0
      case 1:
115
0
        table[index].rw = val;
116
0
        break;
117
0
      case 2:
118
0
        table[index].rh = val;
119
0
        break;
120
0
      case 3:
121
0
        table[index].lm = val;
122
0
        break;
123
0
      case 4:
124
0
        table[index].tm = val;
125
0
        break;
126
0
      case 5:
127
0
        table[index].rm = val;
128
0
        break;
129
0
      case 6:
130
0
        table[index].bm = val;
131
0
        break;
132
0
      case 7:
133
0
        table[index].lf = val;
134
0
        break;
135
0
      case 8:
136
0
        table[index].cf = val;
137
0
        break;
138
0
      case 9:
139
0
        table[index].max = val;
140
0
        break;
141
0
      case 10:
142
0
        table[index].flags = val;
143
0
        break;
144
0
      case 11:
145
0
        strncpy(table[index].t_make, start, sizeof(table[index].t_make) - 1);
146
0
        break;
147
0
      case 12:
148
0
        strncpy(table[index].t_model, start, sizeof(table[index].t_model) - 1);
149
0
        break;
150
0
      case 13:
151
0
        table[index].offset = val;
152
0
        break;
153
0
      default:
154
0
        break;
155
0
      }
156
0
      start = end;
157
0
    }
158
0
    free(string);
159
0
    if (table[index].t_make[0])
160
0
      index++;
161
0
  }
162
0
  return index;
163
0
}
164
165
void LibRaw::derror()
166
132M
{
167
132M
  if (!libraw_internal_data.unpacker_data.data_error &&
168
2.72k
      libraw_internal_data.internal_data.input)
169
2.72k
  {
170
2.72k
    if (libraw_internal_data.internal_data.input->eof())
171
1.67k
    {
172
1.67k
      if (callbacks.data_cb)
173
1.67k
        (*callbacks.data_cb)(callbacks.datacb_data,
174
1.67k
                             libraw_internal_data.internal_data.input->fname(),
175
1.67k
                             -1);
176
1.67k
      throw LIBRAW_EXCEPTION_IO_EOF;
177
1.67k
    }
178
1.04k
    else
179
1.04k
    {
180
1.04k
      if (callbacks.data_cb)
181
1.04k
        (*callbacks.data_cb)(callbacks.datacb_data,
182
1.04k
                             libraw_internal_data.internal_data.input->fname(),
183
1.04k
                             libraw_internal_data.internal_data.input->tell());
184
      // throw LIBRAW_EXCEPTION_IO_CORRUPT;
185
1.04k
    }
186
2.72k
  }
187
132M
  libraw_internal_data.unpacker_data.data_error++;
188
132M
}
189
190
0
const char *LibRaw::version() { return LIBRAW_VERSION_STR; }
191
0
int LibRaw::versionNumber() { return LIBRAW_VERSION; }
192
0
const char *LibRaw::strerror(int p) { return libraw_strerror(p); }
193
194
unsigned LibRaw::capabilities()
195
0
{
196
0
  unsigned ret = 0;
197
#ifdef USE_RAWSPEED
198
  ret |= LIBRAW_CAPS_RAWSPEED;
199
#endif
200
#ifdef USE_RAWSPEED3
201
  ret |= LIBRAW_CAPS_RAWSPEED3;
202
#endif
203
#ifdef USE_RAWSPEED_BITS
204
  ret |= LIBRAW_CAPS_RAWSPEED_BITS;
205
#endif
206
#ifdef USE_DNGSDK
207
  ret |= LIBRAW_CAPS_DNGSDK;
208
#ifdef USE_GPRSDK
209
  ret |= LIBRAW_CAPS_GPRSDK;
210
#endif
211
#ifdef LIBRAW_WIN32_UNICODEPATHS
212
  ret |= LIBRAW_CAPS_UNICODEPATHS;
213
#endif
214
#endif
215
#ifdef USE_X3FTOOLS
216
  ret |= LIBRAW_CAPS_X3FTOOLS;
217
#endif
218
#ifdef USE_6BY9RPI
219
  ret |= LIBRAW_CAPS_RPI6BY9;
220
#endif
221
0
#ifdef USE_ZLIB
222
0
  ret |= LIBRAW_CAPS_ZLIB;
223
0
#endif
224
#ifdef USE_JPEG
225
  ret |= LIBRAW_CAPS_JPEG;
226
#endif
227
0
  return ret;
228
0
}
229
230
int LibRaw::is_sraw()
231
0
{
232
0
  return load_raw == &LibRaw::canon_sraw_load_raw ||
233
0
         load_raw == &LibRaw::nikon_load_sraw ||
234
0
      load_raw == &LibRaw::sony_ycbcr_load_raw;
235
0
}
236
int LibRaw::is_coolscan_nef()
237
0
{
238
0
  return load_raw == &LibRaw::nikon_coolscan_load_raw;
239
0
}
240
int LibRaw::is_jpeg_thumb()
241
0
{
242
0
  return libraw_internal_data.unpacker_data.thumb_format == LIBRAW_INTERNAL_THUMBNAIL_JPEG;
243
0
}
244
245
0
int LibRaw::is_nikon_sraw() { return load_raw == &LibRaw::nikon_load_sraw; }
246
int LibRaw::sraw_midpoint()
247
0
{
248
0
  if (load_raw == &LibRaw::canon_sraw_load_raw)
249
0
    return 8192;
250
0
  else if (load_raw == &LibRaw::sony_ycbcr_load_raw)
251
0
    return 8192; // adjusted as in canon sRAW
252
0
  else if (load_raw == &LibRaw::nikon_load_sraw)
253
0
    return 2048;
254
0
  else
255
0
    return 0;
256
0
}
257
258
void *LibRaw::malloc(size_t t)
259
10.3k
{
260
10.3k
  void *p = memmgr.malloc(t);
261
10.3k
  if (!p)
262
0
    throw LIBRAW_EXCEPTION_ALLOC;
263
10.3k
  return p;
264
10.3k
}
265
void *LibRaw::realloc(void *q, size_t t)
266
8.06k
{
267
8.06k
  void *p = memmgr.realloc(q, t);
268
8.06k
  if (!p)
269
0
    throw LIBRAW_EXCEPTION_ALLOC;
270
8.06k
  return p;
271
8.06k
}
272
273
void *LibRaw::calloc(size_t n, size_t t)
274
228k
{
275
228k
  void *p = memmgr.calloc(n, t);
276
228k
  if (!p)
277
0
    throw LIBRAW_EXCEPTION_ALLOC;
278
228k
  return p;
279
228k
}
280
210k
void LibRaw::free(void *p) { memmgr.free(p); }
281
282
void LibRaw::recycle_datastream()
283
49.4k
{
284
49.4k
  if (libraw_internal_data.internal_data.input &&
285
20.0k
      libraw_internal_data.internal_data.input_internal)
286
5.15k
  {
287
5.15k
    delete libraw_internal_data.internal_data.input;
288
5.15k
    libraw_internal_data.internal_data.input = NULL;
289
5.15k
  }
290
49.4k
  libraw_internal_data.internal_data.input_internal = 0;
291
49.4k
}
292
293
void LibRaw::clearCancelFlag()
294
0
{
295
#ifdef _MSC_VER
296
  InterlockedExchange(&_exitflag, 0);
297
#else
298
0
  __sync_fetch_and_and(&_exitflag, 0);
299
0
#endif
300
#ifdef RAWSPEED_FASTEXIT
301
  if (_rawspeed_decoder)
302
  {
303
    RawSpeed::RawDecoder *d =
304
        static_cast<RawSpeed::RawDecoder *>(_rawspeed_decoder);
305
    d->resumeProcessing();
306
  }
307
#endif
308
0
}
309
310
void LibRaw::setCancelFlag()
311
0
{
312
#ifdef _MSC_VER
313
  InterlockedExchange(&_exitflag, 1);
314
#else
315
0
  __sync_fetch_and_add(&_exitflag, 1);
316
0
#endif
317
#ifdef RAWSPEED_FASTEXIT
318
  if (_rawspeed_decoder)
319
  {
320
    RawSpeed::RawDecoder *d =
321
        static_cast<RawSpeed::RawDecoder *>(_rawspeed_decoder);
322
    d->cancelProcessing();
323
  }
324
#endif
325
0
}
326
327
void LibRaw::checkCancel()
328
19.1M
{
329
#ifdef _MSC_VER
330
  if (InterlockedExchange(&_exitflag, 0))
331
    throw LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK;
332
#else
333
19.1M
  if (__sync_fetch_and_and(&_exitflag, 0))
334
0
    throw LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK;
335
19.1M
#endif
336
19.1M
}
337
338
int LibRaw::is_curve_linear()
339
0
{
340
0
  for (int i = 0; i < 0x10000; i++)
341
0
    if (imgdata.color.curve[i] != i)
342
0
      return 0;
343
0
  return 1;
344
0
}
345
346
void LibRaw::free_image(void)
347
1.53k
{
348
1.53k
  if (imgdata.image)
349
1.53k
  {
350
1.53k
    free(imgdata.image);
351
1.53k
    imgdata.image = 0;
352
1.53k
    imgdata.progress_flags = LIBRAW_PROGRESS_START | LIBRAW_PROGRESS_OPEN |
353
1.53k
                             LIBRAW_PROGRESS_IDENTIFY |
354
1.53k
                             LIBRAW_PROGRESS_SIZE_ADJUST |
355
1.53k
                             LIBRAW_PROGRESS_LOAD_RAW;
356
1.53k
  }
357
1.53k
}
358
359
int LibRaw::is_phaseone_compressed()
360
13.5k
{
361
13.5k
  return (load_raw == &LibRaw::phase_one_load_raw_c ||
362
12.9k
      load_raw == &LibRaw::phase_one_load_raw_s ||
363
12.9k
          load_raw == &LibRaw::phase_one_load_raw);
364
13.5k
}
365
366
0
int LibRaw::is_canon_600() { return load_raw == &LibRaw::canon_600_load_raw; }
367
const char *LibRaw::strprogress(enum LibRaw_progress p)
368
0
{
369
0
  switch (p)
370
0
  {
371
0
  case LIBRAW_PROGRESS_START:
372
0
    return "Starting";
373
0
  case LIBRAW_PROGRESS_OPEN:
374
0
    return "Opening file";
375
0
  case LIBRAW_PROGRESS_IDENTIFY:
376
0
    return "Reading metadata";
377
0
  case LIBRAW_PROGRESS_SIZE_ADJUST:
378
0
    return "Adjusting size";
379
0
  case LIBRAW_PROGRESS_LOAD_RAW:
380
0
    return "Reading RAW data";
381
0
  case LIBRAW_PROGRESS_REMOVE_ZEROES:
382
0
    return "Clearing zero values";
383
0
  case LIBRAW_PROGRESS_BAD_PIXELS:
384
0
    return "Removing dead pixels";
385
0
  case LIBRAW_PROGRESS_DARK_FRAME:
386
0
    return "Subtracting dark frame data";
387
0
  case LIBRAW_PROGRESS_FOVEON_INTERPOLATE:
388
0
    return "Interpolating Foveon sensor data";
389
0
  case LIBRAW_PROGRESS_SCALE_COLORS:
390
0
    return "Scaling colors";
391
0
  case LIBRAW_PROGRESS_PRE_INTERPOLATE:
392
0
    return "Pre-interpolating";
393
0
  case LIBRAW_PROGRESS_INTERPOLATE:
394
0
    return "Interpolating";
395
0
  case LIBRAW_PROGRESS_MIX_GREEN:
396
0
    return "Mixing green channels";
397
0
  case LIBRAW_PROGRESS_MEDIAN_FILTER:
398
0
    return "Median filter";
399
0
  case LIBRAW_PROGRESS_HIGHLIGHTS:
400
0
    return "Highlight recovery";
401
0
  case LIBRAW_PROGRESS_FUJI_ROTATE:
402
0
    return "Rotating Fuji diagonal data";
403
0
  case LIBRAW_PROGRESS_FLIP:
404
0
    return "Flipping image";
405
0
  case LIBRAW_PROGRESS_APPLY_PROFILE:
406
0
    return "ICC conversion";
407
0
  case LIBRAW_PROGRESS_CONVERT_RGB:
408
0
    return "Converting to RGB";
409
0
  case LIBRAW_PROGRESS_STRETCH:
410
0
    return "Stretching image";
411
0
  case LIBRAW_PROGRESS_THUMB_LOAD:
412
0
    return "Loading thumbnail";
413
0
  default:
414
0
    return "Some strange things";
415
0
  }
416
0
}
417
int LibRaw::adjust_sizes_info_only(void)
418
0
{
419
0
  CHECK_ORDER_LOW(LIBRAW_PROGRESS_IDENTIFY);
420
421
0
  raw2image_start();
422
0
  if (O.use_fuji_rotate)
423
0
  {
424
0
    if (IO.fuji_width)
425
0
    {
426
0
      IO.fuji_width = (IO.fuji_width - 1 + IO.shrink) >> IO.shrink;
427
0
      S.iwidth = (ushort)(IO.fuji_width / sqrt(0.5));
428
0
      S.iheight = (ushort)((S.iheight - IO.fuji_width) / sqrt(0.5));
429
0
    }
430
0
    else
431
0
    {
432
0
      if (S.pixel_aspect < 0.995)
433
0
        S.iheight = (ushort)(S.iheight / S.pixel_aspect + 0.5);
434
0
      if (S.pixel_aspect > 1.005)
435
0
        S.iwidth = (ushort)(S.iwidth * S.pixel_aspect + 0.5);
436
0
    }
437
0
  }
438
0
  SET_PROC_FLAG(LIBRAW_PROGRESS_FUJI_ROTATE);
439
0
  if (S.flip & 4)
440
0
  {
441
0
    unsigned short t = S.iheight;
442
0
    S.iheight = S.iwidth;
443
0
    S.iwidth = t;
444
0
    SET_PROC_FLAG(LIBRAW_PROGRESS_FLIP);
445
0
  }
446
0
  return 0;
447
0
}
448
int LibRaw::adjust_maximum()
449
8.31k
{
450
8.31k
  ushort real_max;
451
8.31k
  float auto_threshold;
452
453
8.31k
  if (O.adjust_maximum_thr < 0.00001)
454
1.19k
    return LIBRAW_SUCCESS;
455
7.11k
  else if (O.adjust_maximum_thr > 0.99999)
456
314
    auto_threshold = LIBRAW_DEFAULT_ADJUST_MAXIMUM_THRESHOLD;
457
6.80k
  else
458
6.80k
    auto_threshold = O.adjust_maximum_thr;
459
460
7.11k
  real_max = C.data_maximum;
461
7.11k
  if (real_max > 0 && real_max < C.maximum &&
462
3.34k
      real_max > C.maximum * auto_threshold)
463
1.11k
  {
464
1.11k
    C.maximum = real_max;
465
1.11k
  }
466
7.11k
  return LIBRAW_SUCCESS;
467
8.31k
}
468
void LibRaw::adjust_bl()
469
10.1k
{
470
10.1k
  int clear_repeat = 0;
471
10.1k
  if (O.user_black >= 0)
472
2.35k
  {
473
2.35k
    C.black = O.user_black;
474
2.35k
    clear_repeat = 1;
475
2.35k
  }
476
50.7k
  for (int i = 0; i < 4; i++)
477
40.6k
    if (O.user_cblack[i] > -1000000)
478
0
    {
479
0
      C.cblack[i] = O.user_cblack[i];
480
0
      clear_repeat = 1;
481
0
    }
482
483
10.1k
  if (clear_repeat)
484
2.35k
    C.cblack[4] = C.cblack[5] = 0;
485
486
  // Add common part to cblack[] early
487
10.1k
  if (imgdata.idata.filters > 1000 && (C.cblack[4] + 1) / 2 == 1 &&
488
214
      (C.cblack[5] + 1) / 2 == 1)
489
178
  {
490
178
    int clrs[4];
491
178
    int lastg = -1, gcnt = 0;
492
890
    for (int c = 0; c < 4; c++)
493
712
    {
494
712
      clrs[c] = FC(c / 2, c % 2);
495
712
      if (clrs[c] == 1)
496
172
      {
497
172
        gcnt++;
498
172
        lastg = c;
499
172
      }
500
712
    }
501
178
    if (gcnt > 1 && lastg >= 0)
502
29
      clrs[lastg] = 3;
503
890
    for (int c = 0; c < 4; c++)
504
712
      C.cblack[clrs[c]] +=
505
712
          C.cblack[6 + c / 2 % C.cblack[4] * C.cblack[5] + c % 2 % C.cblack[5]];
506
178
    C.cblack[4] = C.cblack[5] = 0;
507
    // imgdata.idata.filters = sfilters;
508
178
  }
509
9.97k
  else if (imgdata.idata.filters <= 1000 && C.cblack[4] == 1 &&
510
13
           C.cblack[5] == 1) // Fuji RAF dng
511
13
  {
512
65
    for (int c = 0; c < 4; c++)
513
52
      C.cblack[c] += C.cblack[6];
514
13
    C.cblack[4] = C.cblack[5] = 0;
515
13
  }
516
  // remove common part from C.cblack[]
517
10.1k
  int i = C.cblack[3];
518
10.1k
  int c;
519
40.6k
  for (c = 0; c < 3; c++)
520
30.4k
    if (i > (int)C.cblack[c])
521
848
      i = C.cblack[c];
522
523
50.7k
  for (c = 0; c < 4; c++)
524
40.6k
    C.cblack[c] -= i; // remove common part
525
10.1k
  C.black += i;
526
527
  // Now calculate common part for cblack[6+] part and move it to C.black
528
529
10.1k
  if (C.cblack[4] && C.cblack[5])
530
959
  {
531
959
    i = C.cblack[6];
532
266k
    for (c = 1; c < int(C.cblack[4] * C.cblack[5]); c++)
533
265k
      if (i > int(C.cblack[6 + c]))
534
2.33k
        i = C.cblack[6 + c];
535
    // Remove i from cblack[6+]
536
959
    int nonz = 0;
537
267k
    for (c = 0; c < int(C.cblack[4] * C.cblack[5]); c++)
538
266k
    {
539
266k
      C.cblack[6 + c] -= i;
540
266k
      if (C.cblack[6 + c])
541
234k
        nonz++;
542
266k
    }
543
959
    C.black += i;
544
959
    if (!nonz)
545
166
      C.cblack[4] = C.cblack[5] = 0;
546
959
  }
547
50.7k
  for (c = 0; c < 4; c++)
548
40.6k
    C.cblack[c] += C.black;
549
10.1k
}
550
int LibRaw::getwords(char *line, char *words[], int maxwords, int maxlen)
551
2.97k
{
552
2.97k
  line[maxlen - 1] = 0;
553
2.97k
  unsigned char *p = (unsigned char*)line;
554
2.97k
  int nwords = 0;
555
556
4.90k
  while (1)
557
4.90k
  {
558
6.77k
    while (isspace(*p))
559
1.87k
      p++;
560
4.90k
    if (*p == '\0')
561
987
      return nwords;
562
3.92k
    words[nwords++] = (char*)p;
563
70.9k
    while (!isspace(*p) && *p != '\0')
564
67.0k
      p++;
565
3.92k
    if (*p == '\0')
566
1.75k
      return nwords;
567
2.17k
    *p++ = '\0';
568
2.17k
    if (nwords >= maxwords)
569
235
      return nwords;
570
2.17k
  }
571
2.97k
}
572
int LibRaw::stread(char *buf, size_t len, LibRaw_abstract_datastream *fp)
573
44.6k
{
574
44.6k
  if (len > 0)
575
33.9k
  {
576
33.9k
    int r = fp->read(buf, len, 1);
577
33.9k
    buf[len - 1] = 0;
578
33.9k
    return r;
579
33.9k
  }
580
10.6k
  else
581
10.6k
    return 0;
582
44.6k
}
583
584
int LibRaw::find_ifd_by_offset(INT64 o)
585
1.22k
{
586
2.08k
    for(unsigned i = 0; i < libraw_internal_data.identify_data.tiff_nifds && i < LIBRAW_IFD_MAXCOUNT; i++)
587
1.82k
        if(tiff_ifd[i].offset == o)
588
961
            return i;
589
266
    return -1;
590
1.22k
}
591
592
short LibRaw::tiff_sget (unsigned save, uchar *buf, unsigned buf_len, INT64 *tag_offset,
593
                         unsigned *tag_id, unsigned *tag_type, INT64 *tag_dataoffset,
594
110
                         unsigned *tag_datalen, int *tag_dataunitlen) {
595
110
  uchar *pos = buf + *tag_offset;
596
110
  if ((((*tag_offset) + 12) > buf_len) || (*tag_offset < 0)) { // abnormal, tag buffer overrun
597
0
    return -1;
598
0
  }
599
110
  *tag_id      = sget2(pos); pos += 2;
600
110
  *tag_type    = sget2(pos); pos += 2;
601
110
  *tag_datalen = sget4(pos); pos += 4;
602
110
  *tag_dataunitlen = tagtype_dataunit_bytes[(*tag_type <= LIBRAW_EXIFTAG_TYPE_IFD8) ? *tag_type : 0];
603
110
  if ((*tag_datalen * (*tag_dataunitlen)) > 4) {
604
110
    *tag_dataoffset = sget4(pos) - save;
605
110
    if ((*tag_dataoffset + *tag_datalen) > buf_len) { // abnormal, tag data buffer overrun
606
110
      return -2;
607
110
    }
608
110
  } else *tag_dataoffset = *tag_offset + 8;
609
0
  *tag_offset += 12;
610
0
  return 0;
611
110
}
612
613
0
#define rICC  imgdata.sizes.raw_inset_crops
614
0
#define S imgdata.sizes
615
0
#define RS imgdata.rawdata.sizes
616
int LibRaw::adjust_to_raw_inset_crop(unsigned mask, float maxcrop)
617
618
0
{
619
0
    int adjindex = -1;
620
0
  int limwidth = int(S.width * maxcrop);
621
0
  int limheight = int(S.height * maxcrop);
622
623
0
    for(int i = 1; i >= 0; i--)
624
0
        if (mask & (1<<i))
625
0
            if (rICC[i].ctop < 0xffff && rICC[i].cleft < 0xffff
626
0
                && rICC[i].cleft + rICC[i].cwidth <= S.raw_width
627
0
                && rICC[i].ctop + rICC[i].cheight <= S.raw_height
628
0
        && rICC[i].cwidth >= limwidth && rICC[i].cheight >= limheight)
629
0
            {
630
0
                adjindex = i;
631
0
                break;
632
0
            }
633
634
0
    if (adjindex >= 0)
635
0
    {
636
0
        RS.left_margin = S.left_margin = rICC[adjindex].cleft;
637
0
        RS.top_margin = S.top_margin = rICC[adjindex].ctop;
638
0
        RS.width = S.width = MIN(rICC[adjindex].cwidth, int(S.raw_width) - int(S.left_margin));
639
0
        RS.height = S.height = MIN(rICC[adjindex].cheight, int(S.raw_height) - int(S.top_margin));
640
0
    }
641
0
    return adjindex + 1;
642
0
}
643
644
char** LibRaw::malloc_omp_buffers(int buffer_count, size_t buffer_size)
645
1.17k
{
646
1.17k
    char** buffers = (char**)calloc(sizeof(char*), buffer_count);
647
648
2.35k
    for (int i = 0; i < buffer_count; i++)
649
1.17k
    {
650
1.17k
        buffers[i] = (char*)calloc(buffer_size,1);
651
1.17k
    }
652
1.17k
    return buffers;
653
1.17k
}
654
655
void LibRaw::free_omp_buffers(char** buffers, int buffer_count)
656
1.17k
{
657
2.35k
    for (int i = 0; i < buffer_count; i++)
658
1.17k
        if(buffers[i])
659
1.17k
            free(buffers[i]);
660
1.17k
    free(buffers);
661
1.17k
}
662
663
void  LibRaw::libraw_swab(void *arr, int len)
664
71.0k
{
665
71.0k
#ifdef LIBRAW_OWN_SWAB
666
71.0k
  uint16_t *array = (uint16_t*)arr;
667
71.0k
  int bytes = len/2;
668
585k
  for(; bytes; --bytes)
669
514k
  {
670
514k
    *array = ((*array << 8) & 0xff00) | ((*array >> 8) & 0xff);
671
514k
    array++;
672
514k
  }
673
#else
674
  swab((char*)arr,(char*)arr,len);
675
#endif
676
677
71.0k
}
678
679
14.6k
checked_buffer_t::checked_buffer_t(short ord, int size) : _order(ord), storage(size + 64)
680
14.6k
{
681
14.6k
  _data = storage.data();
682
14.6k
  _len = size;
683
14.6k
}
684
333
checked_buffer_t::checked_buffer_t(short ord, unsigned char *dd, int ss) : _order(ord), _data(dd), _len(ss) {}
685
686
ushort checked_buffer_t::sget2(int offset)
687
3.63M
{
688
3.63M
  checkoffset(offset);
689
3.63M
  checkoffset(offset + 2);
690
3.63M
  return libraw_sget2_static(_order, _data + offset);
691
3.63M
}
692
void checked_buffer_t::checkoffset(int off)
693
26.3M
{
694
26.3M
  if (off >= _len || off < 0)
695
2.89k
    throw LIBRAW_EXCEPTION_IO_EOF;
696
26.3M
}
697
unsigned char checked_buffer_t::operator[](int idx)
698
9.69k
{
699
9.69k
  checkoffset(idx);
700
9.69k
  return _data[idx];
701
9.69k
}
702
unsigned checked_buffer_t::sget4(int offset)
703
118k
{
704
118k
  checkoffset(offset);
705
118k
  checkoffset(offset + 4);
706
118k
  return libraw_sget4_static(_order, _data + offset);
707
118k
}
708
709
double checked_buffer_t::sgetreal(int type, int offset)
710
0
{
711
0
  checkoffset(offset);
712
0
  int sz = libraw_tagtype_dataunit_bytes(type);
713
0
  checkoffset(offset + sz);
714
0
  return libraw_sgetreal_static(_order, type, _data + offset);
715
0
}
716
717
int checked_buffer_t::tiff_sget(unsigned save, INT64 *tag_offset, unsigned *tag_id, unsigned *tag_type, INT64 *tag_dataoffset,
718
              unsigned *tag_datalen, int *tag_dataunitlen)
719
2.82k
{
720
2.82k
  if ((((*tag_offset) + 12) > _len) || (*tag_offset < 0))
721
2.19k
  { // abnormal, tag buffer overrun
722
2.19k
    return -1;
723
2.19k
  }
724
628
  int pos = int(*tag_offset);
725
628
  *tag_id = sget2(pos);
726
628
  pos += 2;
727
628
  *tag_type = sget2(pos);
728
628
  pos += 2;
729
628
  *tag_datalen = sget4(pos);
730
628
  pos += 4;
731
628
  *tag_dataunitlen = libraw_tagtype_dataunit_bytes(*tag_type);
732
628
  if ((*tag_datalen * (*tag_dataunitlen)) > 4)
733
628
  {
734
628
    *tag_dataoffset = sget4(pos) - save;
735
628
    if ((*tag_dataoffset + *tag_datalen) > _len)
736
612
    { // abnormal, tag data buffer overrun
737
612
      return -2;
738
612
    }
739
628
  }
740
0
  else
741
0
    *tag_dataoffset = *tag_offset + 8;
742
16
  *tag_offset += 12;
743
16
  return 0;
744
628
}
745