Coverage Report

Created: 2026-08-17 07:50

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
0
{
23
0
  static const short mul[4][5] = {{667, 358, 397, 565, 452},
24
0
                                  {731, 390, 367, 499, 517},
25
0
                                  {1119, 396, 348, 448, 537},
26
0
                                  {1399, 485, 431, 508, 688}};
27
0
  int lo, hi, i;
28
0
  float frac = 0;
29
30
0
  for (lo = 4; --lo;)
31
0
    if (*mul[lo] <= temp)
32
0
      break;
33
0
  for (hi = 0; hi < 3; hi++)
34
0
    if (*mul[hi] >= temp)
35
0
      break;
36
0
  if (lo != hi)
37
0
    frac = (float)(temp - *mul[lo]) / (*mul[hi] - *mul[lo]);
38
0
  for (i = 1; i < 5; i++)
39
0
    pre_mul[i - 1] = 1 / (frac * mul[hi][i] + (1 - frac) * mul[lo][i]);
40
0
}
41
42
/* Return values:  0 = white  1 = near white  2 = not white */
43
int LibRaw::canon_600_color(int ratio[2], int mar)
44
0
{
45
0
  int clipped = 0, target, miss;
46
47
0
  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
0
  else
61
0
  {
62
0
    if (ratio[1] < -264 || ratio[1] > 461)
63
0
      return 2;
64
0
    if (ratio[1] < -50)
65
0
    {
66
0
      ratio[1] = -50;
67
0
      clipped = 1;
68
0
    }
69
0
    if (ratio[1] > 307)
70
0
    {
71
0
      ratio[1] = 307;
72
0
      clipped = 1;
73
0
    }
74
0
  }
75
0
  target = flash_used || ratio[1] < 197 ? -38 - (398 * ratio[1] >> 10)
76
0
                                        : -123 + (48 * ratio[1] >> 10);
77
0
  if (target - mar <= ratio[0] && target + 20 >= ratio[0] && !clipped)
78
0
    return 0;
79
0
  miss = target - ratio[0];
80
0
  if (abs(miss) >= mar * 4)
81
0
    return 2;
82
0
  if (miss < -20)
83
0
    miss = -20;
84
0
  if (miss > mar)
85
0
    miss = mar;
86
0
  ratio[0] = target - miss;
87
0
  return 1;
88
0
}
89
90
void LibRaw::canon_600_auto_wb()
91
0
{
92
0
  int mar, row, col, i, j, st, count[] = {0, 0};
93
0
  int test[8], total[2][8], ratio[2][2], stat[2];
94
95
0
  memset(&total, 0, sizeof total);
96
0
  i = int(canon_ev + 0.5);
97
0
  if (i < 10)
98
0
    mar = 150;
99
0
  else if (i > 12)
100
0
    mar = 20;
101
0
  else
102
0
    mar = 280 - 20 * i;
103
0
  if (flash_used)
104
0
    mar = 80;
105
0
  for (row = 14; row < height - 14; row += 4)
106
0
    for (col = 10; col < width; col += 2)
107
0
    {
108
0
      for (i = 0; i < 8; i++)
109
0
        test[(i & 4) + FC(row + (i >> 1), col + (i & 1))] =
110
0
            BAYER(row + (i >> 1), col + (i & 1));
111
0
      for (i = 0; i < 8; i++)
112
0
        if (test[i] < 150 || test[i] > 1500)
113
0
          goto next;
114
0
      for (i = 0; i < 4; i++)
115
0
        if (abs(test[i] - test[i + 4]) > 50)
116
0
          goto next;
117
0
      for (i = 0; i < 2; i++)
118
0
      {
119
0
        for (j = 0; j < 4; j += 2)
120
0
          ratio[i][j >> 1] =
121
0
              ((test[i * 4 + j + 1] - test[i * 4 + j]) << 10) / test[i * 4 + j];
122
0
        stat[i] = canon_600_color(ratio[i], mar);
123
0
      }
124
0
      if ((st = stat[0] | stat[1]) > 1)
125
0
        goto next;
126
0
      for (i = 0; i < 2; i++)
127
0
        if (stat[i])
128
0
          for (j = 0; j < 2; j++)
129
0
            test[i * 4 + j * 2 + 1] =
130
0
                test[i * 4 + j * 2] * (0x400 + ratio[i][j]) >> 10;
131
0
      for (i = 0; i < 8; i++)
132
0
        total[st][i] += test[i];
133
0
      count[st]++;
134
0
    next:;
135
0
    }
136
0
  if (count[0] | count[1])
137
0
  {
138
0
    st = count[0] * 200 < count[1];
139
0
    for (i = 0; i < 4; i++)
140
0
    if (total[st][i] + total[st][i + 4])
141
0
      pre_mul[i] = 1.0f / (total[st][i] + total[st][i + 4]);
142
0
  }
143
0
}
144
145
void LibRaw::canon_600_coeff()
146
0
{
147
0
  static const short table[6][12] = {
148
0
      {-190, 702, -1878, 2390, 1861, -1349, 905, -393, -432, 944, 2617, -2105},
149
0
      {-1203, 1715, -1136, 1648, 1388, -876, 267, 245, -1641, 2153, 3921,
150
0
       -3409},
151
0
      {-615, 1127, -1563, 2075, 1437, -925, 509, 3, -756, 1268, 2519, -2007},
152
0
      {-190, 702, -1886, 2398, 2153, -1641, 763, -251, -452, 964, 3040, -2528},
153
0
      {-190, 702, -1878, 2390, 1861, -1349, 905, -393, -432, 944, 2617, -2105},
154
0
      {-807, 1319, -1785, 2297, 1388, -876, 769, -257, -230, 742, 2067, -1555}};
155
0
  int t = 0, i, c;
156
0
  float mc, yc;
157
158
0
  mc = pre_mul[1] / pre_mul[2];
159
0
  yc = pre_mul[3] / pre_mul[2];
160
0
  if (mc > 1 && mc <= 1.28 && yc < 0.8789)
161
0
    t = 1;
162
0
  if (mc > 1.28 && mc <= 2)
163
0
  {
164
0
    if (yc < 0.8789)
165
0
      t = 3;
166
0
    else if (yc <= 2)
167
0
      t = 4;
168
0
  }
169
0
  if (flash_used)
170
0
    t = 5;
171
0
  for (raw_color = i = 0; i < 3; i++)
172
0
    FORCC rgb_cam[i][c] = float(table[t][i * 4 + c]) / 1024.f;
173
0
}
174
175
void LibRaw::canon_600_load_raw()
176
0
{
177
0
  uchar data[1120], *dp;
178
0
  ushort *pix;
179
0
  int irow, row;
180
181
0
  for (irow = row = 0; irow < height; irow++)
182
0
  {
183
0
    checkCancel();
184
0
    if (fread(data, 1, 1120, ifp) < 1120)
185
0
      derror();
186
0
    pix = raw_image + row * raw_width;
187
0
    for (dp = data; dp < data + 1120; dp += 10, pix += 8)
188
0
    {
189
0
      pix[0] = (dp[0] << 2) + (dp[1] >> 6);
190
0
      pix[1] = (dp[2] << 2) + (dp[1] >> 4 & 3);
191
0
      pix[2] = (dp[3] << 2) + (dp[1] >> 2 & 3);
192
0
      pix[3] = (dp[4] << 2) + (dp[1] & 3);
193
0
      pix[4] = (dp[5] << 2) + (dp[9] & 3);
194
0
      pix[5] = (dp[6] << 2) + (dp[9] >> 2 & 3);
195
0
      pix[6] = (dp[7] << 2) + (dp[9] >> 4 & 3);
196
0
      pix[7] = (dp[8] << 2) + (dp[9] >> 6);
197
0
    }
198
0
    if ((row += 2) > height)
199
0
      row = 1;
200
0
  }
201
0
}
202
203
void LibRaw::canon_600_correct()
204
0
{
205
0
  int row, col, val;
206
0
  static const short mul[4][2] = {
207
0
      {1141, 1145}, {1128, 1109}, {1178, 1149}, {1128, 1109}};
208
209
0
  for (row = 0; row < height; row++)
210
0
  {
211
0
    checkCancel();
212
0
    for (col = 0; col < width; col++)
213
0
    {
214
0
      if ((val = BAYER(row, col) - black) < 0)
215
0
        val = 0;
216
0
      val = val * mul[row & 3][col & 1] >> 9;
217
0
      BAYER(row, col) = val;
218
0
    }
219
0
  }
220
0
  canon_600_fixed_wb(1311);
221
0
  canon_600_auto_wb();
222
0
  canon_600_coeff();
223
0
  maximum = (0x3ff - black) * 1109 >> 9;
224
0
  black = 0;
225
0
}