Coverage Report

Created: 2025-08-26 07:07

/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
36.9k
{
20
  // restore color,sizes and internal data into raw_image fields
21
36.9k
  memmove(&imgdata.color, &imgdata.rawdata.color, sizeof(imgdata.color));
22
36.9k
  memmove(&imgdata.sizes, &imgdata.rawdata.sizes, sizeof(imgdata.sizes));
23
36.9k
  memmove(&imgdata.idata, &imgdata.rawdata.iparams, sizeof(imgdata.idata));
24
36.9k
  memmove(&libraw_internal_data.internal_output_params,
25
36.9k
          &imgdata.rawdata.ioparams,
26
36.9k
          sizeof(libraw_internal_data.internal_output_params));
27
28
36.9k
  if (O.user_flip >= 0)
29
36.9k
    S.flip = O.user_flip;
30
31
36.9k
  switch ((S.flip + 3600) % 360)
32
36.9k
  {
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
36.9k
  }
43
44
184k
  for (int c = 0; c < 4; c++)
45
147k
    if (O.aber[c] < 0.001 || O.aber[c] > 1000.f)
46
21.0k
      O.aber[c] = 1.0;
47
48
  // adjust for half mode!
49
36.9k
  IO.shrink =
50
36.9k
    !imgdata.rawdata.color4_image && !imgdata.rawdata.color3_image &&
51
36.9k
    !imgdata.rawdata.float4_image && !imgdata.rawdata.float3_image &&
52
36.9k
      P1.filters &&
53
36.9k
      (O.half_size || ((O.threshold || O.aber[0] != 1 || O.aber[2] != 1)));
54
55
36.9k
  S.iheight = (S.height + IO.shrink) >> IO.shrink;
56
36.9k
  S.iwidth = (S.width + IO.shrink) >> IO.shrink;
57
36.9k
}
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
940
    {
71
940
      phase_one_allocate_tempbuffer();
72
940
    free_p1_buffer = true;
73
940
      int rc = phase_one_subtract_black((ushort *)imgdata.rawdata.raw_alloc,
74
940
                                        imgdata.rawdata.raw_image);
75
940
      if (rc == 0 && imgdata.params.use_p1_correction)
76
940
        rc = phase_one_correct();
77
940
      if (rc != 0)
78
374
      {
79
374
        phase_one_free_tempbuffer();
80
374
        return rc;
81
374
      }
82
940
    }
83
84
    // free and re-allocate image bitmap
85
4.89k
  int extra = P1.filters ? (P1.filters == 9 ? 6 : 2) : 0;
86
4.89k
    if (imgdata.image)
87
36
    {
88
36
      imgdata.image = (ushort(*)[4])realloc(
89
36
          imgdata.image, (S.iheight+extra) * (S.iwidth+extra) * sizeof(*imgdata.image));
90
36
      memset(imgdata.image, 0, (S.iheight+extra) * (S.iwidth+extra) * sizeof(*imgdata.image));
91
36
    }
92
4.86k
    else
93
4.86k
      imgdata.image =
94
4.86k
          (ushort(*)[4])calloc((S.iheight+extra) * (S.iwidth+extra), sizeof(*imgdata.image));
95
96
97
4.89k
    libraw_decoder_info_t decoder_info;
98
4.89k
    get_decoder_info(&decoder_info);
99
100
    // Copy area size
101
4.89k
    int copyheight = MAX(0, MIN(int(S.height), int(S.raw_height) - int(S.top_margin)));
102
4.89k
    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.89k
    if ((imgdata.idata.filters || P1.colors == 1) && imgdata.rawdata.raw_image)
106
4.44k
    {
107
4.44k
      if (IO.fuji_width)
108
590
      {
109
590
        unsigned r, c;
110
590
        int row, col;
111
23.8k
        for (row = 0; row < S.raw_height - S.top_margin * 2; row++)
112
23.2k
        {
113
23.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
114M
            {
120
114M
              r = IO.fuji_width - 1 - col + (row >> 1);
121
114M
              c = col + ((row + 1) >> 1);
122
114M
            }
123
83.4M
            else
124
83.4M
            {
125
83.4M
              r = IO.fuji_width - 1 + row - (col >> 1);
126
83.4M
              c = row + ((col + 1) >> 1);
127
83.4M
            }
128
198M
            if (r < S.height && c < S.width && col + int(S.left_margin) < int(S.raw_width))
129
876k
              imgdata.image[((r) >> IO.shrink) * S.iwidth + ((c) >> IO.shrink)]
130
876k
                           [FC(r, c)] =
131
876k
                  imgdata.rawdata
132
876k
                      .raw_image[(row + S.top_margin) * S.raw_pitch / 2 +
133
876k
                                 (col + S.left_margin)];
134
198M
          }
135
23.2k
        }
136
590
      }
137
3.85k
      else
138
3.85k
      {
139
3.85k
        int row, col;
140
1.27M
        for (row = 0; row < copyheight; row++)
141
331M
          for (col = 0; col < copywidth; col++)
142
330M
            imgdata.image[((row) >> IO.shrink) * S.iwidth +
143
330M
                          ((col) >> IO.shrink)][fcol(row, col)] =
144
330M
                imgdata.rawdata
145
330M
                    .raw_image[(row + S.top_margin) * S.raw_pitch / 2 +
146
330M
                               (col + S.left_margin)];
147
3.85k
      }
148
4.44k
    }
149
452
    else // if(decoder_info.decoder_flags & LIBRAW_DECODER_LEGACY)
150
452
    {
151
452
      if (imgdata.rawdata.color4_image)
152
415
      {
153
415
        if (S.width * 8u == S.raw_pitch && S.height == S.raw_height)
154
351
          memmove(imgdata.image, imgdata.rawdata.color4_image,
155
351
                  S.width * S.height * sizeof(*imgdata.image));
156
64
        else
157
64
        {
158
16.0k
            for (int row = 0; row < copyheight; row++)
159
16.0k
            memmove(&imgdata.image[row * S.width],
160
16.0k
                    &imgdata.rawdata
161
16.0k
                         .color4_image[(row + S.top_margin) * S.raw_pitch / 8 +
162
16.0k
                                       S.left_margin],
163
16.0k
                    copywidth * sizeof(*imgdata.image));
164
64
        }
165
415
      }
166
37
      else if (imgdata.rawdata.color3_image)
167
36
      {
168
36
        unsigned char *c3image = (unsigned char *)imgdata.rawdata.color3_image;
169
369k
        for (int row = 0; row < copyheight; row++)
170
369k
        {
171
369k
          ushort(*srcrow)[3] =
172
369k
              (ushort(*)[3]) & c3image[(row + S.top_margin) * S.raw_pitch];
173
369k
          ushort(*dstrow)[4] = (ushort(*)[4]) & imgdata.image[row * S.width];
174
11.4M
          for (int col = 0; col < copywidth; col++)
175
11.0M
          {
176
44.3M
            for (int c = 0; c < 3; c++)
177
33.2M
              dstrow[col][c] = srcrow[S.left_margin + col][c];
178
11.0M
            dstrow[col][3] = 0;
179
11.0M
          }
180
369k
        }
181
36
      }
182
1
      else
183
1
      {
184
        // legacy decoder, but no data?
185
1
        throw LIBRAW_EXCEPTION_DECODE_RAW;
186
1
      }
187
452
    }
188
189
    // Free PhaseOne separate copy allocated at function start
190
4.89k
    if (free_p1_buffer)
191
566
    {
192
566
      phase_one_free_tempbuffer();
193
566
    }
194
    // hack - clear later flags!
195
196
4.89k
    if (load_raw == &LibRaw::canon_600_load_raw && S.width < S.raw_width)
197
112
    {
198
112
      canon_600_correct();
199
112
    }
200
201
4.89k
    imgdata.progress_flags =
202
4.89k
        LIBRAW_PROGRESS_START | LIBRAW_PROGRESS_OPEN |
203
4.89k
        LIBRAW_PROGRESS_RAW2_IMAGE | LIBRAW_PROGRESS_IDENTIFY |
204
4.89k
        LIBRAW_PROGRESS_SIZE_ADJUST | LIBRAW_PROGRESS_LOAD_RAW;
205
4.89k
    return 0;
206
4.89k
  }
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
3.64k
{
220
#if defined(LIBRAW_USE_OPENMP)
221
#pragma omp parallel for schedule(dynamic) default(none) firstprivate(cblack) shared(dmaxp)
222
#endif
223
126k
  for (int row = 0; row < int(S.raw_height) - int(S.top_margin) * 2; row++)
224
122k
  {
225
122k
    int col;
226
122k
    unsigned short ldmax = 0;
227
122k
    for (col = 0;
228
6.92M
         col < IO.fuji_width << int(!libraw_internal_data.unpacker_data.fuji_layout)
229
6.92M
         && col + int(S.left_margin) < int(S.raw_width);
230
6.80M
         col++)
231
6.80M
    {
232
6.80M
      unsigned r, c;
233
6.80M
      if (libraw_internal_data.unpacker_data.fuji_layout)
234
1.72M
      {
235
1.72M
        r = IO.fuji_width - 1 - col + (row >> 1);
236
1.72M
        c = col + ((row + 1) >> 1);
237
1.72M
      }
238
5.07M
      else
239
5.07M
      {
240
5.07M
        r = IO.fuji_width - 1 + row - (col >> 1);
241
5.07M
        c = row + ((col + 1) >> 1);
242
5.07M
      }
243
6.80M
      if (r < S.height && c < S.width)
244
6.13M
      {
245
6.13M
        unsigned short val =
246
6.13M
            imgdata.rawdata.raw_image[(row + S.top_margin) * S.raw_pitch / 2 +
247
6.13M
                                      (col + S.left_margin)];
248
6.13M
        int cc = FC(r, c);
249
6.13M
        if (val > cblack[cc])
250
2.41M
        {
251
2.41M
          val -= cblack[cc];
252
2.41M
          if (val > ldmax)
253
298k
            ldmax = val;
254
2.41M
        }
255
3.71M
        else
256
3.71M
          val = 0;
257
6.13M
        imgdata.image[((r) >> IO.shrink) * S.iwidth + ((c) >> IO.shrink)][cc] =
258
6.13M
            val;
259
6.13M
      }
260
6.80M
    }
261
#if defined(LIBRAW_USE_OPENMP)
262
#pragma omp critical(dataupdate)
263
#endif
264
122k
    {
265
122k
      if (*dmaxp < ldmax)
266
7.11k
        *dmaxp = ldmax;
267
122k
    }
268
122k
  }
269
3.64k
}
270
271
void LibRaw::copy_bayer(unsigned short cblack[4], unsigned short *dmaxp)
272
24.8k
{
273
  // Both cropped and uncropped
274
24.8k
  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
7.73M
  for (int row = 0; row < maxHeight ; row++)
279
7.70M
  {
280
7.70M
    int col;
281
7.70M
    unsigned short ldmax = 0;
282
1.99G
    for (col = 0; col < S.width && col + S.left_margin < S.raw_width; col++)
283
1.98G
    {
284
1.98G
      unsigned short val =
285
1.98G
          imgdata.rawdata.raw_image[(row + S.top_margin) * S.raw_pitch / 2 +
286
1.98G
                                    (col + S.left_margin)];
287
1.98G
      int cc = fcol(row, col);
288
1.98G
      if (val > cblack[cc])
289
1.11G
      {
290
1.11G
        val -= cblack[cc];
291
1.11G
        if (val > ldmax)
292
20.0M
          ldmax = val;
293
1.11G
      }
294
874M
      else
295
874M
        val = 0;
296
1.98G
      imgdata.image[((row) >> IO.shrink) * S.iwidth + ((col) >> IO.shrink)][cc] = val;
297
1.98G
    }
298
#if defined(LIBRAW_USE_OPENMP)
299
#pragma omp critical(dataupdate)
300
#endif
301
7.70M
    {
302
7.70M
      if (*dmaxp < ldmax)
303
48.5k
        *dmaxp = ldmax;
304
7.70M
    }
305
7.70M
  }
306
24.8k
}
307
308
int LibRaw::raw2image_ex(int do_subtract_black)
309
31.6k
{
310
311
31.6k
  CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);
312
313
31.6k
  try
314
31.6k
  {
315
31.6k
    raw2image_start();
316
31.6k
  bool free_p1_buffer = false;
317
318
    // Compressed P1 files with bl data!
319
31.6k
    if (is_phaseone_compressed() && (imgdata.rawdata.raw_alloc || (imgdata.process_warnings & LIBRAW_WARN_RAWSPEED3_PROCESSED)))
320
2.99k
    {
321
2.99k
      phase_one_allocate_tempbuffer();
322
2.99k
    free_p1_buffer = true;
323
2.99k
      int rc = phase_one_subtract_black((ushort *)imgdata.rawdata.raw_alloc,
324
2.99k
                                        imgdata.rawdata.raw_image);
325
2.99k
      if (rc == 0 && imgdata.params.use_p1_correction)
326
2.99k
        rc = phase_one_correct();
327
2.99k
      if (rc != 0)
328
0
      {
329
0
        phase_one_free_tempbuffer();
330
0
        return rc;
331
0
      }
332
2.99k
    }
333
334
    // process cropping
335
31.6k
    int do_crop = 0;
336
31.6k
    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.6k
  int extra = P1.filters ? (P1.filters == 9 ? 6 : 2) : 0;
393
31.6k
    int alloc_width = S.iwidth + extra;
394
31.6k
    int alloc_height = S.iheight + extra;
395
396
31.6k
    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.6k
    int alloc_sz = alloc_width * alloc_height;
406
407
31.6k
    if (imgdata.image)
408
26.7k
    {
409
26.7k
      imgdata.image = (ushort(*)[4])realloc(imgdata.image,
410
26.7k
                                            alloc_sz * sizeof(*imgdata.image));
411
26.7k
      memset(imgdata.image, 0, alloc_sz * sizeof(*imgdata.image));
412
26.7k
    }
413
4.89k
    else
414
4.89k
      imgdata.image = (ushort(*)[4])calloc(alloc_sz, sizeof(*imgdata.image));
415
416
31.6k
    libraw_decoder_info_t decoder_info;
417
31.6k
    get_decoder_info(&decoder_info);
418
419
    // Adjust black levels
420
31.6k
    unsigned short cblack[4] = {0, 0, 0, 0};
421
31.6k
    unsigned short dmax = 0;
422
31.6k
    if (do_subtract_black)
423
27.0k
    {
424
27.0k
      adjust_bl();
425
135k
      for (int i = 0; i < 4; i++)
426
108k
        cblack[i] = (unsigned short)C.cblack[i];
427
27.0k
    }
428
429
    // Max area size to definitely not overrun in/out buffers
430
31.6k
    int copyheight = MAX(0, MIN(int(S.height), int(S.raw_height) - int(S.top_margin)));
431
31.6k
    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.6k
    if ((imgdata.idata.filters || P1.colors == 1) && imgdata.rawdata.raw_image)
435
28.4k
    {
436
28.4k
      if (IO.fuji_width)
437
3.64k
      {
438
3.64k
        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
3.64k
        else
488
3.64k
        {
489
3.64k
          copy_fuji_uncropped(cblack, &dmax);
490
3.64k
        }
491
3.64k
      } // end Fuji
492
24.8k
      else
493
24.8k
      {
494
24.8k
        copy_bayer(cblack, &dmax);
495
24.8k
      }
496
28.4k
    }
497
3.15k
    else // if(decoder_info.decoder_flags & LIBRAW_DECODER_LEGACY)
498
3.15k
    {
499
3.15k
      if (imgdata.rawdata.color4_image)
500
2.90k
      {
501
2.90k
          if (S.raw_pitch != S.width * 8u || S.height != S.raw_height)
502
448
          {
503
112k
              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
448
          }
510
2.45k
          else
511
2.45k
          {
512
              // legacy is always 4channel and not shrinked!
513
2.45k
              memmove(imgdata.image, imgdata.rawdata.color4_image,
514
2.45k
                  S.width*copyheight * sizeof(*imgdata.image));
515
2.45k
          }
516
2.90k
      }
517
252
      else if (imgdata.rawdata.color3_image)
518
252
      {
519
252
          unsigned char *c3image = (unsigned char *)imgdata.rawdata.color3_image;
520
2.58M
          for (int row = 0; row < copyheight; row++)
521
2.58M
        {
522
2.58M
          ushort(*srcrow)[3] =
523
2.58M
              (ushort(*)[3]) & c3image[(row + S.top_margin) * S.raw_pitch];
524
2.58M
          ushort(*dstrow)[4] = (ushort(*)[4]) & imgdata.image[row * S.width];
525
80.1M
          for (int col = 0; col < copywidth; col++)
526
77.5M
          {
527
310M
            for (int c = 0; c < 3; c++)
528
232M
              dstrow[col][c] = srcrow[S.left_margin + col][c];
529
77.5M
            dstrow[col][3] = 0;
530
77.5M
          }
531
2.58M
        }
532
252
      }
533
0
      else
534
0
      {
535
        // legacy decoder, but no data?
536
0
        throw LIBRAW_EXCEPTION_DECODE_RAW;
537
0
      }
538
3.15k
    }
539
540
    // Free PhaseOne separate copy allocated at function start
541
31.6k
    if (free_p1_buffer)
542
2.99k
    {
543
2.99k
      phase_one_free_tempbuffer();
544
2.99k
    }
545
31.6k
    if (load_raw == &LibRaw::canon_600_load_raw && S.width < S.raw_width)
546
784
    {
547
784
      canon_600_correct();
548
784
    }
549
550
31.6k
    if (do_subtract_black)
551
27.0k
    {
552
27.0k
      C.data_maximum = (int)dmax;
553
27.0k
      C.maximum -= C.black;
554
      //        ZERO(C.cblack);
555
27.0k
      C.cblack[0] = C.cblack[1] = C.cblack[2] = C.cblack[3] = 0;
556
27.0k
      C.black = 0;
557
27.0k
    }
558
559
    // hack - clear later flags!
560
31.6k
    imgdata.progress_flags =
561
31.6k
        LIBRAW_PROGRESS_START | LIBRAW_PROGRESS_OPEN |
562
31.6k
        LIBRAW_PROGRESS_RAW2_IMAGE | LIBRAW_PROGRESS_IDENTIFY |
563
31.6k
        LIBRAW_PROGRESS_SIZE_ADJUST | LIBRAW_PROGRESS_LOAD_RAW;
564
31.6k
    return 0;
565
31.6k
  }
566
31.6k
  catch (const LibRaw_exceptions& err)
567
31.6k
  {
568
0
    EXCEPTION_HANDLER(err);
569
0
  }
570
31.6k
}