Coverage Report

Created: 2026-06-07 07:20

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
0
  {
26
0
    if (offset < 0)
27
0
      fprintf(stderr, "%s: Unexpected end of file\n",
28
0
              file ? file : "unknown file");
29
0
    else
30
0
      fprintf(stderr, "%s: data corrupted at %lld\n",
31
0
              file ? file : "unknown file", offset);
32
0
  }
33
  const char *libraw_strerror(int e)
34
27.4k
  {
35
27.4k
    enum LibRaw_errors errorcode = (LibRaw_errors)e;
36
27.4k
    switch (errorcode)
37
27.4k
    {
38
0
    case LIBRAW_SUCCESS:
39
0
      return "No error";
40
0
    case LIBRAW_UNSPECIFIED_ERROR:
41
0
      return "Unspecified error";
42
13.0k
    case LIBRAW_FILE_UNSUPPORTED:
43
13.0k
      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
3
    case LIBRAW_MEMPOOL_OVERFLOW:
59
3
      return "Libraw internal mempool overflowed";
60
1
    case LIBRAW_UNSUFFICIENT_MEMORY:
61
1
      return "Unsufficient memory";
62
10
    case LIBRAW_DATA_ERROR:
63
10
      return "Corrupted data or unexpected EOF";
64
14.3k
    case LIBRAW_IO_ERROR:
65
14.3k
      return "Input/output error";
66
22
    case LIBRAW_CANCELLED_BY_CALLBACK:
67
22
      return "Cancelled by user callback";
68
0
    case LIBRAW_BAD_CROP:
69
0
      return "Bad crop box";
70
11
    case LIBRAW_TOO_BIG:
71
11
      return "Image too big for processing";
72
0
    default:
73
0
      return "Unknown error code";
74
27.4k
    }
75
27.4k
  }
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
29.8k
{
85
29.8k
  if (!list)
86
29.8k
    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
27.1M
{
167
27.1M
  if (!libraw_internal_data.unpacker_data.data_error &&
168
2.29k
      libraw_internal_data.internal_data.input)
169
2.29k
  {
170
2.29k
    if (libraw_internal_data.internal_data.input->eof())
171
1.12k
    {
172
1.12k
      if (callbacks.data_cb)
173
1.12k
        (*callbacks.data_cb)(callbacks.datacb_data,
174
1.12k
                             libraw_internal_data.internal_data.input->fname(),
175
1.12k
                             -1);
176
1.12k
      throw LIBRAW_EXCEPTION_IO_EOF;
177
1.12k
    }
178
1.16k
    else
179
1.16k
    {
180
1.16k
      if (callbacks.data_cb)
181
1.16k
        (*callbacks.data_cb)(callbacks.datacb_data,
182
1.16k
                             libraw_internal_data.internal_data.input->fname(),
183
1.16k
                             libraw_internal_data.internal_data.input->tell());
184
      // throw LIBRAW_EXCEPTION_IO_CORRUPT;
185
1.16k
    }
186
2.29k
  }
187
27.1M
  libraw_internal_data.unpacker_data.data_error++;
188
27.1M
}
189
190
14
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
6.04k
{
260
6.04k
  void *p = memmgr.malloc(t);
261
6.04k
  if (!p)
262
0
    throw LIBRAW_EXCEPTION_ALLOC;
263
6.04k
  return p;
264
6.04k
}
265
void *LibRaw::realloc(void *q, size_t t)
266
0
{
267
0
  void *p = memmgr.realloc(q, t);
268
0
  if (!p)
269
0
    throw LIBRAW_EXCEPTION_ALLOC;
270
0
  return p;
271
0
}
272
273
void *LibRaw::calloc(size_t n, size_t t)
274
207k
{
275
207k
  void *p = memmgr.calloc(n, t);
276
207k
  if (!p)
277
0
    throw LIBRAW_EXCEPTION_ALLOC;
278
207k
  return p;
279
207k
}
280
179k
void LibRaw::free(void *p) { memmgr.free(p); }
281
282
void LibRaw::recycle_datastream()
283
74.0k
{
284
74.0k
  if (libraw_internal_data.internal_data.input &&
285
29.8k
      libraw_internal_data.internal_data.input_internal)
286
4.44k
  {
287
4.44k
    delete libraw_internal_data.internal_data.input;
288
4.44k
    libraw_internal_data.internal_data.input = NULL;
289
4.44k
  }
290
74.0k
  libraw_internal_data.internal_data.input_internal = 0;
291
74.0k
}
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
2.47M
{
329
#ifdef _MSC_VER
330
  if (InterlockedExchange(&_exitflag, 0))
331
    throw LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK;
332
#else
333
2.47M
  if (__sync_fetch_and_and(&_exitflag, 0))
334
0
    throw LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK;
335
2.47M
#endif
336
2.47M
}
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
0
{
348
0
  if (imgdata.image)
349
0
  {
350
0
    free(imgdata.image);
351
0
    imgdata.image = 0;
352
0
    imgdata.progress_flags = LIBRAW_PROGRESS_START | LIBRAW_PROGRESS_OPEN |
353
0
                             LIBRAW_PROGRESS_IDENTIFY |
354
0
                             LIBRAW_PROGRESS_SIZE_ADJUST |
355
0
                             LIBRAW_PROGRESS_LOAD_RAW;
356
0
  }
357
0
}
358
359
int LibRaw::is_phaseone_compressed()
360
2.51k
{
361
2.51k
  return (load_raw == &LibRaw::phase_one_load_raw_c ||
362
2.44k
      load_raw == &LibRaw::phase_one_load_raw_s ||
363
2.44k
          load_raw == &LibRaw::phase_one_load_raw);
364
2.51k
}
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
1.42k
{
450
1.42k
  ushort real_max;
451
1.42k
  float auto_threshold;
452
453
1.42k
  if (O.adjust_maximum_thr < 0.00001)
454
0
    return LIBRAW_SUCCESS;
455
1.42k
  else if (O.adjust_maximum_thr > 0.99999)
456
0
    auto_threshold = LIBRAW_DEFAULT_ADJUST_MAXIMUM_THRESHOLD;
457
1.42k
  else
458
1.42k
    auto_threshold = O.adjust_maximum_thr;
459
460
1.42k
  real_max = C.data_maximum;
461
1.42k
  if (real_max > 0 && real_max < C.maximum &&
462
214
      real_max > C.maximum * auto_threshold)
463
29
  {
464
29
    C.maximum = real_max;
465
29
  }
466
1.42k
  return LIBRAW_SUCCESS;
467
1.42k
}
468
void LibRaw::adjust_bl()
469
2.18k
{
470
2.18k
  int clear_repeat = 0;
471
2.18k
  if (O.user_black >= 0)
472
0
  {
473
0
    C.black = O.user_black;
474
0
    clear_repeat = 1;
475
0
  }
476
10.9k
  for (int i = 0; i < 4; i++)
477
8.72k
    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
2.18k
  if (clear_repeat)
484
0
    C.cblack[4] = C.cblack[5] = 0;
485
486
  // Add common part to cblack[] early
487
2.18k
  if (imgdata.idata.filters > 1000 && (C.cblack[4] + 1) / 2 == 1 &&
488
13
      (C.cblack[5] + 1) / 2 == 1)
489
10
  {
490
10
    int clrs[4];
491
10
    int lastg = -1, gcnt = 0;
492
50
    for (int c = 0; c < 4; c++)
493
40
    {
494
40
      clrs[c] = FC(c / 2, c % 2);
495
40
      if (clrs[c] == 1)
496
15
      {
497
15
        gcnt++;
498
15
        lastg = c;
499
15
      }
500
40
    }
501
10
    if (gcnt > 1 && lastg >= 0)
502
6
      clrs[lastg] = 3;
503
50
    for (int c = 0; c < 4; c++)
504
40
      C.cblack[clrs[c]] +=
505
40
          C.cblack[6 + c / 2 % C.cblack[4] * C.cblack[5] + c % 2 % C.cblack[5]];
506
10
    C.cblack[4] = C.cblack[5] = 0;
507
    // imgdata.idata.filters = sfilters;
508
10
  }
509
2.17k
  else if (imgdata.idata.filters <= 1000 && C.cblack[4] == 1 &&
510
5
           C.cblack[5] == 1) // Fuji RAF dng
511
2
  {
512
10
    for (int c = 0; c < 4; c++)
513
8
      C.cblack[c] += C.cblack[6];
514
2
    C.cblack[4] = C.cblack[5] = 0;
515
2
  }
516
  // remove common part from C.cblack[]
517
2.18k
  int i = C.cblack[3];
518
2.18k
  int c;
519
8.72k
  for (c = 0; c < 3; c++)
520
6.54k
    if (i > (int)C.cblack[c])
521
86
      i = C.cblack[c];
522
523
10.9k
  for (c = 0; c < 4; c++)
524
8.72k
    C.cblack[c] -= i; // remove common part
525
2.18k
  C.black += i;
526
527
  // Now calculate common part for cblack[6+] part and move it to C.black
528
529
2.18k
  if (C.cblack[4] && C.cblack[5])
530
177
  {
531
177
    i = C.cblack[6];
532
59.3k
    for (c = 1; c < int(C.cblack[4] * C.cblack[5]); c++)
533
59.1k
      if (i > int(C.cblack[6 + c]))
534
708
        i = C.cblack[6 + c];
535
    // Remove i from cblack[6+]
536
177
    int nonz = 0;
537
59.5k
    for (c = 0; c < int(C.cblack[4] * C.cblack[5]); c++)
538
59.3k
    {
539
59.3k
      C.cblack[6 + c] -= i;
540
59.3k
      if (C.cblack[6 + c])
541
56.0k
        nonz++;
542
59.3k
    }
543
177
    C.black += i;
544
177
    if (!nonz)
545
4
      C.cblack[4] = C.cblack[5] = 0;
546
177
  }
547
10.9k
  for (c = 0; c < 4; c++)
548
8.72k
    C.cblack[c] += C.black;
549
2.18k
}
550
int LibRaw::getwords(char *line, char *words[], int maxwords, int maxlen)
551
6.91k
{
552
6.91k
  line[maxlen - 1] = 0;
553
6.91k
  unsigned char *p = (unsigned char*)line;
554
6.91k
  int nwords = 0;
555
556
9.08k
  while (1)
557
9.08k
  {
558
10.2k
    while (isspace(*p))
559
1.12k
      p++;
560
9.08k
    if (*p == '\0')
561
3.16k
      return nwords;
562
5.92k
    words[nwords++] = (char*)p;
563
97.9k
    while (!isspace(*p) && *p != '\0')
564
92.0k
      p++;
565
5.92k
    if (*p == '\0')
566
3.53k
      return nwords;
567
2.39k
    *p++ = '\0';
568
2.39k
    if (nwords >= maxwords)
569
219
      return nwords;
570
2.39k
  }
571
6.91k
}
572
int LibRaw::stread(char *buf, size_t len, LibRaw_abstract_datastream *fp)
573
58.6k
{
574
58.6k
  if (len > 0)
575
41.4k
  {
576
41.4k
    int r = fp->read(buf, len, 1);
577
41.4k
    buf[len - 1] = 0;
578
41.4k
    return r;
579
41.4k
  }
580
17.2k
  else
581
17.2k
    return 0;
582
58.6k
}
583
584
int LibRaw::find_ifd_by_offset(INT64 o)
585
1.28k
{
586
2.35k
    for(unsigned i = 0; i < libraw_internal_data.identify_data.tiff_nifds && i < LIBRAW_IFD_MAXCOUNT; i++)
587
2.16k
        if(tiff_ifd[i].offset == o)
588
1.09k
            return i;
589
187
    return -1;
590
1.28k
}
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
0
                         unsigned *tag_datalen, int *tag_dataunitlen) {
595
0
  uchar *pos = buf + *tag_offset;
596
0
  if ((((*tag_offset) + 12) > buf_len) || (*tag_offset < 0)) { // abnormal, tag buffer overrun
597
0
    return -1;
598
0
  }
599
0
  *tag_id      = sget2(pos); pos += 2;
600
0
  *tag_type    = sget2(pos); pos += 2;
601
0
  *tag_datalen = sget4(pos); pos += 4;
602
0
  *tag_dataunitlen = tagtype_dataunit_bytes[(*tag_type <= LIBRAW_EXIFTAG_TYPE_IFD8) ? *tag_type : 0];
603
0
  if ((*tag_datalen * (*tag_dataunitlen)) > 4) {
604
0
    *tag_dataoffset = sget4(pos) - save;
605
0
    if ((*tag_dataoffset + *tag_datalen) > buf_len) { // abnormal, tag data buffer overrun
606
0
      return -2;
607
0
    }
608
0
  } else *tag_dataoffset = *tag_offset + 8;
609
0
  *tag_offset += 12;
610
0
  return 0;
611
0
}
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.45k
{
646
1.45k
    char** buffers = (char**)calloc(sizeof(char*), buffer_count);
647
648
2.91k
    for (int i = 0; i < buffer_count; i++)
649
1.45k
    {
650
1.45k
        buffers[i] = (char*)calloc(buffer_size,1);
651
1.45k
    }
652
1.45k
    return buffers;
653
1.45k
}
654
655
void LibRaw::free_omp_buffers(char** buffers, int buffer_count)
656
1.45k
{
657
2.91k
    for (int i = 0; i < buffer_count; i++)
658
1.45k
        if(buffers[i])
659
1.45k
            free(buffers[i]);
660
1.45k
    free(buffers);
661
1.45k
}
662
663
void  LibRaw::libraw_swab(void *arr, int len)
664
1.42k
{
665
1.42k
#ifdef LIBRAW_OWN_SWAB
666
1.42k
  uint16_t *array = (uint16_t*)arr;
667
1.42k
  int bytes = len/2;
668
130k
  for(; bytes; --bytes)
669
128k
  {
670
128k
    *array = ((*array << 8) & 0xff00) | ((*array >> 8) & 0xff);
671
128k
    array++;
672
128k
  }
673
#else
674
  swab((char*)arr,(char*)arr,len);
675
#endif
676
677
1.42k
}
678
679
12.8k
checked_buffer_t::checked_buffer_t(short ord, int size) : _order(ord), storage(size + 64)
680
12.8k
{
681
12.8k
  _data = storage.data();
682
12.8k
  _len = size;
683
12.8k
}
684
444
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.21M
{
688
3.21M
  checkoffset(offset);
689
3.21M
  checkoffset(offset + 2);
690
3.21M
  return libraw_sget2_static(_order, _data + offset);
691
3.21M
}
692
void checked_buffer_t::checkoffset(int off)
693
27.1M
{
694
27.1M
  if (off >= _len || off < 0)
695
3.57k
    throw LIBRAW_EXCEPTION_IO_EOF;
696
27.1M
}
697
unsigned char checked_buffer_t::operator[](int idx)
698
0
{
699
0
  checkoffset(idx);
700
0
  return _data[idx];
701
0
}
702
unsigned checked_buffer_t::sget4(int offset)
703
240k
{
704
240k
  checkoffset(offset);
705
240k
  checkoffset(offset + 4);
706
240k
  return libraw_sget4_static(_order, _data + offset);
707
240k
}
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
34.3k
{
720
34.3k
  if ((((*tag_offset) + 12) > _len) || (*tag_offset < 0))
721
10.8k
  { // abnormal, tag buffer overrun
722
10.8k
    return -1;
723
10.8k
  }
724
23.4k
  int pos = int(*tag_offset);
725
23.4k
  *tag_id = sget2(pos);
726
23.4k
  pos += 2;
727
23.4k
  *tag_type = sget2(pos);
728
23.4k
  pos += 2;
729
23.4k
  *tag_datalen = sget4(pos);
730
23.4k
  pos += 4;
731
23.4k
  *tag_dataunitlen = libraw_tagtype_dataunit_bytes(*tag_type);
732
23.4k
  if ((*tag_datalen * (*tag_dataunitlen)) > 4)
733
23.4k
  {
734
23.4k
    *tag_dataoffset = sget4(pos) - save;
735
23.4k
    if ((*tag_dataoffset + *tag_datalen) > _len)
736
23.4k
    { // abnormal, tag data buffer overrun
737
23.4k
      return -2;
738
23.4k
    }
739
23.4k
  }
740
0
  else
741
0
    *tag_dataoffset = *tag_offset + 8;
742
10
  *tag_offset += 12;
743
10
  return 0;
744
23.4k
}
745