Coverage Report

Created: 2026-07-20 07:19

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