diff options
| author | Roy Ben-Shabat <Roy@Twine-s.com> | 2018-11-01 16:03:08 +0200 |
|---|---|---|
| committer | Roy Ben-Shabat <Roy@Twine-s.com> | 2018-11-01 16:03:08 +0200 |
| commit | 7c250f479434f1f3e00531fac5168ab78d611c2e (patch) | |
| tree | 3b3e3852533743a9b003b9f58099df46659e6cc2 /Software/Visual_Studio/Native | |
| parent | 5bf030a1137f09e9d9898c8a837e49a1af0468f9 (diff) | |
| download | Tango-7c250f479434f1f3e00531fac5168ab78d611c2e.tar.gz Tango-7c250f479434f1f3e00531fac5168ab78d611c2e.zip | |
New color conversion.
Added new pid parameters.
Changes dispenser widget orientation.
Modified NoneEmptyIdsPacks to GetSupportedIdsPacks.
Diffstat (limited to 'Software/Visual_Studio/Native')
14 files changed, 1231 insertions, 449 deletions
diff --git a/Software/Visual_Studio/Native/Tango.ColorLib/ColorConverter.cpp b/Software/Visual_Studio/Native/Tango.ColorLib/ColorConverter.cpp index 87c389c43..e99a56d26 100644 --- a/Software/Visual_Studio/Native/Tango.ColorLib/ColorConverter.cpp +++ b/Software/Visual_Studio/Native/Tango.ColorLib/ColorConverter.cpp @@ -9,7 +9,8 @@ #include "OutputLiquid.pb-c.h" #include "InputLiquid.pb-c.h" #include "LiquidType.pb-c.h" - +#include <iostream> +#include <stdio.h> #include "Dense" #include "C_RGB_XYZ_Lab.h" #include "ColorConvert.h" @@ -19,6 +20,20 @@ #include <cmath> #include <algorithm> #include <sstream> +//#include <vld.h> + +/*#define _CRTDBG_MAP_ALLOC +#include <stdlib.h> +#include <crtdbg.h> +#include <cstdlib> + +#ifdef _DEBUG +#define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ ) +// Replace _NORMAL_BLOCK with _CLIENT_BLOCK if you want the +// allocations to be of _CLIENT_BLOCK type +#else +#define DBG_NEW new +#endif */ #define dL 2.0 #define dC 2.0 @@ -31,12 +46,14 @@ #define NegValue -1000 #define WPTol 1.0 #define dETol 2.0 +# define ROUNDINGDigits 2.0 +#define maxPerRegion 100.0 Tango::ColorLib::ColorConverter::ColorConverter() :m_A2BTransform(NULL), m_B2ATransform(NULL), -m_GBD(NULL), m_CalibCurves(NULL), m_CalibDatasize(NULL), m_Conv02(NULL), +m_GBD(NULL), m_CalibCurves(NULL), m_Conv02(NULL), m_maxNlPerCM(NULL), m_nA2BnSepIn(0), m_nA2BnSepOut(0), m_nB2AnSepIn(0), m_nB2AnSepOut(0), -m_nInks(0), m_nVolumes(0), m_AdaptWP(false) +m_nInks(0), m_nVolumes(0), m_AdaptWP(false), m_LinInterp(NULL), m_InvLinInterp(NULL) { m_whitepointLab.Set(-1, -1, -1); m_whitepointXYZ_Strip.Set(-1, -1, -1); @@ -66,16 +83,21 @@ Tango::ColorLib::ColorConverter::~ColorConverter() delete m_Conv02; m_Conv02 = NULL; } - if (m_CalibDatasize != NULL) - { - delete[] m_CalibDatasize; - m_CalibDatasize = NULL; - } if (m_CalibCurves != NULL) { delete[] m_CalibCurves; m_CalibCurves = NULL; } + if (m_LinInterp != NULL) + { + delete [] m_LinInterp; + m_LinInterp = NULL; + } + if (m_InvLinInterp != NULL) + { + delete [] m_InvLinInterp; + m_InvLinInterp = NULL; + } } void Tango::ColorLib::ColorConverter::ProcessHiveNeighbors(VectorXd Lab, VectorXd RGB, VectorXd Volume, int InGamutRegion, @@ -103,17 +125,17 @@ void Tango::ColorLib::ColorConverter::ProcessHiveNeighbors(VectorXd Lab, VectorX for (int i = 0; i < 6; ++i) { Jab1(i, 0) = Jab(0); - Jab1(i, 1) = Jab(1) + dC * cos(hue + i * dH6); - Jab1(i, 2) = Jab(2) + dC * sin(hue + i * dH6); + Jab1(i, 1) = Jab(1) + dC*cos(hue + i*dH6); + Jab1(i, 2) = Jab(2) + dC*sin(hue + i*dH6); } int j1 = 0, j2 = 0; - double dC2 = dC * 2.0; + double dC2 = dC*2.0; for (int i = 0; i < 12; ++i) { j1 = i + 6; Jab1(j1, 0) = Jab(0); - Jab1(j1, 1) = Jab(1) + dC2 * cos(hue + i * dH12); - Jab1(j1, 2) = Jab(2) + dC2 * sin(hue + i * dH12); + Jab1(j1, 1) = Jab(1) + dC2*cos(hue + i*dH12); + Jab1(j1, 2) = Jab(2) + dC2*sin(hue + i*dH12); } /* for (int i = 0; i < 2; ++i) { @@ -139,14 +161,20 @@ void Tango::ColorLib::ColorConverter::ProcessHiveNeighbors(VectorXd Lab, VectorX VectorXd xyz(3); VectorXd JabTmp(3); C_RGB_XYZ_Lab xyzVal, LabVal; - double *tmpRGB; + double *tmpRGB = new double[3]; + //double *tmpRGB = DBG_NEW double[3]; double *InkOut = new double[m_nInks]; - //int *GamutRegion = new int[nHive + 2]; + //double *InkOut = DBG_NEW double[m_nInks]; + int *GamutRegion = new int[nHive + 1]; - + //int *GamutRegion = DBG_NEW int[nHive + 1]; double *Lab1P = new double[3]; + //double *Lab1P = DBG_NEW double[3]; VectorXd Vol(m_nVolumes); int j = 0; + double * LabInFinal1= new double[3]; + //double * LabInFinal1 = DBG_NEW double[3]; + double * LabInFinal2; //= new double[3]; for (int i = 0; i < nHive; ++i) { //fill data @@ -164,34 +192,36 @@ void Tango::ColorLib::ColorConverter::ProcessHiveNeighbors(VectorXd Lab, VectorX m_A2BTransform->evalInkP2Lab(InkOut, Lab1P, GamutRegion[i]); //Check if whitepoints match //LabOut is under D65 illumination - double * LabInFinal = Lab1P; + //Convert to CT WP - LabInFinal = m_Conv02->ChangeWP(LabInFinal, m_whitepointXYZ_CT, m_WP); //dest, source + m_Conv02->ChangeWP(Lab1P, LabInFinal1, m_whitepointXYZ_CT, m_WP); //dest, source + LabInFinal2 = LabInFinal1; if (m_AdaptWP) { //Convert to Strip whitepoint - LabInFinal = m_Conv02->ChangeWP(LabInFinal, m_whitepointXYZ_Strip, m_whitepointXYZ_CT); + m_Conv02->ChangeWP(LabInFinal2, LabInFinal2, m_whitepointXYZ_Strip, m_whitepointXYZ_CT); } m_Conv02->SetReferenceWhite(D65); //Convert to RGB - tmpRGB = m_Conv02->LabtoRGB(LabInFinal); + //m_Conv02->LabtoRGB(LabInFinal2, tmpRGB); + m_Conv02->LabtoRGB(Lab1P, tmpRGB); for (int j = 0; j < 3; ++j) RGBTmpVec(i, j) = std::min(std::max(tmpRGB[j], 0.0), 255.0); VectorXd InkOutV = DoubleToVector(InkOut, m_nInks); ConvertToNLInks(InkOutV, InkOutV); NLInkPToVolume(InkOutV, Vol); - for (int j = 0; j < 3; ++j) + //make sure the rounded sum does not exceed the limit in the gamut region + for (int j = 0; j < m_nInks; ++j) VolumeHive(i, j) = Vol(j); } //for (int i = 0; i < 2; ++i) for (int i = 0; i < 1; ++i) { - for (j = 0; j < 3; ++j) - { + for (j = 0; j < m_nInks; ++j) VolumeHive(nHive + i, j) = Volume(j); + for (j = 0; j < 3; ++j) RGBTmpVec(nHive + i, j) = RGB(j); - } GamutRegion[nHive + i] = InGamutRegion; } @@ -217,20 +247,44 @@ void Tango::ColorLib::ColorConverter::ProcessHiveNeighbors(VectorXd Lab, VectorX delete[] Lab1P; Lab1P = NULL; } + if (tmpRGB != NULL) + { + delete[] tmpRGB; + tmpRGB = NULL; + } + /*if (LabInFinal2 != NULL) + { + delete[]LabInFinal2; + LabInFinal2 = NULL; + }*/ + if (LabInFinal1 != NULL) + { + delete[]LabInFinal1; + LabInFinal1 = NULL; + } return; } void Tango::ColorLib::ColorConverter::FindTriplet(VectorXd Lab, MatrixXd Lab1, int nHive, int*indDataMax) { - int vecSize = nHive * (nHive - 1) / 2; + int vecSize = nHive*(nHive - 1) / 2; double *dECMC = new double[vecSize]; + //double *dECMC = DBG_NEW double[vecSize]; + int i, j; + for (i = 0; i < vecSize; ++i) + dECMC[i] = -1; int **indexpairs = new int*[vecSize]; + //int **indexpairs = DBG_NEW int*[vecSize]; + for (i = 0; i < vecSize; ++i) + indexpairs[i] = new int[2]; + //indexpairs[i] = DBG_NEW int[2]; + int ind = -1; ColorConvert ColConv(D65, D65); VectorXd Labi(3); VectorXd Labj(3); - int i, j; + for (i = 0; i < nHive; ++i) { Labi << Lab1(i, 0), Lab1(i, 1), Lab1(i, 2); @@ -238,7 +292,6 @@ void Tango::ColorLib::ColorConverter::FindTriplet(VectorXd Lab, MatrixXd Lab1, { Labj << Lab1(j, 0), Lab1(j, 1), Lab1(j, 2); ind++; - indexpairs[ind] = new int[2]; ColConv.SymmetricaldECMC(Labi, Labj, dECMC[ind]); indexpairs[ind][0] = i; indexpairs[ind][1] = j; @@ -264,7 +317,7 @@ void Tango::ColorLib::ColorConverter::FindTriplet(VectorXd Lab, MatrixXd Lab1, if (indexpairs != NULL) { - for (int i = 0; i < 2; ++i) + for (int i = 0; i < vecSize; ++i) delete[] indexpairs[i]; delete[] indexpairs; indexpairs = NULL; @@ -314,7 +367,7 @@ void Tango::ColorLib::ColorConverter::fillVolume(OutputCoordinates *&outputCoor { outputLiquids[i]->has_volume = true; outputLiquids[i]->has_liquidtype = true; - outputLiquids[i]->liquidtype = (LiquidType)m_CalibCurves[i].getInkName(); + outputLiquids[i]->liquidtype = (LiquidType)(m_CalibCurves[i].getInkName()); outputLiquids[i]->volume = Volume(i); break; } @@ -341,20 +394,16 @@ void Tango::ColorLib::ColorConverter::fillRGB(OutputCoordinates *outputCoords, V void Tango::ColorLib::ColorConverter::readColorTransformations(ConversionInput* conversionInput) { //Read thread white. Thread White is given in CIELab Space - if (conversionInput->has_threadl && conversionInput->has_threada && conversionInput->has_threadb) - { + m_whitepointLab.Set(conversionInput->threadl, conversionInput->threada, conversionInput->threadb); //White point in XYZ Color Space ColorConvert CConvert(D65, D65); C_RGB_XYZ_Lab tmpW; tmpW = CConvert.LabToXYZ(m_whitepointLab); m_whitepointXYZ_Strip.Set(tmpW.Get_x(), tmpW.Get_y(), tmpW.Get_z()); - } - else - { - throw std::exception("misssing one of the whitepoint components"); - return; - } + + + //parse Color Tansformations, placed in forward data int bytesread = 0; NumConversions conv; @@ -370,15 +419,24 @@ void Tango::ColorLib::ColorConverter::readColorTransformations(ConversionInput* bytesread += 4; //read Tag Table char **TagNames = new char*[tag_count]; + //char **TagNames = DBG_NEW char*[tag_count]; int **TagSize = new int*[tag_count]; - char *tmpC; + //int **TagSize = DBG_NEW int*[tag_count]; + char *tmpC = NULL; int n = 0; int i, j; for (i = 0; i < tag_count; ++i) { TagSize[i] = new int[3]; + //TagSize[i] = DBG_NEW int[3]; tmp = conv.ByteToInt(buff, bytesread); - tmpC = conv.getchar(tmp, n); + n = sizeof((char*)&tmp); + delete[] tmpC; + tmpC = NULL; + tmpC = new char[n]; + //tmpC = DBG_NEW char[n]; + conv.getchar(tmp, n, tmpC); + //TagNames[i] = DBG_NEW char[n]; TagNames[i] = new char[n]; for (j = 0; j < n; ++j) TagNames[i][j] = tmpC[j]; @@ -388,7 +446,9 @@ void Tango::ColorLib::ColorConverter::readColorTransformations(ConversionInput* TagSize[i][1] = conv.ByteToInt(buff, bytesread); bytesread += 4; } + delete[] tmpC; int *TList = new int[tag_count]; + //int *TList = DBG_NEW int[tag_count]; for (int k = 0; k < tag_count; ++k) { if (strncmp(TagNames[k], "A2B ", 4) == 0) @@ -415,6 +475,7 @@ void Tango::ColorLib::ColorConverter::readColorTransformations(ConversionInput* uint8_t *A2BLUT = &(conversionInput->forwarddata.data[TagSize[k][0]]); int A2BLutsize = TagSize[k][1]; m_A2BTransform = new ColorTransf(); + //m_A2BTransform = DBG_NEW ColorTransf(); m_A2BTransform->InitData(A2BLUT, A2BLutsize); break; } @@ -423,6 +484,7 @@ void Tango::ColorLib::ColorConverter::readColorTransformations(ConversionInput* uint8_t *B2ALUT = &(conversionInput->forwarddata.data[TagSize[k][0]]); int B2ALutsize = TagSize[k][1]; m_B2ATransform = new ColorTransf(); + //m_B2ATransform = DBG_NEW ColorTransf(); m_B2ATransform->InitData(B2ALUT, B2ALutsize); break; } @@ -430,6 +492,7 @@ void Tango::ColorLib::ColorConverter::readColorTransformations(ConversionInput* { uint8_t *GBDList = &(conversionInput->forwarddata.data[TagSize[k][0]]); m_GBD = new GBD(); + //m_GBD = DBG_NEW GBD(); int GBDSize = TagSize[k][1]; m_GBD->InitData(GBDList, GBDSize); break; @@ -468,6 +531,9 @@ void Tango::ColorLib::ColorConverter::readColorTransformations(ConversionInput* delete[]TagNames; delete[] TagSize; delete[] TList; + delete header.ColorSpace; + delete header.ConnectionSpace; + delete header.DeviceManufacturer; } @@ -498,14 +564,15 @@ void Tango::ColorLib::ColorConverter::readColorTransformations(ConversionInput* void Tango::ColorLib::ColorConverter::readCalibrationTables(ConversionInput* conversionInput) { SetNumberofInks((int)(conversionInput->inputcoordinates->n_inputliquids)); - CalibData *CalibCurves = new CalibData[m_nInks]; + //CalibData *CalibCurves = new CalibData[m_nInks]; m_CalibCurves = new CalibData[m_nInks]; + //m_CalibCurves = DBG_NEW CalibData[m_nInks]; for (int i = 0; i < m_nInks; ++i) { InputLiquid* InkType = conversionInput->inputcoordinates->inputliquids[i]; - //CalibCurves[i].SetCalibName((int)(InkType->calibrationdata->liquidtype)); + m_CalibCurves[i].SetCalibName((int)(InkType->calibrationdata->liquidtype)); - //CalibCurves[i].SetMaxNlPerCM(conversionInput->inputcoordinates->inputliquids[i]->maxnanoliterpercentimeter); + m_CalibCurves[i].SetMaxNlPerCM(conversionInput->inputcoordinates->inputliquids[i]->maxnanoliterpercentimeter); switch (InkType->calibrationdata->liquidtype) { @@ -526,7 +593,6 @@ void Tango::ColorLib::ColorConverter::readCalibrationTables(ConversionInput* con } } } - // m_CalibCurves=CalibCurves; return; } @@ -547,6 +613,8 @@ void Tango::ColorLib::ColorConverter::SetCalibData(CalibrationData *calibrationD //Iterate over calibration points.. double *pointsx = new double[calibrationData->n_calibrationpoints]; double *pointsy = new double[calibrationData->n_calibrationpoints]; + //double *pointsx = DBG_NEW double[calibrationData->n_calibrationpoints]; + //double *pointsy = DBG_NEW double[calibrationData->n_calibrationpoints]; for (size_t j = 0; j < calibrationData->n_calibrationpoints; ++j) { //Calibration Point @@ -582,50 +650,60 @@ void Tango::ColorLib::ColorConverter::ConvertColorToLinearInks(ConversionInput* { // Basic assumption: if data is given in RGB space, conversion should be in relative colorimetric, //We expect that [255,255,255](white) will be mapped to the thread white, meaning all inks should be zero - // and the coverted RGB will refect the color of the thread + // and the coverted RGB will refect the color of the thread, but will be shown in Relative Colorimetric to the user //The workflow is a follows: //1. Convert RGB to Lab (Whitepoint is D65, same as tables) //2. Convert Lab to Inks (B2A tables), Inks to Volume //3. Convert Inks to Lab (A2B tables) to get the in/on Gamut Lab //4. Convert Lab to Absolute colorimetric taking into account the Strip and CT whitepoints - //5. Use the above Lab to obtain RGB + //5. Use the Relative Colorimetric Lab to obtain RGB RGBOut(0) = conversionInput->inputcoordinates->red; RGBOut(1) = conversionInput->inputcoordinates->green; RGBOut(2) = conversionInput->inputcoordinates->blue; //convert to Lab ColorConvert CConvertD65(D65, D65); //Destination, source - double *LabIn; - double *RGBOutP = VectorToDouble(RGBOut); + double *LabIn = new double[3]; + double *RGBOutP = new double[3]; + //double *LabIn = DBG_NEW double[3]; + //double *RGBOutP = DBG_NEW double[3]; + VectorToDouble(RGBOut, RGBOutP); //RGB to Lab - LabIn = CConvertD65.RGBtoLab(RGBOutP); //Values are in Relative Colorimetric, D65 + CConvertD65.RGBtoLab(RGBOutP, LabIn); //Values are in Relative Colorimetric, D65 - double *LabInFinal = LabIn; + double *LabInFinal = new double[3]; + //double *LabInFinal = DBG_NEW double[3]; + memcpy(LabInFinal , LabIn, 3*sizeof(double)); //Is In Gamut? InGamut = IsInGamut(LabIn, sur); //convert to inks int GamutRegion; double *InkOutP = new double[m_nB2AnSepOut]; + //double *InkOutP = DBG_NEW double[m_nB2AnSepOut]; //LabInFinal is in Relative Colorimetric, just like the Color Tables m_B2ATransform->evalLab2InkP(LabInFinal, InkOutP, GamutRegion); //InkOut is in units of 16 bits InkOut = DoubleToVector(InkOutP, m_nInks); //Convert to Lab to get the actual in Gamut Lab double *LabInP = new double[3]; + //double *LabInP = DBG_NEW double[3]; m_A2BTransform->evalInkP2Lab(InkOutP, LabInP, GamutRegion); //Lab is in Relative Colorimetric LabOut = DoubleToVector(LabInP, 3); //Convert to CT thread, LabIn is in Relative Colorimetric Space - LabInFinal = CConvertD65.ChangeWP(LabInP, m_whitepointXYZ_CT, m_WP); + CConvertD65.ChangeWP(LabInP, LabInFinal, m_whitepointXYZ_CT, m_WP); //check if the thread to be used is the same as the one in the color tables if (m_AdaptWP) { //Convert to Strip White Point - LabInFinal = CConvertD65.ChangeWP(LabInFinal, m_whitepointXYZ_Strip, m_whitepointXYZ_CT); + CConvertD65.ChangeWP(LabInFinal, LabInFinal, m_whitepointXYZ_Strip, m_whitepointXYZ_CT); } CConvertD65.SetReferenceWhite(D65); //Get the Gamut Mapped RGB Based on Absolute Colorimetric Data - RGBOutP = CConvertD65.LabtoRGB(LabInFinal); - RGBOut = DoubleToVector(RGBOutP, 3); + double *RGBOutP1 = new double[3]; + //double *RGBOutP1 = DBG_NEW double[3]; + //CConvertD65.LabtoRGB(LabInFinal, RGBOutP1); + CConvertD65.LabtoRGB(LabInP, RGBOutP1); + RGBOut = DoubleToVector(RGBOutP1, 3); if (LabInP != NULL) { delete[] LabInP; @@ -638,14 +716,24 @@ void Tango::ColorLib::ColorConverter::ConvertColorToLinearInks(ConversionInput* } if (LabIn != NULL) { - delete LabIn; + delete [] LabIn; LabIn = NULL; } if (RGBOutP != NULL) { - delete RGBOutP; + delete [] RGBOutP; RGBOutP = NULL; } + if (RGBOutP1 != NULL) + { + delete [] RGBOutP1; + RGBOutP1 = NULL; + } + if (LabInFinal != NULL) + { + delete [] LabInFinal; + LabInFinal = NULL; + } break; } case (COLOR_SPACE__LAB): @@ -656,42 +744,54 @@ void Tango::ColorLib::ColorConverter::ConvertColorToLinearInks(ConversionInput* //2. Convert Lab to Inks (B2A tables), Inks to Volume //3. Convert Inks to Lab (A2B tables) to get the in/on Gamut Lab //4. Convert Lab to Absolute colorimetric taking into account the Strip and CT whitepoints - //5. Use the above Lab to obtain RGB + //5. Use the Relative Colorimetric Lab to obtain RGB double *LabIn = new double[3]; + //double *LabIn = DBG_NEW double[3]; LabIn[0] = conversionInput->inputcoordinates->l; LabIn[1] = conversionInput->inputcoordinates->a; LabIn[2] = conversionInput->inputcoordinates->b; //the assumption is that the color space has illumination that matches the whitepoint of the Strip ColorConvert CConvertD65(D65, D65); //Destination, source - double *LabInFinal = LabIn; + double *LabInFinal1 = new double[3]; + //double *LabInFinal1 = DBG_NEW double[3]; + memcpy(LabInFinal1, LabIn, 3*sizeof(double)); + //LabInFinal1 = LabIn; // Lab is assumed to match the color of the STRIP, however the tables could have a different WP //Check if Color Tables and Strip whitepoints are the same, otherwise convert if (m_AdaptWP) { - LabInFinal = CConvertD65.ChangeWP(LabInFinal, m_whitepointXYZ_CT, m_whitepointXYZ_Strip); //to Color Tables + CConvertD65.ChangeWP(LabInFinal1, LabInFinal1, m_whitepointXYZ_CT, m_whitepointXYZ_Strip); //to Color Tables + LabIn = LabInFinal1; } - LabInFinal = CConvertD65.ChangeWP(LabInFinal, m_WP, m_whitepointXYZ_CT); //to Relative - InGamut = IsInGamut(LabInFinal, sur); + double *LabInFinal2 = new double[3]; + //double *LabInFinal2 = DBG_NEW double[3]; + CConvertD65.ChangeWP(LabIn, LabInFinal2, m_WP, m_whitepointXYZ_CT); //to Relative + InGamut = IsInGamut(LabInFinal2, sur); //convert to Inks int GamutRegion; double *InkOutP = new double[m_nB2AnSepOut]; - m_B2ATransform->evalLab2InkP(LabInFinal, InkOutP, GamutRegion); //InkOut is in units of 16 bits + //double *InkOutP = DBG_NEW double[m_nB2AnSepOut]; + m_B2ATransform->evalLab2InkP(LabInFinal2, InkOutP, GamutRegion); //InkOut is in units of 16 bits //Convert Inks to Lab to get the Gamut Mapped Lab m_A2BTransform->evalInkP2Lab(InkOutP, LabIn, GamutRegion); LabOut = DoubleToVector(LabIn, 3); InkOut = DoubleToVector(InkOutP, m_nInks); - double *LabOutFinal = LabIn; + double *LabOutFinal = new double[3]; + //double *LabOutFinal = DBG_NEW double[3]; + memcpy(LabOutFinal , LabIn, 3*sizeof(double)); //LabOutFinal is in Relative Colorimetric //Reverse the conversion process to bring back Lab to STRIP white point - LabOutFinal = CConvertD65.ChangeWP(LabOutFinal, m_whitepointXYZ_CT, m_WP); + CConvertD65.ChangeWP(LabOutFinal, LabOutFinal, m_whitepointXYZ_CT, m_WP); if (m_AdaptWP) { - LabOutFinal = CConvertD65.ChangeWP(LabOutFinal, m_whitepointXYZ_Strip, m_whitepointXYZ_CT); + CConvertD65.ChangeWP(LabOutFinal, LabOutFinal, m_whitepointXYZ_Strip, m_whitepointXYZ_CT); } CConvertD65.SetReferenceWhite(D65); //Convert to RGB - double *RGBOutP; //= new double[3]; - RGBOutP = CConvertD65.LabtoRGB(LabOutFinal); + double *RGBOutP = new double[3]; + // double *RGBOutP = DBG_NEW double[3]; + //CConvertD65.LabtoRGB(LabOutFinal, RGBOutP); + CConvertD65.LabtoRGB(LabIn, RGBOutP); RGBOut = DoubleToVector(RGBOutP, 3); if (InkOutP != NULL) @@ -704,23 +804,43 @@ void Tango::ColorLib::ColorConverter::ConvertColorToLinearInks(ConversionInput* delete[] LabIn; LabIn = NULL; } - break; + if (LabInFinal1 != NULL) + { + delete[]LabInFinal1; + LabInFinal1 = NULL; + } + if (LabInFinal2 != NULL) + { + delete[]LabInFinal2; + LabInFinal2 = NULL; + } + if (LabOutFinal != NULL) + { + delete[]LabOutFinal; + LabOutFinal = NULL; + } + + if (RGBOutP != NULL) + { + delete[] RGBOutP; + RGBOutP = NULL; + } + break; } + case(COLOR_SPACE__CMYK): {//no conversion //missing from structure light inks or special colors // just convert Lab for rgb display double *outData = new double[m_nA2BnSepIn]; + //double *outData = DBG_NEW double[m_nA2BnSepIn]; size_t CountSep = 0; - outData[0] = conversionInput->inputcoordinates->cyan; - outData[1] = conversionInput->inputcoordinates->magenta; - outData[2] = conversionInput->inputcoordinates->yellow; - CountSep = 3; - if (conversionInput->inputcoordinates->has_key) - { - outData[3] = conversionInput->inputcoordinates->key; - CountSep++; - } + outData[0] = (double)(conversionInput->inputcoordinates->cyan); + outData[1] = (double)(conversionInput->inputcoordinates->magenta); + outData[2] = (double)(conversionInput->inputcoordinates->yellow); + outData[3] = conversionInput->inputcoordinates->key; + CountSep=4; + if (CountSep != m_nA2BnSepIn) { //mismatch between table and sent data @@ -730,27 +850,43 @@ void Tango::ColorLib::ColorConverter::ConvertColorToLinearInks(ConversionInput* //Convert to RGB int GamutRegion = 0; double *InkOutP = new double[m_nA2BnSepIn]; + //double *InkOutP = DBG_NEW double[m_nA2BnSepIn]; for (int i = 0; i < m_nA2BnSepIn; ++i) InkOutP[i] = outData[i]; double *LabOutP = new double[3]; + //double *LabOutP = DBG_NEW double[3]; m_A2BTransform->evalInkP2Lab(InkOutP, LabOutP, GamutRegion); InkOut = DoubleToVector(InkOutP, m_nInks); //LabOut is in relative colorimetric ColorConvert CConvertD65(D65, D65); - double *LabOutFinal = LabOutP; + double *LabOutFinal1 = new double[3]; + //double *LabOutFinal1 = DBG_NEW double[3]; + LabOutFinal1 = LabOutP; + double *LabOutFinal2 = new double[3]; + //double *LabOutFinal2 = DBG_NEW double[3]; + LabOutFinal2 = LabOutP; InGamut = true; //Check if white points match - LabOutFinal = CConvertD65.ChangeWP(LabOutFinal, m_whitepointXYZ_CT, m_WP); + CConvertD65.ChangeWP(LabOutFinal1, LabOutFinal1, m_whitepointXYZ_CT, m_WP); if (m_AdaptWP) {//check if this is needed - LabOutFinal = CConvertD65.ChangeWP(LabOutFinal, m_whitepointXYZ_Strip, m_whitepointXYZ_CT); + CConvertD65.ChangeWP(LabOutFinal1, LabOutFinal2, m_whitepointXYZ_Strip, m_whitepointXYZ_CT); + LabOutFinal1 = LabOutFinal2; } - LabOut = DoubleToVector(LabOutFinal, 3); + LabOut = DoubleToVector(LabOutFinal1, 3); CConvertD65.SetReferenceWhite(D65); //Get RGB - double *RGBOutP; - RGBOutP = CConvertD65.LabtoRGB(LabOutFinal); + double *RGBOutP = new double[3]; + //double *RGBOutP = DBG_NEW double[3]; + //CConvertD65.LabtoRGB(LabOutFinal1, RGBOutP); + CConvertD65.LabtoRGB(LabOutP, RGBOutP); RGBOut = DoubleToVector(RGBOutP, 3); + + if (outData != NULL) + { + delete[] outData; + outData = NULL; + } if (LabOutP != NULL) { delete[] LabOutP; @@ -761,14 +897,24 @@ void Tango::ColorLib::ColorConverter::ConvertColorToLinearInks(ConversionInput* delete[] InkOutP; InkOutP = NULL; } - if (LabOutFinal != NULL) + if (RGBOutP != NULL) { - delete LabOutFinal; - LabOutFinal = NULL; + delete[] RGBOutP; + RGBOutP = NULL; + } + if (LabOutFinal1 != NULL) + { + delete [] LabOutFinal1; + LabOutFinal1 = NULL; + } + if (LabOutFinal2 != NULL) + { + delete [] LabOutFinal2; + LabOutFinal2 = NULL; } if (RGBOutP != NULL) { - delete RGBOutP; + delete [] RGBOutP; RGBOutP = NULL; } break; @@ -785,7 +931,7 @@ void Tango::ColorLib::ColorConverter::ConvertColorToLinearInks(ConversionInput* return; } break; - //missing calclulation method and pantone table, either in terms of RGB or CMY or Lab + //missing calculation method and pantone table, either in terms of RGB or CMY or Lab } default: @@ -800,16 +946,9 @@ void Tango::ColorLib::ColorConverter::ConvertColorToLinearInks(ConversionInput* void Tango::ColorLib::ColorConverter::ConvertToNLInks(VectorXd InkIn, VectorXd &InkOut) { - Interp LinInterp; - double *xValues(NULL); - double *yValues(NULL); - for (int i = 0; i < m_nVolumes; ++i) { - xValues = m_CalibCurves[i].getyCoords(); - yValues = m_CalibCurves[i].getxCoords(); - LinInterp.Init(xValues, yValues, m_CalibCurves[i].getSize()); - LinInterp.Eval(InkIn(i), InkOut(i)); + m_InvLinInterp[i].Eval(InkIn(i), InkOut(i)); } return; @@ -817,16 +956,9 @@ void Tango::ColorLib::ColorConverter::ConvertToNLInks(VectorXd InkIn, VectorXd void Tango::ColorLib::ColorConverter::ConvertToLinearInks(VectorXd InkIn, VectorXd &InkOut) { - Interp LinInterp; - double *xValues(NULL); - double *yValues(NULL); - for (int i = 0; i < m_nVolumes; ++i) { - xValues = m_CalibCurves[i].getxCoords(); - yValues = m_CalibCurves[i].getyCoords(); - LinInterp.Init(xValues, yValues, m_CalibCurves[i].getSize()); - LinInterp.Eval(InkIn(i), InkOut(i)); + m_LinInterp[i].Eval(InkIn(i), InkOut(i)); } return; @@ -840,7 +972,7 @@ void Tango::ColorLib::ColorConverter::VolumeToNLInkP(VectorXd Volume, VectorXd & double InkSum = 0.; for (int i = 0; i < m_nVolumes; ++i) { - InkP(i) = 100 * Volume(i) / m_maxNlPerCM(i); + InkP(i) = Volume(i); /// 100 * Volume(i) / m_maxNlPerCM(i); //Volume is in % if (InkMax < InkP(i)) { InkMax = InkP(i); @@ -849,6 +981,13 @@ void Tango::ColorLib::ColorConverter::VolumeToNLInkP(VectorXd Volume, VectorXd & InkSum += InkP(i); } NLInkP(MaxInd) = InkSum; + if (InkSum == 0.0) + { + for (int i = 0; i < m_nVolumes; ++i) + NLInkP(i) = 0.0; + return; + } + //Prepare Matrix to get the remainder values MatrixXd MatNLI(m_nVolumes - 1, m_nVolumes - 1); VectorXd RHSide(m_nVolumes - 1); @@ -875,7 +1014,7 @@ void Tango::ColorLib::ColorConverter::VolumeToNLInkP(VectorXd Volume, VectorXd & //Solve System of Linear Equations MatrixXd MatNLIInv(m_nVolumes - 1, m_nVolumes - 1); MatNLIInv = MatNLI.inverse(); - VectorXd Result = MatNLIInv * RHSide; + VectorXd Result = MatNLIInv*RHSide; //VectorXd Result = MatNLI.colPivHouseholderQr().solve(RHSide); //rearrange solution ind = -1; @@ -907,11 +1046,48 @@ void Tango::ColorLib::ColorConverter::NLInkPToVolume(VectorXd NLInk, VectorXd &V for (i = 0; i < m_nInks; ++i) Volume(i) = 0.0; else + { + for (i = 0; i < m_nInks; ++i) + { + InkNorm(i) = MaxInk*NLInk(i) / InkSum; + Volume(i) = InkNorm(i); // InkNorm(i) * m_maxNlPerCM(i) / 100; // Volume is in % + } + // Round to k decimal digits, verify that sum in within allowed values. + double sumNorm = 0.0; + double RsumNorm = 0.0; + VectorXd RVolNorm(m_nInks); + double ROUNDINGTol = pow(10, ROUNDINGDigits); + for (i = 0; i < m_nInks; ++i) { - InkNorm(i) = MaxInk * NLInk(i) / InkSum; - Volume(i) = InkNorm(i) * m_maxNlPerCM(i) / 100; + sumNorm += Volume(i); + RVolNorm(i) = round(Volume(i)*ROUNDINGTol) / ROUNDINGTol; + RsumNorm += RVolNorm(i); } + if (RsumNorm > 200.0 || abs(sumNorm - RsumNorm) >= 1 / ROUNDINGTol) + { + VectorXd dd(m_nInks); + double maxdd = -1; + int maxInd; + for (int i = 0; i < m_nInks; ++i) + { + dd(i) = Volume(i) - RVolNorm(i); + if (abs(dd(i)) > maxdd) + { + maxdd = dd(i); + maxInd = i; + } + } + int signdd = 0; + if (dd(maxInd) > 0) + signdd = 1; + else + signdd = -1; + RVolNorm(maxInd) = RVolNorm(maxInd) + signdd / ROUNDINGTol; + } + for (int i = 0; i < m_nInks; ++i) + Volume(i) = RVolNorm(i); + } return; } @@ -926,39 +1102,31 @@ void Tango::ColorLib::ColorConverter::ConvertVolumeToRGBDisplay(ConversionInput* // Set Calibration Data LiquidType LQ; if (m_CalibCurves == NULL) + { m_CalibCurves = new CalibData[m_nInks]; - - //CalibData *CalibCurves = new CalibData[m_nInks]; - for (int i = 0; i < m_nVolumes; ++i) - { - LQ = conversionInput->inputcoordinates->inputliquids[i]->calibrationdata->liquidtype; - if (LQ == LIQUID_TYPE__Cyan || LQ == LIQUID_TYPE__Magenta || LQ == LIQUID_TYPE__Yellow || LQ == LIQUID_TYPE__Black) + //m_CalibCurves = DBG_NEW CalibData[m_nInks]; + for (int i = 0; i < m_nVolumes; ++i) { - //check if calibration data exists - // if (m_CalibCurves == NULL) - // { - //Get calibration data. - CalibrationData* calibrationData = conversionInput->inputcoordinates->inputliquids[i]->calibrationdata; - // SetCalibData(calibrationData, i, &CalibCurves[i]); - SetCalibData(calibrationData, i, &m_CalibCurves[i]); - SetMaxNLperCM(conversionInput->inputcoordinates->inputliquids[i]->maxnanoliterpercentimeter, i); - // CalibCurves[i].SetCalibName((int)(conversionInput->inputcoordinates->inputliquids[i]->calibrationdata->liquidtype)); - m_CalibCurves[i].SetCalibName((int)(conversionInput->inputcoordinates->inputliquids[i]->calibrationdata->liquidtype)); - // } + LQ = conversionInput->inputcoordinates->inputliquids[i]->calibrationdata->liquidtype; + if (LQ == LIQUID_TYPE__Cyan || LQ == LIQUID_TYPE__Magenta || LQ == LIQUID_TYPE__Yellow || LQ == LIQUID_TYPE__Black) + { + //Get calibration data. + CalibrationData* calibrationData = conversionInput->inputcoordinates->inputliquids[i]->calibrationdata; + SetCalibData(calibrationData, i, &m_CalibCurves[i]); + SetMaxNLperCM(conversionInput->inputcoordinates->inputliquids[i]->maxnanoliterpercentimeter, i); + m_CalibCurves[i].SetCalibName((int)(conversionInput->inputcoordinates->inputliquids[i]->calibrationdata->liquidtype)); + } + else + std::exception("unsupported volume"); } - else - std::exception("unsupported volume"); } - // if (m_CalibCurves == NULL) - // m_CalibCurves = CalibCurves; VectorXd NLInkP((int)(m_nVolumes)); VectorXd InkOut((int)(m_nVolumes)); //Convert to Nonlinear Inks for (int i = 0; i < m_nVolumes; ++i) - Volume(i) = conversionInput->inputcoordinates->inputliquids[i]->volume; + Volume(i) = conversionInput->inputcoordinates->inputliquids[i]->volume; //volume is given in % VolumeToNLInkP(Volume, NLInkP); - //Convert to Linear Inks ConvertToLinearInks(NLInkP, InkOut); @@ -967,27 +1135,33 @@ void Tango::ColorLib::ColorConverter::ConvertVolumeToRGBDisplay(ConversionInput* //Convert to Lab double *InkOutP = new double[m_nA2BnSepIn]; double *LabOutP = new double[m_nA2BnSepOut]; + //double *InkOutP = DBG_NEW double[m_nA2BnSepIn]; + //double *LabOutP = DBG_NEW double[m_nA2BnSepOut]; for (int i = 0; i < m_nA2BnSepIn; ++i) InkOutP[i] = InkOut(i); m_A2BTransform->evalInkP2Lab(InkOutP, LabOutP, GamutRegion); //LabOut is in Relative Colorimetric ColorConvert CConvertD65(D65, D65); - double *LabOutFinal; //= new double[3]; - LabOutFinal = LabOutP; - LabOutFinal = CConvertD65.ChangeWP(LabOutFinal, m_whitepointXYZ_CT, m_WP); + double *LabOutFinal1 = new double[3]; + //double *LabOutFinal1 = DBG_NEW double[3]; + double *LabOutFinal = LabOutP; + CConvertD65.ChangeWP(LabOutFinal, LabOutFinal1, m_whitepointXYZ_CT, m_WP); + LabOutFinal = LabOutFinal1; if (m_AdaptWP) { - LabOutFinal = CConvertD65.ChangeWP(LabOutFinal, m_whitepointXYZ_Strip, m_whitepointXYZ_CT); + CConvertD65.ChangeWP(LabOutFinal, LabOutFinal, m_whitepointXYZ_Strip, m_whitepointXYZ_CT); } CConvertD65.SetReferenceWhite(D65); - double *RGBOutP; // = new double[3]; - RGBOutP = CConvertD65.LabtoRGB(LabOutFinal); - + double *RGBOutP = new double[3]; + //double *RGBOutP = DBG_NEW double[3]; + //CConvertD65.LabtoRGB(LabOutFinal, RGBOutP); + CConvertD65.LabtoRGB(LabOutP, RGBOutP); for (int i = 0; i < 3; ++i) { RGBOut(i) = RGBOutP[i]; - LabOut(i) = LabOutFinal[i]; + //LabOut(i) = LabOutFinal[i]; + LabOut(i) = LabOutP[i]; } if (InkOutP != NULL) { @@ -1001,20 +1175,23 @@ void Tango::ColorLib::ColorConverter::ConvertVolumeToRGBDisplay(ConversionInput* } if (RGBOutP != NULL) { - delete RGBOutP; + delete [] RGBOutP; RGBOutP = NULL; } + if (LabOutFinal1 != NULL) + { + delete [] LabOutFinal1; + LabOutFinal1 = NULL; + } return; } -double *Tango::ColorLib::ColorConverter::VectorToDouble(VectorXd Vec) +void Tango::ColorLib::ColorConverter::VectorToDouble(VectorXd VecIn, double * doubOut) { - int nSize = Vec.size(); - double *doub = new double[nSize]; + int nSize = VecIn.size(); for (int i = 0; i < nSize; ++i) - doub[i] = Vec(i); - return(doub); + doubOut[i] = VecIn(i); } VectorXd Tango::ColorLib::ColorConverter::DoubleToVector(double *doub, int nSize) @@ -1041,7 +1218,11 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i //Filter and arrange colors (Should change from 3 to 4 if black ink is included) - int expected_liquids = 3; + + int numofInks = CountNumberofInks(conversionInput); + if(numofInks <0) + throw std::exception("Duplicate inks"); + int expected_liquids = numofInks; original_input_liquids_count = conversionInput->inputcoordinates->n_inputliquids; original_input_liquids = conversionInput->inputcoordinates->inputliquids; @@ -1062,6 +1243,9 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i case LIQUID_TYPE__Yellow: filteredInputLiquids[2] = liquid; break; + case LIQUID_TYPE__Black: + filteredInputLiquids[3] = liquid; + break; } } @@ -1081,26 +1265,35 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i bool InGamut = false; m_WP.Set(0.9505, 1.00, 1.0888); //D65 //count number if inks - int numofInks = CountNumberofInks(conversionInput); + // int numofInks = CountNumberofInks(conversionInput); readColorTransformations(conversionInput); - //Initialize CIECAM02 transformation - Illum IL = D65; - SURROUND sur = average; - CAM02CS CS = UCS; - m_Conv02 = new ColorConvert(IL, IL, Y_b, L_A, sur, CS); + //read calibration tables and store them in m_CalibCurves + + readCalibrationTables(conversionInput); + m_LinInterp = new Interp[numofInks]; + //m_LinInterp = DBG_NEW Interp[numofInks]; + m_InvLinInterp = new Interp[numofInks]; + //m_InvLinInterp = DBG_NEW Interp[numofInks]; + InitInterpolations(numofInks, m_LinInterp, m_InvLinInterp); - SetnA2BnSepIn(m_A2BTransform->GetSeparationsIn()); - SetnA2BnSepOut(m_A2BTransform->GetSeparationsOut()); - SetnB2AnSepIn(m_B2ATransform->GetSeparationsIn()); - SetnB2AnSepOut(m_B2ATransform->GetSeparationsOut()); - SetNumberOfInks(m_nB2AnSepOut); - // Compare Strip White point to Color Table White Point - CompareWhitePoints(); + //Initialize CIECAM02 transformation + Illum IL = D65; + SURROUND sur = average; + CAM02CS CS = UCS; + m_Conv02 = new ColorConvert(IL, IL, Y_b, L_A, sur, CS); + //m_Conv02 = DBG_NEW ColorConvert(IL, IL, Y_b, L_A, sur, CS); + SetnA2BnSepIn(m_A2BTransform->GetSeparationsIn()); + SetnA2BnSepOut(m_A2BTransform->GetSeparationsOut()); + SetnB2AnSepIn(m_B2ATransform->GetSeparationsIn()); + SetnB2AnSepOut(m_B2ATransform->GetSeparationsOut()); + + SetNumberOfInks(m_nB2AnSepOut); + // Compare Strip White point to Color Table White Point + CompareWhitePoints(); - readCalibrationTables(conversionInput); - if (numofInks != m_nB2AnSepOut) - throw std::exception("Number of available inks does not match ink tables"); + if (numofInks != m_nB2AnSepOut) + throw std::exception("Number of available inks does not match ink tables"); VectorXd InkOut(m_nB2AnSepOut); VectorXd RGBOut(3); @@ -1141,80 +1334,81 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i //input was processed. //process neighboring values - //nHive includes 2 outer neighbors og the central Lab value, chroma + delta, chroma + 2delta + //nhive includes 2 outer neighbors of the central Lab value, chroma + delta, chroma + 2delta // and variation in L positioned on the side of the beehive. //The set is arrange in a 5x6 matrix, where the 5x5 contains the variation in (Hue, chroma) // and the last 5 contain the variation in L int nHive = 18; //22; // 18; int MatHive = 25;// 30; //25; - MatrixXd RGBHive(MatHive, 3); - VectorXd RGBHive1(3); - VectorXd VolumeHive1(3); - MatrixXd VolumeHive(MatHive, m_nVolumes); - int *GamutRegionV = new int[MatHive]; - for (int i = 0; i < MatHive + 1; ++i) - GamutRegionV[i] = -1; + MatrixXd RGBHive(MatHive, 3); + VectorXd RGBHive1(3); + VectorXd VolumeHive1(m_nVolumes); + MatrixXd VolumeHive(MatHive, m_nVolumes); + int *GamutRegionV = new int[MatHive]; + //int *GamutRegionV = DBG_NEW int[MatHive]; + for (int i = 0; i < MatHive ; ++i) + GamutRegionV[i] = -1; - int indDataMax[2]; - int j = 0; - // Matrix values are initially set to -1; - RGBHive.setConstant(NegValue); - VolumeHive.setConstant(NegValue); + int indDataMax[2]; + int j = 0; + // Matrix values are initially set to -1; + RGBHive.setConstant(NegValue); + VolumeHive.setConstant(NegValue); - ProcessHiveNeighbors(LabOut, RGBOut, Volume, GamutRegion, RGBHive, VolumeHive, nHive, GamutRegionV, indDataMax); - OutputCoordinates** hiveData = (OutputCoordinates**)malloc(sizeof(OutputCoordinates*) * MatHive); - conversionOutput->hivecoordinates = hiveData; - conversionOutput->n_hivecoordinates = MatHive; - conversionOutput->n_triplecoordinates = 3; - for (int i = 0; i < MatHive; i++) + ProcessHiveNeighbors(LabOut, RGBOut, Volume, GamutRegion, RGBHive, VolumeHive, nHive, GamutRegionV, indDataMax); + OutputCoordinates** hiveData = (OutputCoordinates**)malloc(sizeof(OutputCoordinates*) * MatHive); + conversionOutput->hivecoordinates = hiveData; + conversionOutput->n_hivecoordinates = MatHive; + conversionOutput->n_triplecoordinates = 3; + for (int i = 0; i < MatHive; i++) + { + // OutputCoordinates SingleCell = OUTPUT_COORDINATES__INIT; + hiveData[i] = (OutputCoordinates*)malloc(sizeof(OutputCoordinates)); + output_coordinates__init(hiveData[i]); + if (RGBHive(i, 0) != NegValue) { - // OutputCoordinates SingleCell = OUTPUT_COORDINATES__INIT; - hiveData[i] = (OutputCoordinates*)malloc(sizeof(OutputCoordinates)); - output_coordinates__init(hiveData[i]); - if (RGBHive(i, 0) != NegValue) - { - for (j = 0; j < 3; ++j) - RGBHive1(j) = RGBHive(i, j); - fillRGB(hiveData[i], RGBHive1); - for (j = 0; j < 3; ++j) - VolumeHive1(j) = VolumeHive(i, j); - fillVolume(hiveData[i], VolumeHive1); - hiveData[i]->has_processparameterstableindex = true; - hiveData[i]->processparameterstableindex = GamutRegionV[i]; - hiveData[i]->n_outputliquids = m_nInks; - } - conversionOutput->hivecoordinates[i] = hiveData[i]; + for (j = 0; j < 3; ++j) + RGBHive1(j) = RGBHive(i, j); + fillRGB(hiveData[i], RGBHive1); + for (j = 0; j < m_nVolumes; ++j) + VolumeHive1(j) = VolumeHive(i, j); + fillVolume(hiveData[i], VolumeHive1); + hiveData[i]->has_processparameterstableindex = true; + hiveData[i]->processparameterstableindex = GamutRegionV[i]; + hiveData[i]->n_outputliquids = m_nInks; } + conversionOutput->hivecoordinates[i] = hiveData[i]; + } - //Triplet - OutputCoordinates** TripletData = (OutputCoordinates**)malloc(sizeof(OutputCoordinates*) * 3); - conversionOutput->triplecoordinates = TripletData; - int tripletIndex[3] = { indDataMax[0] , (int)(12), indDataMax[1] }; - for (int i = 0; i < 3; ++i) - { - // OutputCoordinates SingleCell = OUTPUT_COORDINATES__INIT; - TripletData[i] = (OutputCoordinates*)malloc(sizeof(OutputCoordinates)); - output_coordinates__init(TripletData[i]); - for (j = 0; j < 3; ++j) - RGBHive1(j) = RGBHive(tripletIndex[i], j); - fillRGB(TripletData[i], RGBHive1); - for (j = 0; j < 3; ++j) - VolumeHive1(j) = VolumeHive(tripletIndex[i], j); - fillVolume(TripletData[i], VolumeHive1); - TripletData[i]->has_processparameterstableindex = true; - TripletData[i]->processparameterstableindex = GamutRegionV[tripletIndex[i]]; - TripletData[i]->n_outputliquids = m_nInks; - conversionOutput->triplecoordinates[i] = TripletData[i]; - } + //Triplet + OutputCoordinates** TripletData = (OutputCoordinates**)malloc(sizeof(OutputCoordinates*) * 3); + conversionOutput->triplecoordinates = TripletData; + int tripletIndex[3] = { indDataMax[0] , (int)(12), indDataMax[1] }; + for (int i = 0; i < 3; ++i) + { + // OutputCoordinates SingleCell = OUTPUT_COORDINATES__INIT; + TripletData[i] = (OutputCoordinates*)malloc(sizeof(OutputCoordinates)); + output_coordinates__init(TripletData[i]); + for (j = 0; j < 3; ++j) + RGBHive1(j) = RGBHive(tripletIndex[i], j); + fillRGB(TripletData[i], RGBHive1); + for (j = 0; j < m_nVolumes; ++j) + VolumeHive1(j) = VolumeHive(tripletIndex[i], j); + fillVolume(TripletData[i], VolumeHive1); + TripletData[i]->has_processparameterstableindex = true; + TripletData[i]->processparameterstableindex = GamutRegionV[tripletIndex[i]]; + TripletData[i]->n_outputliquids = m_nInks; + conversionOutput->triplecoordinates[i] = TripletData[i]; + } - /* //Clean up - if (GamutRegionV != NULL) - { - delete GamutRegionV; - GamutRegionV = NULL; - } */ + //Clean up + if (GamutRegionV != NULL) + { + delete [] GamutRegionV; + GamutRegionV = NULL; + } //Pack output... @@ -1243,7 +1437,7 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i conversionOutput->has_haserror = true; conversionOutput->haserror = true; - const char* what = e.what(); + const char* what = e.what(); conversionOutput->errormessage = (char*)malloc(strlen(what)); strcpy(conversionOutput->errormessage, e.what()); @@ -1264,25 +1458,85 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i } } + + +void Tango::ColorLib::ColorConverter::InitInterpolations(int numofInks, Interp *linearInterp, Interp *InvLinearInterp) +{ + double *xCoords; + double *yCoords; + + for (int i = 0; i < numofInks; ++i) + { + xCoords = m_CalibCurves[i].getxCoords(); + yCoords = m_CalibCurves[i].getyCoords(); + int npts = m_CalibCurves[i].getSize(); + linearInterp[i].SetXCoords(xCoords); + linearInterp[i].SetYCoords(yCoords); + linearInterp[i].SetNPoints(npts); + InvLinearInterp[i].SetXCoords(yCoords); + InvLinearInterp[i].SetYCoords(xCoords); + InvLinearInterp[i].SetNPoints(npts); + } +} + int Tango::ColorLib::ColorConverter::CountNumberofInks(ConversionInput* conversionInput) { int nLiquids = conversionInput->inputcoordinates->n_inputliquids; int numberofInks = 0; + //Cyan + int nCyan = 0;; + for (int i = 0; i < nLiquids; ++i) + { + if (conversionInput->inputcoordinates->inputliquids[i]->liquidtype == LIQUID_TYPE__Cyan) + nCyan++; + } + if (nCyan > 1) + { + numberofInks = -1; + return(numberofInks); + } + int nMagenta = 0; for (int i = 0; i < nLiquids; ++i) { - if (conversionInput->inputcoordinates->inputliquids[i]->liquidtype == LIQUID_TYPE__Cyan || - conversionInput->inputcoordinates->inputliquids[i]->liquidtype == LIQUID_TYPE__Magenta || - conversionInput->inputcoordinates->inputliquids[i]->liquidtype == LIQUID_TYPE__Yellow || - conversionInput->inputcoordinates->inputliquids[i]->liquidtype == LIQUID_TYPE__Black) - numberofInks++; + if (conversionInput->inputcoordinates->inputliquids[i]->liquidtype == LIQUID_TYPE__Magenta) + nMagenta++; + } + if (nMagenta > 1) + { + numberofInks = -1; + return(numberofInks); + } + int nYellow = 0; + for (int i = 0; i < nLiquids; ++i) + { + if (conversionInput->inputcoordinates->inputliquids[i]->liquidtype == LIQUID_TYPE__Yellow) + nYellow++; + } + if (nYellow > 1) + { + numberofInks = -1; + return(numberofInks); } + int nBlack = 0; + for (int i = 0; i < nLiquids; ++i) + { + if (conversionInput->inputcoordinates->inputliquids[i]->liquidtype == LIQUID_TYPE__Black) + nBlack++; + } + if (nBlack > 1) + { + numberofInks = -1; + return(numberofInks); + } + numberofInks = nCyan + nMagenta + nYellow + nBlack; return(numberofInks); } bool Tango::ColorLib::ColorConverter::IsInGamut(double *InLab, SURROUND sur) { - int nInLab = sizeof(InLab); + int nInLab =3; double *xCoord = new double[nInLab]; + //double *xCoord = DBG_NEW double[nInLab]; //Convert InLab to CIECam02 coordinates bool InGamut = true; double ctr[3]; @@ -1293,8 +1547,9 @@ bool Tango::ColorLib::ColorConverter::IsInGamut(double *InLab, SURROUND sur) ctr[0] = -JLab(0) + center.Get_x(); ctr[1] = -JLab(1) + center.Get_y(); ctr[2] = -JLab(2) + center.Get_z(); - double *dJLab; - dJLab = VectorToDouble(JLab); + double *dJLab = new double[3]; + //double *dJLab = DBG_NEW double[3]; + VectorToDouble(JLab, dJLab); bool intersect = false; m_GBD->TriangleRayIntersection(dJLab, ctr, intersect, xCoord); if (intersect) @@ -1302,7 +1557,7 @@ bool Tango::ColorLib::ColorConverter::IsInGamut(double *InLab, SURROUND sur) VectorXd V1(3); VectorXd V2(3); V1 << JLab[0], JLab[1], JLab[2]; - V2 << xCoord[0], xCoord[1], xCoord[2]; + V2<< xCoord[0], xCoord[1], xCoord[2]; double dECMC; m_Conv02->SymmetricaldECMC(V1, V2, dECMC); if (dECMC < dETol) @@ -1317,43 +1572,62 @@ bool Tango::ColorLib::ColorConverter::IsInGamut(double *InLab, SURROUND sur) delete[] xCoord; xCoord = NULL; } + if (dJLab != NULL) + { + delete[]dJLab; + dJLab = NULL; + } return(InGamut); } Tango::CT_Header Tango::ColorLib::ColorConverter::read_header(ConversionInput* conversionInput, int &bytesread) { - CT_Header *Header = new CT_Header; + //CT_Header *Header = new CT_Header; + //CT_Header *Header = DBG_NEW CT_Header; + CT_Header Header; + // unsigned int tmp = (buffer[2 * i + 1] << 8) | buffer[2 * i]; uint8_t *ColorTable = conversionInput->forwarddata.data; //File Size NumConversions Conv; - Header->TblSIze = Conv.ByteToInt(ColorTable, bytesread); + Header.TblSIze = Conv.ByteToInt(ColorTable, bytesread); bytesread = 4; uint8_t versionBCT[2]; versionBCT[0] = (unsigned int)ColorTable[bytesread]; bytesread += 1; versionBCT[1] = (unsigned int)ColorTable[bytesread]; - Header->Version[0] = versionBCT[0]; - Header->Version[1] = versionBCT[1] << 4; - Header->Version[2] = versionBCT[1] & 15; + Header.Version[0] = versionBCT[0]; + Header.Version[1] = versionBCT[1] << 4; + Header.Version[2] = versionBCT[1] & 15; bytesread += 1; uint32_t tmp = Conv.ByteToInt(ColorTable, bytesread); - int n = 0; - char *tmpC; - tmpC = Conv.getchar(tmp, n); - Header->ColorSpace = new char[n]; - Header->ColorSpace = tmpC; + int n = sizeof((char*)&tmp); + //char *tmpC = DBG_NEW char[n]; + char *tmpC = new char[n]; + Conv.getchar(tmp, n, tmpC); + //Header.ColorSpace = DBG_NEW char[n]; + Header.ColorSpace = new char[n]; + memcpy_s(Header.ColorSpace, n + 1, tmpC, n); + // strncpy_s(Header->ColorSpace, n+1, tmpC, n); + //Header->ColorSpace = tmpC; bytesread += 4; tmp = Conv.ByteToInt(ColorTable, bytesread); - tmpC = Conv.getchar(tmp, n); - Header->ConnectionSpace = tmpC; + Conv.getchar(tmp, n, tmpC); + //Header.ConnectionSpace = DBG_NEW char[n]; + Header.ConnectionSpace = new char[n]; + memcpy_s(Header.ConnectionSpace, n + 1, tmpC, n); bytesread += 4; bytesread += 12; tmp = Conv.ByteToInt(ColorTable, bytesread); - tmpC = Conv.getchar(tmp, n); - Header->DeviceManufacturer = tmpC; + Conv.getchar(tmp, n, tmpC); + //Header.DeviceManufacturer = DBG_NEW char[n]; + Header.DeviceManufacturer = new char[n]; + memcpy_s(Header.DeviceManufacturer, n + 1, tmpC, n); +// strncpy_s(Header->DeviceManufacturer, n + 1, tmpC, n); + //Header->DeviceManufacturer = tmpC; + delete[]tmpC; bytesread += 4; //read illuminant double xyz[3]; @@ -1363,11 +1637,11 @@ Tango::CT_Header Tango::ColorLib::ColorConverter::read_header(ConversionInput* c xyz[j] = (double)(tmp) / 65536; bytesread += 4; } - Header->Illuminant.Set(xyz[0], xyz[1], xyz[2]); + Header.Illuminant.Set(xyz[0], xyz[1], xyz[2]); if (bytesread < 128) { bytesread = 128; - return(*Header); + return(Header); } else { @@ -1415,11 +1689,14 @@ void Tango::ColorLib::ColorConverter::read_xyz_type(int offset, int data_size, C NumConversions Conv; int bytesread = 0; int tmpxyz = Conv.ByteToInt(buff, bytesread); - char* tmpC; - int n = 0; - tmpC = Conv.getchar(tmpxyz, n); + + int n = sizeof(tmpxyz); + //char* tmpC = DBG_NEW char[n]; + char* tmpC = new char[n]; + Conv.getchar(tmpxyz, n, tmpC); char *xyztype = new char[n + 1]; + //char *xyztype = DBG_NEW char[n + 1]; strncpy_s(xyztype, n + 1, tmpC, n); if (strncmp(xyztype, "XYZ ", n) != 0) { @@ -1427,6 +1704,7 @@ void Tango::ColorLib::ColorConverter::read_xyz_type(int offset, int data_size, C return; } delete[] xyztype; + delete[] tmpC; bytesread = 8; int num_values = (data_size - 8) / 4; if (floor((double)(num_values) / 3) * 3 != num_values) @@ -1466,10 +1744,12 @@ void Tango::ColorLib::ColorConverter::read_text_type(int offset, int data_size, int bytesread = 0; NumConversions Conv; int tmp = Conv.ByteToInt(buff, bytesread); - int n = 0; - char *tmpC; - tmpC = Conv.getchar(tmp, n); + int n = sizeof((char*)&tmp); + //char *tmpC = DBG_NEW char[n]; + char *tmpC = new char[n]; + Conv.getchar(tmp, n, tmpC); char *tagtype = new char[n + 1]; + //char *tagtype = DBG_NEW char[n + 1]; strncpy_s(tagtype, n + 1, tmpC, n); if (strcmp(tagtype, "text") != 0) { @@ -1479,6 +1759,7 @@ void Tango::ColorLib::ColorConverter::read_text_type(int offset, int data_size, return; } delete[] tagtype; + delete[]tmpC; bytesread += 8; uint8_t tmp1; for (int i = bytesread; i < data_size; ++i) @@ -1503,10 +1784,12 @@ void Tango::ColorLib::ColorConverter::read_text_description_type(int offset, int int bytesread = 0; NumConversions Conv; int tmp = Conv.ByteToInt(buff, bytesread); - int n = 0; - char *tmpC; - tmpC = Conv.getchar(tmp, n); + int n = sizeof((char*)&tmp); + //char *tmpC= DBG_NEW char[n]; + char *tmpC = new char[n]; + Conv.getchar(tmp, n, tmpC); char *tagtype = new char[n + 1]; + //char *tagtype = DBG_NEW char[n + 1]; strncpy_s(tagtype, n + 1, tmpC, n); std::stringstream strstr; if (strcmp(tagtype, "desc") != 0) @@ -1517,6 +1800,7 @@ void Tango::ColorLib::ColorConverter::read_text_description_type(int offset, int return; } delete[] tagtype; + delete[] tmpC; bytesread += 8; int count = Conv.ByteToInt(buff, bytesread); bytesread += 4; @@ -1698,3 +1982,226 @@ void Tango::ColorLib::ColorConverter::CompareWhitePoints() // // return conversion_output__pack(&conversionOutput, output_buffer); //} + + + +size_t Tango::ColorLib::ColorConverter::P_IsInGamut(uint8_t * input_buffer, size_t input_buffer_size, uint8_t *& output_buffer) +{ + + //Get Input + ConversionInput* conversionInput = (ConversionInput*)malloc(sizeof(ConversionInput)); + + conversionInput = conversion_input__unpack(NULL, input_buffer_size, input_buffer); + + + + //Filter and arrange colors (Should change from 3 to 4 if black ink is included) + /*int expected_liquids = 3; + + InputLiquid** filteredInputLiquids = (InputLiquid**)malloc(sizeof(InputLiquid*) * expected_liquids); + + for (size_t i = 0; i < conversionInput->inputcoordinates->n_inputliquids; i++) + { + InputLiquid* liquid = conversionInput->inputcoordinates->inputliquids[i]; + + switch (liquid->liquidtype) + { + case LIQUID_TYPE__Cyan: + filteredInputLiquids[0] = liquid; + break; + case LIQUID_TYPE__Magenta: + filteredInputLiquids[1] = liquid; + break; + case LIQUID_TYPE__Yellow: + filteredInputLiquids[2] = liquid; + break; + } + } + + conversionInput->inputcoordinates->inputliquids = filteredInputLiquids; + conversionInput->inputcoordinates->n_inputliquids = expected_liquids; + //Filter and arrange colors + + */ + + //Initialize Output... + ConversionOutput *conversionOutput = (ConversionOutput*)malloc(sizeof(ConversionOutput)); + if (conversionOutput != NULL) + conversion_output__init(conversionOutput); + else + return(0); + + // ConversionOutput conversionOutput = CONVERSION_OUTPUT__INIT; + size_t n_elements = 0; + bool InGamut = false; + m_WP.Set(0.9505, 1.00, 1.0888); //D65 + //count number if inks + int numofInks = CountNumberofInks(conversionInput); + readColorTransformations(conversionInput); + + //read calibration tables and store them in m_CalibCurves + + readCalibrationTables(conversionInput); + + //Initialize CIECAM02 transformation + Illum IL = D65; + SURROUND sur = average; + CAM02CS CS = UCS; + m_Conv02 = new ColorConvert(IL, IL, Y_b, L_A, sur, CS); + //m_Conv02 = DBG_NEW ColorConvert(IL, IL, Y_b, L_A, sur, CS); + SetnA2BnSepIn(m_A2BTransform->GetSeparationsIn()); + SetnA2BnSepOut(m_A2BTransform->GetSeparationsOut()); + SetnB2AnSepIn(m_B2ATransform->GetSeparationsIn()); + SetnB2AnSepOut(m_B2ATransform->GetSeparationsOut()); + SetNumberOfInks(m_nB2AnSepOut); + + // Compare Strip White point to Color Table White Point + CompareWhitePoints(); + + if (numofInks != m_nB2AnSepOut) + throw std::exception("Number of available inks does not match ink tables"); + + VectorXd InkOut(m_nB2AnSepOut); + VectorXd RGBOut(3); + VectorXd LabOut(3); + VectorXd NLInkOut(m_nB2AnSepOut); + VectorXd Volume(m_nB2AnSepOut); + + C_RGB_XYZ_Lab DataLab; + //SURROUND sur = m_Conv02->getSurround(); + switch (conversionInput->colorspace) + { + case (COLOR_SPACE__RGB): + { + // Basic assumption: if data is given in RGB space, conversion should be in relative colorimetric, + //We expect that [255,255,255](white) will be mapped to the thread white, meaning all inks should be zero + // and the coverted RGB will refect the color of the thread + //The workflow is a follows: + //1. Convert RGB to Lab (Whitepoint is D65, same as tables) + //2.Fiond if Lab is InGamut + + RGBOut(0) = conversionInput->inputcoordinates->red; + RGBOut(1) = conversionInput->inputcoordinates->green; + RGBOut(2) = conversionInput->inputcoordinates->blue; + //convert to Lab + ColorConvert CConvertD65(D65, D65); //Destination, source + //double *LabIn = DBG_NEW double[3]; + //double *RGBOutP = DBG_NEW double[3]; + double *LabIn = new double[3]; + double *RGBOutP = new double[3]; + VectorToDouble(RGBOut, RGBOutP); + //RGB to Lab + CConvertD65.RGBtoLab(RGBOutP, LabIn); //Values are in Relative Colorimetric, D65 + + //Is In Gamut? + InGamut = IsInGamut(LabIn, sur); + + if (LabIn != NULL) + { + delete [] LabIn; + LabIn = NULL; + } + if (RGBOutP != NULL) + { + delete [] RGBOutP; + RGBOutP = NULL; + } + break; + } + case (COLOR_SPACE__LAB): + { + // Basic assumption: Lab data has the same whitepoint as the STRIP thread. + //The workflow is a follows: + //1. Convert Lab to Relative colorimetric. check if there is a match between STRIP and Color Tables + //2. Find if Lab is InGamut + + double *LabIn = new double[3]; + //double *LabIn = DBG_NEW double[3]; + LabIn[0] = conversionInput->inputcoordinates->l; + LabIn[1] = conversionInput->inputcoordinates->a; + LabIn[2] = conversionInput->inputcoordinates->b; + //the assumption is that the color space has illumination that matches the whitepoint of the Strip + ColorConvert CConvertD65(D65, D65); //Destination, source + double *LabInFinal1 = new double[3]; + //double *LabInFinal1 = DBG_NEW double[3]; + memcpy(LabInFinal1, LabIn, 3*sizeof(double)); + // Lab is assumed to match the color of the STRIP, however the tables could have a different WP + //Check if Color Tables and Strip whitepoints are the same, otherwise convert + if (m_AdaptWP) + { + CConvertD65.ChangeWP(LabInFinal1, LabInFinal1, m_whitepointXYZ_CT, m_whitepointXYZ_Strip); //to Color Tables + LabIn = LabInFinal1; + } + double *LabInFinal2 = new double[3]; + //double *LabInFinal2 = DBG_NEW double[3]; + CConvertD65.ChangeWP(LabIn, LabInFinal2, m_WP, m_whitepointXYZ_CT); //to Relative + InGamut = IsInGamut(LabInFinal2, sur); + + if (LabIn != NULL) + { + delete[] LabIn; + LabIn = NULL; + } + if (LabInFinal1 != NULL) + { + delete[]LabInFinal1; + LabInFinal1 = NULL; + } + if (LabInFinal2 != NULL) + { + delete[]LabInFinal2; + LabInFinal2 = NULL; + } + break; + } + case(COLOR_SPACE__CMYK): + {//no conversion + //missing from structure light inks or special colors + // just convert Lab for rgb display + InGamut = true; + } + case(COLOR_SPACE__PANTON): + { + int32_t inData; + if (conversionInput->inputcoordinates->has_pantoncode) + inData = conversionInput->inputcoordinates->pantoncode; + else + { + //mismatch between color space and data + throw std::exception("Mismatch between color space and data"); + return(0); + } + break; + //missing calclulation method and pantone table, either in terms of RGB or CMY or Lab + } + default: + { + throw std::exception(" Unsupported Color Space"); + return(0); + } + } + + //Pack data + OutputCoordinates *outputCoords = (OutputCoordinates*)malloc(sizeof(OutputCoordinates)); + output_coordinates__init(outputCoords); + conversionOutput->has_outofgamut = true; + conversionOutput->outofgamut = !(InGamut); + conversionOutput->singlecoordinates = outputCoords; + + //Pack output... + output_buffer = (uint8_t*)malloc(conversion_output__get_packed_size(conversionOutput)); + int size = conversion_output__pack(conversionOutput, output_buffer); + +#pragma region Free Conversion Input & Output + + //conversionInput->inputcoordinates->inputliquids = original_input_liquids; + //conversionInput->inputcoordinates->n_inputliquids = original_input_liquids_count; + + conversion_input__free_unpacked(conversionInput, NULL); + + conversion_output__free_unpacked(conversionOutput, NULL); + +#pragma endregion + + return (size); +}
\ No newline at end of file diff --git a/Software/Visual_Studio/Native/Tango.ColorLib/ColorConverter.h b/Software/Visual_Studio/Native/Tango.ColorLib/ColorConverter.h index 1d61877fd..74d804913 100644 --- a/Software/Visual_Studio/Native/Tango.ColorLib/ColorConverter.h +++ b/Software/Visual_Studio/Native/Tango.ColorLib/ColorConverter.h @@ -11,6 +11,7 @@ #include "ConversionOutput.pb-c.h" #include "CalibrationData.pb-c.h" #include "ConversionInput.pb-c.h" +#include "Interp.h" #pragma once namespace Tango @@ -61,11 +62,14 @@ namespace Tango void VolumeToNLInkP(VectorXd Volume, VectorXd &NLInkP); void NLInkPToVolume(VectorXd NLInkP, VectorXd &Volume); void SetMaxNLperCM(double maxNlPerCM, int i); + size_t P_IsInGamut(uint8_t * input_buffer, size_t input_buffer_size, uint8_t *& output_buffer); private: ColorTransf *m_B2ATransform; ColorTransf *m_A2BTransform; GBD *m_GBD; ColorConvert *m_Conv02; + Interp *m_LinInterp; + Interp *m_InvLinInterp; C_RGB_XYZ_Lab m_whitepointLab; C_RGB_XYZ_Lab m_whitepointXYZ_Strip; C_RGB_XYZ_Lab m_whitepointXYZ_CT; @@ -75,7 +79,6 @@ namespace Tango int m_nA2BnSepOut; bool m_AdaptWP; CalibData *m_CalibCurves; - size_t *m_CalibDatasize; int m_nInks; int m_nVolumes; C_RGB_XYZ_Lab m_WP; @@ -90,6 +93,7 @@ namespace Tango void SetNumberofInks(int nInks) { m_nInks = nInks; }; void SetNumberOfVolumes(int nVol) { m_nVolumes = nVol; }; void SetNumberOfInks(int nInks) { m_nInks = nInks; }; + void InitInterpolations(int numofInks, Interp *linearInterp, Interp *InvLinearInterp); void fillRGB(OutputCoordinates *outputCoords, VectorXd RGBOut); void fillVolume(OutputCoordinates *&outputCoords, VectorXd Volume); void ProcessHiveNeighbors(VectorXd LabC, VectorXd RGBC, VectorXd VolumeC, int InGamutRegion, @@ -98,7 +102,7 @@ namespace Tango int nHive, MatrixXd &RGBHive, MatrixXd &OVolumeHive, int *&OGamutRegion); void FindTriplet(VectorXd Lab, MatrixXd Lab1, int nHive, int*indDataMax); int CountNumberofInks(ConversionInput* conversionInput); - double *VectorToDouble(VectorXd Vec); + void VectorToDouble(VectorXd Vec, double *doub); VectorXd DoubleToVector(double *doub, int nSize); void CompareWhitePoints(); bool IsInGamut(double *InLab, SURROUND sur); diff --git a/Software/Visual_Studio/Native/Tango.ColorLib/Utils/C_RGB_XYZ_Lab.cpp b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/C_RGB_XYZ_Lab.cpp index 25f035e0c..10d7aa243 100644 --- a/Software/Visual_Studio/Native/Tango.ColorLib/Utils/C_RGB_XYZ_Lab.cpp +++ b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/C_RGB_XYZ_Lab.cpp @@ -2,6 +2,20 @@ //#include <cmath> //#include <algorithm> // std::min, max +/*#define _CRTDBG_MAP_ALLOC +#include <stdlib.h> +#include <crtdbg.h> +#include <cstdlib> + +#ifdef _DEBUG +#define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ ) +// Replace _NORMAL_BLOCK with _CLIENT_BLOCK if you want the +// allocations to be of _CLIENT_BLOCK type +#else +#define DBG_NEW new +#endif*/ + + // Default Constructor ... C_RGB_XYZ_Lab = (0, 0, 0) C_RGB_XYZ_Lab::C_RGB_XYZ_Lab(void) : m_x(0.0), diff --git a/Software/Visual_Studio/Native/Tango.ColorLib/Utils/CalibData.cpp b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/CalibData.cpp index 7893e9b28..67fd024b5 100644 --- a/Software/Visual_Studio/Native/Tango.ColorLib/Utils/CalibData.cpp +++ b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/CalibData.cpp @@ -1,18 +1,45 @@ #include "CalibData.h" +/*#define _CRTDBG_MAP_ALLOC +#include <stdlib.h> +#include <crtdbg.h> +#include <cstdlib> + +#ifdef _DEBUG +#define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ ) +// Replace _NORMAL_BLOCK with _CLIENT_BLOCK if you want the +// allocations to be of _CLIENT_BLOCK type +#else +#define DBG_NEW new +#endif */ + CalibData::CalibData(): m_npoints(0), m_XCoords(NULL), -m_YCoords(NULL), m_InkName(0) +m_YCoords(NULL), m_InkName(0), m_maxNlPerCM(0) { } CalibData::CalibData(const CalibData &rhs) : m_npoints(rhs.m_npoints), m_XCoords(rhs.m_XCoords), -m_YCoords(rhs.m_YCoords), m_InkName(rhs.m_InkName) +m_YCoords(rhs.m_YCoords), m_InkName(rhs.m_InkName), m_maxNlPerCM(rhs.m_maxNlPerCM) { } +CalibData::~CalibData() +{ + if (m_XCoords != NULL) + { + delete[] m_XCoords; + m_XCoords = NULL; + } + if (m_YCoords != NULL) + { + delete[] m_YCoords; + m_YCoords = NULL; + } +} void CalibData::SetXCoords(double * XCoords) { m_XCoords = new double[m_npoints]; + //m_XCoords = DBG_NEW double[m_npoints]; for (int i=0; i<m_npoints; ++i) m_XCoords[i] = XCoords[i]; } @@ -20,6 +47,7 @@ void CalibData::SetXCoords(double * XCoords) void CalibData::SetYCoords(double* YCoords) { m_YCoords = new double[m_npoints]; + //m_YCoords = DBG_NEW double[m_npoints]; for (int i = 0; i<m_npoints; ++i) m_YCoords[i] = YCoords[i]; } diff --git a/Software/Visual_Studio/Native/Tango.ColorLib/Utils/CalibData.h b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/CalibData.h index 322c75a55..50f22bccc 100644 --- a/Software/Visual_Studio/Native/Tango.ColorLib/Utils/CalibData.h +++ b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/CalibData.h @@ -7,6 +7,7 @@ class CalibData public: CalibData(void) ; CalibData (const CalibData &rhs); + ~CalibData(); int getSize() { return(m_npoints); } double *getxCoords() { return(m_XCoords); } double *getyCoords() { return(m_YCoords); } diff --git a/Software/Visual_Studio/Native/Tango.ColorLib/Utils/ColorConvert.cpp b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/ColorConvert.cpp index 6014df298..07b1535e8 100644 --- a/Software/Visual_Studio/Native/Tango.ColorLib/Utils/ColorConvert.cpp +++ b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/ColorConvert.cpp @@ -2,6 +2,19 @@ #include <cmath> #include <algorithm> +/*#define _CRTDBG_MAP_ALLOC +#include <stdlib.h> +#include <crtdbg.h> +#include <cstdlib> + +#ifdef _DEBUG +#define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ ) +// Replace _NORMAL_BLOCK with _CLIENT_BLOCK if you want the +// allocations to be of _CLIENT_BLOCK type +#else +#define DBG_NEW new +#endif */ + //define constants for RGB conversion const static double CHROMATICITIES[nRGB*nXYZ] = { 0.0, 0.6400, 0.3300, 0.0, 0.3000, 0.6000, 0.0, 0.1500, 0.0600 }; static double m_Chromaticities[nRGB*nXYZ] = { 0.0, 0.6400, 0.3300, 0.0, 0.3000, 0.6000, 0.0, 0.1500, 0.0600 }; @@ -32,8 +45,8 @@ ColorConvert::ColorConvert (void) m_SourceWhite.Set(White2DegreeD50[0], White2DegreeD50[1], White2DegreeD50[2]); m_InvReferenceWhite.Set ((1.0/m_ReferenceWhite.Get_x()), (1.0/m_ReferenceWhite.Get_y()), (1.0/m_ReferenceWhite.Get_z())); m_BradfordMatrix << 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0; -// m_JabParams = NULL; -// m_ParamsCIECam02 = NULL; + Initciecam02_parameters(); + InitJab_parameters(); } ColorConvert::ColorConvert(C_RGB_XYZ_Lab DestWhite, Illum D) @@ -53,8 +66,8 @@ ColorConvert::ColorConvert(C_RGB_XYZ_Lab DestWhite, Illum D) m_ReferenceWhite =DestWhite; m_InvReferenceWhite.Set((1.0 / m_ReferenceWhite.Get_x()), (1.0 / m_ReferenceWhite.Get_y()), (1.0 / m_ReferenceWhite.Get_z())); CAT_BradfordMat(); -// m_JabParams = NULL; -// m_ParamsCIECam02 = NULL; + Initciecam02_parameters(); + InitJab_parameters(); } // Constructor for setting reference white ColorConvert::ColorConvert(Illum D, C_RGB_XYZ_Lab SourceWhite) @@ -74,8 +87,8 @@ ColorConvert::ColorConvert(Illum D, C_RGB_XYZ_Lab SourceWhite) m_InvReferenceWhite.Set((1.0 / m_ReferenceWhite.Get_x()), (1.0 / m_ReferenceWhite.Get_y()), (1.0 / m_ReferenceWhite.Get_z())); m_SourceWhite = SourceWhite; CAT_BradfordMat(); -// m_JabParams = NULL; -// m_ParamsCIECam02 = NULL; + Initciecam02_parameters(); + InitJab_parameters(); } ColorConvert::ColorConvert(Illum DDest, Illum DSource) @@ -107,8 +120,8 @@ ColorConvert::ColorConvert(Illum DDest, Illum DSource) } } CAT_BradfordMat(); -// m_JabParams = NULL; -// m_ParamsCIECam02 = NULL; + Initciecam02_parameters(); + InitJab_parameters(); } ColorConvert::ColorConvert(C_RGB_XYZ_Lab DDest, C_RGB_XYZ_Lab DSource) @@ -118,8 +131,8 @@ ColorConvert::ColorConvert(C_RGB_XYZ_Lab DDest, C_RGB_XYZ_Lab DSource) m_InvReferenceWhite.Set((1.0 / m_ReferenceWhite.Get_x()), (1.0 / m_ReferenceWhite.Get_y()), (1.0 / m_ReferenceWhite.Get_z())); m_SourceWhite = DSource; CAT_BradfordMat(); -// m_JabParams = NULL; -// m_ParamsCIECam02 = NULL; + Initciecam02_parameters(); + InitJab_parameters(); } ColorConvert::ColorConvert(Illum DDest, Illum DSource, double Y_b, double L_A, SURROUND sur, CAM02CS CS) @@ -153,8 +166,8 @@ ColorConvert::ColorConvert(Illum DDest, Illum DSource, double Y_b, double L_A, S } } CAT_BradfordMat(); - m_JabParams =new Jab_Params; - m_ParamsCIECam02 = new CIECAM02Params; + //m_JabParams =new Jab_Params; + //m_ParamsCIECam02 = new CIECAM02Params; InitCiecamParams(Y_b, L_A, sur, CS); } @@ -187,9 +200,8 @@ ColorConvert &ColorConvert::operator = (const ColorConvert &rhs) ColorConvert::~ColorConvert() { -/* delete m_JabParams; - delete m_ParamsCIECam02;*/ - + //delete m_JabParams; + //delete m_ParamsCIECam02; } @@ -347,17 +359,16 @@ const C_RGB_XYZ_Lab &ColorConvert::GetReferenceWhite(void) const return(C_RGB_XYZ_Lab(rgb)); } - double *ColorConvert::LabtoRGB(double*Lab) + void ColorConvert::LabtoRGB(double*InLab, double *OutRGB) { C_RGB_XYZ_Lab DataLab; - DataLab.Set(Lab[0], Lab[1], Lab[2]); + DataLab.Set(InLab[0], InLab[1], InLab[2]); C_RGB_XYZ_Lab DataRGB; DataRGB =LabtoRGB(DataLab); - double *RGB = new double[3]; - RGB[0] = DataRGB.Get_x(); - RGB[1] = DataRGB.Get_y(); - RGB[2] = DataRGB.Get_z(); - return(RGB); + // double *RGB = new double[3]; + OutRGB[0] = DataRGB.Get_x(); + OutRGB[1] = DataRGB.Get_y(); + OutRGB[2] = DataRGB.Get_z(); } C_RGB_XYZ_Lab ColorConvert::LabtoRGB(C_RGB_XYZ_Lab& LabVal) @@ -369,17 +380,17 @@ const C_RGB_XYZ_Lab &ColorConvert::GetReferenceWhite(void) const return(DataRGB); } - double *ColorConvert::RGBtoLab(double*RGB) + void ColorConvert::RGBtoLab(double*InRGB, double *OutLab) { - C_RGB_XYZ_Lab DataRGB(RGB[0], RGB[1], RGB[2]); + C_RGB_XYZ_Lab DataRGB(InRGB[0], InRGB[1], InRGB[2]); C_RGB_XYZ_Lab DataLab; DataLab = RGBtoLab(DataRGB); - double *LabOut = new double[3]; - LabOut[0] = DataLab.Get_x(); - LabOut[1] = DataLab.Get_y(); - LabOut[2] = DataLab.Get_z(); - return(LabOut); + //double *LabOut = new double[3]; + OutLab[0] = DataLab.Get_x(); + OutLab[1] = DataLab.Get_y(); + OutLab[2] = DataLab.Get_z(); } + C_RGB_XYZ_Lab ColorConvert::RGBtoLab(C_RGB_XYZ_Lab& RGBVal) { C_RGB_XYZ_Lab DataXYZ; @@ -394,7 +405,7 @@ const C_RGB_XYZ_Lab &ColorConvert::GetReferenceWhite(void) const } - double *ColorConvert::ChangeWP(double *LabIn, C_RGB_XYZ_Lab SourceWhite, C_RGB_XYZ_Lab DestWhite) + void ColorConvert::ChangeWP(double *LabIn, double *LabOut, C_RGB_XYZ_Lab SourceWhite, C_RGB_XYZ_Lab DestWhite) { SetReferenceWhite(SourceWhite); C_RGB_XYZ_Lab Lab; @@ -404,10 +415,10 @@ const C_RGB_XYZ_Lab &ColorConvert::GetReferenceWhite(void) const C_RGB_XYZ_Lab LabOut1; LabOut1 = XYZToLab(XYZ); LabOut1.Clamp(LowLab, HighLab); - double *LabD = new double[3]; - LabD[0] = LabOut1.Get_x(); - LabD[1] = LabOut1.Get_y(); - LabD[2] = LabOut1.Get_z(); + // double *LabD = new double[3]; + LabOut[0] = LabOut1.Get_x(); + LabOut[1] = LabOut1.Get_y(); + LabOut[2] = LabOut1.Get_z(); // SetReferenceWhite(SourceWhite); /* C_RGB_XYZ_Lab LabOut2; LabOut2 = XYZToLab(XYZ); @@ -418,7 +429,6 @@ const C_RGB_XYZ_Lab &ColorConvert::GetReferenceWhite(void) const LabD[1] = f*LabOut1.Get_y() + (1 - f) *LabOut2.Get_y(); LabD[2] = f*LabOut1.Get_z() + (1 - f) *LabOut2.Get_z(); return(LabD); */ - return(LabD); } void ColorConvert::InitializeConversionMatrices() @@ -560,10 +570,9 @@ const C_RGB_XYZ_Lab &ColorConvert::GetReferenceWhite(void) const } void ColorConvert::SetCIECamWhitePoint(C_RGB_XYZ_Lab ReferenceWhite) { - m_ParamsCIECam02->XYZ_WP = new double[3]; - m_ParamsCIECam02->XYZ_WP[0] = 100 * ReferenceWhite.Get_x(); - m_ParamsCIECam02->XYZ_WP[1] = 100 * ReferenceWhite.Get_y(); - m_ParamsCIECam02->XYZ_WP[2] =100 * ReferenceWhite.Get_z(); + m_ParamsCIECam02.XYZ_WP[0] = 100 * ReferenceWhite.Get_x(); + m_ParamsCIECam02.XYZ_WP[1] = 100 * ReferenceWhite.Get_y(); + m_ParamsCIECam02.XYZ_WP[2] =100 * ReferenceWhite.Get_z(); } void ColorConvert::ciecam02_parameters( double Y_b, double L_A, SURROUND sur) @@ -592,29 +601,29 @@ const C_RGB_XYZ_Lab &ColorConvert::GetReferenceWhite(void) const { case (average): { - m_ParamsCIECam02->F = 1.0; - m_ParamsCIECam02->c = 0.690; - m_ParamsCIECam02->N_c = 1.00; + m_ParamsCIECam02.F = 1.0; + m_ParamsCIECam02.c = 0.690; + m_ParamsCIECam02.N_c = 1.00; break; } case 'dim': { - m_ParamsCIECam02->F = 0.9; - m_ParamsCIECam02->c = 0.590; - m_ParamsCIECam02->N_c = 1.95; + m_ParamsCIECam02.F = 0.9; + m_ParamsCIECam02.c = 0.590; + m_ParamsCIECam02.N_c = 1.95; break; } case 'dark': { - m_ParamsCIECam02->F = 0.8; - m_ParamsCIECam02->c = 0.525; - m_ParamsCIECam02->N_c = 1.80; + m_ParamsCIECam02.F = 0.8; + m_ParamsCIECam02.c = 0.525; + m_ParamsCIECam02.N_c = 1.80; break; } default: - m_ParamsCIECam02->F = 1.0; - m_ParamsCIECam02->c = 0.690; - m_ParamsCIECam02->N_c = 1.00; + m_ParamsCIECam02.F = 1.0; + m_ParamsCIECam02.c = 0.690; + m_ParamsCIECam02.N_c = 1.00; break; } //Define Matrices @@ -626,85 +635,85 @@ const C_RGB_XYZ_Lab &ColorConvert::GetReferenceWhite(void) const MatCAT02 << 0.7328, 0.4296, -0.1624, -0.7036, 1.6975, 0.0061, 0.003, 0.0136, 0.9834; - m_ParamsCIECam02->M_CAT02 = MatCAT02; -/*m_ParamsCIECam02->M_CAT02.setOnes(3,3); - m_ParamsCIECam02->M_CAT02 << 0.7328, 0.4296, -0.1624, + m_ParamsCIECam02.M_CAT02 = MatCAT02; +/* m_ParamsCIECam02.M_CAT02.setOnes(3,3); + m_ParamsCIECam02.M_CAT02 << 0.7328, 0.4296, -0.1624, -0.7036, 1.6975, 0.0061, 0.003, 0.0136, 0.9834; */ MatrixXd MatHPE(3, 3); MatHPE << 0.38971, 0.68898, -0.07868, -0.22981, 1.1834, 0.04641, 0, 0, 1; - m_ParamsCIECam02->M_HPE = MatHPE; - /*m_ParamsCIECam02->M_HPE.resize(3, 3); - m_ParamsCIECam02->M_HPE << 0.38971, 0.68898, -0.07868, + m_ParamsCIECam02.M_HPE = MatHPE; + /* m_ParamsCIECam02.M_HPE.resize(3, 3); + m_ParamsCIECam02.M_HPE << 0.38971, 0.68898, -0.07868, -0.22981, 1.1834, 0.04641, 0, 0, 1; */ //Hue Data VectorXd Vh_i(5); Vh_i << 20.14, 90.00, 164.25, 237.53, 380.14; - m_ParamsCIECam02->h_i = Vh_i; - /*m_ParamsCIECam02->h_i << 20.14, 90.00, 164.25, 237.53, 380.14; */ + m_ParamsCIECam02.h_i = Vh_i; + /* m_ParamsCIECam02.h_i << 20.14, 90.00, 164.25, 237.53, 380.14; */ VectorXd Ve_i(5); Ve_i << 0.8, 0.7, 1.0, 1.2, 0.8; - m_ParamsCIECam02->e_i = Ve_i; + m_ParamsCIECam02.e_i = Ve_i; - /*m_ParamsCIECam02->e_i.resize(5); - m_ParamsCIECam02->e_i << 0.8, 0.7, 1.0, 1.2, 0.8; */ + /* m_ParamsCIECam02.e_i.resize(5); + m_ParamsCIECam02.e_i << 0.8, 0.7, 1.0, 1.2, 0.8; */ VectorXd VH_i(5); VH_i << 0, 100, 200, 300, 400; - m_ParamsCIECam02->H_i = VH_i; -// m_ParamsCIECam02->H_i.resize(5); -// m_ParamsCIECam02->H_i << 0, 100, 200, 300, 400; + m_ParamsCIECam02.H_i = VH_i; +// m_ParamsCIECam02.H_i.resize(5); +// m_ParamsCIECam02.H_i << 0, 100, 200, 300, 400; VectorXd VLMS_w(3); VLMS_w.setZero(); - m_ParamsCIECam02->LMS_w = VLMS_w; - //m_ParamsCIECam02->LMS_w.resize(3); + m_ParamsCIECam02.LMS_w = VLMS_w; + // m_ParamsCIECam02.LMS_w.resize(3); VectorXd XYZtmp(3); - XYZtmp << m_ParamsCIECam02->XYZ_WP[0], m_ParamsCIECam02->XYZ_WP[1], m_ParamsCIECam02->XYZ_WP[2]; - m_ParamsCIECam02->LMS_w = m_ParamsCIECam02->M_CAT02 * XYZtmp; - m_ParamsCIECam02->D = m_ParamsCIECam02->F * (1 - (1 / 3.6)*std::exp(-(L_A + 42) / 92)); - m_ParamsCIECam02->D = std::max(0.0, std::min(1.0, m_ParamsCIECam02->D)); - //m_ParamsCIECam02->LMS_c.resize(3); + XYZtmp << m_ParamsCIECam02.XYZ_WP[0], m_ParamsCIECam02.XYZ_WP[1], m_ParamsCIECam02.XYZ_WP[2]; + m_ParamsCIECam02.LMS_w = m_ParamsCIECam02.M_CAT02 * XYZtmp; + m_ParamsCIECam02.D = m_ParamsCIECam02.F * (1 - (1 / 3.6)*std::exp(-(L_A + 42) / 92)); + m_ParamsCIECam02.D = std::max(0.0, std::min(1.0, m_ParamsCIECam02.D)); + // m_ParamsCIECam02.LMS_c.resize(3); VectorXd VLMS_c(3); VLMS_w.setZero(); - m_ParamsCIECam02->LMS_c = VLMS_c; + m_ParamsCIECam02.LMS_c = VLMS_c; for (int i=0; i<3; ++i) - m_ParamsCIECam02->LMS_c(i) = m_ParamsCIECam02->D* m_ParamsCIECam02->XYZ_WP[1] / m_ParamsCIECam02->LMS_w(i) + 1 - m_ParamsCIECam02->D; -// m_ParamsCIECam02->LMSp_w.resize(3); + m_ParamsCIECam02.LMS_c(i) = m_ParamsCIECam02.D* m_ParamsCIECam02.XYZ_WP[1] / m_ParamsCIECam02.LMS_w(i) + 1 - m_ParamsCIECam02.D; +// m_ParamsCIECam02.LMSp_w.resize(3); VectorXd VLMSp_w(3); VLMSp_w.setZero(); - m_ParamsCIECam02->LMSp_w = VLMSp_w; + m_ParamsCIECam02.LMSp_w = VLMSp_w; VectorXd cwMult(3); for (int i = 0; i < 3; ++i) - cwMult(i) = (m_ParamsCIECam02->LMS_c(i)*m_ParamsCIECam02->LMS_w(i)); + cwMult(i) = (m_ParamsCIECam02.LMS_c(i)*m_ParamsCIECam02.LMS_w(i)); - m_ParamsCIECam02->LMSp_w(0) = (0.7409792 * cwMult(0)) + (0.2180250 * cwMult(1)) + (0.0410058 * cwMult(2)); - m_ParamsCIECam02->LMSp_w(1) = (0.2853532 * cwMult(0)) + (0.6242014 * cwMult(2)) + (0.0904454 * cwMult(2)); - m_ParamsCIECam02->LMSp_w(2) = (-0.0096280 * cwMult(0)) - (0.0056980 * cwMult(1)) + (1.0153260 * cwMult(2)); + m_ParamsCIECam02.LMSp_w(0) = (0.7409792 * cwMult(0)) + (0.2180250 * cwMult(1)) + (0.0410058 * cwMult(2)); + m_ParamsCIECam02.LMSp_w(1) = (0.2853532 * cwMult(0)) + (0.6242014 * cwMult(2)) + (0.0904454 * cwMult(2)); + m_ParamsCIECam02.LMSp_w(2) = (-0.0096280 * cwMult(0)) - (0.0056980 * cwMult(1)) + (1.0153260 * cwMult(2)); - m_ParamsCIECam02->k = 1.0/ (5 * L_A + 1); - m_ParamsCIECam02->F_L =0.2* (pow(m_ParamsCIECam02->k ,4) * (5 * L_A)) + - 0.1 *(pow((1.0 - pow(m_ParamsCIECam02->k, 4.0)), 2.0)) *(pow((5.0 * L_A), (1.0 / 3.0))); + m_ParamsCIECam02.k = 1.0/ (5 * L_A + 1); + m_ParamsCIECam02.F_L =0.2* (pow(m_ParamsCIECam02.k ,4) * (5 * L_A)) + + 0.1 *(pow((1.0 - pow(m_ParamsCIECam02.k, 4.0)), 2.0)) *(pow((5.0 * L_A), (1.0 / 3.0))); - m_ParamsCIECam02->n = Y_b / m_ParamsCIECam02->XYZ_WP[1]; - m_ParamsCIECam02->z = 1.48 + sqrt(m_ParamsCIECam02->n); - m_ParamsCIECam02->N_bb = 0.725 * pow(m_ParamsCIECam02->n, -0.2); - m_ParamsCIECam02->N_cb = m_ParamsCIECam02->N_bb; + m_ParamsCIECam02.n = Y_b / m_ParamsCIECam02.XYZ_WP[1]; + m_ParamsCIECam02.z = 1.48 + sqrt( m_ParamsCIECam02.n); + m_ParamsCIECam02.N_bb = 0.725 * pow( m_ParamsCIECam02.n, -0.2); + m_ParamsCIECam02.N_cb = m_ParamsCIECam02.N_bb; VectorXd tmpVec(3); VectorXd VLMSp_aw(3); VLMSp_aw.setZero(); -m_ParamsCIECam02->LMSp_aw = VLMSp_aw; -//m_ParamsCIECam02->LMSp_aw.resize(3); + m_ParamsCIECam02.LMSp_aw = VLMSp_aw; +// m_ParamsCIECam02.LMSp_aw.resize(3); for (int i = 0; i < 3; ++i) { - tmpVec(i) = pow((m_ParamsCIECam02->F_L*m_ParamsCIECam02->LMSp_w(i)) / 100, 0.42); - m_ParamsCIECam02->LMSp_aw(i) = 400 * (tmpVec(i) / (27.13 + tmpVec(i))) + 0.1; + tmpVec(i) = pow(( m_ParamsCIECam02.F_L* m_ParamsCIECam02.LMSp_w(i)) / 100, 0.42); + m_ParamsCIECam02.LMSp_aw(i) = 400 * (tmpVec(i) / (27.13 + tmpVec(i))) + 0.1; } -m_ParamsCIECam02->A_w = (2.0 * m_ParamsCIECam02->LMSp_aw(0) + m_ParamsCIECam02->LMSp_aw(1) + ((1.0 / 20.0) * m_ParamsCIECam02->LMSp_aw(2)) - 0.305) * m_ParamsCIECam02->N_bb; + m_ParamsCIECam02.A_w = (2.0 * m_ParamsCIECam02.LMSp_aw(0) + m_ParamsCIECam02.LMSp_aw(1) + ((1.0 / 20.0) * m_ParamsCIECam02.LMSp_aw(2)) - 0.305) * m_ParamsCIECam02.N_bb; } @@ -738,16 +747,16 @@ m_ParamsCIECam02->A_w = (2.0 * m_ParamsCIECam02->LMSp_aw(0) + m_ParamsCIECam02-> //Convert // Step 1: cone responses : VectorXd LMS(3); - LMS = m_ParamsCIECam02->M_CAT02 * XYZ; + LMS = m_ParamsCIECam02.M_CAT02 * XYZ; //Step 2 : cone responses considering luminance and surround : VectorXd LMS_C(3); for (int i=0; i<3;++i) - LMS_C(i) = (m_ParamsCIECam02->LMS_c(i))*LMS(i); + LMS_C(i) = ( m_ParamsCIECam02.LMS_c(i))*LMS(i); //Step 3: Hunt - Pointer - Estevez response : VectorXd LMSp(3); - LMSp = (m_ParamsCIECam02->M_HPE * m_ParamsCIECam02->M_CAT02.inverse())*LMS_C; + LMSp = ( m_ParamsCIECam02.M_HPE * m_ParamsCIECam02.M_CAT02.inverse())*LMS_C; //Step 4 : post - adaption cone response : VectorXd LMSp_signs(3); @@ -761,7 +770,7 @@ m_ParamsCIECam02->A_w = (2.0 * m_ParamsCIECam02->LMSp_aw(0) + m_ParamsCIECam02-> LMSp_signs(i) = -1; else LMSp_signs(i) = 1; - tmp = pow(m_ParamsCIECam02->F_L* (LMSp_signs(i)*LMSp(i)) / 100., 0.42); + tmp = pow( m_ParamsCIECam02.F_L* (LMSp_signs(i)*LMSp(i)) / 100., 0.42); LMSp_a(i) = 400 * LMSp_signs(i)*(tmp / ((tmp + 27.13))) + 0.1; } @@ -797,24 +806,24 @@ m_ParamsCIECam02->A_w = (2.0 * m_ParamsCIECam02->LMSp_aw(0) + m_ParamsCIECam02-> //Step 7: achromatic response : -double A = (2*LMSp_a(0) + LMSp_a(1) +(1 / 20)*LMSp_a(2) - 0.305)*m_ParamsCIECam02->N_bb; +double A = (2*LMSp_a(0) + LMSp_a(1) +(1 / 20)*LMSp_a(2) - 0.305)* m_ParamsCIECam02.N_bb; //Step 8: correlate of lightness : - double J = 100 * pow((A / m_ParamsCIECam02->A_w), (m_ParamsCIECam02->c)*(m_ParamsCIECam02->z)); // lightness + double J = 100 * pow((A / m_ParamsCIECam02.A_w), ( m_ParamsCIECam02.c)*( m_ParamsCIECam02.z)); // lightness JQCMsHh[0] = J; //Step 9: correlate of brightness : - double Q = (4. / m_ParamsCIECam02->c)*sqrt(J / 100.) * (m_ParamsCIECam02->A_w + 4)*pow(m_ParamsCIECam02->F_L,0.25); // brightness + double Q = (4. / m_ParamsCIECam02.c)*sqrt(J / 100.) * ( m_ParamsCIECam02.A_w + 4)*pow( m_ParamsCIECam02.F_L,0.25); // brightness JQCMsHh[1] = Q; //Step 10: correlates of chroma, colorfulness, and saturation : - double e = (12500. / 13.)*m_ParamsCIECam02->N_c*m_ParamsCIECam02->N_cb * (cos(h_radian + 2) + 3.8); // eccentricity + double e = (12500. / 13.)* m_ParamsCIECam02.N_c* m_ParamsCIECam02.N_cb * (cos(h_radian + 2) + 3.8); // eccentricity tmp = e*sqrt(a*a + b*b) / (LMSp_a(0) + LMSp_a(1) + (21. / 20.)*LMSp_a(2)); - double C = pow(tmp,0.9)*sqrt(J / 100) * pow(1.64 - pow(0.29,m_ParamsCIECam02->n),0.73); //chroma + double C = pow(tmp,0.9)*sqrt(J / 100) * pow(1.64 - pow(0.29, m_ParamsCIECam02.n),0.73); //chroma JQCMsHh[2] = C; - double M = C*pow(m_ParamsCIECam02->F_L, 0.25); //colorfulness + double M = C*pow( m_ParamsCIECam02.F_L, 0.25); //colorfulness double s = 100 * sqrt(M / Q); // saturation JQCMsHh[3] = M; JQCMsHh[4] = s; @@ -835,34 +844,34 @@ void ColorConvert::Jab_parameters(CAM02CS CS) { case UCS: { - m_JabParams->KL = 1.00; - m_JabParams->c1 = 0.007; - m_JabParams->c2 = 0.0228; - m_JabParams->CS = UCS; + m_JabParams.KL = 1.00; + m_JabParams.c1 = 0.007; + m_JabParams.c2 = 0.0228; + m_JabParams.CS = UCS; break; } case LCD: { - m_JabParams->KL = 0.77; - m_JabParams->c1 = 0.007; - m_JabParams->c2 = 0.0053; - m_JabParams->CS = LCD; + m_JabParams.KL = 0.77; + m_JabParams.c1 = 0.007; + m_JabParams.c2 = 0.0053; + m_JabParams.CS = LCD; break; } case SCD: { - m_JabParams->KL = 1.24; - m_JabParams->c1 = 0.007; - m_JabParams->c2 = 0.0363; - m_JabParams->CS = SCD; + m_JabParams.KL = 1.24; + m_JabParams.c1 = 0.007; + m_JabParams.c2 = 0.0363; + m_JabParams.CS = SCD; break; } default: { - m_JabParams->KL = 1.00; - m_JabParams->c1 = 0.007; - m_JabParams->c2 = 0.0228; - m_JabParams->CS = UCS; + m_JabParams.KL = 1.00; + m_JabParams.c1 = 0.007; + m_JabParams.c2 = 0.0228; + m_JabParams.CS = UCS; break; } } @@ -873,9 +882,9 @@ void ColorConvert::Jab_parameters(CAM02CS CS) // Convert from CIECAM02 JMh values to the perceptually uniform Jab colorspace // JMH are the lightness, colorfullness and hue angle. (similar to LCH) - double Jp = (1 + 100 * m_JabParams->c1)*JMh(0) / (1 + m_JabParams->c1*JMh(0)); - Jp /= m_JabParams->KL; - double Mp = (1 / m_JabParams->c2) * log(1 + m_JabParams->c2 * JMh(1)); + double Jp = (1 + 100 * m_JabParams.c1)*JMh(0) / (1 + m_JabParams.c1*JMh(0)); + Jp /= m_JabParams.KL; + double Mp = (1 / m_JabParams.c2) * log(1 + m_JabParams.c2 * JMh(1)); double ap = Mp*cos(JMh(2)*EIGEN_PI/180); double bp = Mp*sin(JMh(2)*EIGEN_PI / 180); VectorXd Jab(3); @@ -905,15 +914,15 @@ void ColorConvert::Jab_parameters(CAM02CS CS) double ap = Jab(1); double bp = Jab(2); - Jp = Jp * m_JabParams->KL; - double J = -Jp / (m_JabParams->c1 * Jp - 100 * m_JabParams->c1 - 1); + Jp = Jp * m_JabParams.KL; + double J = -Jp / (m_JabParams.c1 * Jp - 100 * m_JabParams.c1 - 1); double h = 0; if (ap == 0. && bp == 0.) h = 0.; else h = atan2(bp, ap) * 180 / EIGEN_PI; double Mp = sqrt(ap*ap + bp*bp); - double M = (exp(m_JabParams->c2*Mp) - 1) / m_JabParams->c2; + double M = (exp(m_JabParams.c2*Mp) - 1) / m_JabParams.c2; VectorXd JMh(3); JMh << J, M, h; @@ -927,16 +936,16 @@ void ColorConvert::Jab_parameters(CAM02CS CS) //Step 1: Get Data double J = JMh(0); - double C = JMh(1) / pow(m_ParamsCIECam02->F_L, 0.25); + double C = JMh(1) / pow( m_ParamsCIECam02.F_L, 0.25); double h = JMh(2); // Step 2: - double d = sqrt(J / 100)*pow(1.64 - pow(0.29, m_ParamsCIECam02->n), 0.73); + double d = sqrt(J / 100)*pow(1.64 - pow(0.29, m_ParamsCIECam02.n), 0.73); double t =pow (C /d, (1 / 0.9)); double et = (cos(EIGEN_PI*h / 180 + 2) + 3.8) / 4; - double A = m_ParamsCIECam02->A_w * pow((J / 100) , 1 / (m_ParamsCIECam02->c*m_ParamsCIECam02->z)); - double p1 = (50000 / 13) * (m_ParamsCIECam02->N_c * m_ParamsCIECam02->N_cb) * et / t; - double p2 = A / m_ParamsCIECam02->N_bb + 0.305; + double A = m_ParamsCIECam02.A_w * pow((J / 100) , 1 / ( m_ParamsCIECam02.c* m_ParamsCIECam02.z)); + double p1 = (50000 / 13) * ( m_ParamsCIECam02.N_c * m_ParamsCIECam02.N_cb) * et / t; + double p2 = A / m_ParamsCIECam02.N_bb + 0.305; double p3 = 21. / 20.; double nom = 460 * (p2 * (2 + p3)) / 1403; double den = 220 * (2 + p3) / 1403; @@ -972,32 +981,32 @@ void ColorConvert::Jab_parameters(CAM02CS CS) SignLMSp_a(i) = -1; else if ((LMSp_a(i)-0.1) > 0) SignLMSp_a(i) = 1; - LMSp(i) = SignLMSp_a(i)* (100. / m_ParamsCIECam02->F_L)*pow(tmp, (1 / 0.42)); + LMSp(i) = SignLMSp_a(i)* (100. / m_ParamsCIECam02.F_L)*pow(tmp, (1 / 0.42)); } //Step 6: cone responses considering luminance and surround : - VectorXd LMS_C = (m_ParamsCIECam02->M_CAT02* m_ParamsCIECam02->M_HPE.inverse()) * LMSp; + VectorXd LMS_C = ( m_ParamsCIECam02.M_CAT02* m_ParamsCIECam02.M_HPE.inverse()) * LMSp; //Step 7 : cone responses : VectorXd LMS(3); for (int i = 0; i < 3; ++i) - LMS(i) = LMS_C(i) / m_ParamsCIECam02->LMS_c(i); + LMS(i) = LMS_C(i) / m_ParamsCIECam02.LMS_c(i); //Step 8: tristimulus values : VectorXd XYZ(3); - XYZ = m_ParamsCIECam02->M_CAT02.inverse()*LMS; + XYZ = m_ParamsCIECam02.M_CAT02.inverse()*LMS; return(XYZ); } VectorXd ColorConvert::XYZtoJab(VectorXd pColor, SURROUND sur) { C_RGB_XYZ_Lab wp(3); - if (m_ParamsCIECam02->XYZ_WP[1] == 1.) - wp.Set(m_ParamsCIECam02->XYZ_WP[0] *100, m_ParamsCIECam02->XYZ_WP[0] * 100, m_ParamsCIECam02->XYZ_WP[2] * 100); + if ( m_ParamsCIECam02.XYZ_WP[1] == 1.) + wp.Set( m_ParamsCIECam02.XYZ_WP[0] *100, m_ParamsCIECam02.XYZ_WP[0] * 100, m_ParamsCIECam02.XYZ_WP[2] * 100); else - wp.Set(m_ParamsCIECam02->XYZ_WP[0] , m_ParamsCIECam02->XYZ_WP[1] , m_ParamsCIECam02->XYZ_WP[2]); + wp.Set( m_ParamsCIECam02.XYZ_WP[0] , m_ParamsCIECam02.XYZ_WP[1] , m_ParamsCIECam02.XYZ_WP[2]); VectorXd surParam(3); surParam << 1, 0.69, 1; @@ -1023,11 +1032,13 @@ void ColorConvert::Jab_parameters(CAM02CS CS) for (int i = 0; i < 3; ++i) Vec(i) = pColor[i]; VectorXd OutVec = LabToJab(Vec, sur); - double Out[3]; + double *Out = new double[3]; + //double *Out = DBG_NEW double[3]; for (int i = 0; i < 3; ++i) Out[i]= OutVec(i); return(Out); } + VectorXd ColorConvert::LabToJab(VectorXd pColor, SURROUND sur) { C_RGB_XYZ_Lab Color(pColor); @@ -1083,7 +1094,7 @@ void ColorConvert::Jab_parameters(CAM02CS CS) //reference F parameter double refX_F = sqrt(refX_CQ / (refX_CQ + 1900)); // reference T parameter - double refX_T; + double refX_T = 0; if ((refX_H > 164) & (refX_H < 345)) refX_T = 0.56 + abs(0.2*cos(EIGEN_PI*(refX_H + 168) / 180)); else if ((refX_H >= 345) | (refX_H <= 164)) @@ -1102,4 +1113,38 @@ void ColorConvert::Jab_parameters(CAM02CS CS) double dE = sqrt(dL*dL + (refX(1) - samX(1))* (refX(1) - samX(1)) + (refX(2) - samX(2))* (refX(2) - samX(2))); double dH = sqrt(dE*dE - dC*dC - dL*dL); dECMC = sqrt(pow(dL / (2 * refX_SL),2) + pow(dC / refX_SC,2) + pow(dH / refX_SH,2)); + } + + void ColorConvert::Initciecam02_parameters() + { + m_ParamsCIECam02.XYZ_WP[0] = 0; + m_ParamsCIECam02.XYZ_WP[1] = 0; + m_ParamsCIECam02.XYZ_WP[2] = 0; + m_ParamsCIECam02.F = 0; + m_ParamsCIECam02.c = 0; + m_ParamsCIECam02.N_c = 0; + m_ParamsCIECam02.M_CAT02 = MatrixXd::Zero(3,3); + m_ParamsCIECam02.M_HPE = MatrixXd::Zero(3, 3); + m_ParamsCIECam02.h_i = VectorXd::Zero(5); + m_ParamsCIECam02.e_i = VectorXd::Zero(5); + m_ParamsCIECam02.H_i = VectorXd::Zero(5); + m_ParamsCIECam02.LMS_w = VectorXd::Zero(3); + m_ParamsCIECam02.D = 0; + m_ParamsCIECam02.LMS_c= VectorXd::Zero(3); + m_ParamsCIECam02.LMSp_w = VectorXd::Zero(3); + m_ParamsCIECam02.k = 0; + m_ParamsCIECam02.F_L = 0; + m_ParamsCIECam02.n = 0; + m_ParamsCIECam02.N_bb = 0; + m_ParamsCIECam02.N_cb = 0; + m_ParamsCIECam02.z = 0; + m_ParamsCIECam02.LMSp_aw = VectorXd::Zero(3); + m_ParamsCIECam02.A_w = 0; + } + void ColorConvert::InitJab_parameters() + { + m_JabParams.CS = CAM02CS(0); + m_JabParams.KL = 0; + m_JabParams.c1 = 0; + m_JabParams.c2 = 0; }
\ No newline at end of file diff --git a/Software/Visual_Studio/Native/Tango.ColorLib/Utils/ColorConvert.h b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/ColorConvert.h index f51ebc7f4..6d349da8c 100644 --- a/Software/Visual_Studio/Native/Tango.ColorLib/Utils/ColorConvert.h +++ b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/ColorConvert.h @@ -10,7 +10,7 @@ using Eigen::VectorXd; struct CIECAM02Params { - double *XYZ_WP; + double XYZ_WP[3]; double F; double c; double N_c; @@ -74,10 +74,10 @@ class ColorConvert VectorXd GetChromaticities(); C_RGB_XYZ_Lab RGBtoXYZ(C_RGB_XYZ_Lab & rgbVal); C_RGB_XYZ_Lab XYZtoRGB(C_RGB_XYZ_Lab& xyzVal); - double *LabtoRGB(double*Lab); - double *ChangeWP(double *LabIn, C_RGB_XYZ_Lab SourceWhite, C_RGB_XYZ_Lab DestWhite); + void LabtoRGB(double*InLab, double* OutRGB ); + void ChangeWP(double *LabIn, double *LabOut, C_RGB_XYZ_Lab SourceWhite, C_RGB_XYZ_Lab DestWhite); C_RGB_XYZ_Lab LabtoRGB(C_RGB_XYZ_Lab& LabVal); - double *RGBtoLab(double*RGB); + void RGBtoLab(double *InRGB, double *OutLab); C_RGB_XYZ_Lab RGBtoLab(C_RGB_XYZ_Lab& RGB); void InitializeConversionMatrices(); void RecalculateConversionMatrices(const VectorXd& chromaticites); @@ -100,8 +100,10 @@ class ColorConvert void InverseOfThreeByThreeMatrix(const MatrixXd& A, MatrixXd& B); void ComputeRGBtoXYZmatrix(); void ComputeXYZtoRGBmatrix(); - Jab_Params *m_JabParams; - CIECAM02Params *m_ParamsCIECam02; + Jab_Params m_JabParams; + CIECAM02Params m_ParamsCIECam02; + void Initciecam02_parameters(); + void InitJab_parameters(); void ciecam02_parameters( double Y_b, double L_A, SURROUND sur); VectorXd XYZ_2_ciecam02(VectorXd XYZ); VectorXd Jab_2_JMh(VectorXd Jab); diff --git a/Software/Visual_Studio/Native/Tango.ColorLib/Utils/ColorTransf.cpp b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/ColorTransf.cpp index 51d0dbd2d..218642472 100644 --- a/Software/Visual_Studio/Native/Tango.ColorLib/Utils/ColorTransf.cpp +++ b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/ColorTransf.cpp @@ -15,13 +15,28 @@ using namespace std; #define InkFactor 100 #define Uint16Factor 65535 +/*#define _CRTDBG_MAP_ALLOC +#include <stdlib.h> +#include <crtdbg.h> +#include <cstdlib> + +#ifdef _DEBUG +#define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ ) +// Replace _NORMAL_BLOCK with _CLIENT_BLOCK if you want the +// allocations to be of _CLIENT_BLOCK type +#else +#define DBG_NEW new +#endif */ + + // NHedral interpolation given the NDimensional LUT. N=3 or N=4 are supported. //Assumes the right table is loaded ColorTransf::ColorTransf() : m_MSBShift(0), m_DataBuffer(NULL), m_SeparationsIn(0), - m_SeparationsOut(0), m_nGridPoints(0), m_GamutLimitsNlperCM(NULL) + m_SeparationsOut(0), m_nGridPoints(0), m_GamutLimitsNlperCM(NULL), + m_NGamutRegions(0) { } @@ -65,10 +80,13 @@ using namespace std; int bytesread = 0; int tmpB =Conv.ByteToInt(buffer, 0); bytesread += 4; - char *tmpC; - int n = 0; - tmpC = Conv.getchar(tmpB, n); + + int n = sizeof((char*)&tmpB); + //char *tmpC = DBG_NEW char[n] ; + char *tmpC = new char[n]; + Conv.getchar(tmpB, n, tmpC); char *luttype = new char[n+1]; + //char *luttype = DBG_NEW char[n + 1]; strncpy_s(luttype, n+1,tmpC, n); int TablePrecision; if (strncmp(luttype, "prc1",n)==0) @@ -80,6 +98,16 @@ using namespace std; throw std::exception("Wrong precision in Color Tables"); return; } + if (luttype != NULL) + { + delete[] luttype; + luttype = NULL; + } + if (tmpC != NULL) + { + delete[] tmpC; + tmpC = NULL; + } // Skip past reserved padding bytes bytesread += 4; @@ -118,6 +146,7 @@ using namespace std; int lsizeH4 =( lSize - bytesread + 1)/2; // int lsizeH4 = lSizeHalf - totHeader; m_DataBuffer = new unsigned short[lsizeH4]; + //m_DataBuffer = DBG_NEW unsigned short[lsizeH4]; int lSizeperSep = lsizeH4 / m_SeparationsOut; int indR = 0; for (int i = 0; i < lSizeperSep; ++i) @@ -136,7 +165,9 @@ using namespace std; void ColorTransf::SetGamutLimitsNlperCM(double *GamutLimitsNlperCM) { + //m_GamutLimitsNlperCM = DBG_NEW double[m_NGamutRegions]; m_GamutLimitsNlperCM = new double[m_NGamutRegions]; + for (int i = 0; i < m_NGamutRegions; ++i) m_GamutLimitsNlperCM[i] = GamutLimitsNlperCM[i]; } @@ -148,10 +179,12 @@ void ColorTransf::evalLab2InkP(double *ColorIn, double *&ColorOut, int &GamutR tmpColorOut = tmpColorOut.labdouble_to_labuint16(ColorIn); /*Convert ColorIn to uint16 */ uint16_t *iColorIn = new uint16_t[m_SeparationsIn]; + //uint16_t *iColorIn = DBG_NEW uint16_t[m_SeparationsIn]; iColorIn[0] = uint16_t(tmpColorOut.Get_x()); iColorIn[1] = uint16_t(tmpColorOut.Get_y()); iColorIn[2] = uint16_t(tmpColorOut.Get_z()); - double *tmpColor = new double[m_SeparationsIn]; + double *tmpColor = new double[m_SeparationsOut]; + //double *tmpColor = DBG_NEW double[m_SeparationsIn]; if (m_SeparationsIn == 3) m_InterpColor.ColorMap3(iColorIn, tmpColor); else if (m_SeparationsIn == 4) @@ -171,7 +204,7 @@ void ColorTransf::evalLab2InkP(double *ColorIn, double *&ColorOut, int &GamutR if (tmpColor != NULL) { delete[] tmpColor; - tmpColorOut = NULL; + tmpColor = NULL; } return; @@ -180,23 +213,24 @@ void ColorTransf::evalLab2InkP(double *ColorIn, double *&ColorOut, int &GamutR void ColorTransf::evalInkP2Lab(double *ColorIn, double *&ColorOut, int &GamutRegion) { double *tmpColorOut = new double[m_SeparationsOut]; - + //double *tmpColorOut = DBG_NEW double[m_SeparationsOut]; /*Convert ColorIn to uint16 */ uint16_t *iColorIn = new uint16_t[m_SeparationsIn]; + //uint16_t *iColorIn = DBG_NEW uint16_t[m_SeparationsIn]; for (int i=0; i<m_SeparationsIn; ++i) iColorIn[i] = uint16_t(double(ColorIn[i] / InkFactor)*Uint16Factor); if (m_SeparationsIn == 3) - m_InterpColor.ColorMap3(iColorIn, tmpColorOut); // return Valu is double in units of 16 bits + m_InterpColor.ColorMap3(iColorIn, tmpColorOut); // return Value is double in units of 16 bits else if (m_SeparationsIn == 4) m_InterpColor.ColorMap4(iColorIn, tmpColorOut); // return value is double in units on 16 bits else throw std::exception("Unsupported Number of Separations in ColorTransf::evalInkP2Lab"); //Normalize to Lab Space C_RGB_XYZ_Lab tmpLabOut; - uint16_t *UInt16ColorOut = new uint16_t[m_SeparationsIn]; - for (int i = 0; i < m_SeparationsIn; ++i) - UInt16ColorOut[i] = (uint16_t)tmpColorOut[i]; - tmpLabOut = tmpLabOut.labuint16_to_labdouble(UInt16ColorOut); + uint16_t int16ColorOut[3]; + for (int i=0; i<3; ++i) + int16ColorOut[i] = (uint16_t )(tmpColorOut[i]); + tmpLabOut = tmpLabOut.labuint16_to_labdouble(int16ColorOut); ColorOut[0] = tmpLabOut.Get_x(); ColorOut[1] = tmpLabOut.Get_y(); ColorOut[2] = tmpLabOut.Get_z(); @@ -211,11 +245,7 @@ void ColorTransf::evalInkP2Lab(double *ColorIn, double *&ColorOut, int &GamutReg delete[] tmpColorOut; tmpColorOut = NULL; } - if (UInt16ColorOut != NULL) - { - delete[] UInt16ColorOut; - UInt16ColorOut = NULL; - } + return; } diff --git a/Software/Visual_Studio/Native/Tango.ColorLib/Utils/GBD.cpp b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/GBD.cpp index 43132ab20..05abf2335 100644 --- a/Software/Visual_Studio/Native/Tango.ColorLib/Utils/GBD.cpp +++ b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/GBD.cpp @@ -2,6 +2,19 @@ #define _CRT_SECURE_NO_WARNINGS #endif +/*#define _CRTDBG_MAP_ALLOC +#include <stdlib.h> +#include <crtdbg.h> +#include <cstdlib> + +#ifdef _DEBUG +#define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ ) +// Replace _NORMAL_BLOCK with _CLIENT_BLOCK if you want the +// allocations to be of _CLIENT_BLOCK type +#else +#define DBG_NEW new +#endif */ + #include "GBD.h" #include <iostream> #include <stdio.h> @@ -27,13 +40,41 @@ typedef enum { GBD::GBD() : m_prec(0), m_nPCSChan(0), - m_nDevChan(0), m_CenterLab(0), m_nVertices(0), m_Vertices(NULL) + m_nDevChan(0), m_CenterLab(0), m_nVertices(0), m_Vertices(NULL), + m_nTriangles(0), m_vert0(NULL), m_vert1(NULL), m_vert2(NULL) { } GBD::~GBD() { + if (m_vert0 != NULL) + { + for (int i = 0; i < m_nTriangles; ++i) + delete[] m_vert0[i]; + delete[] m_vert0; + m_vert0 = NULL; + } + if (m_vert1 != NULL) + { + for (int i = 0; i < m_nTriangles; ++i) + delete[] m_vert1[i]; + delete[] m_vert1; + m_vert1 = NULL; + } + if (m_vert2 != NULL) + { + for (int i = 0; i < m_nTriangles; ++i) + delete[] m_vert2[i]; + delete[] m_vert2; + m_vert2 = NULL; + } + if (m_Vertices != NULL) + { + delete[] m_Vertices; + m_Vertices = NULL; + } + } void GBD::TriangleRayIntersection(double *origin, double *direction, bool &intersect, double *xCoor) @@ -71,11 +112,11 @@ void GBD::TriangleRayIntersection(double *origin, double *direction, bool &inter } crossProduct(VDirection, edge2, pvec); det = dotProduct(edge1, pvec); - //std::cout << "edge1 " << edge1(0) <<" "<< edge1(1) <<" "<< edge1(2) << "\n"; - //std::cout << "edge2 " << edge2(0) << " " << edge2(1) << " " << edge2(2)<< "\n"; - //std::cout << "tvec " << tvec(0) << " " << tvec(1) << " " << tvec(2) << "\n"; - //std::cout << "crossProduct " << pvec(0) << " " << pvec(1) << " " << pvec(2)<< "\n"; - //std::cout << "Det " << det << "\n"; + // std::cout << "edge1 " << edge1(0) <<" "<< edge1(1) <<" "<< edge1(2) << "\n"; + // std::cout << "edge2 " << edge2(0) << " " << edge2(1) << " " << edge2(2)<< "\n"; + // std::cout << "tvec " << tvec(0) << " " << tvec(1) << " " << tvec(2) << "\n"; + // std::cout << "crossProduct " << pvec(0) << " " << pvec(1) << " " << pvec(2)<< "\n"; + // std::cout << "Det " << det << "\n"; switch (rtri) { @@ -90,6 +131,7 @@ void GBD::TriangleRayIntersection(double *origin, double *direction, bool &inter default: throw std::exception("Wrong Parameterin Ray-TriageIntersetion"); } + //determinant GT 0 if (std::abs(det) > eps) { u = dotProduct(tvec, pvec) / det; @@ -97,11 +139,11 @@ void GBD::TriangleRayIntersection(double *origin, double *direction, bool &inter v = dotProduct(VDirection, qvec) / det; t = dotProduct(edge2, qvec) / det; ok = (angleOK && (u >= -eps) && (v >= -eps) && ((u + v) <= 1 + eps)); - //std::cout << "u " << u << "\n"; - //std::cout << "v " << v << "\n"; - //std::cout << "Qvec " << qvec(0) << " " << qvec(1) << " " << qvec(2) << "\n"; - //std::cout << "t " << t << "\n"; - //std::cout << "OK " << ok << "\n"; + // std::cout << "u " << u << "\n"; + // std::cout << "v " << v << "\n"; + // std::cout << "Qvec " << qvec(0) << " " << qvec(1) << " " << qvec(2) << "\n"; + // std::cout << "t " << t << "\n"; + // std::cout << "OK " << ok << "\n"; } else ok = false; @@ -164,11 +206,15 @@ void GBD::InitData(unsigned char* colorTransformBuffer, long colorTransformFileS int bytesread = 0; int tmpB = Conv.ByteToInt(buffer, 0); bytesread += 4; - char *tmpC; - int n = 0; - tmpC = Conv.getchar(tmpB, n); + + int n = sizeof((char*)&tmpB); + //char *tmpC = DBG_NEW char[n]; + char *tmpC = new char[n]; + Conv.getchar(tmpB, n, tmpC); char *tableType = new char[n + 1]; + //char *tableType = DBG_NEW char[n + 1]; strncpy_s(tableType, n + 1, tmpC, n); + int TablePrecision; if (strncmp(tableType, "prc1", n) == 0) TablePrecision = 1; @@ -179,6 +225,18 @@ void GBD::InitData(unsigned char* colorTransformBuffer, long colorTransformFileS throw std::exception("Wrong precision in gbd tables"); return; } + if (tableType != NULL) + { + delete[] tableType; + tableType = NULL; + } + if (tmpC != NULL) + { + delete[] tmpC; + tmpC = NULL; + } + + // Skip past reserved padding bytes bytesread += 4; uint16_t num_gbd_points = Conv.ByteToShort(buffer, bytesread); @@ -213,11 +271,16 @@ void GBD::InitData(unsigned char* colorTransformBuffer, long colorTransformFileS m_vert0 = new double*[m_nTriangles]; m_vert1 = new double*[m_nTriangles]; m_vert2 = new double*[m_nTriangles]; + + /*m_vert0 = DBG_NEW double*[m_nTriangles]; + m_vert1 = DBG_NEW double*[m_nTriangles]; + m_vert2 = DBG_NEW double*[m_nTriangles];*/ uint16_t tmp[3]; C_RGB_XYZ_Lab tmp1; for (i = 0; i < m_nTriangles; ++i) { m_vert0[i] = new double[m_nPCSChan]; + //m_vert0[i] = DBG_NEW double[m_nPCSChan]; for (j = 0; j < m_nPCSChan; ++j) { tmp[j] = Conv.ByteToShort(buffer, bytesread); @@ -231,6 +294,8 @@ void GBD::InitData(unsigned char* colorTransformBuffer, long colorTransformFileS for (i = 0; i < m_nTriangles; ++i) { m_vert1[i] = new double[m_nPCSChan]; + //m_vert1[i] = DBG_NEW double[m_nPCSChan]; + for (j = 0; j < m_nPCSChan; ++j) { tmp[j] = Conv.ByteToShort(buffer, bytesread); @@ -244,6 +309,7 @@ void GBD::InitData(unsigned char* colorTransformBuffer, long colorTransformFileS for (i = 0; i < m_nTriangles; ++i) { m_vert2[i] = new double[m_nPCSChan]; + //m_vert2[i] = DBG_NEW double[m_nPCSChan]; for (j = 0; j < m_nPCSChan; ++j) { tmp[j] = Conv.ByteToShort(buffer, bytesread); diff --git a/Software/Visual_Studio/Native/Tango.ColorLib/Utils/Interp.cpp b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/Interp.cpp index 68b7e0c93..802a63b81 100644 --- a/Software/Visual_Studio/Native/Tango.ColorLib/Utils/Interp.cpp +++ b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/Interp.cpp @@ -5,20 +5,58 @@ #include <iostream> #include <stdio.h> +/*#define _CRTDBG_MAP_ALLOC +#include <stdlib.h> +#include <crtdbg.h> +#include <cstdlib> + +#ifdef _DEBUG +#define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ ) +// Replace _NORMAL_BLOCK with _CLIENT_BLOCK if you want the +// allocations to be of _CLIENT_BLOCK type +#else +#define DBG_NEW new +#endif */ + #define epsTol 0.05 -Interp::Interp(void) + +Interp::Interp(void):m_xValues(NULL), m_yValues(NULL) , m_length(0) +{ +} + +Interp::Interp(const Interp &rhs):m_xValues(NULL), m_yValues(NULL), m_length(0) { } -Interp::Interp(const Interp &rhs):m_xValues(NULL), m_yValues(NULL) +Interp::~Interp() { + /*if (m_xValues != NULL) + { + delete[] m_xValues; + m_xValues = NULL; + } + if (m_yValues != NULL) + { + delete[] m_yValues; + m_yValues = NULL; + }*/ } void Interp::Init(double *xValues, double *yValues, int nlength) { - m_xValues = xValues; - m_yValues = yValues; m_length = nlength; + if (m_xValues == NULL) + //m_xValues = DBG_NEW double(m_length); + m_xValues = new double(m_length); + if (m_yValues == NULL) + //m_yValues = DBG_NEW double(m_length); + m_yValues = new double(m_length); + + for (int i=0; i<m_length; ++i) + { + m_xValues[i] = double(xValues[i]); + m_yValues[i] = double(yValues[i]); + } } void Interp::Eval(double InValue, double &OutValue) @@ -29,7 +67,7 @@ void Interp::Eval(double InValue, double &OutValue) ind = -1; //Check Bounds if((InValue<m_xValues[0] - epsTol) || (InValue >m_xValues[m_length - 1] + epsTol)) - throw std::exception("Value out of Bounds"); + throw std::exception("Interp Eval: Value out of Bounds"); if ((InValue > m_xValues[0] - epsTol) && (InValue < m_xValues[0])) InValue = m_xValues[0]; @@ -62,6 +100,14 @@ void Interp::Eval(int InValue, int &OutValue) ind = -1; d_InValue = (double)InValue; + //Check Bounds + if ((d_InValue<m_xValues[0] - epsTol) || (d_InValue >m_xValues[m_length - 1] + epsTol)) + throw std::exception("Interp Eval: Value out of Bounds"); + if ((d_InValue > m_xValues[0] - epsTol) && (d_InValue < m_xValues[0])) + d_InValue = m_xValues[0]; + + if ((d_InValue > m_xValues[m_length - 1]) && (d_InValue < m_xValues[m_length - 1] + epsTol)) + d_InValue = m_xValues[m_length - 1]; for (m = 0; m < m_length - 1; ++m) { if (m_xValues[m] <= d_InValue && m_xValues[m + 1] >= d_InValue) diff --git a/Software/Visual_Studio/Native/Tango.ColorLib/Utils/Interp.h b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/Interp.h index cf733d45e..eef16546e 100644 --- a/Software/Visual_Studio/Native/Tango.ColorLib/Utils/Interp.h +++ b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/Interp.h @@ -6,14 +6,18 @@ class Interp public: Interp(void); Interp(const Interp &rhs); + ~Interp(); void Eval(double InValue, double &OutValue); void Eval(int InValue, int &OutValue); void Init(double *xValues, double *yValues, int nlength); + void SetXCoords(double* xCoords) {m_xValues = xCoords;}; + void SetYCoords(double * yCoords) { m_yValues = yCoords; }; + void SetNPoints(int npts) { m_length = npts; }; private: double *m_xValues; double* m_yValues; int m_length; - + }; #endif // __INTERP_H__ diff --git a/Software/Visual_Studio/Native/Tango.ColorLib/Utils/NDInterpUtils.cpp b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/NDInterpUtils.cpp index ebf25e14b..dbaeb85b6 100644 --- a/Software/Visual_Studio/Native/Tango.ColorLib/Utils/NDInterpUtils.cpp +++ b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/NDInterpUtils.cpp @@ -5,12 +5,26 @@ #include "NDInterpUtils.h" #include <stdio.h> +/*#define _CRTDBG_MAP_ALLOC +#include <stdlib.h> +#include <crtdbg.h> +#include <cstdlib> + +#ifdef _DEBUG +#define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ ) +// Replace _NORMAL_BLOCK with _CLIENT_BLOCK if you want the +// allocations to be of _CLIENT_BLOCK type +#else +#define DBG_NEW new +#endif */ + extern "C" { NDInterpUtils::NDInterpUtils() : - m_MSBShift(Sh4MSB), m_DataBuffer(NULL), m_nSeparationsIn(nSeparationsIn), - m_nSeparationsOut(nSeparationsOut), m_nGridPoints(0) + m_MSBShift(Sh4MSB), m_DataBuffer(NULL), m_nSeparationsIn(nSeparationsIn), m_Point(NULL), + m_nSeparationsOut(nSeparationsOut), m_nGridPoints(0), m_SubCubeSize(0), m_LastCubeComp(0), + m_tmpResult(NULL) { } @@ -25,6 +39,8 @@ extern "C" SetLastCubeComp(); m_Point = new unsigned short[m_nSeparationsIn + 1]; m_tmpResult = new int[m_nSeparationsOut]; + //m_Point = DBG_NEW unsigned short[m_nSeparationsIn + 1]; + //m_tmpResult = DBG_NEW int[m_nSeparationsOut]; } NDInterpUtils::~NDInterpUtils() diff --git a/Software/Visual_Studio/Native/Tango.ColorLib/Utils/NumConversions.cpp b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/NumConversions.cpp index 2ec57149e..cdbc98d00 100644 --- a/Software/Visual_Studio/Native/Tango.ColorLib/Utils/NumConversions.cpp +++ b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/NumConversions.cpp @@ -5,6 +5,19 @@ #include <iostream> #include <stdio.h> +/*#define _CRTDBG_MAP_ALLOC +#include <stdlib.h> +#include <crtdbg.h> +#include <cstdlib> + +#ifdef _DEBUG +#define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ ) +// Replace _NORMAL_BLOCK with _CLIENT_BLOCK if you want the +// allocations to be of _CLIENT_BLOCK type +#else +#define DBG_NEW new +#endif */ + NumConversions::NumConversions(void) { } @@ -13,6 +26,10 @@ NumConversions::NumConversions(const NumConversions &rhs) { } +NumConversions::~NumConversions() +{ + +} int NumConversions::ByteToInt(uint8_t *byteN, int start) { int res; @@ -31,16 +48,17 @@ res = (uint16_t)((unsigned short)byteN[start] << 8 | return(res); } -char* NumConversions::getchar(uint32_t num,int &nlen) +void NumConversions::getchar(uint32_t num, int &nlen, char *tmpC) { char *getChar; getChar = (char*)# nlen = sizeof(getChar); //reverse order - char *tmp = new char[nlen]; + //char *tmp = new char[nlen]; + //char *tmp = DBG_NEW char[nlen]; for (int i = 0; i < nlen; ++i) { - tmp[i] = getChar[nlen - 1 - i]; + tmpC[i] = getChar[nlen - 1 - i]; } - return(tmp); +// return(tmp); } diff --git a/Software/Visual_Studio/Native/Tango.ColorLib/Utils/NumConversions.h b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/NumConversions.h index b5e9d28e5..d18fd2a1c 100644 --- a/Software/Visual_Studio/Native/Tango.ColorLib/Utils/NumConversions.h +++ b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/NumConversions.h @@ -8,9 +8,10 @@ class NumConversions public: NumConversions(void); NumConversions(const NumConversions &rhs); + ~NumConversions(); int ByteToInt(uint8_t *byteN, int Start); uint16_t ByteToShort(uint8_t *byteN, int Start); - char* getchar(uint32_t num, int &nlen); + void getchar(uint32_t num, int &nlen, char *tmpC); private: }; #endif //__NUMCONVERSIONS_H__
\ No newline at end of file |
