File indexing completed on 2025-01-05 03:56:49

0001 /* -*- C++ -*-
0002  * Copyright 2019-2021 LibRaw LLC (info@libraw.org)
0003  *
0004  LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder,
0005  dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net.
0006  LibRaw do not use RESTRICTED code from dcraw.c
0007 
0008  LibRaw is free software; you can redistribute it and/or modify
0009  it under the terms of the one of two licenses as you choose:
0010 
0011 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
0012    (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
0013 
0014 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
0015    (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
0016 
0017  */
0018 
0019 #include "../../internal/dcraw_defs.h"
0020 
0021 void LibRaw::canon_600_fixed_wb(int temp)
0022 {
0023   static const short mul[4][5] = {{667, 358, 397, 565, 452},
0024                                   {731, 390, 367, 499, 517},
0025                                   {1119, 396, 348, 448, 537},
0026                                   {1399, 485, 431, 508, 688}};
0027   int lo, hi, i;
0028   float frac = 0;
0029 
0030   for (lo = 4; --lo;)
0031     if (*mul[lo] <= temp)
0032       break;
0033   for (hi = 0; hi < 3; hi++)
0034     if (*mul[hi] >= temp)
0035       break;
0036   if (lo != hi)
0037     frac = (float)(temp - *mul[lo]) / (*mul[hi] - *mul[lo]);
0038   for (i = 1; i < 5; i++)
0039     pre_mul[i - 1] = 1 / (frac * mul[hi][i] + (1 - frac) * mul[lo][i]);
0040 }
0041 
0042 /* Return values:  0 = white  1 = near white  2 = not white */
0043 int LibRaw::canon_600_color(int ratio[2], int mar)
0044 {
0045   int clipped = 0, target, miss;
0046 
0047   if (flash_used)
0048   {
0049     if (ratio[1] < -104)
0050     {
0051       ratio[1] = -104;
0052       clipped = 1;
0053     }
0054     if (ratio[1] > 12)
0055     {
0056       ratio[1] = 12;
0057       clipped = 1;
0058     }
0059   }
0060   else
0061   {
0062     if (ratio[1] < -264 || ratio[1] > 461)
0063       return 2;
0064     if (ratio[1] < -50)
0065     {
0066       ratio[1] = -50;
0067       clipped = 1;
0068     }
0069     if (ratio[1] > 307)
0070     {
0071       ratio[1] = 307;
0072       clipped = 1;
0073     }
0074   }
0075   target = flash_used || ratio[1] < 197 ? -38 - (398 * ratio[1] >> 10)
0076                                         : -123 + (48 * ratio[1] >> 10);
0077   if (target - mar <= ratio[0] && target + 20 >= ratio[0] && !clipped)
0078     return 0;
0079   miss = target - ratio[0];
0080   if (abs(miss) >= mar * 4)
0081     return 2;
0082   if (miss < -20)
0083     miss = -20;
0084   if (miss > mar)
0085     miss = mar;
0086   ratio[0] = target - miss;
0087   return 1;
0088 }
0089 
0090 void LibRaw::canon_600_auto_wb()
0091 {
0092   int mar, row, col, i, j, st, count[] = {0, 0};
0093   int test[8], total[2][8], ratio[2][2], stat[2];
0094 
0095   memset(&total, 0, sizeof total);
0096   i = int(canon_ev + 0.5);
0097   if (i < 10)
0098     mar = 150;
0099   else if (i > 12)
0100     mar = 20;
0101   else
0102     mar = 280 - 20 * i;
0103   if (flash_used)
0104     mar = 80;
0105   for (row = 14; row < height - 14; row += 4)
0106     for (col = 10; col < width; col += 2)
0107     {
0108       for (i = 0; i < 8; i++)
0109         test[(i & 4) + FC(row + (i >> 1), col + (i & 1))] =
0110             BAYER(row + (i >> 1), col + (i & 1));
0111       for (i = 0; i < 8; i++)
0112         if (test[i] < 150 || test[i] > 1500)
0113           goto next;
0114       for (i = 0; i < 4; i++)
0115         if (abs(test[i] - test[i + 4]) > 50)
0116           goto next;
0117       for (i = 0; i < 2; i++)
0118       {
0119         for (j = 0; j < 4; j += 2)
0120           ratio[i][j >> 1] =
0121               ((test[i * 4 + j + 1] - test[i * 4 + j]) << 10) / test[i * 4 + j];
0122         stat[i] = canon_600_color(ratio[i], mar);
0123       }
0124       if ((st = stat[0] | stat[1]) > 1)
0125         goto next;
0126       for (i = 0; i < 2; i++)
0127         if (stat[i])
0128           for (j = 0; j < 2; j++)
0129             test[i * 4 + j * 2 + 1] =
0130                 test[i * 4 + j * 2] * (0x400 + ratio[i][j]) >> 10;
0131       for (i = 0; i < 8; i++)
0132         total[st][i] += test[i];
0133       count[st]++;
0134     next:;
0135     }
0136   if (count[0] | count[1])
0137   {
0138     st = count[0] * 200 < count[1];
0139     for (i = 0; i < 4; i++)
0140         if (total[st][i] + total[st][i + 4])
0141             pre_mul[i] = 1.0f / (total[st][i] + total[st][i + 4]);
0142   }
0143 }
0144 
0145 void LibRaw::canon_600_coeff()
0146 {
0147   static const short table[6][12] = {
0148       {-190, 702, -1878, 2390, 1861, -1349, 905, -393, -432, 944, 2617, -2105},
0149       {-1203, 1715, -1136, 1648, 1388, -876, 267, 245, -1641, 2153, 3921,
0150        -3409},
0151       {-615, 1127, -1563, 2075, 1437, -925, 509, 3, -756, 1268, 2519, -2007},
0152       {-190, 702, -1886, 2398, 2153, -1641, 763, -251, -452, 964, 3040, -2528},
0153       {-190, 702, -1878, 2390, 1861, -1349, 905, -393, -432, 944, 2617, -2105},
0154       {-807, 1319, -1785, 2297, 1388, -876, 769, -257, -230, 742, 2067, -1555}};
0155   int t = 0, i, c;
0156   float mc, yc;
0157 
0158   mc = pre_mul[1] / pre_mul[2];
0159   yc = pre_mul[3] / pre_mul[2];
0160   if (mc > 1 && mc <= 1.28 && yc < 0.8789)
0161     t = 1;
0162   if (mc > 1.28 && mc <= 2)
0163   {
0164     if (yc < 0.8789)
0165       t = 3;
0166     else if (yc <= 2)
0167       t = 4;
0168   }
0169   if (flash_used)
0170     t = 5;
0171   for (raw_color = i = 0; i < 3; i++)
0172     FORCC rgb_cam[i][c] = float(table[t][i * 4 + c]) / 1024.f;
0173 }
0174 
0175 void LibRaw::canon_600_load_raw()
0176 {
0177   uchar data[1120], *dp;
0178   ushort *pix;
0179   int irow, row;
0180 
0181   for (irow = row = 0; irow < height; irow++)
0182   {
0183     checkCancel();
0184     if (fread(data, 1, 1120, ifp) < 1120)
0185       derror();
0186     pix = raw_image + row * raw_width;
0187     for (dp = data; dp < data + 1120; dp += 10, pix += 8)
0188     {
0189       pix[0] = (dp[0] << 2) + (dp[1] >> 6);
0190       pix[1] = (dp[2] << 2) + (dp[1] >> 4 & 3);
0191       pix[2] = (dp[3] << 2) + (dp[1] >> 2 & 3);
0192       pix[3] = (dp[4] << 2) + (dp[1] & 3);
0193       pix[4] = (dp[5] << 2) + (dp[9] & 3);
0194       pix[5] = (dp[6] << 2) + (dp[9] >> 2 & 3);
0195       pix[6] = (dp[7] << 2) + (dp[9] >> 4 & 3);
0196       pix[7] = (dp[8] << 2) + (dp[9] >> 6);
0197     }
0198     if ((row += 2) > height)
0199       row = 1;
0200   }
0201 }
0202 
0203 void LibRaw::canon_600_correct()
0204 {
0205   int row, col, val;
0206   static const short mul[4][2] = {
0207       {1141, 1145}, {1128, 1109}, {1178, 1149}, {1128, 1109}};
0208 
0209   for (row = 0; row < height; row++)
0210   {
0211     checkCancel();
0212     for (col = 0; col < width; col++)
0213     {
0214       if ((val = BAYER(row, col) - black) < 0)
0215         val = 0;
0216       val = val * mul[row & 3][col & 1] >> 9;
0217       BAYER(row, col) = val;
0218     }
0219   }
0220   canon_600_fixed_wb(1311);
0221   canon_600_auto_wb();
0222   canon_600_coeff();
0223   maximum = (0x3ff - black) * 1109 >> 9;
0224   black = 0;
0225 }