File indexing completed on 2025-01-05 03:57:07

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::cubic_spline(const int *x_, const int *y_, const int len)
0022 {
0023   float **A, *b, *c, *d, *x, *y;
0024   int i, j;
0025 
0026   A = (float **)calloc(((2 * len + 4) * sizeof **A + sizeof *A), 2 * len);
0027   if (!A)
0028     return;
0029   A[0] = (float *)(A + 2 * len);
0030   for (i = 1; i < 2 * len; i++)
0031     A[i] = A[0] + 2 * len * i;
0032   y = len + (x = i + (d = i + (c = i + (b = A[0] + i * i))));
0033   for (i = 0; i < len; i++)
0034   {
0035     x[i] = x_[i] / 65535.0;
0036     y[i] = y_[i] / 65535.0;
0037   }
0038   for (i = len - 1; i > 0; i--)
0039   {
0040     float _div = x[i] - x[i - 1];
0041     if (fabs(_div) < 1.0e-15)
0042         _div = 1;
0043     b[i] = (y[i] - y[i - 1]) / _div;
0044     d[i - 1] = _div;
0045   }
0046   for (i = 1; i < len - 1; i++)
0047   {
0048     A[i][i] = 2 * (d[i - 1] + d[i]);
0049     if (i > 1)
0050     {
0051       A[i][i - 1] = d[i - 1];
0052       A[i - 1][i] = d[i - 1];
0053     }
0054     A[i][len - 1] = 6 * (b[i + 1] - b[i]);
0055   }
0056   for (i = 1; i < len - 2; i++)
0057   {
0058     float v = A[i + 1][i] / A[i][i];
0059     for (j = 1; j <= len - 1; j++)
0060       A[i + 1][j] -= v * A[i][j];
0061   }
0062   for (i = len - 2; i > 0; i--)
0063   {
0064     float acc = 0;
0065     for (j = i; j <= len - 2; j++)
0066       acc += A[i][j] * c[j];
0067     c[i] = (A[i][len - 1] - acc) / A[i][i];
0068   }
0069   for (i = 0; i < 0x10000; i++)
0070   {
0071     float x_out = (float)(i / 65535.0);
0072     float y_out = 0;
0073     for (j = 0; j < len - 1; j++)
0074     {
0075       if (x[j] <= x_out && x_out <= x[j + 1])
0076       {
0077         float v = x_out - x[j];
0078         y_out = y[j] +
0079                 ((y[j + 1] - y[j]) / d[j] -
0080                  (2 * d[j] * c[j] + c[j + 1] * d[j]) / 6) *
0081                     v +
0082                 (c[j] * 0.5) * v * v +
0083                 ((c[j + 1] - c[j]) / (6 * d[j])) * v * v * v;
0084       }
0085     }
0086     curve[i] = y_out < 0.0
0087                    ? 0
0088                    : (y_out >= 1.0 ? 65535 : (ushort)(y_out * 65535.0 + 0.5));
0089   }
0090   free(A);
0091 }
0092 void LibRaw::gamma_curve(double pwr, double ts, int mode, int imax)
0093 {
0094   int i;
0095   double g[6], bnd[2] = {0, 0}, r;
0096 
0097   g[0] = pwr;
0098   g[1] = ts;
0099   g[2] = g[3] = g[4] = 0;
0100   bnd[g[1] >= 1] = 1;
0101   if (g[1] && (g[1] - 1) * (g[0] - 1) <= 0)
0102   {
0103     for (i = 0; i < 48; i++)
0104     {
0105       g[2] = (bnd[0] + bnd[1]) / 2;
0106       if (g[0])
0107         bnd[(pow(g[2] / g[1], -g[0]) - 1) / g[0] - 1 / g[2] > -1] = g[2];
0108       else
0109         bnd[g[2] / exp(1 - 1 / g[2]) < g[1]] = g[2];
0110     }
0111     g[3] = g[2] / g[1];
0112     if (g[0])
0113       g[4] = g[2] * (1 / g[0] - 1);
0114   }
0115   if (g[0])
0116     g[5] = 1 / (g[1] * SQR(g[3]) / 2 - g[4] * (1 - g[3]) +
0117                 (1 - pow(g[3], 1 + g[0])) * (1 + g[4]) / (1 + g[0])) -
0118            1;
0119   else
0120     g[5] = 1 / (g[1] * SQR(g[3]) / 2 + 1 - g[2] - g[3] -
0121                 g[2] * g[3] * (log(g[3]) - 1)) -
0122            1;
0123   if (!mode--)
0124   {
0125     memcpy(gamm, g, sizeof gamm);
0126     return;
0127   }
0128   for (i = 0; i < 0x10000; i++)
0129   {
0130     curve[i] = 0xffff;
0131     if ((r = (double)i / imax) < 1)
0132       curve[i] =
0133           0x10000 *
0134           (mode ? (r < g[3] ? r * g[1]
0135                             : (g[0] ? pow(r, g[0]) * (1 + g[4]) - g[4]
0136                                     : log(r) * g[2] + 1))
0137                 : (r < g[2] ? r / g[1]
0138                             : (g[0] ? pow((r + g[4]) / (1 + g[4]), 1 / g[0])
0139                                     : exp((r - 1) / g[2]))));
0140   }
0141 }
0142 
0143 void LibRaw::linear_table(unsigned len)
0144 {
0145   int i;
0146   if (len > 0x10000)
0147     len = 0x10000;
0148   else if (len < 1)
0149     return;
0150   read_shorts(curve, len);
0151   for (i = len; i < 0x10000; i++)
0152     curve[i] = curve[i - 1];
0153   maximum = curve[len < 0x1000 ? 0xfff : len - 1];
0154 }