diff options
| author | Roy <Roy.mail.net@gmail.com> | 2022-12-12 12:38:52 +0200 |
|---|---|---|
| committer | Roy <Roy.mail.net@gmail.com> | 2022-12-12 12:38:52 +0200 |
| commit | 218046025d4c38af2e94cbb099c9d50969e98a18 (patch) | |
| tree | 752d358381bfc6950feb8a9c3e18f2424272d9b3 | |
| parent | acc07c864781f9a62eed5f4fbc8d9b2e4eac7c51 (diff) | |
| parent | d5b7dd5805eb9a7407fdb6b5267456a77b4f43b9 (diff) | |
| download | Tango-218046025d4c38af2e94cbb099c9d50969e98a18.tar.gz Tango-218046025d4c38af2e94cbb099c9d50969e98a18.zip | |
Merged GBD + KLogic from Mirta.
6 files changed, 796 insertions, 233 deletions
diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/ColorConverter.cpp b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/ColorConverter.cpp index 30870a983..812751013 100644 --- a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/ColorConverter.cpp +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/ColorConverter.cpp @@ -92,6 +92,26 @@ bool sortbysec(const std::pair<int, double> &a, return (a.second < b.second); } +template <typename T> T freeVec(T *x) +{ + if (x != NULL) + delete[] x; + x = NULL; + return( 0); +} + +template <typename T> T freeDP(T **x, int n) +{ + if (x != NULL) + { + for (int i = 0; i < n; ++i) + delete[] x[i]; + delete[] x; + x = NULL; + } + return( 0); +} + Tango::ColorLib::ColorConverter::ColorConverter() : m_CalibCurves(NULL), m_Conv02(NULL), m_maxNlPerCM(NULL), m_CTmaxNlPerCM(NULL), m_currentMaxNLPerCM(NULL), m_maxCalX(NULL), @@ -100,15 +120,14 @@ Tango::ColorLib::ColorConverter::ColorConverter() : m_ProcessRangesMinP(NULL), m_CurrentProcessRangesMax(NULL), m_CurrentProcessRangesMin(NULL), m_nProcessRanges(0), m_GamutRegionMaxLim(NULL), m_ThreadGBD(NULL), m_GamutRegionMinLim(NULL), m_ObjFunction(NULL), m_Minimize(NULL), - m_UseLightInks(false), m_InkNames(NULL), m_LightInksThr (0.0), - m_LowVolumeThreshold(0.0), m_LowVolHalf(0.0), m_Has_GBD(false) + m_UseLightInks(false), m_InkNames(NULL), m_LightInksThr (0.0), + m_LowVolumeThreshold(0.0), m_LowVolHalf(0.0), m_Has_GBD(false), m_conversiontype(CONVERSION_TYPE__Default) //, m_NormFactor(0.0), m_InvnormFactor(0.0) { m_whitepointLab.Set(-1, -1, -1); m_whitepointXYZ_Strip.Set(-1, -1, -1); m_WP.Set(-1, -1, -1); m_colortable = new ColorTable(); - m_lubtable.set_conv(&m_Conv02); // OrenLub #ifdef MEMORY_TEST _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG); #endif // MEMORY_TEST @@ -116,7 +135,6 @@ Tango::ColorLib::ColorConverter::ColorConverter() : Tango::ColorLib::ColorConverter::~ColorConverter() { - if (m_colortable != NULL) { delete m_colortable; @@ -131,22 +149,24 @@ Tango::ColorLib::ColorConverter::~ColorConverter() { delete[] m_CalibCurves; m_CalibCurves = NULL; - } + } if (m_GradStops != NULL) { delete[] m_GradStops; m_GradStops = NULL; } - if (m_CalibGain != NULL) + freeVec <double >(m_CalibGain); +/* if (m_CalibGain != NULL) { delete[] m_CalibGain; m_CalibGain = NULL; - } - if (m_CalibOffset != NULL) + }*/ + freeVec <double >(m_CalibOffset); +/* if (m_CalibOffset != NULL) { delete[] m_CalibOffset; m_CalibOffset = NULL; - } + } */ if (m_ThreadGBD != NULL) { delete m_ThreadGBD; @@ -157,47 +177,53 @@ Tango::ColorLib::ColorConverter::~ColorConverter() delete[] m_NormGamutRegionMaxLim; m_NormGamutRegionMaxLim = NULL; } */ - if (m_GamutRegionMaxLim != NULL) + freeVec <double >(m_GamutRegionMaxLim); +/* if (m_GamutRegionMaxLim != NULL) { delete[] m_GamutRegionMaxLim; m_GamutRegionMaxLim = NULL; - } - if (m_GamutRegionMinLim != NULL) + }*/ + freeVec <double >(m_GamutRegionMinLim); +/* if (m_GamutRegionMinLim != NULL) { delete[] m_GamutRegionMinLim; m_GamutRegionMinLim = NULL; - } - if (m_ProcessRangesMaxP != NULL) + } */ + freeVec <double >(m_ProcessRangesMaxP); +/* if (m_ProcessRangesMaxP != NULL) { delete[] m_ProcessRangesMaxP; m_ProcessRangesMaxP = NULL; - } - if (m_ProcessRangesMinP != NULL) + }*/ + freeVec <double >(m_ProcessRangesMinP); +/* if (m_ProcessRangesMinP != NULL) { delete[] m_ProcessRangesMinP; m_ProcessRangesMinP = NULL; - } + } */ if (m_InkNames != NULL) { delete[] m_InkNames; m_InkNames = NULL; } - - if (m_maxCalX != NULL) + freeVec <double >(m_maxCalX); +/* if (m_maxCalX != NULL) { delete[] m_maxCalX; m_maxCalX = NULL; - } - if (m_CurrentProcessRangesMax != NULL) + } */ + freeVec <double >(m_CurrentProcessRangesMax); +/* if (m_CurrentProcessRangesMax != NULL) { delete[] m_CurrentProcessRangesMax; m_CurrentProcessRangesMax = NULL; - } - if (m_CurrentProcessRangesMin != NULL) + } */ + freeVec <double >(m_CurrentProcessRangesMin); +/* if (m_CurrentProcessRangesMin != NULL) { delete[] m_CurrentProcessRangesMin; m_CurrentProcessRangesMin = NULL; - } + } */ if (m_ObjFunction != NULL) { delete m_ObjFunction; @@ -225,7 +251,7 @@ void Tango::ColorLib::ColorConverter::ProcessHiveNeighbors(ConversionInput *conv VectorXd LabCopy = Lab; //Oren: convert to unlub - if (m_lubtable.use_lub()) + if (m_use_lub) { double LabIn[3]; LabIn[0] = Lab(0); LabIn[1] = Lab(1); LabIn[2] = Lab(2); @@ -420,42 +446,42 @@ void Tango::ColorLib::ColorConverter::ProcessHiveNeighbors(ConversionInput *conv indDataMax[0] = (int)(xpos(indDataMax[0]) * 5 + ypos(indDataMax[0])); indDataMax[1] = (int)(xpos(indDataMax[1]) * 5 + ypos(indDataMax[1])); - if (LabOnGamut != NULL) + freeVec <double> (LabOnGamut); +/* if (LabOnGamut != NULL) { delete[]LabOnGamut; LabOnGamut = NULL; - } -/* if (InkOut != NULL) - { - delete[]InkOut; - InkOut = NULL; - }*/ - if (GamutRegion != NULL) + } */ + freeVec <int>(GamutRegion); +/* if (GamutRegion != NULL) { delete[] GamutRegion; GamutRegion = NULL; - } - if (Lab1P != NULL) + } */ + freeVec <double>(Lab1P); +/* if (Lab1P != NULL) { delete[] Lab1P; Lab1P = NULL; - } - if (tmpRGB != NULL) + } */ + freeVec <double>(tmpRGB); +/* if (tmpRGB != NULL) { delete[] tmpRGB; tmpRGB = NULL; - } - - if (LabInFinal1 != NULL) + }*/ + freeVec <double>(LabInFinal1); +/* if (LabInFinal1 != NULL) { delete[]LabInFinal1; LabInFinal1 = NULL; - } - if (InkOutP != NULL) + } */ + freeVec <double>(InkOutP); +/* if (InkOutP != NULL) { delete[] InkOutP; InkOutP = NULL; - } + } */ return; } @@ -504,19 +530,20 @@ void Tango::ColorLib::ColorConverter::FindTriplet(VectorXd Lab, MatrixXd Lab1, } indDataMax[0] = indexpairs[maxInd][0]; indDataMax[1] = indexpairs[maxInd][1]; - if (dECMC != NULL) + freeVec <double> (dECMC); +/* if (dECMC != NULL) { delete[]dECMC; dECMC = NULL; - } - - if (indexpairs != NULL) + }*/ + freeDP <int> (indexpairs, vecSize); +/* if (indexpairs != NULL) { for (int i = 0; i < vecSize; ++i) delete[] indexpairs[i]; delete[] indexpairs; indexpairs = NULL; - } + }*/ return; } @@ -681,7 +708,7 @@ void Tango::ColorLib::ColorConverter::readLubTransformations(ConversionInput* co { uint8_t *data = conversionInput->lubdata.data; - m_lubtable.init_lub_tables(conversionInput->uselubricanttransform, conversionInput->has_lubdata, data); + m_lubtable.init_lub_tables(conversionInput->uselubricanttransform, &(this->m_Conv02), data); } @@ -689,7 +716,7 @@ void Tango::ColorLib::ColorConverter::readLubTransformations(OutOfGamutInput* In { uint8_t *data = Input->lubdata.data; - m_lubtable.init_lub_tables(Input->uselubricanttransform, Input->has_lubdata, data); + m_lubtable.init_lub_tables(Input->uselubricanttransform, &(this->m_Conv02), data); } @@ -697,7 +724,7 @@ void Tango::ColorLib::ColorConverter::readLubTransformations(RecommendedProcessT { uint8_t *data = Input->lubdata.data; - m_lubtable.init_lub_tables(Input->uselubricanttransform, Input->has_lubdata, data); + m_lubtable.init_lub_tables(Input->uselubricanttransform, &(this->m_Conv02), data); } @@ -787,11 +814,12 @@ void Tango::ColorLib::ColorConverter::SetMaxCalValues() { m_maxCalX[i] = maxVal[i]; } - if (maxVal != NULL) + freeVec <double>(maxVal); +/* if (maxVal != NULL) { delete[] maxVal; maxVal = NULL; - } + }*/ } /*void Tango::ColorLib::ColorConverter::SetCalibMode() @@ -883,7 +911,9 @@ void Tango::ColorLib::ColorConverter::SetCalibData(CalibrationData *calibrationD } tmpCurve->SetXCoords(pointsx); tmpCurve->SetYCoords(pointsy); - if (pointsx != NULL) + freeVec <double>(pointsx); + freeVec <double>(pointsy); +/* if (pointsx != NULL) { delete[] pointsx; pointsx = NULL; @@ -893,7 +923,7 @@ void Tango::ColorLib::ColorConverter::SetCalibData(CalibrationData *calibrationD { delete[] pointsy; pointsy = NULL; - } + } */ return; } @@ -940,7 +970,9 @@ bool Tango::ColorLib::ColorConverter::CheckMonotonicity(CalibrationData *calibda retvalue = false; } } - if (xval != NULL) + freeVec <double>(xval); + freeVec <double>(yval); +/* if (xval != NULL) { delete[] xval; xval = NULL; @@ -949,7 +981,7 @@ bool Tango::ColorLib::ColorConverter::CheckMonotonicity(CalibrationData *calibda { delete[] yval; yval = NULL; - } + } */ return retvalue; } @@ -972,7 +1004,7 @@ void Tango::ColorLib::ColorConverter::ConvertLabColorToLinearInks(InputCoordinat LabIn[2] = inputcoordinates->b; // Oren 15.9 - if (m_lubtable.use_lub()) + if (m_use_lub) m_lubtable.apply_transformation(LabIn, Lub2Unlub); //the assumption is that the color space has illumination that matches the whitepoint of the Strip @@ -1016,7 +1048,13 @@ void Tango::ColorLib::ColorConverter::ConvertLabColorToLinearInks(InputCoordinat //Use Relative colorimetric to get RGB CConvertD65.LabtoRGB(LabOnGamut, RGBOutP); RGBOut = DoubleToVector(RGBOutP, 3); - if (LabOnGamut != NULL) + freeVec <double>(LabOnGamut); + freeVec <double>(InkOutP); + freeVec <double>(LabIn); + freeVec <double>(LabInFinal2); + freeVec <double>(LabOutFinal); + freeVec <double>(RGBOutP); +/* if (LabOnGamut != NULL) { delete[] LabOnGamut; LabOnGamut = NULL; @@ -1046,7 +1084,7 @@ void Tango::ColorLib::ColorConverter::ConvertLabColorToLinearInks(InputCoordinat { delete[] RGBOutP; RGBOutP = NULL; - } + } */ } @@ -1080,7 +1118,7 @@ void Tango::ColorLib::ColorConverter::ConvertRGBColorToLinearInks(InputCoordinat CConvertD65.RGBtoLab(RGBOutP, LabIn); //Values are in Absolute Colorimetric, D65 // Oren to unlub 15.9 - if (m_lubtable.use_lub()) + if (m_use_lub) m_lubtable.apply_transformation(LabIn, Lub2Unlub); //Convert LabIn to Relative Colorimetric - Feb 2021 @@ -1114,7 +1152,13 @@ void Tango::ColorLib::ColorConverter::ConvertRGBColorToLinearInks(InputCoordinat CConvertD65.LabtoRGB(LabOnGamut, RGBOutP1); RGBOut = DoubleToVector(RGBOutP1, 3); - if (InkOutP != NULL) + freeVec <double>(LabOnGamut); + freeVec <double>(InkOutP); + freeVec <double>(LabIn); + freeVec <double>(LabInFinal2); + freeVec <double>(LabInFinal1); + freeVec <double>(RGBOutP1); +/* if (InkOutP != NULL) { delete[] InkOutP; InkOutP = NULL; @@ -1138,11 +1182,6 @@ void Tango::ColorLib::ColorConverter::ConvertRGBColorToLinearInks(InputCoordinat { delete[] RGBOutP1; RGBOutP1 = NULL; - } -/* if (LabInFinal != NULL) - { - delete[] LabInFinal; - LabInFinal = NULL; }*/ } @@ -1699,7 +1738,7 @@ void Tango::ColorLib::ColorConverter::ConvertVolumeToRGBDisplay(InputCoordinates m_LabOutFinal[i] = LabOutFinal1[i]; */ // OrenLub - if (m_lubtable.use_lub()) + if (m_use_lub) m_lubtable.apply_transformation(LabOutFinal, Unlub2Lub); LabOut = DoubleToVector(LabOutFinal, 3); @@ -1716,7 +1755,14 @@ void Tango::ColorLib::ColorConverter::ConvertVolumeToRGBDisplay(InputCoordinates for (int i = 0; i < m_nInks; ++i) VolumeNoLI(i) = FinalVolumeNoLI(i); - if (InkOutP != NULL) + + freeVec <double>(LabOutP); + freeVec <double>(InkOutP); + freeVec <double>(LabOutFinal); + freeVec <double>(LinInkP); + freeVec <double>(Ink4RGB); + freeVec <double>(RGBOutP); +/* if (InkOutP != NULL) { delete[]InkOutP; InkOutP = NULL; @@ -1735,13 +1781,9 @@ void Tango::ColorLib::ColorConverter::ConvertVolumeToRGBDisplay(InputCoordinates { delete[] RGBOutP; RGBOutP = NULL; - } -/* if (LabOutFinal1 != NULL) - { - delete[] LabOutFinal1; - LabOutFinal1 = NULL; - }*/ - if (LabOutFinal != NULL) + } */ + +/* if (LabOutFinal != NULL) { delete[] LabOutFinal; LabOutFinal = NULL; @@ -1750,7 +1792,7 @@ void Tango::ColorLib::ColorConverter::ConvertVolumeToRGBDisplay(InputCoordinates { delete[] Ink4RGB; Ink4RGB = NULL; - } + } */ return; } @@ -1855,8 +1897,14 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i m_Minimize->SetMaxIterations(50); m_Minimize->SetTolerance(0.01); } + // OrenLub - readLubTransformations(conversionInput); + m_has_lubdata = conversionInput->has_lubdata; + m_use_lub = conversionInput->has_uselubricanttransform; + if (m_use_lub && !m_has_lubdata) + throw std::exception("No LUB file was read"); + if (m_has_lubdata) + readLubTransformations(conversionInput); //Initialize CIECAM02 transformation Illum IL = D65; @@ -1865,7 +1913,7 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i if (m_Conv02 == NULL) m_Conv02 = new ColorConvert(IL, IL, Y_b, L_A, sur, CS); - if (m_lubtable.use_lub()) + if (m_use_lub) { double x[3]; x[0] = conversionInput->inputcoordinates->l; @@ -1886,6 +1934,13 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i SetMaxCalValues(); SetCalibFactorization(); + //data for fine tuning added Dec. 1, 2022 + if (conversionInput->has_conversiontype) + m_conversiontype = conversionInput->conversiontype; + + else + m_conversiontype = CONVERSION_TYPE__Default; + m_nVolumes = m_nInks; int GamutRegion = 0; //Convert input data to linear inks @@ -1917,9 +1972,19 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i { if (m_colortable->GetTableSubVersion() > 0) { + if (m_conversiontype == CONVERSION_TYPE__FineTuning) + { + //Get previous inks + double *PrevVolume = new double[m_nInks]; + GetPrevVolume(PrevVolume, conversionInput->inputcoordinates); + DirectInversion4FT(IC, colorspace, PrevVolume, InkOut, RGBOut, Volume, + LabOut, GamutRegion, InGamut, sur, CS); + freeVec <double>(PrevVolume); + } + else DirectInversion(IC, colorspace, InkOut, RGBOut, Volume, LabOut, - GamutRegion, InGamut, sur, CS); - PercentagetoNLcm(Volume, Volume); //Volume is in Color Table Units + GamutRegion, InGamut, sur, CS); + PercentagetoNLcm(Volume, Volume); //Volume Out is in Thread Units int CTUnits = 1; GetClosestInk(Volume, GamutRegion, Volume, CTUnits); //Input Volume is in [nl/cm] Output Volume is in [%] ConfineVolumes(Volume); @@ -2059,11 +2124,12 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i } //Clean up - if (GamutRegionV != NULL) + freeVec <int>(GamutRegionV); + /* if (GamutRegionV != NULL) { delete[] GamutRegionV; GamutRegionV = NULL; - } + }*/ } @@ -2577,8 +2643,9 @@ bool Tango::ColorLib::ColorConverter::IsInGamut(double *InLab, SURROUND sur, CA LabCoord[i] = InLab[i]; } //Convert back to Lab - - if (xCoord != NULL) + freeVec <double>(xCoord); + freeVec <double>(dJLab); +/* if (xCoord != NULL) { delete[] xCoord; xCoord = NULL; @@ -2587,7 +2654,7 @@ bool Tango::ColorLib::ColorConverter::IsInGamut(double *InLab, SURROUND sur, CA { delete[]dJLab; dJLab = NULL; - } + }*/ return(InGamut); } @@ -2621,11 +2688,6 @@ void Tango::ColorLib::ColorConverter::read_lut_type(int offset, int data_size, C } - - - - - /*void Tango::ColorLib::ColorConverter::CompareWhitePoints() { ColorConvert ColConv(D65, D65); @@ -2861,7 +2923,12 @@ size_t Tango::ColorLib::ColorConverter::P_IsInGamut(uint8_t * input_buffer, size readThreadGamut(conversionInput); // OrenLub - readLubTransformations(conversionInput); + m_has_lubdata = conversionInput->has_lubdata; + m_use_lub = conversionInput->has_uselubricanttransform; + if (m_use_lub && !m_has_lubdata) + throw std::exception("No LUB file was read"); + if (m_has_lubdata) + readLubTransformations(conversionInput); //read calibration tables and store them in m_CalibCurves int n_inputliquids = numofInks - numLightInks; @@ -2919,8 +2986,10 @@ size_t Tango::ColorLib::ColorConverter::P_IsInGamut(uint8_t * input_buffer, size //Is In Gamut? InGamut = m_colortable->m_GBD->IsInGamut(LabInFinal2, LabInFinal2, dETol, m_Conv02); // OrenLub LimitLab(LabInFinal2); - - if (LabIn != NULL) + freeVec <double>(LabIn); + freeVec <double>(RGBOutP); + freeVec <double>(LabInFinal2); +/* if (LabIn != NULL) { delete[] LabIn; LabIn = NULL; @@ -2934,7 +3003,7 @@ size_t Tango::ColorLib::ColorConverter::P_IsInGamut(uint8_t * input_buffer, size { delete[] LabInFinal2; LabInFinal2 = NULL; - } + } */ break; } case (COLOR_SPACE__LAB): @@ -2958,8 +3027,9 @@ size_t Tango::ColorLib::ColorConverter::P_IsInGamut(uint8_t * input_buffer, size CConvertD65.ChangeWP(LabIn, LabInFinal2, m_WP, m_whitepointXYZ_Strip); //to Relative InGamut = m_colortable->m_GBD->IsInGamut(LabInFinal2, LabInFinal2, dETol, m_Conv02); // OrenLub LimitLab(LabInFinal2); - - if (LabIn != NULL) + freeVec <double>(LabIn); + freeVec <double>(LabInFinal2); +/* if (LabIn != NULL) { delete[] LabIn; LabIn = NULL; @@ -2968,7 +3038,7 @@ size_t Tango::ColorLib::ColorConverter::P_IsInGamut(uint8_t * input_buffer, size { delete[]LabInFinal2; LabInFinal2 = NULL; - } + } */ break; } case(COLOR_SPACE__CMYK): @@ -3378,11 +3448,12 @@ void Tango::ColorLib::ColorConverter::findStops(Gradient &GradStop1, Gradient &G delete[] VecRGBOut_fin; VecRGBOut_fin = NULL; } - if (pos != NULL) + freeVec <int>(pos); + /* if (pos != NULL) { delete[] pos; pos = NULL; - } + } */ } for (int i = 0; i < nOut; ++i) @@ -3416,11 +3487,12 @@ void Tango::ColorLib::ColorConverter::findStops(Gradient &GradStop1, Gradient &G delete[] VecRGBOut_fin; VecRGBOut_fin = NULL; } - if (pos != NULL) + freeVec <int>(pos); +/* if (pos != NULL) { delete[] pos; pos = NULL; - } + }*/ } void Tango::ColorLib::ColorConverter::ConvertGradStoptoVolume(InputCoordinates* inputcoordinates, ColorSpace colorspace, @@ -3507,8 +3579,11 @@ void Tango::ColorLib::ColorConverter::ConvertGradStoptoVolume(InputCoordinates* //recalculate LabOut and RGBOut Values if they changed by bounding } //IsBounded shold follow an Ingamut notification, however it is not really important for the gradients - - if (InkOutP != NULL) + freeVec <double>(LabIn); + freeVec <double>(LabOut); + freeVec <double>(RGBOutP); + freeVec <double>(InkOutP); + /* if (InkOutP != NULL) { delete[] InkOutP; InkOutP = NULL; @@ -3527,7 +3602,7 @@ void Tango::ColorLib::ColorConverter::ConvertGradStoptoVolume(InputCoordinates* { delete[] RGBOutP; RGBOutP = NULL; - } + } */ } else if (colorspace == COLOR_SPACE__LAB) { @@ -3567,8 +3642,9 @@ void Tango::ColorLib::ColorConverter::ConvertGradStoptoVolume(InputCoordinates* ConvertToNLInks(InkOut, NLInkOut); LimitNLInks2Volume(NLInkOut, GamutRegion, Volume, CTUnits, isBounded); } - - if (InkOutP != NULL) + freeVec <double>(LabIn); + freeVec <double>(InkOutP); +/* if (InkOutP != NULL) { delete[] InkOutP; InkOutP = NULL; @@ -3577,7 +3653,7 @@ void Tango::ColorLib::ColorConverter::ConvertGradStoptoVolume(InputCoordinates* { delete[] LabIn; LabIn = NULL; - } + } */ } else { @@ -3849,8 +3925,10 @@ void Tango::ColorLib::ColorConverter::PrepareGradient(GradientConversionInput* c AllRGBOut_tmp[ncountStops][jCS] = VecRGBOut[nOut][jCS]; AllLabOut_tmp[ncountStops][jCS] = VecLabOut[nOut][jCS]; } - - if (VecRGBOut != NULL) + freeDP <double> (VecRGBOut, ninterstops); + freeDP <double> (VecLabOut, ninterstops); + freeVec <double> (posOut); +/* if (VecRGBOut != NULL) { for (int i = 0; i < ninterstops; ++i) delete[]VecRGBOut[i]; @@ -3867,7 +3945,7 @@ void Tango::ColorLib::ColorConverter::PrepareGradient(GradientConversionInput* c { delete[]posOut; posOut = NULL; - } + }*/ //Store Gradient intermediate data in Input Coordinates type structure. //Simplify calculations, we only need the ink values, input values are in RGB color space @@ -3944,7 +4022,10 @@ void Tango::ColorLib::ColorConverter::PrepareGradient(GradientConversionInput* c SubStops[i]->l, SubStops[i]->a, SubStops[i]->b, SubStops[i]->red, SubStops[i]->green, SubStops[i]->blue); } //release memory - if (AllLabOut_tmp != NULL) + freeDP <double>(AllLabOut_tmp, nmaxstops); + freeDP <double>(AllRGBOut_tmp, nmaxstops); + freeVec <double>(AllPos_tmp); +/* if (AllLabOut_tmp != NULL) { for (int i = 0; i < nmaxstops; ++i) delete[] AllLabOut_tmp[i]; @@ -3962,7 +4043,7 @@ void Tango::ColorLib::ColorConverter::PrepareGradient(GradientConversionInput* c { delete[] AllPos_tmp; AllPos_tmp = NULL; - } + }*/ for (int i = 0; i < m_nGradStops; ++i) @@ -4419,7 +4500,11 @@ void Tango::ColorLib::ColorConverter::ProcessGradientStops(InputCoordinates **in } } //free vectors - if (LabOutV != NULL) + freeVec <double>(LabOutV); + freeVec <double>(LabOutFinal); + freeVec <double>(InkOutL); + +/* if (LabOutV != NULL) { delete[] LabOutV; LabOutV = NULL; @@ -4433,7 +4518,7 @@ void Tango::ColorLib::ColorConverter::ProcessGradientStops(InputCoordinates **in { delete[] InkOutL; InkOutL = NULL; - } + }*/ } bool Tango::ColorLib::ColorConverter::CheckLabInRGBGamut(VectorXd Lab) @@ -4536,11 +4621,12 @@ void Tango::ColorLib::ColorConverter::LimitNLInks2VolumeThr(VectorXd NLInks, int LimitLowVolume(Volume, GamutRegion, Volume); // [nl/cm] NLcmtoPercentage(Volume, Volume); // output volume in % ConfineVolumes(Volume); - if (InkOutL != NULL) + freeVec <double>(InkOutL); +/* if (InkOutL != NULL) { delete[]InkOutL; InkOutL = NULL; - } + }*/ } void Tango::ColorLib::ColorConverter::GetClosestInk(VectorXd Volume, int &GamutRegion, VectorXd &BestVolume, int CTUnits) @@ -4571,11 +4657,12 @@ void Tango::ColorLib::ColorConverter::GetClosestInk(VectorXd Volume, int &GamutR } } - if (diffVolume != NULL) + freeVec <double> (diffVolume); +/* if (diffVolume != NULL) { delete[]diffVolume; diffVolume = NULL; - } + }*/ NLcmtoPercentage(Volume, Volume); indCount++; @@ -4629,7 +4716,10 @@ void Tango::ColorLib::ColorConverter::GetClosestInk(VectorXd Volume, int &GamutR } } - if (binPerm != NULL) + freeDP <int> (binPerm, pwr2LVThr); + freeDP <double> (VolumeComb, pwr2LVThr); + freeVec <double>(dE); + /* if (binPerm != NULL) { for (int i = 0; i < pwr2LVThr; ++i) delete[]binPerm[i]; @@ -4647,15 +4737,16 @@ void Tango::ColorLib::ColorConverter::GetClosestInk(VectorXd Volume, int &GamutR { delete[]dE; dE = NULL; - } + } */ } else BestVolume = Volume; - if (LVThrIndex != NULL) + freeVec <int>(LVThrIndex); +/* if (LVThrIndex != NULL) { delete[] LVThrIndex; LVThrIndex = NULL; - } + } */ } void Tango::ColorLib::ColorConverter::ConvertVolumeToLabRel(VectorXd &Volume, VectorXd &LabOut, int GamutRegion, @@ -4723,7 +4814,10 @@ void Tango::ColorLib::ColorConverter::ConvertVolumeToLabRel(VectorXd &Volume, Ve LabOut = DoubleToVector(LabOutFinal, 3); - if (InkOutP != NULL) + freeVec <double>(InkOutP); + freeVec <double>(LabOutP); + freeVec <double>(LabOutFinal); +/* if (InkOutP != NULL) { delete[]InkOutP; InkOutP = NULL; @@ -4734,17 +4828,11 @@ void Tango::ColorLib::ColorConverter::ConvertVolumeToLabRel(VectorXd &Volume, Ve delete[] LabOutP; LabOutP = NULL; } - -/* if (LabOutFinal1 != NULL) - { - delete[] LabOutFinal1; - LabOutFinal1 = NULL; - } */ if (LabOutFinal != NULL) { delete[] LabOutFinal; LabOutFinal = NULL; - } + } */ return; } @@ -4923,7 +5011,10 @@ void Tango::ColorLib::ColorConverter::GetBackLightInks(VectorXd &VolumeLI, int & GamutRegion = PrevGamutRegion; resplit = false; } - if (LgtInksIndex != NULL) + freeVec <int>(LgtInksIndex); + freeVec <double>(LightVol); + +/* if (LgtInksIndex != NULL) { delete[] LgtInksIndex; LgtInksIndex = NULL; @@ -4932,7 +5023,7 @@ void Tango::ColorLib::ColorConverter::GetBackLightInks(VectorXd &VolumeLI, int & { delete[] LightVol; LightVol = NULL; - } + }*/ } @@ -5098,7 +5189,12 @@ size_t Tango::ColorLib::ColorConverter::GetRecommendedProcessParameters(uint8_t m_nProcessRanges = Input->n_processranges; // OrenLub - readLubTransformations(Input); + m_has_lubdata = Input->has_lubdata; + m_use_lub = Input->has_uselubricanttransform; + if (m_use_lub && !m_has_lubdata) + throw std::exception("No LUB file was read"); + if (m_has_lubdata) + readLubTransformations(Input); double *tmpVal; /* if (m_NormGamutRegionMaxLim == NULL) @@ -5359,8 +5455,9 @@ size_t Tango::ColorLib::ColorConverter::GetRecommendedProcessParameters(uint8_t processparameterstableindex = GamutRegion[istops]; } } - delete[] GamutRegion; - GamutRegion = NULL; + freeVec <int>(GamutRegion); + //delete[] GamutRegion; + //GamutRegion = NULL; // all gamut regions were evaluated, pack data //Initialize Output... @@ -5497,7 +5594,12 @@ size_t Tango::ColorLib::ColorConverter::CheckOutOfGamut(uint8_t * input_buffer, readThreadGamut(Input); // OrenLub - readLubTransformations(Input); + m_has_lubdata = Input->has_lubdata; + m_use_lub = Input->has_uselubricanttransform; + if (m_use_lub && !m_has_lubdata) + throw std::exception("No LUB file was read"); + if (m_has_lubdata) + readLubTransformations(Input); if (Input->n_processranges <= 0) throw std::exception("number of process ranges is zero"); @@ -5673,14 +5775,15 @@ void Tango::ColorLib::ColorConverter::DirectInversion(InputCoordinates* inputcoo } // Oren Lub to Unlub - if (m_lubtable.use_lub()) + if (m_use_lub) m_lubtable.apply_transformation(LabIn, Lub2Unlub); DirectInversionCalc(LabIn, InkOut, RGBOut, VolOut, LabOut, GamutRegion, InGamut, sur, CS); - - if (LabIn != NULL) + freeVec <double>(LabIn); + freeVec <double>(RGBIn); + /*if (LabIn != NULL) { delete[] LabIn; LabIn = NULL; @@ -5689,7 +5792,7 @@ void Tango::ColorLib::ColorConverter::DirectInversion(InputCoordinates* inputcoo { delete[] RGBIn; RGBIn = NULL; - } + }*/ } @@ -5752,7 +5855,7 @@ void Tango::ColorLib::ColorConverter::DirectInversionCalc(double *LabIn, VectorX LabTmp.Set(LabOnGamut[0], LabOnGamut[1], LabOnGamut[2]); m_ObjFunction->SetLabGoal(LabOnGamut); //calculate solutions - unsigned int nIterations; +// unsigned int nIterations; for (i = 0; i < nfree; ++i) InitCMY[i] = 0.0; @@ -5760,58 +5863,15 @@ void Tango::ColorLib::ColorConverter::DirectInversionCalc(double *LabIn, VectorX ValK[i] = 0.0; m_Minimize->SetLabIn(LabOnGamut); int CTUnits = 0; - + double *VolumeVec = new double[npars]; for (k = 0; k < nk; ++k) { ValK[0] = (double)k * dK; - m_Minimize->MinimizationAlgorithm(InitCMY, &ValK[0], nIterations); //result is returned in InitCMY - LabOutTmp = DoubleToVector(LabOnGamut, 3); - LabOutTmp += DoubleToVector(m_Minimize->GetLabOut(), 3); - for (int i = 0; i < nfree; ++i) - SolVector[k][i] = std::min(std::max(100 * InitCMY[i], 0.0), 100.0); - SolVector[k][nfree] = std::min(std::max(100 * ValK[0], 0.0), 100.0); //Solution Vector is in linear units in the interval [0,100] - isBounded[k] = false; - for (int i = 0; i < 3; ++i) - finalLab[k][i] = LabOutTmp[i]; - LabOutVec.Set(LabOutTmp[0], LabOutTmp[1], LabOutTmp[2]); - - ColConv.dEcmc(LabTmp, LabOutVec, dECMC[k]); - //Result is in Linear Inks - //apply Nonlinear curves of Loaded thread - // in order to calculate volume - // Volume is used to calculate the feasible solutions - - InkOut = DoubleToVector(SolVector[k], m_nInks); - double *tmpval = m_colortable->GetNormFactor(); - for (int i = 0; i < m_nInks; ++i) - InkOut(i) *= tmpval[i]; // in [%] - //Limit ink percentage, if they changed recalculate Lab and dE - - ColorTable2Threadunits(InkOut, InkOut); //in % - ConvertToNLInks(InkOut, InkOut); // in %, thread units - LimitNLInks2Volume(InkOut, GamutRegion, VolumeTmp, CTUnits, - isBounded[k]); //InkOut contains the modified Inks in nonlinear form, VolumeTmp contains the modified volume - if (isBounded[k]) //inks were changed, recalculate Lab values - { - tmpval = m_colortable->GetInverseNormFactor(); - ConvertToLinearInks(InkOut, InkOut); - VectorToDouble(InkOut, BndSol); - for (int i = 0; i < m_nInks; ++i) - { - BndSol[i] *= tmpval[i]; - BndSol[i] /= 100.0; - } - forwardmodel->CalcFM(BndSol, LabBounded); - for (int i = 0; i < 3; ++i) - finalLab[k][i] = LabBounded[i]; - LabOutVec.Set(LabBounded[0], LabBounded[1], LabBounded[2]); - ColConv.dEcmc(LabTmp, LabOutVec, dECMC[k]); - } - VecGamutRegion[k] = GamutRegion; - // NLInkPToVolume(InkOut, VolumeTmp); // in % + DirectInversionCalcSIter(ValK[0], LabOnGamut, VolumeVec, forwardmodel, dECMC[k], isBounded[k], SolVector[k], GamutRegion, + finalLab[k], nfree, nfixed); for (i = 0; i < npars; ++i) - Vol[k][i] = VolumeTmp(i); - VectorToDouble(InkOut, SolVector[k]); + Vol[k][i] = VolumeVec[i]; + VecGamutRegion[k] = GamutRegion; } //find feasible solutions @@ -5888,7 +5948,7 @@ void Tango::ColorLib::ColorConverter::DirectInversionCalc(double *LabIn, VectorX ColConv.ChangeWP(LabOutFinal, LabOutFinal, m_whitepointXYZ_Strip, m_WP); //OrenLub - if (m_lubtable.use_lub()) + if (m_use_lub) m_lubtable.apply_transformation(LabOutFinal, Unlub2Lub); LabOut = DoubleToVector(LabOutFinal, 3); @@ -5901,7 +5961,18 @@ void Tango::ColorLib::ColorConverter::DirectInversionCalc(double *LabIn, VectorX RGBOut = DoubleToVector(RGBOutP, 3); //Cleanup - if (RGBOutP != NULL) + freeVec <double> (RGBOutP); + freeVec <double> (ValK); + freeVec <int> (VecGamutRegion); + freeDP <double> (SolVector, nk); + freeDP <double>(finalLab, nk); + freeDP <double>(Vol, nk); + freeVec <double>(LabInFinal2); + freeVec <double>(LabOnGamut); + freeVec <double>(LabOutFinal); + freeVec <int>(FeasibleSolutionsInd); + freeVec <bool> (isBounded); +/* if (RGBOutP != NULL) { delete[] RGBOutP; RGBOutP = NULL; @@ -5915,24 +5986,24 @@ void Tango::ColorLib::ColorConverter::DirectInversionCalc(double *LabIn, VectorX { delete[] VecGamutRegion; VecGamutRegion = NULL; - } + } if (SolVector != NULL) { - for (i = 0; i < npars; ++i) + for (i = 0; i < nk; ++i) delete[] SolVector[i]; delete[] SolVector; SolVector = NULL; } if (finalLab != NULL) { - for (i = 0; i < 3; ++i) + for (i = 0; i < nk; ++i) delete[] finalLab[i]; delete[] finalLab; finalLab = NULL; } if (Vol != NULL) { - for (i = 0; i < npars; ++i) + for (i = 0; i < nk; ++i) delete[] Vol[i]; delete[] Vol; Vol = NULL; @@ -5942,11 +6013,6 @@ void Tango::ColorLib::ColorConverter::DirectInversionCalc(double *LabIn, VectorX delete[] LabInFinal2; LabInFinal2 = NULL; } - if (LabOnGamut != NULL) - { - delete[] LabOnGamut; - LabOnGamut = NULL; - } if (LabOutFinal != NULL) { delete[] LabOutFinal; @@ -5956,12 +6022,12 @@ void Tango::ColorLib::ColorConverter::DirectInversionCalc(double *LabIn, VectorX { delete[] FeasibleSolutionsInd; FeasibleSolutionsInd = NULL; - } + } if (isBounded != NULL) { delete[] isBounded; isBounded = NULL; - } + }*/ } @@ -6063,11 +6129,12 @@ void Tango::ColorLib::ColorConverter::LimitInksPercentage(VectorXd inInks, Vecto if (std::fabs(inInks(i) - outInks(i)) > eps) isBounded = true; } - if (BoundedInks != NULL) + freeVec < double >(BoundedInks); +/* if (BoundedInks != NULL) { delete[] BoundedInks; BoundedInks = NULL; - } + }*/ } void Tango::ColorLib::ColorConverter::LimitNLInks2Volume(VectorXd &NLInks, int &GamutRegion, VectorXd &Volume, int CTUnits, @@ -6093,11 +6160,13 @@ void Tango::ColorLib::ColorConverter::LimitNLInks2Volume(VectorXd &NLInks, int & //Covert VolumeC to NLInks and store in NLInks VolumeToNLInkP(VolumeC, NLInks); //NLInks are in % Volume = VolumeC; - if (InkOutL != NULL) + + freeVec <double >(InkOutL); +/* if (InkOutL != NULL) { delete[]InkOutL; InkOutL = NULL; - } + } */ } void Tango::ColorLib::ColorConverter::SetRMLParameters(ConversionInput *conversionInput) @@ -6172,6 +6241,26 @@ void Tango::ColorLib::ColorConverter::SetRMLParameters(ConversionInput *convers m_CTmaxNlPerCM(i) = tmpLF[i]; } +void Tango::ColorLib::ColorConverter::GetPrevVolume(double *PrevVolume, InputCoordinates *inputcoordinates) +{ + if (inputcoordinates->has_cyan) + PrevVolume[0] = inputcoordinates->cyan; + else + throw std::exception("Cyan ink not assigned in Color FT\0"); + if (inputcoordinates->has_magenta) + PrevVolume[1] = inputcoordinates->magenta; + else + throw std::exception("Magenta ink not assigned in Color FT\0"); + if (inputcoordinates->has_yellow) + PrevVolume[2] = inputcoordinates->yellow; + else + throw std::exception("Yellow ink not assigned in Color FT\0"); + if (inputcoordinates->has_key) + PrevVolume[3] = inputcoordinates->key; + else + throw std::exception("Black ink not assigned in Color FT\0"); +} + void Tango::ColorLib::ColorConverter::VerifyGBD() { if (m_Has_GBD) @@ -6194,4 +6283,403 @@ void Tango::ColorLib::ColorConverter::VerifyGBD() throw std::exception(" Process Ranges missmatch\0"); } } -}
\ No newline at end of file +} + +void Tango::ColorLib::ColorConverter::DirectInversion4FT(InputCoordinates* inputcoordinates, ColorSpace colorspace, + double *PrevInk, VectorXd &InkOut, VectorXd &RGBOut, VectorXd &VolOut, + VectorXd &LabOut, int &GamutRegion, bool &InGamut, SURROUND sur, CAM02CS CS) +{ + //Split the calculation into RGB and Lab Color Space + int i = 0; + int k = 0; + double *LabIn = new double[3]; + ColorConvert ColConv(D65, D65); + double Black; + if (colorspace == COLOR_SPACE__LAB) + { + LabIn[0] = inputcoordinates->l; //Absolute Colorimetric + LabIn[1] = inputcoordinates->a; + LabIn[2] = inputcoordinates->b; + } + else + { + throw std::exception(" Color Space for Fine Tuning has to be Lab"); + } + + // Oren Lub to Unlub + if (m_use_lub) + m_lubtable.apply_transformation(LabIn, Lub2Unlub); + + //Volume is in % + if (PrevInk[3] == 0.0) + Black = 0.0; + else + { + //Convert to Nonlinear Inks + m_currentMaxNLPerCM = m_maxNlPerCM; // thread units + for (i = 0; i < m_nProcessRanges; ++i) + { + m_CurrentProcessRangesMax[i] = m_ProcessRangesMaxP[i]; // thread units + m_CurrentProcessRangesMin[i] = m_ProcessRangesMinP[i]; + } + VectorXd NLInkP(m_nInks); + VolumeToNLInkP(DoubleToVector(PrevInk, m_nInks), NLInkP); // NLInkP is in % + double *InkOutP = new double[m_nInks]; + VectorXd Volume(m_nInks); + //Limit inks based on m_maxNlpercm + //Inks are limited in their nonlinear form + LimitInks(NLInkP, InkOutP, 1); //InkOutP is in [nl/cm] + NLInkPToVolume(DoubleToVector(InkOutP, m_nInks), Volume); //Volume is in [nl/cm] + GamutRegion = GetGamutRegion(Volume, m_CurrentProcessRangesMax); + NLcmtoPercentage(Volume, Volume); //Volume is back to percentage + VolumeToNLInkP(Volume, NLInkP); + //Volume and NLInkP were initially bounded by the Gamut Boundary descriptor, + //therefore their limits are according to the thread limits + //Normalize NLInk to the Color Table Range + Thread2ColorTableunits(NLInkP, NLInkP); + //get black value + // Convert to Linear + double *tmpval = m_colortable->GetInverseNormFactor(); + //NLInkP is in Color Table units + for (int i = 0; i < m_nInks; ++i) + NLInkP(i) *= tmpval[i]; //scaled to real units, still in % + VectorToDouble(NLInkP, InkOutP); + ApplyCTLinearCurves(InkOutP, InkOutP); //in Linear , CT space full range + + for (int i = 0; i < m_nInks; ++i) // Forward Model in [0-1] interval + { + InkOutP[i] *= tmpval[i]; + InkOutP[i] /= 100.0; + } + Black = InkOutP[3]; + + freeVec <double>(InkOutP); + /* if (InkOutP != NULL) + { + delete[] InkOutP; + InkOutP = NULL; + }*/ + } + DirectInversionCalc4FT(LabIn, Black, InkOut, RGBOut, VolOut, + LabOut, GamutRegion, InGamut, sur, CS); + + freeVec <double>(LabIn); +/* if (LabIn != NULL) + { + delete[] LabIn; + LabIn = NULL; + } */ + +} + +void Tango::ColorLib::ColorConverter::DirectInversionCalcSIter(double Black, double *LabOnGamut, double *Vol, + ForwardModel* forwardmodel, double &dECMC, bool &isBounded, double *SolVector, int &GamutRegion, + double *finalLab, int nfree, int nfixed) +{ + int i; + int npars = nfree + nfixed; + ColorConvert ColConv(D65, D65); + int CTUnits = 0; + double *InitCMY = new double[m_nInks]; + double *ValK = new double[nfixed]; + double *LabBounded = new double[3]; + VectorXd LabOutTmp(3); + for (i = 0; i < nfree; ++i) + InitCMY[i] = 0.0; + for (i = 0; i < nfixed; ++i) + ValK[i] = Black; + unsigned int nIterations = 0; + C_RGB_XYZ_Lab LabTmp; + LabTmp.Set(LabOnGamut[0], LabOnGamut[1], LabOnGamut[2]); + m_Minimize->MinimizationAlgorithm(InitCMY, &ValK[0], nIterations); //result is returned in InitCMY + LabOutTmp = DoubleToVector(LabOnGamut, 3); + LabOutTmp += DoubleToVector(m_Minimize->GetLabOut(), 3); + for (int i = 0; i < nfree; ++i) + SolVector[i] = std::min(std::max(100 * InitCMY[i], 0.0), 100.0); + SolVector[nfree] = std::min(std::max(100 * ValK[0], 0.0), 100.0); //Solution Vector is in linear units in the interval [0,100] + isBounded = false; + for (int i = 0; i < 3; ++i) + finalLab[i] = LabOutTmp[i]; + C_RGB_XYZ_Lab LabOutVec; + LabOutVec.Set(LabOutTmp[0], LabOutTmp[1], LabOutTmp[2]); + + ColConv.dEcmc(LabTmp, LabOutVec, dECMC); + //Result is in Linear Inks + //apply Nonlinear curves of Loaded thread + // in order to calculate volume + // Volume is used to calculate the feasible solutions + VectorXd InkOut(m_nInks); + InkOut = DoubleToVector(SolVector, m_nInks); + double *tmpval = m_colortable->GetNormFactor(); + for (int i = 0; i < m_nInks; ++i) + InkOut(i) *= tmpval[i]; // in [%] + //Limit ink percentage, if they changed recalculate Lab and dE + VectorXd VolumeTmp(nfree + nfixed); + ColorTable2Threadunits(InkOut, InkOut); //in % + ConvertToNLInks(InkOut, InkOut); // in %, thread units + LimitNLInks2Volume(InkOut, GamutRegion, VolumeTmp, CTUnits, + isBounded); //InkOut contains the modified Inks in nonlinear form, VolumeTmp contains the modified volume + if (isBounded) //inks were changed, recalculate Lab values + { + tmpval = m_colortable->GetInverseNormFactor(); + ConvertToLinearInks(InkOut, InkOut); + double *BndSol = new double[m_nInks]; + VectorToDouble(InkOut, BndSol); + for (int i = 0; i < m_nInks; ++i) + { + BndSol[i] *= tmpval[i]; + BndSol[i] /= 100.0; + } + forwardmodel->CalcFM(BndSol, LabBounded); + freeVec < double >(BndSol); +/* if (BndSol != NULL) + { + delete[] BndSol; + BndSol = NULL; + } */ + + for (int i = 0; i < 3; ++i) + finalLab[i] = LabBounded[i]; + LabOutVec.Set(LabBounded[0], LabBounded[1], LabBounded[2]); + ColConv.dEcmc(LabTmp, LabOutVec, dECMC); + } + for (i = 0; i < npars; ++i) + Vol[i] = VolumeTmp(i); + + freeVec <double>(InitCMY); + freeVec <double>(ValK); + freeVec <double>(LabBounded); + +/* if (InitCMY != NULL) + { + delete[] InitCMY; + InitCMY = NULL; + } + if (ValK != NULL) + { + delete[] ValK; + ValK = NULL; + } + if(LabBounded != NULL) + { + delete[] LabBounded; + LabBounded = NULL; + } */ + +} + +void Tango::ColorLib::ColorConverter::DirectInversionCalc4FT(double *LabIn, double Black, VectorXd &InkOut, + VectorXd &RGBOut, VectorXd &VolOut, VectorXd &LabOut, int &GamutRegion, bool &InGamut, + SURROUND sur, CAM02CS CS) +{ + //Declarations + ColorConvert ColConv(D65, D65); + ForwardModel* forwardmodel = m_colortable->GetForwardModel(); + int i, k; + + //Initialize variables + int nfree = m_ObjFunction->GetNumFreeParams(); + double *InitCMY = new double[nfree]; + int nfixed = m_ObjFunction->GetNumFixedParams(); + int npars = nfree + nfixed; + if (npars != m_nInks) + throw std::exception("Number of parameters does not match number of inks"); + double *ValK = new double[nfixed]; + //Init for single solution + bool FTisBounded; + double *FTSolVector = new double[m_nInks]; + double *FTfinalLab = new double[3]; + double *FTVol = new double[m_nInks]; + double *LabOutFinal = new double[3]; + int FTGamutRegion; + VectorXd InkTmp(m_nInks); + VectorXd VolumeTmp(npars); + C_RGB_XYZ_Lab LabTmp; + double FTdECMC; + + C_RGB_XYZ_Lab LabInVec; + VectorXd LabOutTmp(3); + LabInVec.Set(LabIn[0], LabIn[1], LabIn[2]); + C_RGB_XYZ_Lab LabOutVec; + m_currentMaxNLPerCM = m_maxNlPerCM; // thread units + for (i = 0; i < m_nProcessRanges; ++i) + { + m_CurrentProcessRangesMax[i] = m_ProcessRangesMaxP[i]; // thread units + m_CurrentProcessRangesMin[i] = m_ProcessRangesMinP[i]; + } + double *BndSol = new double[m_nInks]; + double *LabInFinal2 = new double[3]; + double *LabOnGamut = new double[3]; + double *LabBounded = new double[3]; + + ColConv.ChangeWP(LabIn, LabInFinal2, m_WP, m_whitepointXYZ_Strip); //LabInFinal2 is in Relative Colorimetric Space + LimitLab(LabInFinal2); + InGamut = m_colortable->m_GBD->IsInGamut(LabInFinal2, LabOnGamut, dETol, m_Conv02); // OrenLub + LimitLab(LabOnGamut); + + LabTmp.Set(LabOnGamut[0], LabOnGamut[1], LabOnGamut[2]); + m_ObjFunction->SetLabGoal(LabOnGamut); + m_Minimize->SetLabIn(LabOnGamut); + DirectInversionCalcSIter(Black, LabOnGamut, FTVol, forwardmodel, FTdECMC, FTisBounded, FTSolVector, FTGamutRegion, + FTfinalLab, nfree, nfixed); + bool FSInd = true; + for (i = 0; i < npars - 1; ++i) + FSInd = FSInd & ((FTVol[i] < 0.01) | (FTVol[i] > m_LowVolumeThreshold)); + FSInd = FSInd & ((FTVol[npars - 1] < 0.01) | (FTVol[npars - 1] > m_LightInksThr)); + FSInd = FSInd & (FTdECMC < 0.5); + if (FSInd) + { + if (FTisBounded) + InGamut = false; + for (i = 0; i < npars; ++i) + { + InkOut(i) = FTSolVector[i]; + VolOut(i) = FTVol[i]; + } + GamutRegion = GamutRegion; + for (int i = 0; i < 3; ++i) + LabOutFinal[i] = FTfinalLab[i]; + //cleanup + freeVec <double>(FTSolVector); + freeVec <double>(FTfinalLab); + freeVec <double>(FTVol); + } + else // no solution was found for fixed K, find the closest solution among feasible ones. + { + //calculate solutions + int CTUnits = 0; + int nk = 100 + 1; + double dK = 1.0 / (double)(nk - 1); + bool *isBounded = new bool[nk]; + double **SolVector = new double*[nk]; + double **finalLab = new double *[nk]; + double **Vol = new double*[nk]; + int *FeasibleSolutionsInd = new int[nk]; + int *VecGamutRegion = new int[nk]; + double *dECMC = new double[nk]; + double *VolumeVec = new double[npars]; + for (i = 0; i < nk; ++i) + { + SolVector[i] = new double[npars]; + finalLab[i] = new double[3]; + Vol[i] = new double[npars]; + } + + for (k = 0; k < nk; ++k) + { + ValK[0] = (double)k * dK; + DirectInversionCalcSIter(ValK[0], LabOnGamut, VolumeVec, forwardmodel, dECMC[k], isBounded[k], SolVector[k], GamutRegion, + finalLab[k], nfree, nfixed); + for (i = 0; i < npars; ++i) + Vol[k][i] = VolumeVec[i]; + VecGamutRegion[k] = GamutRegion; + } + + //find feasible solutions + int nfeas = -1; + + for (k = 0; k < nk; ++k) + { + bool FSInd = true; + for (i = 0; i < npars - 1; ++i) + FSInd = FSInd & ((Vol[k][i] < 0.01) | (Vol[k][i] > m_LowVolumeThreshold)); + FSInd = FSInd & ((Vol[k][npars - 1] < 0.01) | (Vol[k][npars - 1] > m_LightInksThr)); + FSInd = FSInd & (dECMC[k] < 0.5); + if (FSInd) + { + nfeas++; + FeasibleSolutionsInd[nfeas] = k; + } + } + double minVal = 1e+05; + int minInd = -1; + int kComponent = 3; + if (nfeas >= 0) + { + //find feasible solution whose K component is the closes to the original + for (i = 0; i < nfeas + 1; ++i) + { + if (std::fabs(Black - Vol[FeasibleSolutionsInd[i]][kComponent]) < minVal) + { + minVal = dECMC[FeasibleSolutionsInd[i]]; + minInd = FeasibleSolutionsInd[i]; + } + } + if (isBounded[minInd]) + InGamut = false; + } + else + { + //There are no feasible solutions + //Eliminate all solutions that have a K lower then the uniformity threshold + //Sacrifiicing accuracy to uniformity + + for (i = 0; i < nk; ++i) + { + /* if ((Vol[i][kComponent] > m_LightInksThr) | (Vol[i][kComponent] < 0.01)) + { + if (dECMC[i] < minVal) + { + minVal = dECMC[i]; + minInd = i; + } + } */ //waiting for Program decision Mirta October 27, 2022 + if (dECMC[i] < minVal) + { + minVal = dECMC[i]; + minInd = i; + } + } + if (isBounded[minInd]) + InGamut = false; + } + + for (i = 0; i < npars; ++i) + { + InkOut(i) = SolVector[minInd][i]; + VolOut(i) = Vol[minInd][i]; + } + GamutRegion = VecGamutRegion[minInd]; + for (int i = 0; i < 3; ++i) + LabOutFinal[i] = finalLab[minInd][i]; + + //cleanup + freeVec <int>(VecGamutRegion); + freeDP <double>(SolVector, nk); + freeDP <double>(finalLab, nk); + freeDP <double>(Vol, nk); + freeVec <int>(FeasibleSolutionsInd); + freeVec <bool>(isBounded); + freeVec <double>(dECMC); + } + + //LabOutFinal is in Relative Colorimetric + //Reverse the conversion process to bring back Lab to STRIP white point + ColConv.ChangeWP(LabOutFinal, LabOutFinal, m_whitepointXYZ_Strip, m_WP); + + //OrenLub + if (m_use_lub) + m_lubtable.apply_transformation(LabOutFinal, Unlub2Lub); + + LabOut = DoubleToVector(LabOutFinal, 3); + ColConv.SetReferenceWhite(D65); + //Convert to RGB + double *RGBOutP = new double[3]; + + //Use Relative colorimetric to get RGB + ColConv.LabtoRGB(LabOutFinal, RGBOutP); + RGBOut = DoubleToVector(RGBOutP, 3); + + //Cleanup + freeVec <double>(RGBOutP); + freeVec <double>(ValK); + freeVec <double>(LabInFinal2); + freeVec <double>(LabOnGamut); + freeVec <double>(LabOutFinal); + freeVec <double>(LabBounded); + freeVec <double>(BndSol); + freeVec <double>(InitCMY); +} + + + diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/ColorConverter.h b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/ColorConverter.h index ee247eac4..337513677 100644 --- a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/ColorConverter.h +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/ColorConverter.h @@ -21,6 +21,7 @@ #include "OutOfGamutOutput.pb-c.h" #include "RecommendedProcessTableInput.pb-c.h" #include "RecommendedProcessTableOutput.pb-c.h" +#include "ConversionType.pb-c.h" #include "ObjectiveFunction.h" #include "LevMar.h" #include "Interp.h" @@ -93,8 +94,13 @@ namespace Tango void Tango::ColorLib::ColorConverter::DirectInversion(InputCoordinates* inputcoordinates, ColorSpace colorspace, VectorXd &InkOut, VectorXd &RGBOut, VectorXd &VolOut, VectorXd &LabOut, int &GamutRegion, bool &InGamut, SURROUND sur, CAM02CS CS); + void Tango::ColorLib::ColorConverter::DirectInversion4FT(InputCoordinates* inputcoordinates, ColorSpace colorspace, + double *PrevInk, VectorXd &InkOut, VectorXd &RGBOut, VectorXd &VolOut, + VectorXd &LabOut, int &GamutRegion, bool &InGamut, SURROUND sur, CAM02CS CS); void Tango::ColorLib::ColorConverter::DirectInversionCalc(double *LabIn, VectorXd &InkOut, VectorXd &RGBOut, VectorXd &VolOut, VectorXd &LabOut, int &GamutRegion, bool &InGamut, SURROUND sur, CAM02CS CS); + void Tango::ColorLib::ColorConverter::DirectInversionCalc4FT(double *LabIn, double Black, VectorXd &InkOut, VectorXd &RGBOut, VectorXd &VolOut, + VectorXd &LabOut, int &GamutRegion, bool &InGamut, SURROUND sur, CAM02CS CS); void ConvertToNLInks(VectorXd InkIn, VectorXd &InkOut); void ConvertToLinearInks(VectorXd InkIn, VectorXd &InkOut); void VolumeToNLInkP(VectorXd Volume, VectorXd &NLInkP); @@ -103,6 +109,8 @@ namespace Tango size_t P_IsInGamut(uint8_t * input_buffer, size_t input_buffer_size, uint8_t *& output_buffer); private: LubTable m_lubtable; + bool m_use_lub; + bool m_has_lubdata; ColorTable *m_colortable; ColorTable *m_ThreadGBD; ColorConvert *m_Conv02; @@ -135,11 +143,9 @@ namespace Tango Gradient *m_GradStops; bool same_regions; int m_CalibMode; -// bool m_AdaptWP; + CalibData *m_CalibCurves; - //ForwardModel *m_forwardmodel; - bool m_has_forfinetuning; - bool m_forfinetuning; + ConversionType m_conversiontype; int m_nInks; int m_nVolumes; //double *m_ProcessRangesMaxInkUptake; @@ -241,6 +247,9 @@ namespace Tango bool &resplit, int PrevGamutRegion); void SetRMLParameters(ConversionInput *conversionInput); void VerifyGBD(); + void GetPrevVolume(double *PrevVolume, InputCoordinates *inputcoordinates); + void DirectInversionCalcSIter(double ValK,double *LabOnGamut, double *Vol, ForwardModel* forwardmodel, + double &dECMC, bool &isBounded, double *SolVector, int &GamutRegion, double *finalLab, int nfree, int nfixed); }; } } diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/LubTable.cpp b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/LubTable.cpp index 05bfbc4c4..c4d9c3e7a 100644 --- a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/LubTable.cpp +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/LubTable.cpp @@ -44,7 +44,7 @@ void LubTable::readLubTables(uint8_t *data) else if (strncmp(TagNames[k], "gbd ", 4) == 0) TList[k] = LubTag::gbd; else if (strncmp(TagNames[k], "gbdR", 4) == 0) - TList[k] = LubTag::gbd; + TList[k] = LubTag::gbdR; else if (strncmp(TagNames[k], "cprt", 4) == 0) TList[k] = LubTag::cprt; else if (strncmp(TagNames[k], "UToL", 4) == 0) @@ -544,28 +544,18 @@ LubTable::~LubTable() points_unlub = nullptr; } -void LubTable::init_lub_tables(bool use_Lub, bool has_LubData, uint8_t * data) +void LubTable::init_lub_tables(bool use_Lub, ColorConvert** conv, uint8_t * data) { - this->hasData = has_LubData; - this->useLub = use_Lub; - if (this->hasData) - { - readLubTables(data); - lub2unlub_poly.SetFreeTerm(C_RGB_XYZ_Lab({ 0, 0, 0 })); - unlub2lub_poly.SetFreeTerm(C_RGB_XYZ_Lab({ 0, 0, 0 })); - } + this->set_conv(conv); + readLubTables(data); + lub2unlub_poly.SetFreeTerm(C_RGB_XYZ_Lab({ 0, 0, 0 })); + unlub2lub_poly.SetFreeTerm(C_RGB_XYZ_Lab({ 0, 0, 0 })); } void LubTable::apply_transformation(double LabIn[3], bool direction) { // direction: true = Lub to Unlub, false = Unlub to Lub - if (!hasData) - { - throw std::exception("No LUB file was read"); - return; - } - int n_tetras = nVertices_unlub / 4; int(*tetras)[4] = vertices_unlub; double(*domain)[3] = points_unlub; diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/LubTable.h b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/LubTable.h index 26b206c12..610fdf9b2 100644 --- a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/LubTable.h +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/LubTable.h @@ -33,10 +33,8 @@ public: //LubTable(); LubTable(); ~LubTable(); - void init_lub_tables(bool use_Lub, bool has_LubData, uint8_t *data); // make private under constructor? + void init_lub_tables(bool use_Lub, ColorConvert** conv, uint8_t *data); // make private under constructor? - bool has_data() const { return hasData; } ; - bool use_lub() const { return useLub; } ; void set_conv(ColorConvert** conv) { this->conv = conv; } void apply_transformation (double LabIn[3], bool direction) ; @@ -53,8 +51,6 @@ private: int tableVersion; int tableSubversion; - bool hasData; - bool useLub; int nPoints; int nVertices_lub; int nVertices_unlub; diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/PMR/ColorLab/ConversionType.pb-c.c b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/PMR/ColorLab/ConversionType.pb-c.c new file mode 100644 index 000000000..535cd701b --- /dev/null +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/PMR/ColorLab/ConversionType.pb-c.c @@ -0,0 +1,37 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: ConversionType.proto */ + +/* Do not generate deprecated warnings for self */ +#ifndef PROTOBUF_C__NO_DEPRECATED +#define PROTOBUF_C__NO_DEPRECATED +#endif + +#include "ConversionType.pb-c.h" +static const ProtobufCEnumValue conversion_type__enum_values_by_number[2] = +{ + { "Default", "CONVERSION_TYPE__Default", 0 }, + { "FineTuning", "CONVERSION_TYPE__FineTuning", 1 }, +}; +static const ProtobufCIntRange conversion_type__value_ranges[] = { +{0, 0},{0, 2} +}; +static const ProtobufCEnumValueIndex conversion_type__enum_values_by_name[2] = +{ + { "Default", 0 }, + { "FineTuning", 1 }, +}; +const ProtobufCEnumDescriptor conversion_type__descriptor = +{ + PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC, + "ConversionType", + "ConversionType", + "ConversionType", + "", + 2, + conversion_type__enum_values_by_number, + 2, + conversion_type__enum_values_by_name, + 1, + conversion_type__value_ranges, + NULL,NULL,NULL,NULL /* reserved[1234] */ +}; diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/PMR/ColorLab/ConversionType.pb-c.h b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/PMR/ColorLab/ConversionType.pb-c.h new file mode 100644 index 000000000..72c007851 --- /dev/null +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/PMR/ColorLab/ConversionType.pb-c.h @@ -0,0 +1,43 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: ConversionType.proto */ + +#ifndef PROTOBUF_C_ConversionType_2eproto__INCLUDED +#define PROTOBUF_C_ConversionType_2eproto__INCLUDED + +#include <protobuf-c/protobuf-c.h> + +PROTOBUF_C__BEGIN_DECLS + +#if PROTOBUF_C_VERSION_NUMBER < 1003000 +# error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers. +#elif 1003000 < PROTOBUF_C_MIN_COMPILER_VERSION +# error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c. +#endif + + + + +/* --- enums --- */ + +typedef enum _ConversionType { + CONVERSION_TYPE__Default = 0, + CONVERSION_TYPE__FineTuning = 1 + PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(CONVERSION_TYPE) +} ConversionType; + +/* --- messages --- */ + +/* --- per-message closures --- */ + + +/* --- services --- */ + + +/* --- descriptors --- */ + +extern const ProtobufCEnumDescriptor conversion_type__descriptor; + +PROTOBUF_C__END_DECLS + + +#endif /* PROTOBUF_C_ConversionType_2eproto__INCLUDED */ |
