Coverage Report

Created: 2026-02-14 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/LibRaw/src/utils/open.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_cameraids.h"
18
19
#ifndef LIBRAW_NO_IOSTREAMS_DATASTREAM
20
int LibRaw::open_file(const char *fname, INT64 max_buf_size)
21
{
22
  int big = 0;
23
  if (max_buf_size == LIBRAW_OPEN_BIGFILE)
24
    big = 1;
25
  else if (max_buf_size == LIBRAW_OPEN_FILE)
26
    big = 0;
27
  else
28
  {
29
#ifndef LIBRAW_WIN32_CALLS
30
    struct stat st;
31
    if (stat(fname, &st))
32
      return LIBRAW_IO_ERROR;
33
    big = (st.st_size > max_buf_size) ? 1 : 0;
34
#else
35
    struct _stati64 st;
36
    if (_stati64(fname, &st))
37
      return LIBRAW_IO_ERROR;
38
    big = (st.st_size > max_buf_size) ? 1 : 0;
39
#endif
40
  }
41
42
  LibRaw_abstract_datastream *stream;
43
  try
44
  {
45
    if (big)
46
      stream = new LibRaw_bigfile_datastream(fname);
47
    else
48
      stream = new LibRaw_file_datastream(fname);
49
  }
50
51
  catch (const std::bad_alloc& )
52
  {
53
    recycle();
54
    return LIBRAW_UNSUFFICIENT_MEMORY;
55
  }
56
  if (!stream->valid())
57
  {
58
    delete stream;
59
    return LIBRAW_IO_ERROR;
60
  }
61
  ID.input_internal = 0; // preserve from deletion on error
62
  int ret = open_datastream(stream);
63
  if (ret == LIBRAW_SUCCESS)
64
  {
65
    ID.input_internal = 1; // flag to delete datastream on recycle
66
  }
67
  else
68
  {
69
    delete stream;
70
    ID.input_internal = 0;
71
  }
72
  return ret;
73
}
74
75
#if defined(WIN32) || defined(_WIN32)
76
#ifndef LIBRAW_WIN32_UNICODEPATHS
77
int LibRaw::open_file(const wchar_t *, INT64)
78
{
79
  return LIBRAW_NOT_IMPLEMENTED;
80
}
81
#else
82
int LibRaw::open_file(const wchar_t *fname, INT64 max_buf_size)
83
{
84
  int big = 0;
85
  if (max_buf_size == LIBRAW_OPEN_BIGFILE)
86
    big = 1;
87
  else if (max_buf_size == LIBRAW_OPEN_FILE)
88
    big = 0;
89
  else
90
  {
91
    struct _stati64 st;
92
    if (_wstati64(fname, &st))
93
      return LIBRAW_IO_ERROR;
94
    big = (st.st_size > max_buf_size) ? 1 : 0;
95
  }
96
97
  LibRaw_abstract_datastream *stream;
98
  try
99
  {
100
    if (big)
101
      stream = new LibRaw_bigfile_datastream(fname);
102
    else
103
      stream = new LibRaw_file_datastream(fname);
104
  }
105
106
  catch (const std::bad_alloc&)
107
  {
108
    recycle();
109
    return LIBRAW_UNSUFFICIENT_MEMORY;
110
  }
111
  if (!stream->valid())
112
  {
113
    delete stream;
114
    return LIBRAW_IO_ERROR;
115
  }
116
  ID.input_internal = 0; // preserve from deletion on error
117
  int ret = open_datastream(stream);
118
  if (ret == LIBRAW_SUCCESS)
119
  {
120
    ID.input_internal = 1; // flag to delete datastream on recycle
121
  }
122
  else
123
  {
124
    delete stream;
125
    ID.input_internal = 0;
126
  }
127
  return ret;
128
}
129
#endif
130
#endif
131
132
#else /* LIBRAW_NO_IOSTREAMS_DATASTREAM*/
133
134
int LibRaw::libraw_openfile_tail(LibRaw_abstract_datastream *stream)
135
0
{
136
0
    if (!stream->valid())
137
0
    {
138
0
        delete stream;
139
0
        return LIBRAW_IO_ERROR;
140
0
    }
141
0
    ID.input_internal = 0; // preserve from deletion on error
142
0
    int ret = open_datastream(stream);
143
0
    if (ret == LIBRAW_SUCCESS)
144
0
    {
145
0
        ID.input_internal = 1; // flag to delete datastream on recycle
146
0
    }
147
0
    else
148
0
    {
149
0
        delete stream;
150
0
        ID.input_internal = 0;
151
0
    }
152
0
    return ret;
153
0
}
154
155
int LibRaw::open_file(const char *fname)
156
0
{
157
0
    LibRaw_abstract_datastream *stream;
158
0
    try
159
0
    {
160
#ifdef LIBRAW_WIN32_CALLS
161
        stream = new LibRaw_bigfile_buffered_datastream(fname);
162
#else
163
0
        stream = new LibRaw_bigfile_datastream(fname);
164
0
#endif
165
0
    }
166
0
    catch (const std::bad_alloc&)
167
0
    {
168
0
        recycle();
169
0
        return LIBRAW_UNSUFFICIENT_MEMORY;
170
0
    }
171
0
    if ((stream->size() > (INT64)LIBRAW_MAX_NONDNG_RAW_FILE_SIZE) 
172
0
    && (stream->size() > (INT64)LIBRAW_MAX_DNG_RAW_FILE_SIZE)
173
0
    && (stream->size() > (INT64)LIBRAW_MAX_CR3_RAW_FILE_SIZE)
174
0
    )
175
0
    {
176
0
      delete stream;
177
0
      return LIBRAW_TOO_BIG;
178
0
    }
179
0
    return libraw_openfile_tail(stream);
180
0
}
181
182
#if defined(WIN32) || defined(_WIN32)
183
#ifndef LIBRAW_WIN32_UNICODEPATHS
184
int LibRaw::open_file(const wchar_t *)
185
{
186
    return LIBRAW_NOT_IMPLEMENTED;
187
}
188
#else
189
int LibRaw::open_file(const wchar_t *fname)
190
{
191
    LibRaw_abstract_datastream *stream;
192
    try
193
    {
194
#ifdef LIBRAW_WIN32_CALLS
195
        stream = new LibRaw_bigfile_buffered_datastream(fname);
196
#else
197
        stream = new LibRaw_bigfile_datastream(fname);
198
#endif
199
    }
200
    catch (const std::bad_alloc&)
201
    {
202
        recycle();
203
        return LIBRAW_UNSUFFICIENT_MEMORY;
204
    }
205
    if ((stream->size() > (INT64)LIBRAW_MAX_DNG_RAW_FILE_SIZE) 
206
    && (stream->size() > (INT64)LIBRAW_MAX_NONDNG_RAW_FILE_SIZE) &&
207
        (stream->size() > (INT64)LIBRAW_MAX_CR3_RAW_FILE_SIZE)
208
    )
209
    {
210
      delete stream;
211
      return LIBRAW_TOO_BIG;
212
    }
213
214
    return libraw_openfile_tail(stream);
215
}
216
#endif
217
#endif
218
219
#endif
220
221
int LibRaw::open_buffer(const void *buffer, size_t size)
222
0
{
223
  // this stream will close on recycle()
224
0
  if (!buffer || buffer == (const void *)-1)
225
0
    return LIBRAW_IO_ERROR;
226
227
0
  if ((size > (INT64)LIBRAW_MAX_DNG_RAW_FILE_SIZE) 
228
0
    && (size > (INT64)LIBRAW_MAX_NONDNG_RAW_FILE_SIZE)
229
0
        && (size > (INT64)LIBRAW_MAX_CR3_RAW_FILE_SIZE)
230
0
    )
231
0
      return LIBRAW_TOO_BIG;
232
233
0
  LibRaw_buffer_datastream *stream;
234
0
  try
235
0
  {
236
0
    stream = new LibRaw_buffer_datastream(buffer, size);
237
0
  }
238
0
  catch (const std::bad_alloc& )
239
0
  {
240
0
    recycle();
241
0
    return LIBRAW_UNSUFFICIENT_MEMORY;
242
0
  }
243
0
  if (!stream->valid())
244
0
  {
245
0
    delete stream;
246
0
    return LIBRAW_IO_ERROR;
247
0
  }
248
0
  ID.input_internal = 0; // preserve from deletion on error
249
0
  int ret = open_datastream(stream);
250
0
  if (ret == LIBRAW_SUCCESS)
251
0
  {
252
0
    ID.input_internal = 1; // flag to delete datastream on recycle
253
0
  }
254
0
  else
255
0
  {
256
0
    delete stream;
257
0
    ID.input_internal = 0;
258
0
  }
259
0
  return ret;
260
0
}
261
262
int LibRaw::open_bayer(const unsigned char *buffer, unsigned datalen,
263
                       ushort _raw_width, ushort _raw_height,
264
                       ushort _left_margin, ushort _top_margin,
265
                       ushort _right_margin, ushort _bottom_margin,
266
                       unsigned char procflags, unsigned char bayer_pattern,
267
                       unsigned unused_bits, unsigned otherflags,
268
                       unsigned black_level)
269
0
{
270
  // this stream will close on recycle()
271
0
  if (!buffer || buffer == (const void *)-1)
272
0
    return LIBRAW_IO_ERROR;
273
274
0
  LibRaw_buffer_datastream *stream;
275
0
  try
276
0
  {
277
0
    stream = new LibRaw_buffer_datastream(buffer, datalen);
278
0
  }
279
0
  catch (const std::bad_alloc& )
280
0
  {
281
0
    recycle();
282
0
    return LIBRAW_UNSUFFICIENT_MEMORY;
283
0
  }
284
0
  if (!stream->valid())
285
0
  {
286
0
    delete stream;
287
0
    return LIBRAW_IO_ERROR;
288
0
  }
289
0
  ID.input = stream;
290
0
  SET_PROC_FLAG(LIBRAW_PROGRESS_OPEN);
291
  // From identify
292
0
  initdata();
293
0
  strcpy(imgdata.idata.make, "BayerDump");
294
0
  snprintf(imgdata.idata.model, sizeof(imgdata.idata.model) - 1,
295
0
           "%u x %u pixels", _raw_width, _raw_height);
296
0
  S.flip = procflags >> 2;
297
0
  libraw_internal_data.internal_output_params.zero_is_bad = procflags & 2;
298
0
  libraw_internal_data.unpacker_data.data_offset = 0;
299
0
  S.raw_width = _raw_width;
300
0
  S.raw_height = _raw_height;
301
0
  S.left_margin = _left_margin;
302
0
  S.top_margin = _top_margin;
303
0
  S.width = S.raw_width - S.left_margin - _right_margin;
304
0
  S.height = S.raw_height - S.top_margin - _bottom_margin;
305
306
0
  imgdata.idata.filters = 0x1010101 * bayer_pattern;
307
0
  imgdata.idata.colors =
308
0
      4 - !((imgdata.idata.filters & imgdata.idata.filters >> 1) & 0x5555);
309
0
  libraw_internal_data.unpacker_data.load_flags = otherflags;
310
0
  switch (libraw_internal_data.unpacker_data.tiff_bps =
311
0
              (datalen)*8 / (S.raw_width * S.raw_height))
312
0
  {
313
0
  case 8:
314
0
    load_raw = &LibRaw::eight_bit_load_raw;
315
0
    break;
316
0
  case 10:
317
0
    if ((datalen) / S.raw_height * 3u >= S.raw_width * 4u)
318
0
    {
319
0
      load_raw = &LibRaw::android_loose_load_raw;
320
0
      break;
321
0
    }
322
0
    else if (libraw_internal_data.unpacker_data.load_flags & 1)
323
0
    {
324
0
      load_raw = &LibRaw::android_tight_load_raw;
325
0
      break;
326
0
    }
327
0
  case 12:
328
0
    libraw_internal_data.unpacker_data.load_flags |= 128;
329
0
    load_raw = &LibRaw::packed_load_raw;
330
0
    break;
331
0
  case 16:
332
0
    libraw_internal_data.unpacker_data.order =
333
0
        0x4949 | 0x404 * (libraw_internal_data.unpacker_data.load_flags & 1);
334
0
    libraw_internal_data.unpacker_data.tiff_bps -=
335
0
        libraw_internal_data.unpacker_data.load_flags >> 4;
336
0
    libraw_internal_data.unpacker_data.tiff_bps -=
337
0
        libraw_internal_data.unpacker_data.load_flags =
338
0
            libraw_internal_data.unpacker_data.load_flags >> 1 & 7;
339
0
    load_raw = &LibRaw::unpacked_load_raw;
340
0
  }
341
0
  C.maximum =
342
0
      (1 << libraw_internal_data.unpacker_data.tiff_bps) - (1 << unused_bits);
343
0
  C.black = black_level;
344
0
  S.iwidth = S.width;
345
0
  S.iheight = S.height;
346
0
  imgdata.idata.colors = 3;
347
0
  imgdata.idata.filters |= ((imgdata.idata.filters >> 2 & 0x22222222) |
348
0
                            (imgdata.idata.filters << 2 & 0x88888888)) &
349
0
                           imgdata.idata.filters << 1;
350
351
0
  imgdata.idata.raw_count = 1;
352
0
  for (int i = 0; i < 4; i++)
353
0
    imgdata.color.pre_mul[i] = 1.0;
354
355
0
  strcpy(imgdata.idata.cdesc, "RGBG");
356
357
0
  ID.input_internal = 1;
358
0
  SET_PROC_FLAG(LIBRAW_PROGRESS_IDENTIFY);
359
0
  return LIBRAW_SUCCESS;
360
0
}
361
362
struct foveon_data_t
363
{
364
  const char *make;
365
  const char *model;
366
  const int raw_width, raw_height;
367
  const int white;
368
  const int left_margin, top_margin;
369
  const int width, height;
370
} foveon_data[] = {
371
    {"Sigma", "SD9", 2304, 1531, 12000, 20, 8, 2266, 1510},
372
    {"Sigma", "SD9", 1152, 763, 12000, 10, 2, 1132, 755},
373
    {"Sigma", "SD10", 2304, 1531, 12000, 20, 8, 2266, 1510},
374
    {"Sigma", "SD10", 1152, 763, 12000, 10, 2, 1132, 755},
375
    {"Sigma", "SD14", 2688, 1792, 14000, 18, 12, 2651, 1767},
376
    {"Sigma", "SD14", 2688, 896, 14000, 18, 6, 2651, 883}, // 2/3
377
    {"Sigma", "SD14", 1344, 896, 14000, 9, 6, 1326, 883},  // 1/2
378
    {"Sigma", "SD15", 2688, 1792, 2900, 18, 12, 2651, 1767},
379
    {"Sigma", "SD15", 2688, 896, 2900, 18, 6, 2651, 883}, // 2/3 ?
380
    {"Sigma", "SD15", 1344, 896, 2900, 9, 6, 1326, 883},  // 1/2 ?
381
    {"Sigma", "DP1", 2688, 1792, 2100, 18, 12, 2651, 1767},
382
    {"Sigma", "DP1", 2688, 896, 2100, 18, 6, 2651, 883}, // 2/3 ?
383
    {"Sigma", "DP1", 1344, 896, 2100, 9, 6, 1326, 883},  // 1/2 ?
384
    {"Sigma", "DP1S", 2688, 1792, 2200, 18, 12, 2651, 1767},
385
    {"Sigma", "DP1S", 2688, 896, 2200, 18, 6, 2651, 883}, // 2/3
386
    {"Sigma", "DP1S", 1344, 896, 2200, 9, 6, 1326, 883},  // 1/2
387
    {"Sigma", "DP1X", 2688, 1792, 3560, 18, 12, 2651, 1767},
388
    {"Sigma", "DP1X", 2688, 896, 3560, 18, 6, 2651, 883}, // 2/3
389
    {"Sigma", "DP1X", 1344, 896, 3560, 9, 6, 1326, 883},  // 1/2
390
    {"Sigma", "DP2", 2688, 1792, 2326, 13, 16, 2651, 1767},
391
    {"Sigma", "DP2", 2688, 896, 2326, 13, 8, 2651, 883}, // 2/3 ??
392
    {"Sigma", "DP2", 1344, 896, 2326, 7, 8, 1325, 883},  // 1/2 ??
393
    {"Sigma", "DP2S", 2688, 1792, 2300, 18, 12, 2651, 1767},
394
    {"Sigma", "DP2S", 2688, 896, 2300, 18, 6, 2651, 883}, // 2/3
395
    {"Sigma", "DP2S", 1344, 896, 2300, 9, 6, 1326, 883},  // 1/2
396
    {"Sigma", "DP2X", 2688, 1792, 2300, 18, 12, 2651, 1767},
397
    {"Sigma", "DP2X", 2688, 896, 2300, 18, 6, 2651, 883},           // 2/3
398
    {"Sigma", "DP2X", 1344, 896, 2300, 9, 6, 1325, 883},            // 1/2
399
    {"Sigma", "SD1", 4928, 3264, 3900, 12, 52, 4807, 3205},         // Full size
400
    {"Sigma", "SD1", 4928, 1632, 3900, 12, 26, 4807, 1603},         // 2/3 size
401
    {"Sigma", "SD1", 2464, 1632, 3900, 6, 26, 2403, 1603},          // 1/2 size
402
    {"Sigma", "SD1 Merrill", 4928, 3264, 3900, 12, 52, 4807, 3205}, // Full size
403
    {"Sigma", "SD1 Merrill", 4928, 1632, 3900, 12, 26, 4807, 1603}, // 2/3 size
404
    {"Sigma", "SD1 Merrill", 2464, 1632, 3900, 6, 26, 2403, 1603},  // 1/2 size
405
    {"Sigma", "DP1 Merrill", 4928, 3264, 3900, 12, 0, 4807, 3205},
406
    {"Sigma", "DP1 Merrill", 2464, 1632, 3900, 12, 0, 2403, 1603}, // 1/2 size
407
    {"Sigma", "DP1 Merrill", 4928, 1632, 3900, 12, 0, 4807, 1603}, // 2/3 size
408
    {"Sigma", "DP2 Merrill", 4928, 3264, 3900, 12, 0, 4807, 3205},
409
    {"Sigma", "DP2 Merrill", 2464, 1632, 3900, 12, 0, 2403, 1603}, // 1/2 size
410
    {"Sigma", "DP2 Merrill", 4928, 1632, 3900, 12, 0, 4807, 1603}, // 2/3 size
411
    {"Sigma", "DP3 Merrill", 4928, 3264, 3900, 12, 0, 4807, 3205},
412
    {"Sigma", "DP3 Merrill", 2464, 1632, 3900, 12, 0, 2403, 1603}, // 1/2 size
413
    {"Sigma", "DP3 Merrill", 4928, 1632, 3900, 12, 0, 4807, 1603}, // 2/3 size
414
    {"Polaroid", "x530", 1440, 1088, 2700, 10, 13, 1419, 1059},
415
    // dp2 Q
416
    {"Sigma", "dp3 Quattro", 5888, 3776, 16383, 204, 76, 5446,
417
     3624}, // full size, new fw ??
418
    {"Sigma", "dp3 Quattro", 5888, 3672, 16383, 204, 24, 5446,
419
     3624}, // full size
420
    {"Sigma", "dp3 Quattro", 2944, 1836, 16383, 102, 12, 2723,
421
     1812}, // half size
422
    {"Sigma", "dp3 Quattro", 2944, 1888, 16383, 102, 38, 2723,
423
     1812}, // half size, new fw??
424
425
    {"Sigma", "dp2 Quattro", 5888, 3776, 16383, 204, 76, 5446,
426
     3624}, // full size, new fw
427
    {"Sigma", "dp2 Quattro", 5888, 3672, 16383, 204, 24, 5446,
428
     3624}, // full size
429
    {"Sigma", "dp2 Quattro", 2944, 1836, 16383, 102, 12, 2723,
430
     1812}, // half size
431
    {"Sigma", "dp2 Quattro", 2944, 1888, 16383, 102, 38, 2723,
432
     1812}, // half size, new fw
433
434
    {"Sigma", "dp1 Quattro", 5888, 3776, 16383, 204, 76, 5446,
435
     3624}, // full size, new fw??
436
    {"Sigma", "dp1 Quattro", 5888, 3672, 16383, 204, 24, 5446,
437
     3624}, // full size
438
    {"Sigma", "dp1 Quattro", 2944, 1836, 16383, 102, 12, 2723,
439
     1812}, // half size
440
    {"Sigma", "dp1 Quattro", 2944, 1888, 16383, 102, 38, 2723,
441
     1812}, // half size, new fw
442
443
    {"Sigma", "dp0 Quattro", 5888, 3776, 16383, 204, 76, 5446,
444
     3624}, // full size, new fw??
445
    {"Sigma", "dp0 Quattro", 5888, 3672, 16383, 204, 24, 5446,
446
     3624}, // full size
447
    {"Sigma", "dp0 Quattro", 2944, 1836, 16383, 102, 12, 2723,
448
     1812}, // half size
449
    {"Sigma", "dp0 Quattro", 2944, 1888, 16383, 102, 38, 2723,
450
     1812}, // half size, new fw
451
    // Sigma sd Quattro
452
    {"Sigma", "sd Quattro", 5888, 3776, 16383, 204, 76, 5446,
453
     3624}, // full size
454
    {"Sigma", "sd Quattro", 2944, 1888, 16383, 102, 38, 2723,
455
     1812}, // half size
456
    // Sd Quattro H
457
    {"Sigma", "sd Quattro H", 6656, 4480, 4000, 224, 160, 6208,
458
     4160}, // full size
459
    {"Sigma", "sd Quattro H", 3328, 2240, 4000, 112, 80, 3104,
460
     2080},                                                        // half size
461
    {"Sigma", "sd Quattro H", 5504, 3680, 4000, 0, 4, 5496, 3668}, // full size
462
    {"Sigma", "sd Quattro H", 2752, 1840, 4000, 0, 2, 2748, 1834}, // half size
463
};
464
const int foveon_count = sizeof(foveon_data) / sizeof(foveon_data[0]);
465
466
int LibRaw::open_datastream(LibRaw_abstract_datastream *stream)
467
31.8k
{
468
469
31.8k
  if (!stream)
470
0
    return ENOENT;
471
31.8k
  if (!stream->valid())
472
0
    return LIBRAW_IO_ERROR;
473
31.8k
  if ((stream->size() > (INT64)LIBRAW_MAX_DNG_RAW_FILE_SIZE) 
474
0
    && (stream->size() > (INT64)LIBRAW_MAX_NONDNG_RAW_FILE_SIZE) &&
475
0
      (stream->size() > (INT64)LIBRAW_MAX_CR3_RAW_FILE_SIZE)
476
31.8k
    )
477
0
      return LIBRAW_TOO_BIG;
478
479
31.8k
  recycle();
480
31.8k
  if (callbacks.pre_identify_cb)
481
0
  {
482
0
    int r = (callbacks.pre_identify_cb)(this);
483
0
    if (r == 1)
484
0
      goto final;
485
0
  }
486
487
31.8k
  try
488
31.8k
  {
489
31.8k
    ID.input = stream;
490
31.8k
    SET_PROC_FLAG(LIBRAW_PROGRESS_OPEN);
491
492
31.8k
    identify();
493
494
    // Fuji layout files: either DNG or unpacked_load_raw should be used
495
31.8k
    if (libraw_internal_data.internal_output_params.fuji_width || libraw_internal_data.unpacker_data.fuji_layout)
496
86
    {
497
86
      if (!imgdata.idata.dng_version && load_raw != &LibRaw::unpacked_load_raw
498
6
        && load_raw != &LibRaw::unpacked_load_raw_FujiDBP
499
6
        && load_raw != &LibRaw::unpacked_load_raw_fuji_f700s20
500
86
        )
501
6
        return LIBRAW_FILE_UNSUPPORTED;
502
86
    }
503
    // Remove unsupported Nikon thumbnails
504
31.7k
    if (makeIs(LIBRAW_CAMERAMAKER_Nikon) &&
505
608
      (!strncasecmp(imgdata.idata.model, "Z 8", 3) || !strcasecmp(imgdata.idata.model, "Z f")
506
588
        || !strncasecmp(imgdata.idata.model, "Z6_3", 4))
507
22
      &&
508
22
      imgdata.thumbs_list.thumbcount > 1)
509
8
    {
510
8
      int tgtidx = 0;
511
24
      for (int idx = 0; idx < imgdata.thumbs_list.thumbcount && idx < LIBRAW_THUMBNAIL_MAXCOUNT; idx++)
512
16
      {
513
16
        int bps = imgdata.thumbs_list.thumblist[idx].tmisc & 0x1f;
514
16
        if (bps > 8) // remove high-bit thumbs
515
8
        {
516
          // nothing: just skip this item
517
8
        }
518
8
        else
519
8
        {
520
8
          if (tgtidx < idx)
521
0
          {
522
0
            memmove(&imgdata.thumbs_list.thumblist[tgtidx], &imgdata.thumbs_list.thumblist[idx],
523
0
              sizeof(imgdata.thumbs_list.thumblist[idx]));
524
0
            tgtidx++;
525
0
          }
526
8
          else // same index, just assign next tgtidx
527
8
            tgtidx = idx + 1;
528
8
        }
529
16
      }
530
8
      if (tgtidx > 0 && tgtidx < imgdata.thumbs_list.thumbcount)
531
0
      {
532
0
        int selidx = 0;
533
0
        INT64 maximgbits = INT64(imgdata.thumbs_list.thumblist[0].twidth) *
534
0
          INT64(imgdata.thumbs_list.thumblist[0].theight) * INT64(imgdata.thumbs_list.thumblist[0].tmisc & 0x1f);
535
0
        for (int i = 1; i < tgtidx; i++)
536
0
        {
537
0
          INT64 imgbits = INT64(imgdata.thumbs_list.thumblist[i].twidth) *
538
0
            INT64(imgdata.thumbs_list.thumblist[i].theight) *
539
0
            INT64(imgdata.thumbs_list.thumblist[i].tmisc & 0x1f);
540
0
          if (imgbits > maximgbits)
541
0
          {
542
0
            selidx = i;
543
0
            maximgbits = imgbits;
544
0
          }
545
0
        }
546
0
        libraw_internal_data.internal_data.toffset = imgdata.thumbs_list.thumblist[selidx].toffset;
547
0
        imgdata.thumbnail.tlength = imgdata.thumbs_list.thumblist[selidx].tlength;
548
0
        libraw_internal_data.unpacker_data.thumb_format = imgdata.thumbs_list.thumblist[selidx].tformat;
549
0
        imgdata.thumbnail.twidth = imgdata.thumbs_list.thumblist[selidx].twidth;
550
0
        imgdata.thumbnail.theight = imgdata.thumbs_list.thumblist[selidx].theight;
551
0
        libraw_internal_data.unpacker_data.thumb_misc = imgdata.thumbs_list.thumblist[selidx].tmisc;
552
        // find another largest thumb and copy it to single thumbnail data
553
0
      }
554
8
      imgdata.thumbs_list.thumbcount = tgtidx > 0 ? tgtidx : 1;
555
8
    }
556
557
    // promote the old single thumbnail to the thumbs_list if not present already
558
31.7k
    if (imgdata.thumbs_list.thumbcount < LIBRAW_THUMBNAIL_MAXCOUNT)
559
18.7k
    {
560
18.7k
      bool already = false;
561
18.7k
      if (imgdata.thumbnail.tlength || libraw_internal_data.internal_data.toffset)
562
2.42k
        for (int i = 0; i < imgdata.thumbs_list.thumbcount; i++)
563
366
          if (imgdata.thumbs_list.thumblist[i].toffset == libraw_internal_data.internal_data.toffset
564
316
            && imgdata.thumbs_list.thumblist[i].tlength == imgdata.thumbnail.tlength)
565
310
          {
566
310
            already = true;
567
310
            break;
568
310
          }
569
18.7k
      if (!already)
570
18.4k
      {
571
18.4k
        int idx = imgdata.thumbs_list.thumbcount;
572
18.4k
        imgdata.thumbs_list.thumblist[idx].toffset = libraw_internal_data.internal_data.toffset;
573
18.4k
        imgdata.thumbs_list.thumblist[idx].tlength = imgdata.thumbnail.tlength;
574
18.4k
        imgdata.thumbs_list.thumblist[idx].tflip = 0xffff;
575
18.4k
        imgdata.thumbs_list.thumblist[idx].tformat = libraw_internal_data.unpacker_data.thumb_format;
576
18.4k
        imgdata.thumbs_list.thumblist[idx].tmisc = libraw_internal_data.unpacker_data.thumb_misc;
577
        // promote if set
578
18.4k
        imgdata.thumbs_list.thumblist[idx].twidth = imgdata.thumbnail.twidth;
579
18.4k
        imgdata.thumbs_list.thumblist[idx].theight = imgdata.thumbnail.theight;
580
18.4k
        imgdata.thumbs_list.thumbcount++;
581
18.4k
      }
582
18.7k
    }
583
584
585
31.7k
    imgdata.lens.Lens[sizeof(imgdata.lens.Lens) - 1] = 0; // make sure lens is 0-terminated
586
587
31.7k
    if (callbacks.post_identify_cb)
588
0
      (callbacks.post_identify_cb)(this);
589
590
31.7k
#define isRIC imgdata.sizes.raw_inset_crops[0]
591
592
31.7k
    if (!imgdata.idata.dng_version && makeIs(LIBRAW_CAMERAMAKER_Fujifilm)
593
1.40k
      && (!strcmp(imgdata.idata.normalized_model, "S3Pro")
594
1.40k
        || !strcmp(imgdata.idata.normalized_model, "S5Pro")
595
1.40k
        || !strcmp(imgdata.idata.normalized_model, "S2Pro")))
596
14
    {
597
14
      isRIC.cleft = isRIC.ctop = 0xffff;
598
14
      isRIC.cwidth = isRIC.cheight = 0;
599
14
    }
600
    // Wipe out canon  incorrect in-camera crop
601
31.7k
    if (!imgdata.idata.dng_version && makeIs(LIBRAW_CAMERAMAKER_Canon)
602
1.26k
      && isRIC.cleft == 0 && isRIC.ctop == 0 // non symmetric!
603
8
      && isRIC.cwidth < (imgdata.sizes.raw_width * 4 / 5))  // less than 80% of sensor width
604
2
    {
605
2
      isRIC.cleft = isRIC.ctop = 0xffff;
606
2
      isRIC.cwidth = isRIC.cheight = 0;
607
2
    }
608
609
    // Wipe out non-standard WB
610
31.7k
    if (!imgdata.idata.dng_version &&
611
15.1k
      (makeIs(LIBRAW_CAMERAMAKER_Sony) && !strcmp(imgdata.idata.normalized_model, "DSC-F828"))
612
38
      && !(imgdata.rawparams.options & LIBRAW_RAWOPTIONS_PROVIDE_NONSTANDARD_WB))
613
38
    {
614
190
      for (int i = 0; i < 4; i++) imgdata.color.cam_mul[i] = (i == 1);
615
38
      memset(imgdata.color.WB_Coeffs, 0, sizeof(imgdata.color.WB_Coeffs));
616
38
      memset(imgdata.color.WBCT_Coeffs, 0, sizeof(imgdata.color.WBCT_Coeffs));
617
38
    }
618
619
31.7k
    if (load_raw == &LibRaw::nikon_load_raw)
620
246
      nikon_read_curve();
621
622
31.7k
    if (load_raw == &LibRaw::lossless_jpeg_load_raw &&
623
1.15k
      MN.canon.RecordMode && makeIs(LIBRAW_CAMERAMAKER_Kodak) &&
624
      /* Not normalized models here, it is intentional */
625
4
      (!strncasecmp(imgdata.idata.model, "EOS D2000", 9) || // if we want something different for B&W cameras,
626
4
        !strncasecmp(imgdata.idata.model, "EOS D6000", 9)))  // it's better to compare with CamIDs
627
2
    {
628
2
      imgdata.color.black = 0;
629
2
      imgdata.color.maximum = 4501;
630
2
      memset(imgdata.color.cblack, 0, sizeof(imgdata.color.cblack));
631
2
      memset(imgdata.sizes.mask, 0, sizeof(imgdata.sizes.mask));
632
2
      imgdata.sizes.mask[0][3] = 1; // to skip mask re-calc
633
2
      libraw_internal_data.unpacker_data.load_flags |= 512;
634
2
    }
635
636
31.7k
    if (load_raw == &LibRaw::panasonic_load_raw)
637
86
    {
638
86
      if (libraw_internal_data.unpacker_data.pana_encoding == 6 ||
639
86
        libraw_internal_data.unpacker_data.pana_encoding == 7 ||
640
86
        libraw_internal_data.unpacker_data.pana_encoding == 8)
641
0
      {
642
0
        for (int i = 0; i < 3; i++)
643
0
          imgdata.color.cblack[i] =
644
0
          libraw_internal_data.internal_data.pana_black[i];
645
0
        imgdata.color.cblack[3] = imgdata.color.cblack[1];
646
0
        imgdata.color.cblack[4] = imgdata.color.cblack[5] = 0;
647
0
        imgdata.color.black = 0;
648
0
        imgdata.color.maximum =
649
0
          MAX(imgdata.color.linear_max[0],
650
0
            MAX(imgdata.color.linear_max[1], imgdata.color.linear_max[2]));
651
0
      }
652
653
86
      if (libraw_internal_data.unpacker_data.pana_encoding == 6)
654
0
      {
655
0
        int rowbytes11 = imgdata.sizes.raw_width / 11 * 16;
656
0
        int rowbytes14 = imgdata.sizes.raw_width / 14 * 16;
657
0
        INT64 ds = INT64(libraw_internal_data.unpacker_data.data_size);
658
0
        if (!ds)
659
0
          ds = libraw_internal_data.internal_data.input->size() - libraw_internal_data.unpacker_data.data_offset;
660
0
        if ((imgdata.sizes.raw_width % 11) == 0 &&
661
0
          (INT64(imgdata.sizes.raw_height) * rowbytes11 == ds))
662
0
          load_raw = &LibRaw::panasonicC6_load_raw;
663
0
        else if ((imgdata.sizes.raw_width % 14) == 0 &&
664
0
          (INT64(imgdata.sizes.raw_height) * rowbytes14 == ds))
665
0
          load_raw = &LibRaw::panasonicC6_load_raw;
666
0
        else
667
0
          imgdata.idata.raw_count = 0; // incorrect size
668
0
      }
669
86
      else if (libraw_internal_data.unpacker_data.pana_encoding == 7)
670
0
      {
671
0
        int pixperblock =
672
0
          libraw_internal_data.unpacker_data.pana_bpp == 14 ? 9 : 10;
673
0
        int rowbytes = imgdata.sizes.raw_width / pixperblock * 16;
674
0
        if ((imgdata.sizes.raw_width % pixperblock) == 0 &&
675
0
          (INT64(imgdata.sizes.raw_height) * rowbytes ==
676
0
            INT64(libraw_internal_data.unpacker_data.data_size)))
677
0
          load_raw = &LibRaw::panasonicC7_load_raw;
678
0
        else
679
0
          imgdata.idata.raw_count = 0; // incorrect size
680
0
      }
681
86
      else if (libraw_internal_data.unpacker_data.pana_encoding == 8)
682
0
      {
683
0
        if (libraw_internal_data.unpacker_data.pana8.stripe_count > 0)
684
0
          load_raw = &LibRaw::panasonicC8_load_raw;
685
0
        else
686
0
          imgdata.idata.raw_count = 0; // incorrect stripes count
687
0
      }
688
86
    }
689
690
31.7k
#define NIKON_14BIT_SIZE(rw, rh)                                               \
691
31.7k
  (((unsigned)(ceilf((float)(rw * 7 / 4) / 16.f)) * 16) * rh)
692
693
31.7k
#define NIKON_14BIT_SIZE3COLOR(rw, rh) ( ceilf(float(rw * 21 / 4)/16.f) * 16 * rh)
694
695
    // Ugly hack, replace with proper data/line size for different
696
    // cameras/format when available
697
31.7k
    if (makeIs(LIBRAW_CAMERAMAKER_Nikon)
698
608
      && (!strncasecmp(imgdata.idata.model, "Z", 1) || !strcasecmp(imgdata.idata.model, "D6"))
699
31.7k
      )
700
32
    {
701
32
      if (NIKON_14BIT_SIZE(imgdata.sizes.raw_width, imgdata.sizes.raw_height) ==
702
32
        libraw_internal_data.unpacker_data.data_size)
703
12
      {
704
12
        load_raw = &LibRaw::nikon_14bit_load_raw;
705
12
      }
706
32
          if (NIKON_14BIT_SIZE3COLOR(imgdata.sizes.raw_width, imgdata.sizes.raw_height) ==
707
32
              libraw_internal_data.unpacker_data.data_size)
708
12
          {
709
12
            load_raw = &LibRaw::nikon_14bit_load_raw;
710
12
      imgdata.idata.filters = 0; // 3-color nefx image
711
12
          }
712
32
    }
713
31.7k
#undef NIKON_14BIT_SIZE
714
31.7k
#undef NIKON_14BIT_SIZE3COLOR
715
716
    // Linear max from 14-bit camera, but on 12-bit data?
717
31.7k
    if (makeIs(LIBRAW_CAMERAMAKER_Sony) &&
718
1.42k
      imgdata.color.maximum > 0 &&
719
752
      imgdata.color.linear_max[0] > imgdata.color.maximum &&
720
6
      imgdata.color.linear_max[0] <= imgdata.color.maximum * 4)
721
10
      for (int c = 0; c < 4; c++)
722
8
        imgdata.color.linear_max[c] /= 4;
723
724
31.7k
    if (makeIs(LIBRAW_CAMERAMAKER_Canon))
725
1.64k
    {
726
1.64k
      if (!imgdata.idata.dng_version && (MN.canon.DefaultCropAbsolute.l != -1))  // tag 0x00e0 SensorInfo was parsed
727
180
      {
728
180
        if (imgdata.sizes.raw_aspect != LIBRAW_IMAGE_ASPECT_UNKNOWN)
729
14
        { // tag 0x009a AspectInfo was parsed
730
14
          isRIC.cleft += MN.canon.DefaultCropAbsolute.l;
731
14
          isRIC.ctop  += MN.canon.DefaultCropAbsolute.t;
732
14
        }
733
166
        else
734
166
        {
735
166
          isRIC.cleft   = MN.canon.DefaultCropAbsolute.l;
736
166
          isRIC.ctop    = MN.canon.DefaultCropAbsolute.t;
737
166
          isRIC.cwidth  = MN.canon.DefaultCropAbsolute.r - MN.canon.DefaultCropAbsolute.l + 1;
738
166
          isRIC.cheight = MN.canon.DefaultCropAbsolute.b - MN.canon.DefaultCropAbsolute.t + 1;
739
166
        }
740
180
      }
741
1.46k
      else
742
1.46k
      {
743
1.46k
        if (imgdata.sizes.raw_aspect != LIBRAW_IMAGE_ASPECT_UNKNOWN)
744
50
        {
745
50
        }
746
1.41k
        else
747
1.41k
        { // Canon PowerShot S2 IS
748
1.41k
        }
749
1.46k
      }
750
1.64k
#undef isRIC
751
1.64k
          if (imgdata.color.raw_bps < 14 && !imgdata.idata.dng_version && load_raw != &LibRaw::canon_sraw_load_raw)
752
1.18k
          {
753
1.18k
              int xmax = (1 << imgdata.color.raw_bps) - 1;
754
1.18k
              if (MN.canon.SpecularWhiteLevel > xmax) // Adjust 14-bit metadata to real bps
755
50
              {
756
50
                int div = 1 << (14 - imgdata.color.raw_bps);
757
250
                for (int c = 0; c < 4; c++) imgdata.color.linear_max[c] /= div;
758
250
                for (int c = 0; c < 4; c++)  MN.canon.ChannelBlackLevel[c] /= div;
759
50
                MN.canon.AverageBlackLevel /= div;
760
50
                MN.canon.SpecularWhiteLevel /= div;
761
50
                MN.canon.NormalWhiteLevel /= div;
762
50
              }
763
1.18k
          }
764
1.64k
    }
765
766
31.7k
    if (makeIs(LIBRAW_CAMERAMAKER_Canon) &&
767
1.64k
      (load_raw == &LibRaw::canon_sraw_load_raw) &&
768
72
      imgdata.sizes.raw_width > 0)
769
70
    {
770
70
      float ratio =
771
70
        float(imgdata.sizes.raw_height) / float(imgdata.sizes.raw_width);
772
70
      if ((ratio < 0.57 || ratio > 0.75) &&
773
44
        MN.canon.SensorHeight > 1 &&
774
42
        MN.canon.SensorWidth > 1)
775
34
      {
776
34
        imgdata.sizes.raw_width = MN.canon.SensorWidth;
777
34
        imgdata.sizes.left_margin = MN.canon.DefaultCropAbsolute.l;
778
34
        imgdata.sizes.iwidth = imgdata.sizes.width =
779
34
          MN.canon.DefaultCropAbsolute.r - MN.canon.DefaultCropAbsolute.l + 1;
780
34
        imgdata.sizes.raw_height = MN.canon.SensorHeight;
781
34
        imgdata.sizes.top_margin = MN.canon.DefaultCropAbsolute.t;
782
34
        imgdata.sizes.iheight = imgdata.sizes.height =
783
34
          MN.canon.DefaultCropAbsolute.b - MN.canon.DefaultCropAbsolute.t + 1;
784
34
        libraw_internal_data.unpacker_data.load_flags |=
785
34
          256; // reset width/height in canon_sraw_load_raw()
786
34
        imgdata.sizes.raw_pitch = 8 * imgdata.sizes.raw_width;
787
34
      }
788
36
      else if (imgdata.sizes.raw_width == 4032 &&
789
0
        imgdata.sizes.raw_height == 3402 &&
790
0
        !strcasecmp(imgdata.idata.model, "EOS 80D")) // 80D hardcoded
791
0
      {
792
0
        imgdata.sizes.raw_width = 4536;
793
0
        imgdata.sizes.left_margin = 28;
794
0
        imgdata.sizes.iwidth = imgdata.sizes.width =
795
0
          imgdata.sizes.raw_width - imgdata.sizes.left_margin;
796
0
        imgdata.sizes.raw_height = 3024;
797
0
        imgdata.sizes.top_margin = 8;
798
0
        imgdata.sizes.iheight = imgdata.sizes.height =
799
0
          imgdata.sizes.raw_height - imgdata.sizes.top_margin;
800
0
        libraw_internal_data.unpacker_data.load_flags |= 256;
801
0
        imgdata.sizes.raw_pitch = 8 * imgdata.sizes.raw_width;
802
0
      }
803
70
    }
804
805
#ifdef USE_DNGSDK
806
    if (imgdata.idata.dng_version
807
      &&libraw_internal_data.unpacker_data.tiff_compress == 34892
808
      && libraw_internal_data.unpacker_data.tiff_bps == 8
809
      && libraw_internal_data.unpacker_data.tiff_samples == 3
810
      && load_raw == &LibRaw::lossy_dng_load_raw)
811
    {
812
      // Data should be linearized by DNG SDK
813
      C.black = 0;
814
      memset(C.cblack, 0, sizeof(C.cblack));
815
    }
816
#endif
817
818
    // XTrans Compressed?
819
31.7k
    if (!imgdata.idata.dng_version &&
820
15.1k
      makeIs(LIBRAW_CAMERAMAKER_Fujifilm) &&
821
1.40k
      (load_raw == &LibRaw::unpacked_load_raw))
822
1.30k
    {
823
1.30k
      if (imgdata.sizes.raw_width * (imgdata.sizes.raw_height * 2ul) !=
824
1.30k
        libraw_internal_data.unpacker_data.data_size)
825
1.26k
      {
826
1.26k
        if ((imgdata.sizes.raw_width * (imgdata.sizes.raw_height * 7ul)) / 4 ==
827
1.26k
          libraw_internal_data.unpacker_data.data_size)
828
0
          load_raw = &LibRaw::fuji_14bit_load_raw;
829
1.26k
        else
830
1.26k
          parse_fuji_compressed_header();
831
1.26k
      }
832
42
      else if (!strcmp(imgdata.idata.normalized_model, "X-H2S") 
833
8
        && libraw_internal_data.internal_data.input->size() 
834
8
        < (libraw_internal_data.unpacker_data.data_size + libraw_internal_data.unpacker_data.data_offset))
835
6
      {
836
6
            parse_fuji_compressed_header(); // try to use compressed header: X-H2S may record wrong data size
837
6
      }
838
1.30k
    }
839
      // set raw_inset_crops[1] via raw_aspect
840
31.7k
      if (imgdata.sizes.raw_aspect >= LIBRAW_IMAGE_ASPECT_MINIMAL_REAL_ASPECT_VALUE
841
262
          && imgdata.sizes.raw_aspect <= LIBRAW_IMAGE_ASPECT_MAXIMAL_REAL_ASPECT_VALUE
842
          /* crops[0] is valid*/
843
262
          && (imgdata.sizes.raw_inset_crops[0].cleft < 0xffff)
844
56
          && (imgdata.sizes.raw_inset_crops[0].cleft + imgdata.sizes.raw_inset_crops[0].cwidth <= imgdata.sizes.raw_width)
845
28
          && (imgdata.sizes.raw_inset_crops[0].ctop < 0xffff)
846
26
          && (imgdata.sizes.raw_inset_crops[0].ctop + imgdata.sizes.raw_inset_crops[0].cheight <= imgdata.sizes.raw_height)
847
10
          && imgdata.sizes.raw_inset_crops[0].cwidth > 0 && imgdata.sizes.raw_inset_crops[0].cheight >0
848
          /* crops[1] is not set*/
849
8
          && (imgdata.sizes.raw_inset_crops[1].cleft == 0xffff)
850
8
          && (imgdata.sizes.raw_inset_crops[1].ctop == 0xffff)
851
31.7k
          )
852
8
      {
853
8
          float c0_ratio = float(imgdata.sizes.raw_inset_crops[0].cwidth) / float(imgdata.sizes.raw_inset_crops[0].cheight);
854
8
          float c1_ratio = float(imgdata.sizes.raw_aspect) / 1000.f;
855
8
          if (c0_ratio / c1_ratio < 0.98 || c0_ratio / c1_ratio > 1.02) // set crops[1]
856
6
          {
857
6
              if (c1_ratio > c0_ratio) // requested image is wider, cut from top/bottom
858
2
              {
859
2
                  int newheight =  int(imgdata.sizes.raw_inset_crops[0].cwidth / c1_ratio);
860
2
                  int dtop = (imgdata.sizes.raw_inset_crops[0].cheight - newheight) / 2;
861
2
                  imgdata.sizes.raw_inset_crops[1].ctop = imgdata.sizes.raw_inset_crops[0].ctop + dtop;
862
2
                  imgdata.sizes.raw_inset_crops[1].cheight = newheight;
863
2
                  imgdata.sizes.raw_inset_crops[1].cleft = imgdata.sizes.raw_inset_crops[0].cleft;
864
2
                  imgdata.sizes.raw_inset_crops[1].cwidth = imgdata.sizes.raw_inset_crops[0].cwidth;
865
2
              }
866
4
              else
867
4
              {
868
4
                  int newwidth = int(imgdata.sizes.raw_inset_crops[0].cheight * c1_ratio);
869
4
                  int dleft = (imgdata.sizes.raw_inset_crops[0].cwidth - newwidth) / 2;
870
4
                  imgdata.sizes.raw_inset_crops[1].cleft = imgdata.sizes.raw_inset_crops[0].cleft + dleft;
871
4
                  imgdata.sizes.raw_inset_crops[1].cwidth = newwidth;
872
4
                  imgdata.sizes.raw_inset_crops[1].ctop = imgdata.sizes.raw_inset_crops[0].ctop;
873
4
                  imgdata.sizes.raw_inset_crops[1].cheight = imgdata.sizes.raw_inset_crops[0].cheight;
874
4
              }
875
6
          }
876
8
      }
877
878
31.7k
      int adjust_margins = 0;
879
31.7k
      if (makeIs(LIBRAW_CAMERAMAKER_Fujifilm) && (imgdata.idata.filters == 9))
880
10
      {
881
          // Adjust top/left margins for X-Trans
882
10
          int newtm = imgdata.sizes.top_margin % 6
883
10
              ? (imgdata.sizes.top_margin / 6 + 1) * 6
884
10
              : imgdata.sizes.top_margin;
885
10
          int newlm = imgdata.sizes.left_margin % 6
886
10
              ? (imgdata.sizes.left_margin / 6 + 1) * 6
887
10
              : imgdata.sizes.left_margin;
888
10
          if (newtm != imgdata.sizes.top_margin ||
889
8
              newlm != imgdata.sizes.left_margin)
890
2
          {
891
2
              imgdata.sizes.height -= (newtm - imgdata.sizes.top_margin);
892
2
              imgdata.sizes.top_margin = newtm;
893
2
              imgdata.sizes.width -= (newlm - imgdata.sizes.left_margin);
894
2
              imgdata.sizes.left_margin = newlm;
895
14
              for (int c1 = 0; c1 < 6; c1++)
896
84
                  for (int c2 = 0; c2 < 6; c2++)
897
72
                      imgdata.idata.xtrans[c1][c2] = imgdata.idata.xtrans_abs[c1][c2];
898
2
          }
899
10
          adjust_margins = 6;
900
10
      }
901
31.7k
      else if (!libraw_internal_data.internal_output_params.fuji_width
902
18.6k
          && imgdata.idata.filters >= 1000)
903
17.1k
    {
904
17.1k
          if ((imgdata.sizes.top_margin % 2) || (imgdata.sizes.left_margin % 2))
905
282
          {
906
282
              int crop[2] = { 0,0 };
907
282
              unsigned filt;
908
282
              int c;
909
282
              if (imgdata.sizes.top_margin % 2)
910
150
              {
911
150
                  imgdata.sizes.top_margin += 1;
912
150
                  imgdata.sizes.height -= 1;
913
150
                  crop[1] = 1;
914
150
              }
915
282
              if (imgdata.sizes.left_margin % 2)
916
234
              {
917
234
                  imgdata.sizes.left_margin += 1;
918
234
                  imgdata.sizes.width -= 1;
919
234
                  crop[0] = 1;
920
234
              }
921
4.79k
              for (filt = c = 0; c < 16; c++)
922
4.51k
                  filt |= FC((c >> 1) + (crop[1]), (c & 1) + (crop[0])) << c * 2;
923
282
              imgdata.idata.filters = filt;
924
282
          }
925
17.1k
          adjust_margins = 2;
926
17.1k
    }
927
928
31.7k
      if(adjust_margins) // adjust crop_inset margins
929
51.4k
          for (int i = 0; i < 2; i++)
930
34.3k
          {
931
34.3k
              if (imgdata.sizes.raw_inset_crops[i].cleft && imgdata.sizes.raw_inset_crops[i].cleft < 0xffff
932
284
                  && imgdata.sizes.raw_inset_crops[i].cwidth && imgdata.sizes.raw_inset_crops[i].cwidth < 0xffff
933
150
                  && (imgdata.sizes.raw_inset_crops[i].cleft%adjust_margins)
934
32
                  && (imgdata.sizes.raw_inset_crops[i].cwidth > adjust_margins))
935
28
              {
936
28
                  int newleft = ((imgdata.sizes.raw_inset_crops[i].cleft / adjust_margins) + 1) * adjust_margins;
937
28
                  int diff = newleft - imgdata.sizes.raw_inset_crops[i].cleft;
938
28
                  if (diff > 0)
939
28
                  {
940
28
                      imgdata.sizes.raw_inset_crops[i].cleft += diff;
941
28
                      imgdata.sizes.raw_inset_crops[i].cwidth -= diff;
942
28
                  }
943
28
              }
944
34.3k
              if (imgdata.sizes.raw_inset_crops[i].ctop && imgdata.sizes.raw_inset_crops[i].ctop < 0xffff
945
384
                  && imgdata.sizes.raw_inset_crops[i].cheight && imgdata.sizes.raw_inset_crops[i].cheight < 0xffff
946
174
                  && (imgdata.sizes.raw_inset_crops[i].ctop%adjust_margins)
947
50
                  && (imgdata.sizes.raw_inset_crops[i].cheight > adjust_margins))
948
40
              {
949
40
                  int newtop = ((imgdata.sizes.raw_inset_crops[i].ctop / adjust_margins) + 1) * adjust_margins;
950
40
                  int diff = newtop - imgdata.sizes.raw_inset_crops[i].ctop;
951
40
                  if (diff > 0)
952
40
                  {
953
40
                      imgdata.sizes.raw_inset_crops[i].ctop += diff;
954
40
                      imgdata.sizes.raw_inset_crops[i].cheight -= diff;
955
40
                  }
956
40
              }
957
34.3k
          }
958
959
960
#ifdef USE_DNGSDK
961
    if (
962
      imgdata.rawparams.use_dngsdk &&
963
      !(imgdata.rawparams.options & (LIBRAW_RAWOPTIONS_DNG_STAGE2 | LIBRAW_RAWOPTIONS_DNG_STAGE3 | LIBRAW_RAWOPTIONS_DNG_DISABLEWBADJUST)))
964
#endif
965
31.7k
    {
966
      // Fix DNG white balance if needed: observed only for Kalpanika X3F tools produced DNGs
967
31.7k
      if (imgdata.idata.dng_version && (imgdata.idata.filters == 0) &&
968
517
        imgdata.idata.colors > 1 && imgdata.idata.colors < 5)
969
346
      {
970
346
        float delta[4] = { 0.f, 0.f, 0.f, 0.f };
971
346
        int black[4];
972
1.73k
        for (int c = 0; c < 4; c++)
973
1.38k
          black[c] = imgdata.color.dng_levels.dng_black +
974
1.38k
          imgdata.color.dng_levels.dng_cblack[c];
975
1.43k
        for (int c = 0; c < imgdata.idata.colors; c++)
976
1.08k
          delta[c] = float(imgdata.color.dng_levels.dng_whitelevel[c] - black[c]);
977
346
        float mindelta = delta[0], maxdelta = delta[0];
978
1.08k
        for (int c = 1; c < imgdata.idata.colors; c++)
979
740
        {
980
740
          if (mindelta > delta[c])
981
46
            mindelta = delta[c];
982
740
          if (maxdelta < delta[c])
983
14
            maxdelta = delta[c];
984
740
        }
985
346
        if (mindelta > 1 && maxdelta < (mindelta * 20)) // safety
986
100
        {
987
392
          for (int c = 0; c < imgdata.idata.colors; c++)
988
292
          {
989
292
            imgdata.color.cam_mul[c] /= (delta[c] / maxdelta);
990
292
            imgdata.color.pre_mul[c] /= (delta[c] / maxdelta);
991
292
          }
992
100
          imgdata.color.maximum = unsigned(imgdata.color.cblack[0] + maxdelta);
993
100
        }
994
346
      }
995
31.7k
    }
996
997
31.7k
    if (imgdata.idata.dng_version &&
998
3.66k
    makeIs(LIBRAW_CAMERAMAKER_Panasonic)
999
2
          && !strcasecmp(imgdata.idata.normalized_model, "DMC-LX100"))
1000
0
      imgdata.sizes.width = 4288;
1001
1002
31.7k
    if (imgdata.idata.dng_version && makeIs(LIBRAW_CAMERAMAKER_Leica))
1003
46
  {
1004
46
    if (!strcasecmp(imgdata.idata.normalized_model, "SL2"))
1005
0
      imgdata.sizes.height -= 16;
1006
46
    else if (!strcasecmp(imgdata.idata.normalized_model, "SL3"))
1007
0
    {
1008
0
      if (imgdata.sizes.raw_width == 9536)
1009
0
        imgdata.sizes.width -= 12;
1010
0
            else if (imgdata.sizes.raw_width == 7424)
1011
0
              imgdata.sizes.width -= 14;
1012
0
            else if (imgdata.sizes.raw_width == 5312)
1013
0
              imgdata.sizes.width -= 18;
1014
0
    }
1015
46
  }
1016
1017
31.7k
  if (makeIs(LIBRAW_CAMERAMAKER_Sony) &&
1018
1.42k
        imgdata.idata.dng_version)
1019
428
    {
1020
428
      if (S.raw_width == 3984)
1021
0
        S.width = 3925;
1022
428
      else if (S.raw_width == 4288)
1023
0
        S.width = S.raw_width - 32;
1024
428
      else if (S.raw_width == 4928 && S.height < 3280)
1025
0
        S.width = S.raw_width - 8;
1026
428
      else if (S.raw_width == 5504)
1027
0
        S.width = S.raw_width - (S.height > 3664 ? 8 : 32);
1028
428
    }
1029
1030
31.7k
  if (makeIs(LIBRAW_CAMERAMAKER_Sony) &&
1031
1.42k
        !imgdata.idata.dng_version)
1032
998
    {
1033
998
        if(load_raw ==&LibRaw::sony_arq_load_raw)
1034
0
        {
1035
0
            if(S.raw_width > 12000) // A7RM4 16x, both APS-C and APS
1036
0
                S.width = S.raw_width - 64;
1037
0
            else // A7RM3/M4 4x merge
1038
0
                S.width = S.raw_width - 32;
1039
0
        }
1040
1041
998
      if (((!strncasecmp(imgdata.idata.model, "ILCE-7RM", 8) ||
1042
982
            !strcasecmp(imgdata.idata.model, "ILCA-99M2")) &&
1043
22
           (S.raw_width == 5216 || S.raw_width == 6304)) // A7RM2/M3/A99M2 in APS mode; A7RM4 in APS-C
1044
998
          ||
1045
998
          (!strcasecmp(imgdata.idata.model, "ILCE-7R") && S.raw_width >= 4580 &&
1046
0
           S.raw_width < 5020) // A7R in crop mode, no samples, so size est.
1047
998
          || (!strcasecmp(imgdata.idata.model, "ILCE-7") &&
1048
2
              S.raw_width == 3968) // A7 in crop mode
1049
998
          ||
1050
998
          ((!strncasecmp(imgdata.idata.model, "ILCE-7M", 7) ||
1051
988
            !strcasecmp(imgdata.idata.model, "ILCE-9") ||
1052
#if 0
1053
            !strcasecmp(imgdata.idata.model,
1054
                        "SLT-A99V")) // Does SLT-A99 also have APS-C mode??
1055
#endif
1056
980
           (mnCamID == SonyID_SLT_A99)) // 2 reasons: some cameras are SLT-A99, no 'V'; some are Hasselblad HV
1057
18
           && S.raw_width > 3750 &&
1058
4
           S.raw_width < 4120) // A7M2, A7M3, AA9, most likely APS-C raw_width
1059
                               // is 3968 (same w/ A7), but no samples, so guess
1060
996
          || (!strncasecmp(imgdata.idata.model, "ILCE-7S", 7) &&
1061
10
              S.raw_width == 2816) // A7S2=> exact, hope it works for A7S-I too
1062
998
      )
1063
2
        S.width = S.raw_width - 32;
1064
998
    }
1065
1066
1067
    // FIXME: it is possible that DNG contains 4x main frames + some previews; in this case imgdata.idata.raw_count will be greater than 4
1068
31.7k
  if (makeIs(LIBRAW_CAMERAMAKER_Pentax) &&
1069
        /*!strcasecmp(imgdata.idata.model,"K-3 II")  &&*/
1070
340
            imgdata.idata.raw_count == 4 &&
1071
0
        (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_PENTAX_PS_ALLFRAMES))
1072
0
    {
1073
0
      imgdata.idata.raw_count = 1;
1074
0
      imgdata.idata.filters = 0;
1075
0
      imgdata.idata.colors = 4;
1076
0
      imgdata.sizes.top_margin+=2;
1077
0
      imgdata.sizes.left_margin+=2;
1078
0
      imgdata.sizes.width-=4;
1079
0
      imgdata.sizes.height-=4;
1080
0
      IO.mix_green = 1;
1081
0
      pentax_component_load_raw = load_raw;
1082
0
      load_raw = &LibRaw::pentax_4shot_load_raw;
1083
0
    }
1084
1085
31.7k
  if (!imgdata.idata.dng_version && makeIs(LIBRAW_CAMERAMAKER_Leaf) &&
1086
224
        !strcmp(imgdata.idata.model, "Credo 50"))
1087
4
    {
1088
4
      imgdata.color.pre_mul[0] = 1.f / 0.3984f;
1089
4
      imgdata.color.pre_mul[2] = 1.f / 0.7666f;
1090
4
      imgdata.color.pre_mul[1] = imgdata.color.pre_mul[3] = 1.0;
1091
4
    }
1092
1093
31.7k
  if (!imgdata.idata.dng_version && makeIs(LIBRAW_CAMERAMAKER_Fujifilm) &&
1094
1.40k
        (!strncmp(imgdata.idata.model, "S20Pro", 6) ||
1095
1.39k
         !strncmp(imgdata.idata.model, "F700", 4)))
1096
44
    {
1097
44
      imgdata.sizes.raw_width /= 2;
1098
44
      load_raw = &LibRaw::unpacked_load_raw_fuji_f700s20;
1099
44
    }
1100
1101
31.7k
    if (load_raw == &LibRaw::packed_load_raw &&
1102
498
    makeIs(LIBRAW_CAMERAMAKER_Nikon) &&
1103
226
        !libraw_internal_data.unpacker_data.load_flags &&
1104
174
        (!strncasecmp(imgdata.idata.model, "D810", 4) ||
1105
170
         !strcasecmp(imgdata.idata.model, "D4S")) &&
1106
4
        libraw_internal_data.unpacker_data.data_size * 2u ==
1107
4
            imgdata.sizes.raw_height * imgdata.sizes.raw_width * 3u)
1108
2
    {
1109
2
      libraw_internal_data.unpacker_data.load_flags = 80;
1110
2
    }
1111
    // Adjust BL for Sony A900/A850
1112
31.7k
    if (load_raw == &LibRaw::packed_load_raw &&
1113
498
    makeIs(LIBRAW_CAMERAMAKER_Sony)) // 12 bit sony, but metadata may be for 14-bit range
1114
102
    {
1115
102
      if (C.maximum > 4095)
1116
36
        C.maximum = 4095;
1117
102
      if (C.black > 256 || C.cblack[0] > 256)
1118
4
      {
1119
4
        C.black /= 4;
1120
20
        for (int c = 0; c < 4; c++)
1121
16
          C.cblack[c] /= 4;
1122
6.06k
        for (unsigned c = 0; c < C.cblack[4] * C.cblack[5]; c++)
1123
6.05k
          C.cblack[6 + c] /= 4;
1124
4
      }
1125
102
    }
1126
1127
31.7k
  if (load_raw == &LibRaw::nikon_yuv_load_raw) // Is it Nikon sRAW?
1128
120
    {
1129
120
      load_raw = &LibRaw::nikon_load_sraw;
1130
120
      C.black = 0;
1131
120
      memset(C.cblack, 0, sizeof(C.cblack));
1132
120
      imgdata.idata.filters = 0;
1133
120
      libraw_internal_data.unpacker_data.tiff_samples = 3;
1134
120
      imgdata.idata.colors = 3;
1135
120
      double beta_1 = -5.79342238397656E-02;
1136
120
      double beta_2 = 3.28163551282665;
1137
120
      double beta_3 = -8.43136004842678;
1138
120
      double beta_4 = 1.03533181861023E+01;
1139
368k
      for (int i = 0; i <= 3072; i++)
1140
368k
      {
1141
368k
        double x = (double)i / 3072.;
1142
368k
        double y = (1. - exp(-beta_1 * x - beta_2 * x * x - beta_3 * x * x * x -
1143
368k
                             beta_4 * x * x * x * x));
1144
368k
        if (y < 0.)
1145
6.72k
          y = 0.;
1146
368k
        imgdata.color.curve[i] = ushort(y * 16383.f);
1147
368k
      }
1148
480
      for (int i = 0; i < 3; i++)
1149
1.80k
        for (int j = 0; j < 4; j++)
1150
1.44k
          imgdata.color.rgb_cam[i][j] = float(i == j);
1151
120
    }
1152
    // Adjust BL for Nikon 12bit
1153
31.7k
    if ((load_raw == &LibRaw::nikon_load_raw ||
1154
18.5k
         load_raw == &LibRaw::packed_load_raw ||
1155
18.0k
         load_raw == &LibRaw::nikon_load_padded_packed_raw) &&
1156
736
     makeIs(LIBRAW_CAMERAMAKER_Nikon) &&
1157
232
        strncmp(imgdata.idata.model, "COOLPIX", 7) &&
1158
208
        libraw_internal_data.unpacker_data.tiff_bps == 12)
1159
44
    {
1160
44
      C.maximum = 4095;
1161
44
      C.black /= 4;
1162
220
      for (int c = 0; c < 4; c++)
1163
176
        C.cblack[c] /= 4;
1164
828
      for (unsigned c = 0; c < C.cblack[4] * C.cblack[5]; c++)
1165
784
        C.cblack[6 + c] /= 4;
1166
44
    }
1167
1168
    // Adjust wb_already_applied
1169
31.7k
    if (load_raw == &LibRaw::nikon_load_sraw)
1170
120
      imgdata.color.as_shot_wb_applied =
1171
120
          LIBRAW_ASWB_APPLIED | LIBRAW_ASWB_NIKON_SRAW;
1172
31.6k
    else if (makeIs(LIBRAW_CAMERAMAKER_Canon) &&
1173
1.64k
             MN.canon.multishot[0] >= 8 &&
1174
18
             MN.canon.multishot[1] > 0)
1175
18
      imgdata.color.as_shot_wb_applied =
1176
18
          LIBRAW_ASWB_APPLIED | LIBRAW_ASWB_CANON;
1177
31.6k
    else if (makeIs(LIBRAW_CAMERAMAKER_Nikon) &&
1178
602
             MN.nikon.ExposureMode == 1)
1179
2
      imgdata.color.as_shot_wb_applied =
1180
2
          LIBRAW_ASWB_APPLIED | LIBRAW_ASWB_NIKON;
1181
31.6k
  else if (makeIs(LIBRAW_CAMERAMAKER_Pentax) &&
1182
340
             ((MN.pentax.MultiExposure & 0x01) == 1))
1183
4
      imgdata.color.as_shot_wb_applied =
1184
4
          LIBRAW_ASWB_APPLIED | LIBRAW_ASWB_PENTAX;
1185
31.6k
  else if (makeIs(LIBRAW_CAMERAMAKER_Sony) && load_raw == &LibRaw::sony_ycbcr_load_raw)
1186
0
    imgdata.color.as_shot_wb_applied = LIBRAW_ASWB_APPLIED | LIBRAW_ASWB_SONY;
1187
31.6k
    else
1188
31.6k
      imgdata.color.as_shot_wb_applied = 0;
1189
1190
    // Adjust Highlight Linearity limit
1191
31.7k
    if (C.linear_max[0] < 0)
1192
0
    {
1193
0
      if (imgdata.idata.dng_version)
1194
0
      {
1195
0
        for (int c = 0; c < 4; c++)
1196
0
          C.linear_max[c] = -1 * C.linear_max[c] + imgdata.color.cblack[c + 6];
1197
0
      }
1198
0
      else
1199
0
      {
1200
0
        for (int c = 0; c < 4; c++)
1201
0
          C.linear_max[c] = -1 * C.linear_max[c] + imgdata.color.cblack[c];
1202
0
      }
1203
0
    }
1204
1205
31.7k
  if (makeIs(LIBRAW_CAMERAMAKER_Nikon) &&
1206
608
    (!C.linear_max[0]) && (C.maximum > 1024) && (load_raw != &LibRaw::nikon_load_sraw))
1207
332
    {
1208
332
      C.linear_max[0] = C.linear_max[1] = C.linear_max[2] = C.linear_max[3] =
1209
332
          (long)((float)(C.maximum) / 1.07f);
1210
332
    }
1211
1212
    // Correct WB for Samsung GX20
1213
31.7k
  if (
1214
#if 0
1215
        /* GX20 should be corrected, but K20 is not */
1216
        makeIs(LIBRAW_CAMERAMAKER_Pentax) &&
1217
    !strcasecmp(imgdata.idata.normalized_model, "K20D")
1218
#endif
1219
#if 0
1220
    !strcasecmp(imgdata.idata.make, "Samsung") &&
1221
        !strcasecmp(imgdata.idata.model, "GX20")
1222
#endif
1223
31.7k
    makeIs(LIBRAW_CAMERAMAKER_Pentax) &&
1224
340
    (mnCamID == PentaxID_GX20) // Samsung rebranding
1225
31.7k
    )
1226
4
    {
1227
104
      for (int cnt = LIBRAW_WBI_Unknown; cnt <= LIBRAW_WBI_StudioTungsten; cnt++) {
1228
100
        if (C.WB_Coeffs[cnt][1]) {
1229
36
          C.WB_Coeffs[cnt][0] = (int)((float)(C.WB_Coeffs[cnt][0]) * 1.0503f);
1230
36
          C.WB_Coeffs[cnt][2] = (int)((float)(C.WB_Coeffs[cnt][2]) * 2.2867f);
1231
36
        }
1232
100
      }
1233
260
      for (int cnt = 0; cnt < 64; cnt++) {
1234
256
        if (C.WBCT_Coeffs[cnt][0] > 0.0f) {
1235
22
          C.WBCT_Coeffs[cnt][1] *= 1.0503f;
1236
22
          C.WBCT_Coeffs[cnt][3] *= 2.2867f;
1237
22
        }
1238
256
      }
1239
20
      for(int cnt = 0; cnt < 4; cnt++)
1240
16
        imgdata.color.pre_mul[cnt] =
1241
16
          float(C.WB_Coeffs[LIBRAW_WBI_Daylight][cnt]);
1242
4
    }
1243
1244
    // Adjust BL for Panasonic
1245
31.7k
    if (load_raw == &LibRaw::panasonic_load_raw &&
1246
86
    makeIs(LIBRAW_CAMERAMAKER_Panasonic) &&
1247
18
        ID.pana_black[0] && ID.pana_black[1] && ID.pana_black[2])
1248
0
    {
1249
0
      if (libraw_internal_data.unpacker_data.pana_encoding == 5)
1250
0
        libraw_internal_data.internal_output_params.zero_is_bad = 0;
1251
0
      C.black = 0;
1252
0
      int add = libraw_internal_data.unpacker_data.pana_encoding == 4 ? 15 : 0;
1253
0
      C.cblack[0] = ID.pana_black[0] + add;
1254
0
      C.cblack[1] = C.cblack[3] = ID.pana_black[1] + add;
1255
0
      C.cblack[2] = ID.pana_black[2] + add;
1256
0
      unsigned i = C.cblack[3];
1257
0
      for (int c = 0; c < 3; c++)
1258
0
        if (i > C.cblack[c])
1259
0
          i = C.cblack[c];
1260
0
      for (int c = 0; c < 4; c++)
1261
0
        C.cblack[c] -= i;
1262
0
      C.black = i;
1263
0
    }
1264
1265
    // Adjust sizes for X3F processing
1266
#ifdef USE_X3FTOOLS
1267
  if (load_raw == &LibRaw::x3f_load_raw)
1268
    {
1269
      for (int i = 0; i < foveon_count; i++)
1270
        if (!strcasecmp(imgdata.idata.make, foveon_data[i].make) &&
1271
            !strcasecmp(imgdata.idata.model, foveon_data[i].model) &&
1272
            imgdata.sizes.raw_width == foveon_data[i].raw_width &&
1273
            imgdata.sizes.raw_height == foveon_data[i].raw_height)
1274
        {
1275
          imgdata.sizes.top_margin = foveon_data[i].top_margin;
1276
          imgdata.sizes.left_margin = foveon_data[i].left_margin;
1277
          imgdata.sizes.width = imgdata.sizes.iwidth = foveon_data[i].width;
1278
          imgdata.sizes.height = imgdata.sizes.iheight = foveon_data[i].height;
1279
          C.maximum = foveon_data[i].white;
1280
          break;
1281
        }
1282
    }
1283
#endif
1284
#if 0
1285
    size_t bytes = ID.input->size()-libraw_internal_data.unpacker_data.data_offset;
1286
    float bpp = float(bytes)/float(S.raw_width)/float(S.raw_height);
1287
    float bpp2 = float(bytes)/float(S.width)/float(S.height);
1288
    if(!strcasecmp(imgdata.idata.make,"Hasselblad") && bpp == 6.0f)
1289
      {
1290
        load_raw = &LibRaw::hasselblad_full_load_raw;
1291
        S.width = S.raw_width;
1292
        S.height = S.raw_height;
1293
        P1.filters = 0;
1294
        P1.colors=3;
1295
        P1.raw_count=1;
1296
        C.maximum=0xffff;
1297
      }
1298
#endif
1299
31.7k
    if (C.profile_length)
1300
70
    {
1301
70
      if (C.profile)
1302
0
        free(C.profile);
1303
70
    INT64 profile_sz = MIN(INT64(C.profile_length), ID.input->size() - ID.profile_offset);
1304
70
    if (profile_sz > 0LL && profile_sz < LIBRAW_MAX_PROFILE_SIZE_MB * 1024LL * 1024LL)
1305
70
    {
1306
70
        C.profile = calloc(size_t(profile_sz),1);
1307
70
        C.profile_length = unsigned(profile_sz);
1308
70
        ID.input->seek(ID.profile_offset, SEEK_SET);
1309
70
        ID.input->read(C.profile, size_t(profile_sz), 1);
1310
70
    }
1311
0
    else
1312
0
      C.profile = NULL;
1313
70
    }
1314
1315
31.7k
    SET_PROC_FLAG(LIBRAW_PROGRESS_IDENTIFY);
1316
31.7k
  }
1317
31.8k
  catch (const std::bad_alloc&)
1318
31.8k
  {
1319
0
      EXCEPTION_HANDLER(LIBRAW_EXCEPTION_ALLOC);
1320
0
  }
1321
31.8k
  catch (const LibRaw_exceptions& err)
1322
31.8k
  {
1323
13.0k
    EXCEPTION_HANDLER(err);
1324
13.0k
  }
1325
31.8k
  catch (const std::exception& )
1326
31.8k
  {
1327
0
    EXCEPTION_HANDLER(LIBRAW_EXCEPTION_IO_CORRUPT);
1328
0
  }
1329
1330
18.7k
final:;
1331
1332
18.7k
  if (P1.raw_count < 1)
1333
11.0k
    return LIBRAW_FILE_UNSUPPORTED;
1334
1335
7.75k
  write_fun = &LibRaw::write_ppm_tiff;
1336
1337
7.75k
  if (load_raw == &LibRaw::kodak_ycbcr_load_raw)
1338
90
  {
1339
90
    S.height += S.height & 1;
1340
90
    S.width += S.width & 1;
1341
90
  }
1342
1343
7.75k
  IO.shrink =
1344
7.75k
      P1.filters &&
1345
6.60k
      (O.half_size || ((O.threshold || O.aber[0] != 1 || O.aber[2] != 1)));
1346
7.75k
  if (IO.shrink && P1.filters >= 1000)
1347
0
  {
1348
0
    S.width &= 65534;
1349
0
    S.height &= 65534;
1350
0
  }
1351
1352
7.75k
  S.iheight = (S.height + IO.shrink) >> IO.shrink;
1353
7.75k
  S.iwidth = (S.width + IO.shrink) >> IO.shrink;
1354
1355
  // Save color,sizes and internal data into raw_image fields
1356
7.75k
  memmove(&imgdata.rawdata.color, &imgdata.color, sizeof(imgdata.color));
1357
7.75k
  memmove(&imgdata.rawdata.sizes, &imgdata.sizes, sizeof(imgdata.sizes));
1358
7.75k
  memmove(&imgdata.rawdata.iparams, &imgdata.idata, sizeof(imgdata.idata));
1359
7.75k
  memmove(&imgdata.rawdata.ioparams,
1360
7.75k
          &libraw_internal_data.internal_output_params,
1361
7.75k
          sizeof(libraw_internal_data.internal_output_params));
1362
1363
7.75k
  SET_PROC_FLAG(LIBRAW_PROGRESS_SIZE_ADJUST);
1364
1365
7.75k
  return LIBRAW_SUCCESS;
1366
18.7k
}