Coverage Report

Created: 2026-09-14 07:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/LibRaw/src/decoders/canon_600.cpp
Line
Count
Source
1
/* -*- C++ -*-
2
 * Copyright 2019-2025 LibRaw LLC (info@libraw.org)
3
 *
4
 LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder,
5
 dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net.
6
 LibRaw do not use RESTRICTED code from dcraw.c
7
8
 LibRaw is free software; you can redistribute it and/or modify
9
 it under the terms of the one of two licenses as you choose:
10
11
1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
12
   (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
13
14
2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
15
   (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
16
17
 */
18
19
#include "../../internal/dcraw_defs.h"
20
21
void LibRaw::canon_600_fixed_wb(int temp)
22
59
{
23
59
  static const short mul[4][5] = {{667, 358, 397, 565, 452},
24
59
                                  {731, 390, 367, 499, 517},
25
59
                                  {1119, 396, 348, 448, 537},
26
59
                                  {1399, 485, 431, 508, 688}};
27
59
  int lo, hi, i;
28
59
  float frac = 0;
29
30
118
  for (lo = 4; --lo;)
31
118
    if (*mul[lo] <= temp)
32
59
      break;
33
236
  for (hi = 0; hi < 3; hi++)
34
177
    if (*mul[hi] >= temp)
35
0
      break;
36
59
  if (lo != hi)
37
59
    frac = (float)(temp - *mul[lo]) / (*mul[hi] - *mul[lo]);
38
295
  for (i = 1; i < 5; i++)
39
236
    pre_mul[i - 1] = 1 / (frac * mul[hi][i] + (1 - frac) * mul[lo][i]);
40
59
}
41
42
/* Return values:  0 = white  1 = near white  2 = not white */
43
int LibRaw::canon_600_color(int ratio[2], int mar)
44
38.5k
{
45
38.5k
  int clipped = 0, target, miss;
46
47
38.5k
  if (flash_used)
48
0
  {
49
0
    if (ratio[1] < -104)
50
0
    {
51
0
      ratio[1] = -104;
52
0
      clipped = 1;
53
0
    }
54
0
    if (ratio[1] > 12)
55
0
    {
56
0
      ratio[1] = 12;
57
0
      clipped = 1;
58
0
    }
59
0
  }
60
38.5k
  else
61
38.5k
  {
62
38.5k
    if (ratio[1] < -264 || ratio[1] > 461)
63
50
      return 2;
64
38.5k
    if (ratio[1] < -50)
65
60
    {
66
60
      ratio[1] = -50;
67
60
      clipped = 1;
68
60
    }
69
38.5k
    if (ratio[1] > 307)
70
18
    {
71
18
      ratio[1] = 307;
72
18
      clipped = 1;
73
18
    }
74
38.5k
  }
75
38.5k
  target = flash_used || ratio[1] < 197 ? -38 - (398 * ratio[1] >> 10)
76
38.5k
                                        : -123 + (48 * ratio[1] >> 10);
77
38.5k
  if (target - mar <= ratio[0] && target + 20 >= ratio[0] && !clipped)
78
5.44k
    return 0;
79
33.0k
  miss = target - ratio[0];
80
33.0k
  if (abs(miss) >= mar * 4)
81
25
    return 2;
82
33.0k
  if (miss < -20)
83
33.0k
    miss = -20;
84
33.0k
  if (miss > mar)
85
13
    miss = mar;
86
33.0k
  ratio[0] = target - miss;
87
33.0k
  return 1;
88
33.0k
}
89
90
void LibRaw::canon_600_auto_wb()
91
59
{
92
59
  int mar, row, col, i, j, st, count[] = {0, 0};
93
59
  int test[8], total[2][8], ratio[2][2], stat[2];
94
95
59
  memset(&total, 0, sizeof total);
96
59
  i = int(canon_ev + 0.5);
97
59
  if (i < 10)
98
59
    mar = 150;
99
0
  else if (i > 12)
100
0
    mar = 20;
101
0
  else
102
0
    mar = 280 - 20 * i;
103
59
  if (flash_used)
104
0
    mar = 80;
105
8.73k
  for (row = 14; row < height - 14; row += 4)
106
3.66M
    for (col = 10; col < width; col += 2)
107
3.66M
    {
108
32.9M
      for (i = 0; i < 8; i++)
109
29.2M
        test[(i & 4) + FC(row + (i >> 1), col + (i & 1))] =
110
29.2M
            BAYER(row + (i >> 1), col + (i & 1));
111
5.29M
      for (i = 0; i < 8; i++)
112
5.27M
        if (test[i] < 150 || test[i] > 1500)
113
3.63M
          goto next;
114
105k
      for (i = 0; i < 4; i++)
115
85.8k
        if (abs(test[i] - test[i + 4]) > 50)
116
3.18k
          goto next;
117
57.8k
      for (i = 0; i < 2; i++)
118
38.5k
      {
119
115k
        for (j = 0; j < 4; j += 2)
120
77.1k
          ratio[i][j >> 1] =
121
77.1k
              ((test[i * 4 + j + 1] - test[i * 4 + j]) << 10) / test[i * 4 + j];
122
38.5k
        stat[i] = canon_600_color(ratio[i], mar);
123
38.5k
      }
124
19.2k
      if ((st = stat[0] | stat[1]) > 1)
125
42
        goto next;
126
57.7k
      for (i = 0; i < 2; i++)
127
38.4k
        if (stat[i])
128
99.1k
          for (j = 0; j < 2; j++)
129
66.1k
            test[i * 4 + j * 2 + 1] =
130
66.1k
                test[i * 4 + j * 2] * (0x400 + ratio[i][j]) >> 10;
131
173k
      for (i = 0; i < 8; i++)
132
153k
        total[st][i] += test[i];
133
19.2k
      count[st]++;
134
3.66M
    next:;
135
3.66M
    }
136
59
  if (count[0] | count[1])
137
39
  {
138
39
    st = count[0] * 200 < count[1];
139
195
    for (i = 0; i < 4; i++)
140
156
    if (total[st][i] + total[st][i + 4])
141
156
      pre_mul[i] = 1.0f / (total[st][i] + total[st][i + 4]);
142
39
  }
143
59
}
144
145
void LibRaw::canon_600_coeff()
146
59
{
147
59
  static const short table[6][12] = {
148
59
      {-190, 702, -1878, 2390, 1861, -1349, 905, -393, -432, 944, 2617, -2105},
149
59
      {-1203, 1715, -1136, 1648, 1388, -876, 267, 245, -1641, 2153, 3921,
150
59
       -3409},
151
59
      {-615, 1127, -1563, 2075, 1437, -925, 509, 3, -756, 1268, 2519, -2007},
152
59
      {-190, 702, -1886, 2398, 2153, -1641, 763, -251, -452, 964, 3040, -2528},
153
59
      {-190, 702, -1878, 2390, 1861, -1349, 905, -393, -432, 944, 2617, -2105},
154
59
      {-807, 1319, -1785, 2297, 1388, -876, 769, -257, -230, 742, 2067, -1555}};
155
59
  int t = 0, i, c;
156
59
  float mc, yc;
157
158
59
  mc = pre_mul[1] / pre_mul[2];
159
59
  yc = pre_mul[3] / pre_mul[2];
160
59
  if (mc > 1 && mc <= 1.28 && yc < 0.8789)
161
20
    t = 1;
162
59
  if (mc > 1.28 && mc <= 2)
163
18
  {
164
18
    if (yc < 0.8789)
165
2
      t = 3;
166
16
    else if (yc <= 2)
167
16
      t = 4;
168
18
  }
169
59
  if (flash_used)
170
0
    t = 5;
171
236
  for (raw_color = i = 0; i < 3; i++)
172
708
    FORCC rgb_cam[i][c] = float(table[t][i * 4 + c]) / 1024.f;
173
59
}
174
175
void LibRaw::canon_600_load_raw()
176
71
{
177
71
  uchar data[1120], *dp;
178
71
  ushort *pix;
179
71
  int irow, row;
180
181
37.5k
  for (irow = row = 0; irow < height; irow++)
182
37.4k
  {
183
37.4k
    checkCancel();
184
37.4k
    if (fread(data, 1, 1120, ifp) < 1120)
185
12
      derror();
186
37.4k
    pix = raw_image + row * raw_width;
187
4.23M
    for (dp = data; dp < data + 1120; dp += 10, pix += 8)
188
4.19M
    {
189
4.19M
      pix[0] = (dp[0] << 2) + (dp[1] >> 6);
190
4.19M
      pix[1] = (dp[2] << 2) + (dp[1] >> 4 & 3);
191
4.19M
      pix[2] = (dp[3] << 2) + (dp[1] >> 2 & 3);
192
4.19M
      pix[3] = (dp[4] << 2) + (dp[1] & 3);
193
4.19M
      pix[4] = (dp[5] << 2) + (dp[9] & 3);
194
4.19M
      pix[5] = (dp[6] << 2) + (dp[9] >> 2 & 3);
195
4.19M
      pix[6] = (dp[7] << 2) + (dp[9] >> 4 & 3);
196
4.19M
      pix[7] = (dp[8] << 2) + (dp[9] >> 6);
197
4.19M
    }
198
37.4k
    if ((row += 2) > height)
199
62
      row = 1;
200
37.4k
  }
201
71
}
202
203
void LibRaw::canon_600_correct()
204
59
{
205
59
  int row, col, val;
206
59
  static const short mul[4][2] = {
207
59
      {1141, 1145}, {1128, 1109}, {1178, 1149}, {1128, 1109}};
208
209
36.2k
  for (row = 0; row < height; row++)
210
36.1k
  {
211
36.1k
    checkCancel();
212
30.9M
    for (col = 0; col < width; col++)
213
30.8M
    {
214
30.8M
      if ((val = BAYER(row, col) - black) < 0)
215
24.1M
        val = 0;
216
30.8M
      val = val * mul[row & 3][col & 1] >> 9;
217
30.8M
      BAYER(row, col) = val;
218
30.8M
    }
219
36.1k
  }
220
59
  canon_600_fixed_wb(1311);
221
59
  canon_600_auto_wb();
222
59
  canon_600_coeff();
223
59
  maximum = (0x3ff - black) * 1109 >> 9;
224
59
  black = 0;
225
59
}