/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

// This file is available under and governed by the GNU General Public
// License version 2 only, as published by the Free Software Foundation.
// However, the following notice accompanied the original version of this
// file:
//
//---------------------------------------------------------------------------------
//
//  Little Color Management System
//  Copyright (c) 1998-2024 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the Software
// is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//---------------------------------------------------------------------------------
//

#include "lcms2_internal.h"


#define cmsmin(a, b) (((a) < (b)) ? (a) : (b))
#define cmsmax(a, b) (((a) > (b)) ? (a) : (b))

// This file contains routines for resampling and LUT optimization, black point detection
// and black preservation.

// Black point detection -------------------------------------------------------------------------


// PCS -> PCS round trip transform, always uses relative intent on the device -> pcs
static
cmsHTRANSFORM CreateRoundtripXForm(cmsHPROFILE hProfile, cmsUInt32Number nIntent)
{
    cmsContext ContextID = cmsGetProfileContextID(hProfile);
    cmsHPROFILE hLab = cmsCreateLab4ProfileTHR(ContextID, NULL);
    cmsHTRANSFORM xform;
    cmsBool BPC[4] = { FALSE, FALSE, FALSE, FALSE };
    cmsFloat64Number States[4] = { 1.0, 1.0, 1.0, 1.0 };
    cmsHPROFILE hProfiles[4];
    cmsUInt32Number Intents[4];

    hProfiles[0] = hLab; hProfiles[1] = hProfile; hProfiles[2] = hProfile; hProfiles[3] = hLab;
    Intents[0]   = INTENT_RELATIVE_COLORIMETRIC; Intents[1] = nIntent; Intents[2] = INTENT_RELATIVE_COLORIMETRIC; Intents[3] = INTENT_RELATIVE_COLORIMETRIC;

    xform =  cmsCreateExtendedTransform(ContextID, 4, hProfiles, BPC, Intents,
        States, NULL, 0, TYPE_Lab_DBL, TYPE_Lab_DBL, cmsFLAGS_NOCACHE|cmsFLAGS_NOOPTIMIZE);

    cmsCloseProfile(hLab);
    return xform;
}

// Use darker colorants to obtain black point. This works in the relative colorimetric intent and
// assumes more ink results in darker colors. No ink limit is assumed.
static
cmsBool  BlackPointAsDarkerColorant(cmsHPROFILE    hInput,
                                    cmsUInt32Number Intent,
                                    cmsCIEXYZ* BlackPoint,
                                    cmsUInt32Number dwFlags)
{
    cmsUInt16Number *Black;
    cmsHTRANSFORM xform;
    cmsColorSpaceSignature Space;
    cmsUInt32Number nChannels;
    cmsUInt32Number dwFormat;
    cmsHPROFILE hLab;
    cmsCIELab  Lab;
    cmsCIEXYZ  BlackXYZ;
    cmsContext ContextID = cmsGetProfileContextID(hInput);

    // If the profile does not support input direction, assume Black point 0
    if (!cmsIsIntentSupported(hInput, Intent, LCMS_USED_AS_INPUT)) {

        BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0;
        return FALSE;
    }

    // Create a formatter which has n channels and no floating point
    dwFormat = cmsFormatterForColorspaceOfProfile(hInput, 2, FALSE);

    // Try to get black by using black colorant
    Space = cmsGetColorSpace(hInput);

    // This function returns darker colorant in 16 bits for several spaces
    if (!_cmsEndPointsBySpace(Space, NULL, &Black, &nChannels)) {

        BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0;
        return FALSE;
    }

    if (nChannels != T_CHANNELS(dwFormat)) {
       BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0;
       return FALSE;
    }

    // Lab will be used as the output space, but lab2 will avoid recursion
    hLab = cmsCreateLab2ProfileTHR(ContextID, NULL);
    if (hLab == NULL) {
       BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0;
       return FALSE;
    }

    // Create the transform
    xform = cmsCreateTransformTHR(ContextID, hInput, dwFormat,
                                hLab, TYPE_Lab_DBL, Intent, cmsFLAGS_NOOPTIMIZE|cmsFLAGS_NOCACHE);
    cmsCloseProfile(hLab);

    if (xform == NULL) {

        // Something went wrong. Get rid of open resources and return zero as black
        BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0;
        return FALSE;
    }

    // Convert black to Lab
    cmsDoTransform(xform, Black, &Lab, 1);

    // Force it to be neutral, check for inconsistencies
    Lab.a = Lab.b = 0;
    if (Lab.L > 50 || Lab.L < 0) Lab.L = 0;

    // Free the resources
    cmsDeleteTransform(xform);

    // Convert from Lab (which is now clipped) to XYZ.
    cmsLab2XYZ(NULL, &BlackXYZ, &Lab);

    if (BlackPoint != NULL)
        *BlackPoint = BlackXYZ;

    return TRUE;

    cmsUNUSED_PARAMETER(dwFlags);
}

// Get a black point of output CMYK profile, discounting any ink-limiting embedded
// in the profile. For doing that, we use perceptual intent in input direction:
// Lab (0, 0, 0) -> [Perceptual] Profile -> CMYK -> [Rel. colorimetric] Profile -> Lab
static
cmsBool BlackPointUsingPerceptualBlack(cmsCIEXYZ* BlackPoint, cmsHPROFILE hProfile)
{
    cmsHTRANSFORM hRoundTrip;
    cmsCIELab LabIn, LabOut;
    cmsCIEXYZ  BlackXYZ;

     // Is the intent supported by the profile?
    if (!cmsIsIntentSupported(hProfile, INTENT_PERCEPTUAL, LCMS_USED_AS_INPUT)) {

        BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0;
        return TRUE;
    }

    hRoundTrip = CreateRoundtripXForm(hProfile, INTENT_PERCEPTUAL);
    if (hRoundTrip == NULL) {
        BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0;
        return FALSE;
    }

    LabIn.L = LabIn.a = LabIn.b = 0;
    cmsDoTransform(hRoundTrip, &LabIn, &LabOut, 1);

    // Clip Lab to reasonable limits
    if (LabOut.L > 50) LabOut.L = 50;
    LabOut.a = LabOut.b = 0;

    cmsDeleteTransform(hRoundTrip);

    // Convert it to XYZ
    cmsLab2XYZ(NULL, &BlackXYZ, &LabOut);

    if (BlackPoint != NULL)
        *BlackPoint = BlackXYZ;

    return TRUE;
}

// This function shouldn't exist at all -- there is such quantity of broken
// profiles on black point tag, that we must somehow fix chromaticity to
// avoid huge tint when doing Black point compensation. This function does
// just that. There is a special flag for using black point tag, but turned
// off by default because it is bogus on most profiles. The detection algorithm
// involves to turn BP to neutral and to use only L component.
cmsBool CMSEXPORT cmsDetectBlackPoint(cmsCIEXYZ* BlackPoint, cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number dwFlags)
{
    cmsProfileClassSignature devClass;

    // Make sure the device class is adequate
    devClass = cmsGetDeviceClass(hProfile);
    if (devClass == cmsSigLinkClass ||
        devClass == cmsSigAbstractClass ||
        devClass == cmsSigNamedColorClass) {
            BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0;
            return FALSE;
    }

    // Make sure intent is adequate
    if (Intent != INTENT_PERCEPTUAL &&
        Intent != INTENT_RELATIVE_COLORIMETRIC &&
        Intent != INTENT_SATURATION) {
            BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0;
            return FALSE;
    }

    // v4 + perceptual & saturation intents does have its own black point, and it is
    // well specified enough to use it. Black point tag is deprecated in V4.
    if ((cmsGetEncodedICCversion(hProfile) >= 0x4000000) &&
        (Intent == INTENT_PERCEPTUAL || Intent == INTENT_SATURATION)) {

            // Matrix shaper share MRC & perceptual intents
            if (cmsIsMatrixShaper(hProfile))
                return BlackPointAsDarkerColorant(hProfile, INTENT_RELATIVE_COLORIMETRIC, BlackPoint, 0);

            // Get Perceptual black out of v4 profiles. That is fixed for perceptual & saturation intents
            BlackPoint -> X = cmsPERCEPTUAL_BLACK_X;
            BlackPoint -> Y = cmsPERCEPTUAL_BLACK_Y;
            BlackPoint -> Z = cmsPERCEPTUAL_BLACK_Z;

            return TRUE;
    }


#ifdef CMS_USE_PROFILE_BLACK_POINT_TAG

    // v2, v4 rel/abs colorimetric
    if (cmsIsTag(hProfile, cmsSigMediaBlackPointTag) &&
        Intent == INTENT_RELATIVE_COLORIMETRIC) {

            cmsCIEXYZ *BlackPtr, BlackXYZ, UntrustedBlackPoint, TrustedBlackPoint, MediaWhite;
            cmsCIELab Lab;

            // If black point is specified, then use it,

            BlackPtr = cmsReadTag(hProfile, cmsSigMediaBlackPointTag);
            if (BlackPtr != NULL) {

                BlackXYZ = *BlackPtr;
                _cmsReadMediaWhitePoint(&MediaWhite, hProfile);

                // Black point is absolute XYZ, so adapt to D50 to get PCS value
                cmsAdaptToIlluminant(&UntrustedBlackPoint, &MediaWhite, cmsD50_XYZ(), &BlackXYZ);

                // Force a=b=0 to get rid of any chroma
                cmsXYZ2Lab(NULL, &Lab, &UntrustedBlackPoint);
                Lab.a = Lab.b = 0;
                if (Lab.L > 50) Lab.L = 50; // Clip to L* <= 50
                cmsLab2XYZ(NULL, &TrustedBlackPoint, &Lab);

                if (BlackPoint != NULL)
                    *BlackPoint = TrustedBlackPoint;

                return TRUE;
            }
    }
#endif

    // That is about v2 profiles.

    // If output profile, discount ink-limiting and that's all
    if (Intent == INTENT_RELATIVE_COLORIMETRIC &&
        (cmsGetDeviceClass(hProfile) == cmsSigOutputClass) &&
        (cmsGetColorSpace(hProfile)  == cmsSigCmykData))
        return BlackPointUsingPerceptualBlack(BlackPoint, hProfile);

    // Nope, compute BP using current intent.
    return BlackPointAsDarkerColorant(hProfile, Intent, BlackPoint, dwFlags);
}



// ---------------------------------------------------------------------------------------------------------

// Least Squares Fit of a Quadratic Curve to Data
// http://www.personal.psu.edu/jhm/f90/lectures/lsq2.html

static
cmsFloat64Number RootOfLeastSquaresFitQuadraticCurve(int n, cmsFloat64Number x[], cmsFloat64Number y[])
{
    double sum_x = 0, sum_x2 = 0, sum_x3 = 0, sum_x4 = 0;
    double sum_y = 0, sum_yx = 0, sum_yx2 = 0;
    double d, a, b, c;
    int i;
    cmsMAT3 m;
    cmsVEC3 v, res;

    if (n < 4) return 0;

    for (i=0; i < n; i++) {

        double xn = x[i];
        double yn = y[i];

        sum_x  += xn;
        sum_x2 += xn*xn;
        sum_x3 += xn*xn*xn;
        sum_x4 += xn*xn*xn*xn;

        sum_y += yn;
        sum_yx += yn*xn;
        sum_yx2 += yn*xn*xn;
    }

    _cmsVEC3init(&m.v[0], n,      sum_x,  sum_x2);
    _cmsVEC3init(&m.v[1], sum_x,  sum_x2, sum_x3);
    _cmsVEC3init(&m.v[2], sum_x2, sum_x3, sum_x4);

    _cmsVEC3init(&v, sum_y, sum_yx, sum_yx2);

    if (!_cmsMAT3solve(&res, &m, &v)) return 0;


    a = res.n[2];
    b = res.n[1];
    c = res.n[0];

    if (fabs(a) < 1.0E-10) {

        if (fabs(b) < 1.0E-10) return 0;
        return cmsmin(0, cmsmax(50, -c/b ));
    }
    else {

         d = b*b - 4.0 * a * c;
         if (d <= 0) {
             return 0;
         }
         else {

             double rt;

             if (fabs(a) < 1.0E-10) return 0;

             rt = (-b + sqrt(d)) / (2.0 * a);

             return cmsmax(0, cmsmin(50, rt));
         }
   }

}



// Calculates the black point of a destination profile.
// This algorithm comes from the Adobe paper disclosing its black point compensation method.
cmsBool CMSEXPORT cmsDetectDestinationBlackPoint(cmsCIEXYZ* BlackPoint, cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number dwFlags)
{
    cmsColorSpaceSignature ColorSpace;
    cmsHTRANSFORM hRoundTrip = NULL;
    cmsCIELab InitialLab, destLab, Lab;
    cmsFloat64Number inRamp[256], outRamp[256];
    cmsFloat64Number MinL, MaxL;
    cmsBool NearlyStraightMidrange = TRUE;
    cmsFloat64Number yRamp[256];
    cmsFloat64Number x[256], y[256];
    cmsFloat64Number lo, hi;
    int n, l;
    cmsProfileClassSignature devClass;

    // Make sure the device class is adequate
    devClass = cmsGetDeviceClass(hProfile);
    if (devClass == cmsSigLinkClass ||
        devClass == cmsSigAbstractClass ||
        devClass == cmsSigNamedColorClass) {
            BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0;
            return FALSE;
    }

    // Make sure intent is adequate
    if (Intent != INTENT_PERCEPTUAL &&
        Intent != INTENT_RELATIVE_COLORIMETRIC &&
        Intent != INTENT_SATURATION) {
            BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0;
            return FALSE;
    }


    // v4 + perceptual & saturation intents does have its own black point, and it is
    // well specified enough to use it. Black point tag is deprecated in V4.
    if ((cmsGetEncodedICCversion(hProfile) >= 0x4000000) &&
        (Intent == INTENT_PERCEPTUAL || Intent == INTENT_SATURATION)) {

            // Matrix shaper share MRC & perceptual intents
            if (cmsIsMatrixShaper(hProfile))
                return BlackPointAsDarkerColorant(hProfile, INTENT_RELATIVE_COLORIMETRIC, BlackPoint, 0);

            // Get Perceptual black out of v4 profiles. That is fixed for perceptual & saturation intents
            BlackPoint -> X = cmsPERCEPTUAL_BLACK_X;
            BlackPoint -> Y = cmsPERCEPTUAL_BLACK_Y;
            BlackPoint -> Z = cmsPERCEPTUAL_BLACK_Z;
            return TRUE;
    }


    // Check if the profile is lut based and gray, rgb or cmyk (7.2 in Adobe's document)
    ColorSpace = cmsGetColorSpace(hProfile);
    if (!cmsIsCLUT(hProfile, Intent, LCMS_USED_AS_OUTPUT ) ||
        (ColorSpace != cmsSigGrayData &&
         ColorSpace != cmsSigRgbData  &&
         ColorSpace != cmsSigCmykData)) {

        // In this case, handle as input case
        return cmsDetectBlackPoint(BlackPoint, hProfile, Intent, dwFlags);
    }

    // It is one of the valid cases!, use Adobe algorithm


    // Set a first guess, that should work on good profiles.
    if (Intent == INTENT_RELATIVE_COLORIMETRIC) {

        cmsCIEXYZ IniXYZ;

        // calculate initial Lab as source black point
        if (!cmsDetectBlackPoint(&IniXYZ, hProfile, Intent, dwFlags)) {
            return FALSE;
        }

        // convert the XYZ to lab
        cmsXYZ2Lab(NULL, &InitialLab, &IniXYZ);

    } else {

        // set the initial Lab to zero, that should be the black point for perceptual and saturation
        InitialLab.L = 0;
        InitialLab.a = 0;
        InitialLab.b = 0;
    }


    // Step 2
    // ======

    // Create a roundtrip. Define a Transform BT for all x in L*a*b*
    hRoundTrip = CreateRoundtripXForm(hProfile, Intent);
    if (hRoundTrip == NULL)  return FALSE;

    // Compute ramps

    for (l=0; l < 256; l++) {

        Lab.L = (cmsFloat64Number) (l * 100.0) / 255.0;
        Lab.a = cmsmin(50, cmsmax(-50, InitialLab.a));
        Lab.b = cmsmin(50, cmsmax(-50, InitialLab.b));

        cmsDoTransform(hRoundTrip, &Lab, &destLab, 1);

        inRamp[l]  = Lab.L;
        outRamp[l] = destLab.L;
    }

    // Make monotonic
    for (l = 254; l > 0; --l) {
        outRamp[l] = cmsmin(outRamp[l], outRamp[l+1]);
    }

    // Check
    if (! (outRamp[0] < outRamp[255])) {

        cmsDeleteTransform(hRoundTrip);
        BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0;
        return FALSE;
    }


    // Test for mid range straight (only on relative colorimetric)
    NearlyStraightMidrange = TRUE;
    MinL = outRamp[0]; MaxL = outRamp[255];
    if (Intent == INTENT_RELATIVE_COLORIMETRIC) {

        for (l=0; l < 256; l++) {

            if (! ((inRamp[l] <= MinL + 0.2 * (MaxL - MinL) ) ||
                (fabs(inRamp[l] - outRamp[l]) < 4.0 )))
                NearlyStraightMidrange = FALSE;
        }

        // If the mid range is straight (as determined above) then the
        // DestinationBlackPoint shall be the same as initialLab.
        // Otherwise, the DestinationBlackPoint shall be determined
        // using curve fitting.
        if (NearlyStraightMidrange) {

            cmsLab2XYZ(NULL, BlackPoint, &InitialLab);
            cmsDeleteTransform(hRoundTrip);
            return TRUE;
        }
    }


    // curve fitting: The round-trip curve normally looks like a nearly constant section at the black point,
    // with a corner and a nearly straight line to the white point.
    for (l=0; l < 256; l++) {

        yRamp[l] = (outRamp[l] - MinL) / (MaxL - MinL);
    }

    // find the black point using the least squares error quadratic curve fitting
    if (Intent == INTENT_RELATIVE_COLORIMETRIC) {
        lo = 0.1;
        hi = 0.5;
    }
    else {

        // Perceptual and saturation
        lo = 0.03;
        hi = 0.25;
    }

    // Capture shadow points for the fitting.
    n = 0;
    for (l=0; l < 256; l++) {

        cmsFloat64Number ff = yRamp[l];

        if (ff >= lo && ff < hi) {
            x[n] = inRamp[l];
            y[n] = yRamp[l];
            n++;
        }
    }


    // No suitable points
    if (n < 3 ) {
        cmsDeleteTransform(hRoundTrip);
        BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0;
        return FALSE;
    }


    // fit and get the vertex of quadratic curve
    Lab.L = RootOfLeastSquaresFitQuadraticCurve(n, x, y);

    if (Lab.L < 0.0) { // clip to zero L* if the vertex is negative
        Lab.L = 0;
    }

    Lab.a = InitialLab.a;
    Lab.b = InitialLab.b;

    cmsLab2XYZ(NULL, BlackPoint, &Lab);

    cmsDeleteTransform(hRoundTrip);
    return TRUE;
}
