Coverage Report

Created: 2026-07-25 07:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/LibRaw/src/preprocessing/raw2image.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
18
void LibRaw::raw2image_start()
19
2.38k
{
20
  // restore color,sizes and internal data into raw_image fields
21
2.38k
  memmove(&imgdata.color, &imgdata.rawdata.color, sizeof(imgdata.color));
22
2.38k
  memmove(&imgdata.sizes, &imgdata.rawdata.sizes, sizeof(imgdata.sizes));
23
2.38k
  memmove(&imgdata.idata, &imgdata.rawdata.iparams, sizeof(imgdata.idata));
24
2.38k
  memmove(&libraw_internal_data.internal_output_params,
25
2.38k
          &imgdata.rawdata.ioparams,
26
2.38k
          sizeof(libraw_internal_data.internal_output_params));
27
28
2.38k
  if (O.user_flip >= 0)
29
0
    S.flip = O.user_flip;
30
31
2.38k
  switch ((S.flip + 3600) % 360)
32
2.38k
  {
33
0
  case 270:
34
0
    S.flip = 5;
35
0
    break;
36
0
  case 180:
37
0
    S.flip = 3;
38
0
    break;
39
0
  case 90:
40
0
    S.flip = 6;
41
0
    break;
42
2.38k
  }
43
44
11.9k
  for (int c = 0; c < 4; c++)
45
9.52k
    if (O.aber[c] < 0.001 || O.aber[c] > 1000.f)
46
0
      O.aber[c] = 1.0;
47
48
  // adjust for half mode!
49
2.38k
  IO.shrink =
50
2.38k
    !imgdata.rawdata.color4_image && !imgdata.rawdata.color3_image &&
51
1.95k
    !imgdata.rawdata.float4_image && !imgdata.rawdata.float3_image &&
52
1.95k
      P1.filters &&
53
1.92k
      (O.half_size || ((O.threshold || O.aber[0] != 1 || O.aber[2] != 1)));
54
55
2.38k
  S.iheight = (S.height + IO.shrink) >> IO.shrink;
56
2.38k
  S.iwidth = (S.width + IO.shrink) >> IO.shrink;
57
2.38k
}
58
59
int LibRaw::raw2image(void)
60
0
{
61
62
0
  CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);
63
64
0
  if (!imgdata.rawdata.raw_image && !imgdata.rawdata.color3_image && !imgdata.rawdata.color4_image)
65
0
    return LIBRAW_OUT_OF_ORDER_CALL;
66
67
0
  try
68
0
  {
69
0
    raw2image_start();
70
71
0
  bool free_p1_buffer = false;
72
0
    if (is_phaseone_compressed() && (imgdata.rawdata.raw_alloc || (imgdata.process_warnings & LIBRAW_WARN_RAWSPEED3_PROCESSED)))
73
0
    {
74
0
      phase_one_allocate_tempbuffer();
75
0
    free_p1_buffer = true;
76
0
      int rc = phase_one_subtract_black((ushort *)imgdata.rawdata.raw_alloc,
77
0
                                        imgdata.rawdata.raw_image);
78
0
      if (rc == 0 && imgdata.params.use_p1_correction)
79
0
        rc = phase_one_correct();
80
0
      if (rc != 0)
81
0
      {
82
0
        phase_one_free_tempbuffer();
83
0
        return rc;
84
0
      }
85
0
    }
86
87
    // free and re-allocate image bitmap
88
0
  INT64 extra = P1.filters ? (P1.filters == 9 ? 6LL : 2LL) : 0LL;
89
0
  INT64 allocate_sz = (INT64(S.iheight) + extra) * (INT64(S.iwidth) + extra);
90
0
    if (imgdata.image)
91
0
    {
92
0
      imgdata.image = (ushort(*)[4])realloc(imgdata.image, allocate_sz * sizeof(*imgdata.image));
93
0
      memset(imgdata.image, 0, allocate_sz * sizeof(*imgdata.image));
94
0
    }
95
0
    else
96
0
      imgdata.image =
97
0
          (ushort(*)[4])calloc(allocate_sz, sizeof(*imgdata.image));
98
99
0
    libraw_decoder_info_t decoder_info;
100
0
    get_decoder_info(&decoder_info);
101
102
    // Copy area size
103
0
    int copyheight = MAX(0, MIN(int(S.height), int(S.raw_height) - int(S.top_margin)));
104
0
    int copywidth = MAX(0, MIN(int(S.width), int(S.raw_width) - int(S.left_margin)));
105
106
    // Move saved bitmap to imgdata.image
107
0
    if ((imgdata.idata.filters || P1.colors == 1) && imgdata.rawdata.raw_image)
108
0
    {
109
0
      if (IO.fuji_width)
110
0
      {
111
0
        unsigned r, c;
112
0
        int row, col;
113
0
        for (row = 0; row < S.raw_height - S.top_margin * 2; row++)
114
0
        {
115
0
          for (col = 0;
116
0
               col < IO.fuji_width
117
0
                         << int(!libraw_internal_data.unpacker_data.fuji_layout);
118
0
               col++)
119
0
          {
120
0
            if (libraw_internal_data.unpacker_data.fuji_layout)
121
0
            {
122
0
              r = IO.fuji_width - 1 - col + (row >> 1);
123
0
              c = col + ((row + 1) >> 1);
124
0
            }
125
0
            else
126
0
            {
127
0
              r = IO.fuji_width - 1 + row - (col >> 1);
128
0
              c = row + ((col + 1) >> 1);
129
0
            }
130
0
            if (r < S.height && c < S.width && col + int(S.left_margin) < int(S.raw_width))
131
0
              imgdata.image[((r) >> IO.shrink) * S.iwidth + ((c) >> IO.shrink)]
132
0
                           [FC(r, c)] =
133
0
                  imgdata.rawdata
134
0
                      .raw_image[(row + S.top_margin) * S.raw_pitch / 2 +
135
0
                                 (col + S.left_margin)];
136
0
          }
137
0
        }
138
0
      }
139
0
      else
140
0
      {
141
0
        int row, col;
142
0
        for (row = 0; row < copyheight; row++)
143
0
          for (col = 0; col < copywidth; col++)
144
0
            imgdata.image[((row) >> IO.shrink) * S.iwidth +
145
0
                          ((col) >> IO.shrink)][fcol(row, col)] =
146
0
                imgdata.rawdata
147
0
                    .raw_image[(row + S.top_margin) * S.raw_pitch / 2 +
148
0
                               (col + S.left_margin)];
149
0
      }
150
0
    }
151
0
    else // if(decoder_info.decoder_flags & LIBRAW_DECODER_LEGACY)
152
0
    {
153
0
      if (imgdata.rawdata.color4_image)
154
0
      {
155
0
        if (S.width * 8u == S.raw_pitch && S.height == S.raw_height)
156
0
          memmove(imgdata.image, imgdata.rawdata.color4_image,
157
0
                  S.width * S.height * sizeof(*imgdata.image));
158
0
        else
159
0
        {
160
0
            for (int row = 0; row < copyheight; row++)
161
0
            memmove(&imgdata.image[row * S.width],
162
0
                    &imgdata.rawdata
163
0
                         .color4_image[(row + S.top_margin) * S.raw_pitch / 8 +
164
0
                                       S.left_margin],
165
0
                    copywidth * sizeof(*imgdata.image));
166
0
        }
167
0
      }
168
0
      else if (imgdata.rawdata.color3_image)
169
0
      {
170
0
        unsigned char *c3image = (unsigned char *)imgdata.rawdata.color3_image;
171
0
        for (int row = 0; row < copyheight; row++)
172
0
        {
173
0
          ushort(*srcrow)[3] =
174
0
              (ushort(*)[3]) & c3image[(row + S.top_margin) * S.raw_pitch];
175
0
          ushort(*dstrow)[4] = (ushort(*)[4]) & imgdata.image[row * S.width];
176
0
          for (int col = 0; col < copywidth; col++)
177
0
          {
178
0
            for (int c = 0; c < 3; c++)
179
0
              dstrow[col][c] = srcrow[S.left_margin + col][c];
180
0
            dstrow[col][3] = 0;
181
0
          }
182
0
        }
183
0
      }
184
0
      else
185
0
      {
186
        // legacy decoder, but no data?
187
0
        throw LIBRAW_EXCEPTION_DECODE_RAW;
188
0
      }
189
0
    }
190
191
    // Free PhaseOne separate copy allocated at function start
192
0
    if (free_p1_buffer)
193
0
    {
194
0
      phase_one_free_tempbuffer();
195
0
    }
196
    // hack - clear later flags!
197
198
0
    if (load_raw == &LibRaw::canon_600_load_raw && S.width < S.raw_width)
199
0
    {
200
0
      canon_600_correct();
201
0
    }
202
203
0
    imgdata.progress_flags =
204
0
        LIBRAW_PROGRESS_START | LIBRAW_PROGRESS_OPEN |
205
0
        LIBRAW_PROGRESS_RAW2_IMAGE | LIBRAW_PROGRESS_IDENTIFY |
206
0
        LIBRAW_PROGRESS_SIZE_ADJUST | LIBRAW_PROGRESS_LOAD_RAW;
207
0
    return 0;
208
0
  }
209
0
  catch (const std::bad_alloc&)
210
0
  {
211
0
      EXCEPTION_HANDLER(LIBRAW_EXCEPTION_ALLOC);
212
0
  }
213
0
  catch (const LibRaw_exceptions& err)
214
0
  {
215
0
    EXCEPTION_HANDLER(err);
216
0
  }
217
0
}
218
219
void LibRaw::copy_fuji_uncropped(unsigned short cblack[4],
220
                                 unsigned short *dmaxp)
221
45
{
222
#if defined(LIBRAW_USE_OPENMP)
223
#pragma omp parallel for schedule(dynamic) default(none) firstprivate(cblack) shared(dmaxp)
224
#endif
225
1.60k
  for (int row = 0; row < int(S.raw_height) - int(S.top_margin) * 2; row++)
226
1.56k
  {
227
1.56k
    int col;
228
1.56k
    unsigned short ldmax = 0;
229
1.56k
    for (col = 0;
230
37.6k
         col < IO.fuji_width << int(!libraw_internal_data.unpacker_data.fuji_layout)
231
36.2k
         && col + int(S.left_margin) < int(S.raw_width);
232
36.0k
         col++)
233
36.0k
    {
234
36.0k
      unsigned r, c;
235
36.0k
      if (libraw_internal_data.unpacker_data.fuji_layout)
236
26.6k
      {
237
26.6k
        r = IO.fuji_width - 1 - col + (row >> 1);
238
26.6k
        c = col + ((row + 1) >> 1);
239
26.6k
      }
240
9.40k
      else
241
9.40k
      {
242
9.40k
        r = IO.fuji_width - 1 + row - (col >> 1);
243
9.40k
        c = row + ((col + 1) >> 1);
244
9.40k
      }
245
36.0k
      if (r < S.height && c < S.width)
246
35.8k
      {
247
35.8k
        unsigned short val =
248
35.8k
            imgdata.rawdata.raw_image[(row + S.top_margin) * S.raw_pitch / 2 +
249
35.8k
                                      (col + S.left_margin)];
250
35.8k
        int cc = FC(r, c);
251
35.8k
        if (val > cblack[cc])
252
22.9k
        {
253
22.9k
          val -= cblack[cc];
254
22.9k
          if (val > ldmax)
255
3.47k
            ldmax = val;
256
22.9k
        }
257
12.8k
        else
258
12.8k
          val = 0;
259
35.8k
        imgdata.image[((r) >> IO.shrink) * S.iwidth + ((c) >> IO.shrink)][cc] =
260
35.8k
            val;
261
35.8k
      }
262
36.0k
    }
263
#if defined(LIBRAW_USE_OPENMP)
264
#pragma omp critical(dataupdate)
265
#endif
266
1.56k
    {
267
1.56k
      if (*dmaxp < ldmax)
268
89
        *dmaxp = ldmax;
269
1.56k
    }
270
1.56k
  }
271
45
}
272
273
void LibRaw::copy_bayer(unsigned short cblack[4], unsigned short *dmaxp)
274
1.77k
{
275
  // Both cropped and uncropped
276
1.77k
  int maxHeight = MIN(int(S.height),int(S.raw_height)-int(S.top_margin));
277
#if defined(LIBRAW_USE_OPENMP)
278
#pragma omp parallel for schedule(dynamic) default(none) shared(dmaxp) firstprivate(cblack, maxHeight)
279
#endif
280
2.18M
  for (int row = 0; row < maxHeight ; row++)
281
2.18M
  {
282
2.18M
    int col;
283
2.18M
    unsigned short ldmax = 0;
284
1.08G
    for (col = 0; col < S.width && col + S.left_margin < S.raw_width; col++)
285
1.08G
    {
286
1.08G
      unsigned short val =
287
1.08G
          imgdata.rawdata.raw_image[(row + S.top_margin) * S.raw_pitch / 2 +
288
1.08G
                                    (col + S.left_margin)];
289
1.08G
      int cc = fcol(row, col);
290
1.08G
      if (val > cblack[cc])
291
761M
      {
292
761M
        val -= cblack[cc];
293
761M
        if (val > ldmax)
294
3.65M
          ldmax = val;
295
761M
      }
296
325M
      else
297
325M
        val = 0;
298
1.08G
      imgdata.image[((row) >> IO.shrink) * S.iwidth + ((col) >> IO.shrink)][cc] = val;
299
1.08G
    }
300
#if defined(LIBRAW_USE_OPENMP)
301
#pragma omp critical(dataupdate)
302
#endif
303
2.18M
    {
304
2.18M
      if (*dmaxp < ldmax)
305
3.69k
        *dmaxp = ldmax;
306
2.18M
    }
307
2.18M
  }
308
1.77k
}
309
310
int LibRaw::raw2image_ex(int do_subtract_black)
311
2.38k
{
312
313
2.38k
  CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);
314
2.38k
  if (!imgdata.rawdata.raw_image && !imgdata.rawdata.color3_image && !imgdata.rawdata.color4_image)
315
0
    return LIBRAW_OUT_OF_ORDER_CALL;
316
317
2.38k
  try
318
2.38k
  {
319
2.38k
    raw2image_start();
320
2.38k
  bool free_p1_buffer = false;
321
322
    // Compressed P1 files with bl data!
323
2.38k
    if (is_phaseone_compressed() && (imgdata.rawdata.raw_alloc || (imgdata.process_warnings & LIBRAW_WARN_RAWSPEED3_PROCESSED)))
324
449
    {
325
449
      phase_one_allocate_tempbuffer();
326
449
    free_p1_buffer = true;
327
449
      int rc = phase_one_subtract_black((ushort *)imgdata.rawdata.raw_alloc,
328
449
                                        imgdata.rawdata.raw_image);
329
449
      if (rc == 0 && imgdata.params.use_p1_correction)
330
449
        rc = phase_one_correct();
331
449
      if (rc != 0)
332
132
      {
333
132
        phase_one_free_tempbuffer();
334
132
        return rc;
335
132
      }
336
449
    }
337
338
    // process cropping
339
2.24k
    int do_crop = 0;
340
2.24k
    if (~O.cropbox[2] && ~O.cropbox[3])
341
0
    {
342
0
      int crop[4], c, filt;
343
0
      for (int q = 0; q < 4; q++)
344
0
      {
345
0
        crop[q] = O.cropbox[q];
346
0
        if (crop[q] < 0)
347
0
          crop[q] = 0;
348
0
      }
349
350
0
      if (IO.fuji_width && imgdata.idata.filters >= 1000)
351
0
      {
352
0
        crop[0] = (crop[0] / 4) * 4;
353
0
        crop[1] = (crop[1] / 4) * 4;
354
0
        if (!libraw_internal_data.unpacker_data.fuji_layout)
355
0
        {
356
0
          crop[2] = int(crop[2] * sqrtf(2.f));
357
0
          crop[3] = int(crop[3] / sqrtf(2.f));
358
0
        }
359
0
        crop[2] = (crop[2] / 4 + 1) * 4;
360
0
        crop[3] = (crop[3] / 4 + 1) * 4;
361
0
      }
362
0
      else if (imgdata.idata.filters == 1)
363
0
      {
364
0
        crop[0] = (crop[0] / 16) * 16;
365
0
        crop[1] = (crop[1] / 16) * 16;
366
0
      }
367
0
      else if (imgdata.idata.filters == LIBRAW_XTRANS)
368
0
      {
369
0
        crop[0] = (crop[0] / 6) * 6;
370
0
        crop[1] = (crop[1] / 6) * 6;
371
0
      }
372
0
      do_crop = 1;
373
374
0
      crop[2] = MIN(crop[2], (signed)S.width - crop[0]);
375
0
      crop[3] = MIN(crop[3], (signed)S.height - crop[1]);
376
0
      if (crop[2] <= 0 || crop[3] <= 0)
377
0
        throw LIBRAW_EXCEPTION_BAD_CROP;
378
379
      // adjust sizes!
380
0
      S.left_margin += crop[0];
381
0
      S.top_margin += crop[1];
382
0
      S.width = crop[2];
383
0
      S.height = crop[3];
384
385
0
      S.iheight = (S.height + IO.shrink) >> IO.shrink;
386
0
      S.iwidth = (S.width + IO.shrink) >> IO.shrink;
387
0
      if (!IO.fuji_width && imgdata.idata.filters &&
388
0
          imgdata.idata.filters >= 1000)
389
0
      {
390
0
        for (filt = c = 0; c < 16; c++)
391
0
          filt |= FC((c >> 1) + (crop[1]), (c & 1) + (crop[0])) << c * 2;
392
0
        imgdata.idata.filters = filt;
393
0
      }
394
0
    }
395
396
2.24k
  int extra = P1.filters ? (P1.filters == 9 ? 6 : 2) : 0;
397
2.24k
    int alloc_width = S.iwidth + extra;
398
2.24k
    int alloc_height = S.iheight + extra;
399
400
2.24k
    if (IO.fuji_width && do_crop)
401
0
    {
402
0
      int IO_fw = S.width >> int(!libraw_internal_data.unpacker_data.fuji_layout);
403
0
      int t_alloc_width =
404
0
          (S.height >> libraw_internal_data.unpacker_data.fuji_layout) + IO_fw;
405
0
      int t_alloc_height = t_alloc_width - 1;
406
0
      alloc_height = (t_alloc_height + IO.shrink) >> IO.shrink;
407
0
      alloc_width = (t_alloc_width + IO.shrink) >> IO.shrink;
408
0
    }
409
2.24k
    INT64 alloc_sz = INT64(alloc_width) * INT64(alloc_height);
410
411
2.24k
    if (imgdata.image)
412
0
    {
413
0
      imgdata.image = (ushort(*)[4])realloc(imgdata.image,
414
0
                                            alloc_sz * sizeof(*imgdata.image));
415
0
      memset(imgdata.image, 0, alloc_sz * sizeof(*imgdata.image));
416
0
    }
417
2.24k
    else
418
2.24k
      imgdata.image = (ushort(*)[4])calloc(alloc_sz, sizeof(*imgdata.image));
419
420
2.24k
    libraw_decoder_info_t decoder_info;
421
2.24k
    get_decoder_info(&decoder_info);
422
423
    // Adjust black levels
424
2.24k
    unsigned short cblack[4] = {0, 0, 0, 0};
425
2.24k
    unsigned short dmax = 0;
426
2.24k
    if (do_subtract_black)
427
1.69k
    {
428
1.69k
      adjust_bl();
429
8.45k
      for (int i = 0; i < 4; i++)
430
6.76k
        cblack[i] = (unsigned short)C.cblack[i];
431
1.69k
    }
432
433
    // Max area size to definitely not overrun in/out buffers
434
2.24k
    int copyheight = MAX(0, MIN(int(S.height), int(S.raw_height) - int(S.top_margin)));
435
2.24k
    int copywidth = MAX(0, MIN(int(S.width), int(S.raw_width) - int(S.left_margin)));
436
437
    // Move saved bitmap to imgdata.image
438
2.24k
    if ((imgdata.idata.filters || P1.colors == 1) && imgdata.rawdata.raw_image)
439
1.82k
    {
440
1.82k
      if (IO.fuji_width)
441
45
      {
442
45
        if (do_crop)
443
0
        {
444
0
          IO.fuji_width =
445
0
              S.width >> int(!libraw_internal_data.unpacker_data.fuji_layout);
446
0
          int IO_fwidth =
447
0
              (S.height >> int(libraw_internal_data.unpacker_data.fuji_layout)) +
448
0
              IO.fuji_width;
449
0
          int IO_fheight = IO_fwidth - 1;
450
451
0
          int row, col;
452
0
          for (row = 0; row < S.height; row++)
453
0
          {
454
0
            for (col = 0; col < S.width; col++)
455
0
            {
456
0
              int r, c;
457
0
              if (libraw_internal_data.unpacker_data.fuji_layout)
458
0
              {
459
0
                r = IO.fuji_width - 1 - col + (row >> 1);
460
0
                c = col + ((row + 1) >> 1);
461
0
              }
462
0
              else
463
0
              {
464
0
                r = IO.fuji_width - 1 + row - (col >> 1);
465
0
                c = row + ((col + 1) >> 1);
466
0
              }
467
468
0
              unsigned short val =
469
0
                  imgdata.rawdata
470
0
                      .raw_image[(row + S.top_margin) * S.raw_pitch / 2 +
471
0
                                 (col + S.left_margin)];
472
0
              int cc = FCF(row, col);
473
0
              if (val > cblack[cc])
474
0
              {
475
0
                val -= cblack[cc];
476
0
                if (dmax < val)
477
0
                  dmax = val;
478
0
              }
479
0
              else
480
0
                val = 0;
481
0
              imgdata.image[((r) >> IO.shrink) * alloc_width +
482
0
                            ((c) >> IO.shrink)][cc] = val;
483
0
            }
484
0
          }
485
0
          S.height = IO_fheight;
486
0
          S.width = IO_fwidth;
487
0
          S.iheight = (S.height + IO.shrink) >> IO.shrink;
488
0
          S.iwidth = (S.width + IO.shrink) >> IO.shrink;
489
0
          S.raw_height -= 2 * S.top_margin;
490
0
        }
491
45
        else
492
45
        {
493
45
          copy_fuji_uncropped(cblack, &dmax);
494
45
        }
495
45
      } // end Fuji
496
1.77k
      else
497
1.77k
      {
498
1.77k
        copy_bayer(cblack, &dmax);
499
1.77k
      }
500
1.82k
    }
501
428
    else // if(decoder_info.decoder_flags & LIBRAW_DECODER_LEGACY)
502
428
    {
503
428
      if (imgdata.rawdata.color4_image)
504
403
      {
505
403
          if (S.raw_pitch != S.width * 8u || S.height != S.raw_height)
506
136
          {
507
23.5k
              for (int row = 0; row < copyheight; row++)
508
23.4k
                  memmove(&imgdata.image[row * S.width],
509
23.4k
                      &imgdata.rawdata
510
23.4k
                      .color4_image[(row + S.top_margin) * S.raw_pitch / 8 +
511
23.4k
                      S.left_margin],
512
23.4k
                      copywidth * sizeof(*imgdata.image));
513
136
          }
514
267
          else
515
267
          {
516
              // legacy is always 4channel and not shrinked!
517
267
              memmove(imgdata.image, imgdata.rawdata.color4_image,
518
267
                  S.width*copyheight * sizeof(*imgdata.image));
519
267
          }
520
403
      }
521
25
      else if (imgdata.rawdata.color3_image)
522
25
      {
523
25
          unsigned char *c3image = (unsigned char *)imgdata.rawdata.color3_image;
524
122k
          for (int row = 0; row < copyheight; row++)
525
122k
        {
526
122k
          ushort(*srcrow)[3] =
527
122k
              (ushort(*)[3]) & c3image[(row + S.top_margin) * S.raw_pitch];
528
122k
          ushort(*dstrow)[4] = (ushort(*)[4]) & imgdata.image[row * S.width];
529
9.43M
          for (int col = 0; col < copywidth; col++)
530
9.31M
          {
531
37.2M
            for (int c = 0; c < 3; c++)
532
27.9M
              dstrow[col][c] = srcrow[S.left_margin + col][c];
533
9.31M
            dstrow[col][3] = 0;
534
9.31M
          }
535
122k
        }
536
25
      }
537
0
      else
538
0
      {
539
        // legacy decoder, but no data?
540
0
        throw LIBRAW_EXCEPTION_DECODE_RAW;
541
0
      }
542
428
    }
543
544
    // Free PhaseOne separate copy allocated at function start
545
2.24k
    if (free_p1_buffer)
546
317
    {
547
317
      phase_one_free_tempbuffer();
548
317
    }
549
2.24k
    if (load_raw == &LibRaw::canon_600_load_raw && S.width < S.raw_width)
550
55
    {
551
55
      canon_600_correct();
552
55
    }
553
554
2.24k
    if (do_subtract_black)
555
1.69k
    {
556
1.69k
      C.data_maximum = (int)dmax;
557
1.69k
      C.maximum -= C.black;
558
      //        ZERO(C.cblack);
559
1.69k
      C.cblack[0] = C.cblack[1] = C.cblack[2] = C.cblack[3] = 0;
560
1.69k
      C.black = 0;
561
1.69k
    }
562
563
    // hack - clear later flags!
564
2.24k
    imgdata.progress_flags =
565
2.24k
        LIBRAW_PROGRESS_START | LIBRAW_PROGRESS_OPEN |
566
2.24k
        LIBRAW_PROGRESS_RAW2_IMAGE | LIBRAW_PROGRESS_IDENTIFY |
567
2.24k
        LIBRAW_PROGRESS_SIZE_ADJUST | LIBRAW_PROGRESS_LOAD_RAW;
568
2.24k
    return 0;
569
2.24k
  }
570
2.38k
  catch (const LibRaw_exceptions& err)
571
2.38k
  {
572
0
    EXCEPTION_HANDLER(err);
573
0
  }
574
2.38k
}