Coverage Report

Created: 2026-01-09 06:17

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libraw/src/preprocessing/subtract_black.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
int LibRaw::subtract_black()
19
0
{
20
0
  adjust_bl();
21
0
  return subtract_black_internal();
22
0
}
23
24
int LibRaw::subtract_black_internal()
25
7.80k
{
26
7.80k
  CHECK_ORDER_LOW(LIBRAW_PROGRESS_RAW2_IMAGE);
27
28
7.80k
  try
29
7.80k
  {
30
7.80k
    if (!is_phaseone_compressed() &&
31
7.06k
        (C.cblack[0] || C.cblack[1] || C.cblack[2] || C.cblack[3] ||
32
2.74k
         (C.cblack[4] && C.cblack[5])))
33
4.43k
    {
34
4.43k
      int cblk[4], i;
35
22.1k
      for (i = 0; i < 4; i++)
36
17.7k
        cblk[i] = C.cblack[i];
37
38
4.43k
      int size = S.iheight * S.iwidth;
39
4.43k
      int dmax = 0;
40
4.43k
      if (C.cblack[4] && C.cblack[5])
41
1.89k
      {
42
77.4M
        for (unsigned q = 0; q < (unsigned)size; q++)
43
77.4M
        {
44
387M
          for (unsigned c = 0; c < 4; c++)
45
309M
          {
46
309M
            int val = imgdata.image[q][c];
47
309M
            val -= C.cblack[6 + q / S.iwidth % C.cblack[4] * C.cblack[5] +
48
309M
                            q % S.iwidth % C.cblack[5]];
49
309M
            val -= cblk[c];
50
309M
            imgdata.image[q][c] = CLIP(val);
51
309M
            if (dmax < val) dmax = val;
52
309M
          }
53
77.4M
        }
54
1.89k
      }
55
2.54k
      else
56
2.54k
      {
57
142M
        for (unsigned q = 0; q < (unsigned)size; q++)
58
142M
        {
59
712M
          for (unsigned c = 0; c < 4; c++)
60
569M
          {
61
569M
            int val = imgdata.image[q][c];
62
569M
            val -= cblk[c];
63
569M
            imgdata.image[q][c] = CLIP(val);
64
569M
            if (dmax < val) dmax = val;
65
569M
          }
66
142M
        }
67
2.54k
      }
68
4.43k
      C.data_maximum = dmax & 0xffff;
69
4.43k
      C.maximum -= C.black;
70
4.43k
      ZERO(C.cblack); // Yeah, we used cblack[6+] values too!
71
4.43k
      C.black = 0;
72
4.43k
    }
73
3.36k
    else
74
3.36k
    {
75
      // Nothing to Do, maximum is already calculated, black level is 0, so no
76
      // change only calculate channel maximum;
77
3.36k
      int idx;
78
3.36k
      ushort *p = (ushort *)imgdata.image;
79
3.36k
      int dmax = 0;
80
412M
      for (idx = 0; idx < S.iheight * S.iwidth * 4; idx++)
81
412M
        if (dmax < p[idx])
82
10.4k
          dmax = p[idx];
83
3.36k
      C.data_maximum = dmax;
84
3.36k
    }
85
7.80k
    return 0;
86
7.80k
  }
87
7.80k
  catch (const LibRaw_exceptions& err)
88
7.80k
  {
89
0
    EXCEPTION_HANDLER(err);
90
0
  }
91
7.80k
}