Coverage Report

Created: 2026-10-14 06:45

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.80k
{
20
  // restore color,sizes and internal data into raw_image fields
21
2.80k
  memmove(&imgdata.color, &imgdata.rawdata.color, sizeof(imgdata.color));
22
2.80k
  memmove(&imgdata.sizes, &imgdata.rawdata.sizes, sizeof(imgdata.sizes));
23
2.80k
  memmove(&imgdata.idata, &imgdata.rawdata.iparams, sizeof(imgdata.idata));
24
2.80k
  memmove(&libraw_internal_data.internal_output_params,
25
2.80k
          &imgdata.rawdata.ioparams,
26
2.80k
          sizeof(libraw_internal_data.internal_output_params));
27
28
2.80k
  if (O.user_flip >= 0)
29
0
    S.flip = O.user_flip;
30
31
2.80k
  switch ((S.flip + 3600) % 360)
32
2.80k
  {
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.80k
  }
43
44
14.0k
  for (int c = 0; c < 4; c++)
45
11.2k
    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.80k
  IO.shrink =
50
2.80k
    !imgdata.rawdata.color4_image && !imgdata.rawdata.color3_image &&
51
2.34k
    !imgdata.rawdata.float4_image && !imgdata.rawdata.float3_image &&
52
2.34k
      P1.filters &&
53
2.31k
      (O.half_size || ((O.threshold || O.aber[0] != 1 || O.aber[2] != 1)));
54
55
2.80k
  S.iheight = (S.height + IO.shrink) >> IO.shrink;
56
2.80k
  S.iwidth = (S.width + IO.shrink) >> IO.shrink;
57
2.80k
}
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.55k
  {
227
1.55k
    int col;
228
1.55k
    unsigned short ldmax = 0;
229
1.55k
    for (col = 0;
230
37.3k
         col < IO.fuji_width << int(!libraw_internal_data.unpacker_data.fuji_layout)
231
35.9k
         && col + int(S.left_margin) < int(S.raw_width);
232
35.7k
         col++)
233
35.7k
    {
234
35.7k
      unsigned r, c;
235
35.7k
      if (libraw_internal_data.unpacker_data.fuji_layout)
236
27.5k
      {
237
27.5k
        r = IO.fuji_width - 1 - col + (row >> 1);
238
27.5k
        c = col + ((row + 1) >> 1);
239
27.5k
      }
240
8.28k
      else
241
8.28k
      {
242
8.28k
        r = IO.fuji_width - 1 + row - (col >> 1);
243
8.28k
        c = row + ((col + 1) >> 1);
244
8.28k
      }
245
35.7k
      if (r < S.height && c < S.width)
246
35.5k
      {
247
35.5k
        unsigned short val =
248
35.5k
            imgdata.rawdata.raw_image[(row + S.top_margin) * S.raw_pitch / 2 +
249
35.5k
                                      (col + S.left_margin)];
250
35.5k
        int cc = FC(r, c);
251
35.5k
        if (val > cblack[cc])
252
22.5k
        {
253
22.5k
          val -= cblack[cc];
254
22.5k
          if (val > ldmax)
255
3.43k
            ldmax = val;
256
22.5k
        }
257
12.9k
        else
258
12.9k
          val = 0;
259
35.5k
        imgdata.image[((r) >> IO.shrink) * S.iwidth + ((c) >> IO.shrink)][cc] =
260
35.5k
            val;
261
35.5k
      }
262
35.7k
    }
263
#if defined(LIBRAW_USE_OPENMP)
264
#pragma omp critical(dataupdate)
265
#endif
266
1.55k
    {
267
1.55k
      if (*dmaxp < ldmax)
268
90
        *dmaxp = ldmax;
269
1.55k
    }
270
1.55k
  }
271
45
}
272
273
void LibRaw::copy_bayer(unsigned short cblack[4], unsigned short *dmaxp)
274
2.14k
{
275
  // Both cropped and uncropped
276
2.14k
  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.74M
  for (int row = 0; row < maxHeight ; row++)
281
2.74M
  {
282
2.74M
    int col;
283
2.74M
    unsigned short ldmax = 0;
284
1.37G
    for (col = 0; col < S.width && col + S.left_margin < S.raw_width; col++)
285
1.37G
    {
286
1.37G
      unsigned short val =
287
1.37G
          imgdata.rawdata.raw_image[(row + S.top_margin) * S.raw_pitch / 2 +
288
1.37G
                                    (col + S.left_margin)];
289
1.37G
      int cc = fcol(row, col);
290
1.37G
      if (val > cblack[cc])
291
910M
      {
292
910M
        val -= cblack[cc];
293
910M
        if (val > ldmax)
294
4.19M
          ldmax = val;
295
910M
      }
296
464M
      else
297
464M
        val = 0;
298
1.37G
      imgdata.image[((row) >> IO.shrink) * S.iwidth + ((col) >> IO.shrink)][cc] = val;
299
1.37G
    }
300
#if defined(LIBRAW_USE_OPENMP)
301
#pragma omp critical(dataupdate)
302
#endif
303
2.74M
    {
304
2.74M
      if (*dmaxp < ldmax)
305
4.25k
        *dmaxp = ldmax;
306
2.74M
    }
307
2.74M
  }
308
2.14k
}
309
310
int LibRaw::raw2image_ex(int do_subtract_black)
311
2.80k
{
312
313
2.80k
  CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);
314
2.80k
  if (!imgdata.rawdata.raw_image && !imgdata.rawdata.color3_image && !imgdata.rawdata.color4_image)
315
0
    return LIBRAW_OUT_OF_ORDER_CALL;
316
317
2.80k
  try
318
2.80k
  {
319
2.80k
    raw2image_start();
320
2.80k
  bool free_p1_buffer = false;
321
322
    // Compressed P1 files with bl data!
323
2.80k
    if (is_phaseone_compressed() && (imgdata.rawdata.raw_alloc || (imgdata.process_warnings & LIBRAW_WARN_RAWSPEED3_PROCESSED)))
324
536
    {
325
536
      phase_one_allocate_tempbuffer();
326
536
    free_p1_buffer = true;
327
536
      int rc = phase_one_subtract_black((ushort *)imgdata.rawdata.raw_alloc,
328
536
                                        imgdata.rawdata.raw_image);
329
536
      if (rc == 0 && imgdata.params.use_p1_correction)
330
536
        rc = phase_one_correct();
331
536
      if (rc != 0)
332
159
      {
333
159
        phase_one_free_tempbuffer();
334
159
        return rc;
335
159
      }
336
536
    }
337
338
    // process cropping
339
2.64k
    int do_crop = 0;
340
2.64k
    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.64k
  int extra = P1.filters ? (P1.filters == 9 ? 6 : 2) : 0;
397
2.64k
    int alloc_width = S.iwidth + extra;
398
2.64k
    int alloc_height = S.iheight + extra;
399
400
2.64k
    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.64k
    INT64 alloc_sz = INT64(alloc_width) * INT64(alloc_height);
410
411
2.64k
    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.64k
    else
418
2.64k
      imgdata.image = (ushort(*)[4])calloc(alloc_sz, sizeof(*imgdata.image));
419
420
2.64k
    libraw_decoder_info_t decoder_info;
421
2.64k
    get_decoder_info(&decoder_info);
422
423
    // Adjust black levels
424
2.64k
    unsigned short cblack[4] = {0, 0, 0, 0};
425
2.64k
    unsigned short dmax = 0;
426
2.64k
    if (do_subtract_black)
427
2.02k
    {
428
2.02k
      adjust_bl();
429
10.1k
      for (int i = 0; i < 4; i++)
430
8.09k
        cblack[i] = (unsigned short)C.cblack[i];
431
2.02k
    }
432
433
    // Max area size to definitely not overrun in/out buffers
434
2.64k
    int copyheight = MAX(0, MIN(int(S.height), int(S.raw_height) - int(S.top_margin)));
435
2.64k
    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.64k
    if ((imgdata.idata.filters || P1.colors == 1) && imgdata.rawdata.raw_image)
439
2.18k
    {
440
2.18k
      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
2.14k
      else
497
2.14k
      {
498
2.14k
        copy_bayer(cblack, &dmax);
499
2.14k
      }
500
2.18k
    }
501
460
    else // if(decoder_info.decoder_flags & LIBRAW_DECODER_LEGACY)
502
460
    {
503
460
      if (imgdata.rawdata.color4_image)
504
437
      {
505
437
          if (S.raw_pitch != S.width * 8u || S.height != S.raw_height)
506
143
          {
507
23.4k
              for (int row = 0; row < copyheight; row++)
508
23.2k
                  memmove(&imgdata.image[row * S.width],
509
23.2k
                      &imgdata.rawdata
510
23.2k
                      .color4_image[(row + S.top_margin) * S.raw_pitch / 8 +
511
23.2k
                      S.left_margin],
512
23.2k
                      copywidth * sizeof(*imgdata.image));
513
143
          }
514
294
          else
515
294
          {
516
              // legacy is always 4channel and not shrinked!
517
294
              memmove(imgdata.image, imgdata.rawdata.color4_image,
518
294
                  S.width*copyheight * sizeof(*imgdata.image));
519
294
          }
520
437
      }
521
23
      else if (imgdata.rawdata.color3_image)
522
23
      {
523
23
          unsigned char *c3image = (unsigned char *)imgdata.rawdata.color3_image;
524
218k
          for (int row = 0; row < copyheight; row++)
525
218k
        {
526
218k
          ushort(*srcrow)[3] =
527
218k
              (ushort(*)[3]) & c3image[(row + S.top_margin) * S.raw_pitch];
528
218k
          ushort(*dstrow)[4] = (ushort(*)[4]) & imgdata.image[row * S.width];
529
16.0M
          for (int col = 0; col < copywidth; col++)
530
15.8M
          {
531
63.3M
            for (int c = 0; c < 3; c++)
532
47.5M
              dstrow[col][c] = srcrow[S.left_margin + col][c];
533
15.8M
            dstrow[col][3] = 0;
534
15.8M
          }
535
218k
        }
536
23
      }
537
0
      else
538
0
      {
539
        // legacy decoder, but no data?
540
0
        throw LIBRAW_EXCEPTION_DECODE_RAW;
541
0
      }
542
460
    }
543
544
    // Free PhaseOne separate copy allocated at function start
545
2.64k
    if (free_p1_buffer)
546
377
    {
547
377
      phase_one_free_tempbuffer();
548
377
    }
549
2.64k
    if (load_raw == &LibRaw::canon_600_load_raw && S.width < S.raw_width)
550
72
    {
551
72
      canon_600_correct();
552
72
    }
553
554
2.64k
    if (do_subtract_black)
555
2.02k
    {
556
2.02k
      C.data_maximum = (int)dmax;
557
2.02k
      C.maximum -= C.black;
558
      //        ZERO(C.cblack);
559
2.02k
      C.cblack[0] = C.cblack[1] = C.cblack[2] = C.cblack[3] = 0;
560
2.02k
      C.black = 0;
561
2.02k
    }
562
563
    // hack - clear later flags!
564
2.64k
    imgdata.progress_flags =
565
2.64k
        LIBRAW_PROGRESS_START | LIBRAW_PROGRESS_OPEN |
566
2.64k
        LIBRAW_PROGRESS_RAW2_IMAGE | LIBRAW_PROGRESS_IDENTIFY |
567
2.64k
        LIBRAW_PROGRESS_SIZE_ADJUST | LIBRAW_PROGRESS_LOAD_RAW;
568
2.64k
    return 0;
569
2.64k
  }
570
2.80k
  catch (const LibRaw_exceptions& err)
571
2.80k
  {
572
0
    EXCEPTION_HANDLER(err);
573
0
  }
574
2.80k
}