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

0001 /* -*- C++ -*-
0002  * Copyright 2019-2021 LibRaw LLC (info@libraw.org)
0003  *
0004 
0005  LibRaw is free software; you can redistribute it and/or modify
0006  it under the terms of the one of two licenses as you choose:
0007 
0008 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
0009    (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
0010 
0011 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
0012    (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
0013 
0014  */
0015 
0016 #include "../../internal/libraw_cxx_defs.h"
0017 
0018 int LibRaw::subtract_black()
0019 {
0020   adjust_bl();
0021   return subtract_black_internal();
0022 }
0023 
0024 int LibRaw::subtract_black_internal()
0025 {
0026   CHECK_ORDER_LOW(LIBRAW_PROGRESS_RAW2_IMAGE);
0027 
0028   try
0029   {
0030     if (!is_phaseone_compressed() &&
0031         (C.cblack[0] || C.cblack[1] || C.cblack[2] || C.cblack[3] ||
0032          (C.cblack[4] && C.cblack[5])))
0033     {
0034       int cblk[4], i;
0035       for (i = 0; i < 4; i++)
0036         cblk[i] = C.cblack[i];
0037 
0038       int size = S.iheight * S.iwidth;
0039       int dmax = 0;
0040       if (C.cblack[4] && C.cblack[5])
0041       {
0042         for (unsigned q = 0; q < (unsigned)size; q++)
0043         {
0044           for (unsigned c = 0; c < 4; c++)
0045           {
0046             int val = imgdata.image[q][c];
0047             val -= C.cblack[6 + q / S.iwidth % C.cblack[4] * C.cblack[5] +
0048                             q % S.iwidth % C.cblack[5]];
0049             val -= cblk[c];
0050             imgdata.image[q][c] = CLIP(val);
0051             if (dmax < val) dmax = val;
0052           }
0053         }
0054       }
0055       else
0056       {
0057         for (unsigned q = 0; q < (unsigned)size; q++)
0058         {
0059           for (unsigned c = 0; c < 4; c++)
0060           {
0061             int val = imgdata.image[q][c];
0062             val -= cblk[c];
0063             imgdata.image[q][c] = CLIP(val);
0064             if (dmax < val) dmax = val;
0065           }
0066         }
0067       }
0068       C.data_maximum = dmax & 0xffff;
0069       C.maximum -= C.black;
0070       ZERO(C.cblack); // Yeah, we used cblack[6+] values too!
0071       C.black = 0;
0072     }
0073     else
0074     {
0075       // Nothing to Do, maximum is already calculated, black level is 0, so no
0076       // change only calculate channel maximum;
0077       int idx;
0078       ushort *p = (ushort *)imgdata.image;
0079       int dmax = 0;
0080       for (idx = 0; idx < S.iheight * S.iwidth * 4; idx++)
0081         if (dmax < p[idx])
0082           dmax = p[idx];
0083       C.data_maximum = dmax;
0084     }
0085     return 0;
0086   }
0087   catch (const LibRaw_exceptions& err)
0088   {
0089     EXCEPTION_HANDLER(err);
0090   }
0091 }