Coverage Report

Created: 2025-07-18 06:59

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