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

0001 /* -*- C++ -*-
0002  * Copyright 2019-2021 LibRaw LLC (info@libraw.org)
0003  *
0004  LibRaw is free software; you can redistribute it and/or modify
0005  it under the terms of the one of two licenses as you choose:
0006 
0007 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
0008    (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
0009 
0010 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
0011    (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
0012 
0013  */
0014 
0015 #include "../../internal/libraw_cxx_defs.h"
0016 
0017 #define TBLN 65535
0018 
0019 void LibRaw::exp_bef(float shift, float smooth)
0020 {
0021   // params limits
0022   if (shift > 8)
0023     shift = 8;
0024   if (shift < 0.25)
0025     shift = 0.25;
0026   if (smooth < 0.0)
0027     smooth = 0.0;
0028   if (smooth > 1.0)
0029     smooth = 1.0;
0030 
0031   unsigned short *lut = (ushort *)malloc((TBLN + 1) * sizeof(unsigned short));
0032 
0033   if (shift <= 1.0)
0034   {
0035     for (int i = 0; i <= TBLN; i++)
0036       lut[i] = (unsigned short)((float)i * shift);
0037   }
0038   else
0039   {
0040     float x1, x2, y1, y2;
0041 
0042     float cstops = log(shift) / log(2.0f);
0043     float room = cstops * 2;
0044     float roomlin = powf(2.0f, room);
0045     x2 = (float)TBLN;
0046     x1 = (x2 + 1) / roomlin - 1;
0047     y1 = x1 * shift;
0048     y2 = x2 * (1 + (1 - smooth) * (shift - 1));
0049     float sq3x = powf(x1 * x1 * x2, 1.0f / 3.0f);
0050     float B = (y2 - y1 + shift * (3 * x1 - 3.0f * sq3x)) /
0051               (x2 + 2.0f * x1 - 3.0f * sq3x);
0052     float A = (shift - B) * 3.0f * powf(x1 * x1, 1.0f / 3.0f);
0053     float CC = y2 - A * powf(x2, 1.0f / 3.0f) - B * x2;
0054     for (int i = 0; i <= TBLN; i++)
0055     {
0056       float X = (float)i;
0057       float Y = A * powf(X, 1.0f / 3.0f) + B * X + CC;
0058       if (i < x1)
0059         lut[i] = (unsigned short)((float)i * shift);
0060       else
0061         lut[i] = Y < 0 ? 0 : (Y > TBLN ? TBLN : (unsigned short)(Y));
0062     }
0063   }
0064   for (int i = 0; i < S.height * S.width; i++)
0065   {
0066     imgdata.image[i][0] = lut[imgdata.image[i][0]];
0067     imgdata.image[i][1] = lut[imgdata.image[i][1]];
0068     imgdata.image[i][2] = lut[imgdata.image[i][2]];
0069     imgdata.image[i][3] = lut[imgdata.image[i][3]];
0070   }
0071 
0072   if (C.data_maximum <= TBLN)
0073     C.data_maximum = lut[C.data_maximum];
0074   if (C.maximum <= TBLN)
0075     C.maximum = lut[C.maximum];
0076   free(lut);
0077 }
0078 
0079 void LibRaw::convert_to_rgb_loop(float out_cam[3][4])
0080 {
0081   int row, col, c;
0082   float out[3];
0083   ushort *img;
0084   memset(libraw_internal_data.output_data.histogram, 0,
0085          sizeof(int) * LIBRAW_HISTOGRAM_SIZE * 4);
0086   if (libraw_internal_data.internal_output_params.raw_color)
0087   {
0088     for (img = imgdata.image[0], row = 0; row < S.height; row++)
0089     {
0090       for (col = 0; col < S.width; col++, img += 4)
0091       {
0092         for (c = 0; c < imgdata.idata.colors; c++)
0093         {
0094           libraw_internal_data.output_data.histogram[c][img[c] >> 3]++;
0095         }
0096       }
0097     }
0098   }
0099   else if (imgdata.idata.colors == 3)
0100   {
0101     for (img = imgdata.image[0], row = 0; row < S.height; row++)
0102     {
0103       for (col = 0; col < S.width; col++, img += 4)
0104       {
0105         out[0] = out_cam[0][0] * img[0] + out_cam[0][1] * img[1] +
0106                  out_cam[0][2] * img[2];
0107         out[1] = out_cam[1][0] * img[0] + out_cam[1][1] * img[1] +
0108                  out_cam[1][2] * img[2];
0109         out[2] = out_cam[2][0] * img[0] + out_cam[2][1] * img[1] +
0110                  out_cam[2][2] * img[2];
0111         img[0] = CLIP((int)out[0]);
0112         img[1] = CLIP((int)out[1]);
0113         img[2] = CLIP((int)out[2]);
0114         libraw_internal_data.output_data.histogram[0][img[0] >> 3]++;
0115         libraw_internal_data.output_data.histogram[1][img[1] >> 3]++;
0116         libraw_internal_data.output_data.histogram[2][img[2] >> 3]++;
0117       }
0118     }
0119   }
0120   else if (imgdata.idata.colors == 4)
0121   {
0122     for (img = imgdata.image[0], row = 0; row < S.height; row++)
0123     {
0124       for (col = 0; col < S.width; col++, img += 4)
0125       {
0126         out[0] = out_cam[0][0] * img[0] + out_cam[0][1] * img[1] +
0127                  out_cam[0][2] * img[2] + out_cam[0][3] * img[3];
0128         out[1] = out_cam[1][0] * img[0] + out_cam[1][1] * img[1] +
0129                  out_cam[1][2] * img[2] + out_cam[1][3] * img[3];
0130         out[2] = out_cam[2][0] * img[0] + out_cam[2][1] * img[1] +
0131                  out_cam[2][2] * img[2] + out_cam[2][3] * img[3];
0132         img[0] = CLIP((int)out[0]);
0133         img[1] = CLIP((int)out[1]);
0134         img[2] = CLIP((int)out[2]);
0135         libraw_internal_data.output_data.histogram[0][img[0] >> 3]++;
0136         libraw_internal_data.output_data.histogram[1][img[1] >> 3]++;
0137         libraw_internal_data.output_data.histogram[2][img[2] >> 3]++;
0138         libraw_internal_data.output_data.histogram[3][img[3] >> 3]++;
0139       }
0140     }
0141   }
0142 }
0143 
0144 void LibRaw::scale_colors_loop(float scale_mul[4])
0145 {
0146   unsigned size = S.iheight * S.iwidth;
0147 
0148   if (C.cblack[4] && C.cblack[5])
0149   {
0150     int val;
0151     for (unsigned i = 0; i < size; i++)
0152     {
0153       for (unsigned c = 0; c < 4; c++)
0154       {
0155         if (!(val = imgdata.image[i][c])) continue;
0156         val -= C.cblack[6 + i / S.iwidth % C.cblack[4] * C.cblack[5] +
0157                         i % S.iwidth % C.cblack[5]];
0158         val -= C.cblack[c];
0159         val *= scale_mul[c];
0160         imgdata.image[i][c] = CLIP(val);
0161       }
0162     }
0163   }
0164   else if (C.cblack[0] || C.cblack[1] || C.cblack[2] || C.cblack[3])
0165   {
0166     for (unsigned i = 0; i < size; i++)
0167     {
0168       for (unsigned c = 0; c < 4; c++)
0169       {
0170         int val = imgdata.image[i][c];
0171         if (!val) continue;
0172         val -= C.cblack[c];
0173         val *= scale_mul[c];
0174         imgdata.image[i][c] = CLIP(val);
0175       }
0176     }
0177   }
0178   else // BL is zero
0179   {
0180     for (unsigned i = 0; i < size; i++)
0181     {
0182       for (unsigned c = 0; c < 4; c++)
0183       {
0184         int val = imgdata.image[i][c];
0185         val *= scale_mul[c];
0186         imgdata.image[i][c] = CLIP(val);
0187       }
0188     }
0189   }
0190 }