aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Native
diff options
context:
space:
mode:
Diffstat (limited to 'Software/Visual_Studio/Native')
-rw-r--r--Software/Visual_Studio/Native/Tango.ColorLib/ColorConverter.cpp812
-rw-r--r--Software/Visual_Studio/Native/Tango.ColorLib/ColorConverter.h51
-rw-r--r--Software/Visual_Studio/Native/Tango.ColorLib/Tango.ColorLib.vcxproj4
-rw-r--r--Software/Visual_Studio/Native/Tango.ColorLib/Tango.ColorLib.vcxproj.filters12
-rw-r--r--Software/Visual_Studio/Native/Tango.ColorLib/Utils/C_RGB_XYZ_Lab.cpp26
-rw-r--r--Software/Visual_Studio/Native/Tango.ColorLib/Utils/C_RGB_XYZ_Lab.h3
-rw-r--r--Software/Visual_Studio/Native/Tango.ColorLib/Utils/ColorConvert.cpp41
-rw-r--r--Software/Visual_Studio/Native/Tango.ColorLib/Utils/ColorConvert.h10
-rw-r--r--Software/Visual_Studio/Native/Tango.ColorLib/Utils/ColorTransf.cpp164
-rw-r--r--Software/Visual_Studio/Native/Tango.ColorLib/Utils/GBD.cpp311
-rw-r--r--Software/Visual_Studio/Native/Tango.ColorLib/Utils/GBD.h38
-rw-r--r--Software/Visual_Studio/Native/Tango.ColorLib/Utils/Interp.h2
-rw-r--r--Software/Visual_Studio/Native/Tango.ColorLib/Utils/NumConversions.cpp46
-rw-r--r--Software/Visual_Studio/Native/Tango.ColorLib/Utils/NumConversions.h16
-rw-r--r--Software/Visual_Studio/Native/Tester/Tester.cpp11
-rw-r--r--Software/Visual_Studio/Native/Tester/Tester.vcxproj1
16 files changed, 1247 insertions, 301 deletions
diff --git a/Software/Visual_Studio/Native/Tango.ColorLib/ColorConverter.cpp b/Software/Visual_Studio/Native/Tango.ColorLib/ColorConverter.cpp
index b311e0e83..ed95ef95b 100644
--- a/Software/Visual_Studio/Native/Tango.ColorLib/ColorConverter.cpp
+++ b/Software/Visual_Studio/Native/Tango.ColorLib/ColorConverter.cpp
@@ -14,9 +14,11 @@
#include "C_RGB_XYZ_Lab.h"
#include "ColorConvert.h"
#include "ColorTransf.h"
+#include "NumConversions.h"
#include "Interp.h"
#include <cmath>
#include <algorithm>
+#include <sstream>
#define dL 2.0
#define dC 2.0
@@ -27,12 +29,19 @@
#define Y_b 20.0
#define eps 1e-06
#define NegValue -1000
+#define WPTol 1.0
+#define dETol 2.0
+
Tango::ColorLib::ColorConverter::ColorConverter() :m_A2BTransform(NULL), m_B2ATransform(NULL),
-m_CalibCurves(NULL), m_CalibDatasize(NULL),
+m_GBD(NULL), m_CalibCurves(NULL), m_CalibDatasize(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_nInks(0), m_nVolumes(0), m_AdaptWP(false)
{
+ m_whitepointLab.Set(-1, -1, -1);
+ m_whitepointXYZ_Strip.Set(-1, -1, -1);
+ m_whitepointXYZ_CT.Set(-1, -1, -1);
+
}
Tango::ColorLib::ColorConverter::~ColorConverter()
@@ -47,6 +56,16 @@ Tango::ColorLib::ColorConverter::~ColorConverter()
delete m_B2ATransform;
m_B2ATransform = NULL;
}
+ if (m_GBD != NULL)
+ {
+ delete m_GBD;
+ m_GBD = NULL;
+ }
+ if (m_Conv02 != NULL)
+ {
+ delete m_Conv02;
+ m_Conv02 = NULL;
+ }
if (m_CalibDatasize != NULL)
{
delete[] m_CalibDatasize;
@@ -59,21 +78,18 @@ Tango::ColorLib::ColorConverter::~ColorConverter()
}
}
-void Tango::ColorLib::ColorConverter::ProcessHiveNeighbors(VectorXd Lab, VectorXd RGB, VectorXd Volume, int InGamutRegion, MatrixXd &ORGBHive, MatrixXd &OVolumeHive, int nHive, int *&OGamutRegion, int *indDataMax)
+void Tango::ColorLib::ColorConverter::ProcessHiveNeighbors(VectorXd Lab, VectorXd RGB, VectorXd Volume, int InGamutRegion,
+ MatrixXd &ORGBHive, MatrixXd &OVolumeHive, int nHive, int *&OGamutRegion, int *indDataMax)
{
size_t retVal = 0;
- //Initialize CIECAM02 transformation
- Illum IL = D65;
- SURROUND sur = average;
- CAM02CS CS = UCS;
- ColorConvert *Conv02 = new ColorConvert(IL, IL, Y_b, L_A, sur, CS);
-
VectorXd LabV(3);
LabV = Lab;
// LabV << Lab[0], Lab[1], Lab[2];
VectorXd Jab(3);
- Jab = Conv02->LabToJab(LabV, sur);
+ SURROUND sur = m_Conv02->getSurround();
+ CAM02CS CS = m_Conv02->getCAM02CS();
+ Jab = m_Conv02->LabToJab(LabV, sur);
//JCH coordinates
double hue = 0.0;
@@ -99,7 +115,7 @@ void Tango::ColorLib::ColorConverter::ProcessHiveNeighbors(VectorXd Lab, VectorX
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)
+/* for (int i = 0; i < 2; ++i)
{
j1 = i + 18;
Jab1(j1, 0) = Jab(0) + (i + 1)*dL;
@@ -112,18 +128,22 @@ void Tango::ColorLib::ColorConverter::ProcessHiveNeighbors(VectorXd Lab, VectorX
Jab1(j1, 0) = Jab(0) - (i + 1)*dL;
Jab1(j1, 1) = Jab(1);
Jab1(j1, 2) = Jab(2);
- }
+ }*/
//convert back to CIELab
MatrixXd Lab1(nHive, 3);
- MatrixXd RGBTmpVec(nHive + 2, 3);
- MatrixXd VolumeHive(nHive + 2, m_nVolumes);
+ //MatrixXd RGBTmpVec(nHive + 2, 3);
+ //MatrixXd VolumeHive(nHive + 2, m_nVolumes);
+ MatrixXd RGBTmpVec(nHive + 1, 3);
+ MatrixXd VolumeHive(nHive + 1, m_nVolumes);
VectorXd xyz(3);
VectorXd JabTmp(3);
C_RGB_XYZ_Lab xyzVal, LabVal;
double *tmpRGB;
double *InkOut = new double[m_nInks];
- int *GamutRegion = new int[nHive + 2];
+ //int *GamutRegion = new int[nHive + 2];
+ int *GamutRegion = new int[nHive + 1];
+
double *Lab1P = new double[3];
VectorXd Vol(m_nVolumes);
int j = 0;
@@ -131,9 +151,9 @@ void Tango::ColorLib::ColorConverter::ProcessHiveNeighbors(VectorXd Lab, VectorX
{
//fill data
JabTmp << Jab1(i, 0), Jab1(i, 1), Jab1(i, 2);
- xyz = Conv02->Jab_2_XYZ(JabTmp, CS);
+ xyz = m_Conv02->Jab_2_XYZ(JabTmp, CS);
xyzVal.Set(xyz / 100.0);
- LabVal = Conv02->XYZToLab(xyzVal);
+ LabVal = m_Conv02->XYZToLab(xyzVal);
Lab1(i, 0) = LabVal.Get_x();
Lab1(i, 1) = LabVal.Get_y();
Lab1(i, 2) = LabVal.Get_z();
@@ -142,33 +162,31 @@ void Tango::ColorLib::ColorConverter::ProcessHiveNeighbors(VectorXd Lab, VectorX
Lab1P[j] = Lab1(i, j);
m_B2ATransform->evalLab2InkP(Lab1P, InkOut, GamutRegion[i]); //InkOut is in units of 16 bits
m_A2BTransform->evalInkP2Lab(InkOut, Lab1P, GamutRegion[i]);
- //Check id whitepoints match
- //LabOut is under D65
+ //Check if whitepoints match
+ //LabOut is under D65 illumination
double * LabInFinal = Lab1P;
- if ((m_whitepointXYZ_Strip.Get_x() != m_whitepointXYZ_CT.Get_x()) ||
- (m_whitepointXYZ_Strip.Get_y() != m_whitepointXYZ_CT.Get_y()) ||
- (m_whitepointXYZ_Strip.Get_z() != m_whitepointXYZ_CT.Get_z()))
+ //Convert to CT WP
+ LabInFinal = m_Conv02->ChangeWP(LabInFinal, m_whitepointXYZ_CT, m_WP); //dest, source
+ if (m_AdaptWP)
{
- LabInFinal = Conv02->ToAbsoluteLab(LabInFinal, m_WP, m_whitepointXYZ_Strip);
- LabInFinal = Conv02->ToAbsoluteLab(LabInFinal, m_whitepointXYZ_Strip, m_whitepointXYZ_CT);
- LabInFinal = Conv02->ToAbsoluteLab(LabInFinal, m_whitepointXYZ_CT, m_WP);
+ //Convert to Strip whitepoint
+ LabInFinal = m_Conv02->ChangeWP(LabInFinal, m_whitepointXYZ_Strip, m_whitepointXYZ_CT);
}
- Conv02->SetReferenceWhite(D65);
+ m_Conv02->SetReferenceWhite(D65);
//Convert to RGB
- tmpRGB = Conv02->LabtoRGB(LabInFinal);
+ tmpRGB = m_Conv02->LabtoRGB(LabInFinal);
for (int j = 0; j < 3; ++j)
RGBTmpVec(i, j) = std::min(std::max(tmpRGB[j], 0.0), 255.0);
- //Use Lab to convert to Linear Inks
- m_B2ATransform->evalLab2InkP(LabInFinal, InkOut, GamutRegion[i]); //InkOut is in units of 16 bits
- //convert to [0-100]
+
VectorXd InkOutV = DoubleToVector(InkOut, m_nInks);
ConvertToNLInks(InkOutV, InkOutV);
NLInkPToVolume(InkOutV, Vol);
for (int j = 0; j < 3; ++j)
VolumeHive(i, j) = Vol(j);
}
- for (int i = 0; i < 2; ++i)
- {
+ //for (int i = 0; i < 2; ++i)
+ for (int i = 0; i < 1; ++i)
+ {
for (j = 0; j < 3; ++j)
{
VolumeHive(nHive + i, j) = Volume(j);
@@ -178,16 +196,12 @@ void Tango::ColorLib::ColorConverter::ProcessHiveNeighbors(VectorXd Lab, VectorX
}
//Organize hive into 5x5 matrix
- //Hive Vector follows the ordering 0-(0,0) 1-(0,1) 2-(0,2),...., 22-(4,2), 23-(4,3), 24-(4,4)
+ //Hive Vector follows the ordering 0-(0,0) 1-(0,1) 2-(0,2),....,
+ //22-(4,2), 23-(4,3), 24-(4,4) not implemented yet
//Some of the matrix elements are empty
ArrangeHiveData(RGBTmpVec, VolumeHive, GamutRegion, nHive, ORGBHive, OVolumeHive, OGamutRegion);
FindTriplet(Lab, Lab1, nHive, indDataMax);
- if (Conv02 != NULL)
- {
- delete Conv02;
- Conv02 = NULL;
- }
-
+
if (InkOut != NULL)
{
delete[]InkOut;
@@ -264,12 +278,14 @@ void Tango::ColorLib::ColorConverter::ArrangeHiveData(MatrixXd RGBTmpVec, Matri
//Some of the matrix elements are empty
//Ordering is by hexagon position in a 5x5 grid.
- VectorXd xpos(nHive + 2);
- xpos << 1, 1, 1, 2, 3, 2, 1, 0, 0, 0, 1, 2, 3, 3, 4, 3, 3, 2, 5, 5, 5, 5, 5, 2;
- VectorXd ypos(nHive + 2);
- ypos << 3, 2, 1, 1, 2, 3, 4, 3, 2, 1, 0, 0, 0, 1, 2, 3, 4, 4, 0, 1, 3, 4, 2, 2;
+ //VectorXd xpos(nHive + 2);
+ VectorXd xpos(nHive + 1);
+ xpos << 1, 1, 1, 2, 3, 2, 1, 0, 0, 0, 1, 2, 3, 3, 4, 3, 3, 2, /*, 5, 5, 5, 5, 5,*/ 2;
+ //VectorXd ypos(nHive + 2);
+ VectorXd ypos(nHive + 1);
+ ypos << 3, 2, 1, 1, 2, 3, 4, 3, 2, 1, 0, 0, 0, 1, 2, 3, 4, 4,/* 0, 1, 3, 4, 2,*/ 2;
int i, j;
- for (i = 0; i <= nHive + 1; ++i)
+ for (i = 0; i < nHive + 1; ++i)
{
int index = (int)(xpos(i) * 5 + ypos(i));
for (j = 0; j < 3; ++j)
@@ -321,6 +337,7 @@ void Tango::ColorLib::ColorConverter::fillRGB(OutputCoordinates *outputCoords, V
outputCoords->blue = (int32_t)std::round(RGBOut(2));
}
+
void Tango::ColorLib::ColorConverter::readColorTransformations(ConversionInput* conversionInput)
{
//Read thread white. Thread White is given in CIELab Space
@@ -331,128 +348,197 @@ void Tango::ColorLib::ColorConverter::readColorTransformations(ConversionInput*
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());
- //***************This is temporary has to be replaced by the table's white point, once the new Color Table Format is set.
- m_whitepointXYZ_CT.Set(tmpW.Get_x(), tmpW.Get_y(), tmpW.Get_z());
+ m_whitepointXYZ_Strip.Set(tmpW.Get_x(), tmpW.Get_y(), tmpW.Get_z());
}
else
{
throw std::exception("misssing one of the whitepoint components");
return;
}
- //get ND color inverse LUT
- uint8_t *B2ALUT;
- long B2ALutsize = 0;
- if (conversionInput->has_inversedata)
+ //parse Color Tansformations, placed in forward data
+ int bytesread = 0;
+ NumConversions conv;
+ int tag_count = 0;
+ if (conversionInput->has_forwarddata)
{
- B2ALUT = conversionInput->inversedata.data;
- B2ALutsize = (long)(conversionInput->inversedata.len);
- m_B2ATransform = new ColorTransf();
- m_B2ATransform->InitData(B2ALUT, B2ALutsize);
- SetnB2AnSepIn(m_B2ATransform->GetSeparationsIn());
- if (m_nB2AnSepIn != 3)
+ //Read Header
+ CT_Header header = read_header(conversionInput, bytesread);
+ uint32_t tmp;
+ uint8_t *buff = conversionInput->forwarddata.data;
+ tmp = conv.ByteToInt(buff, bytesread);
+ tag_count = (int)tmp;
+ bytesread += 4;
+ //read Tag Table
+ char **TagNames = new char*[tag_count];
+ int **TagSize = new int*[tag_count];
+ char *tmpC;
+ int n = 0;
+ int i, j;
+ for ( i = 0; i < tag_count; ++i)
{
- throw std::exception("Wrong input dimensions in B2A transform");
- return;
+ TagSize[i] = new int[3];
+ tmp =conv.ByteToInt(buff, bytesread);
+ tmpC = conv.getchar(tmp, n);
+ TagNames[i] = new char[n];
+ for (j = 0; j<n; ++j)
+ TagNames[i][j] = tmpC[j];
+ bytesread += 4;
+ TagSize[i][0] = conv.ByteToInt(buff, bytesread);
+ bytesread += 4;
+ TagSize[i][1] = conv.ByteToInt(buff, bytesread);
+ bytesread += 4;
}
- SetnB2AnSepOut(m_B2ATransform->GetSeparationsOut());
- }
- else
- {
- if ((conversionInput->colorspace == COLOR_SPACE__RGB) ||
- (conversionInput->colorspace == COLOR_SPACE__LAB) ||
- (conversionInput->colorspace == COLOR_SPACE__PANTON))
- throw std::exception(" Missing necessary Lab to Ink Transform");
- return;
- }
+ int *TList = new int[tag_count];
+ for (int k = 0; k < tag_count; ++k)
+ {
+ if (strncmp(TagNames[k], "A2B ",4) ==0)
+ TList[k] = A2B;
+ else if (strncmp(TagNames[k], "B2A ",4)==0)
+ TList[k] = B2A;
+ else if (strncmp(TagNames[k], "wtpt",4)==0)
+ TList[k] = wtpt;
+ else if (strncmp(TagNames[k], "desc",4)==0)
+ TList[k] = desc;
+ else if (strncmp(TagNames[k], "gbd ",4)==0)
+ TList[k] = gbd;
+ else if (strncmp(TagNames[k], "cprt",2)==0)
+ TList[k] = cprt;
+ else
+ throw std::exception("Unknown Tag in Color Tables");
+ }
+ for (int k = 0; k < tag_count; ++k)
+ {
+ switch (TList[k])
+ {
+ case A2B:
+ {
+ uint8_t *A2BLUT = &(conversionInput->forwarddata.data[TagSize[k][0]]);
+ int A2BLutsize = TagSize[k][1];
+ m_A2BTransform = new ColorTransf();
+ m_A2BTransform->InitData(A2BLUT, A2BLutsize);
+ break;
+ }
+ case B2A:
+ {
+ uint8_t *B2ALUT = &(conversionInput->forwarddata.data[TagSize[k][0]]);
+ int B2ALutsize = TagSize[k][1];
+ m_B2ATransform = new ColorTransf();
+ m_B2ATransform->InitData(B2ALUT, B2ALutsize);
+ break;
+ }
+ case gbd:
+ {
+ uint8_t *GBDList = &(conversionInput->forwarddata.data[TagSize[k][0]]);
+ m_GBD = new GBD();
+ int GBDSize = TagSize[k][1];
+ m_GBD->InitData(GBDList, GBDSize);
+ break;
+ }
+ case wtpt:
+ {
+ read_xyz_type(TagSize[k][0], TagSize[k][1], &m_whitepointXYZ_CT, conversionInput);
- //get ND color forward LUT
- uint8_t *A2BLUT;
- long A2BLutsize;
+ break;
+ }
+ case cprt:
+ {
+ std::string textstr;
+ read_text_type(TagSize[k][0], TagSize[k][1], &textstr, conversionInput);
+ break;
+ }
+ case desc:
+ {
+ std::string textdescstr;
+ read_text_description_type(TagSize[k][0], TagSize[k][1], textdescstr, conversionInput);
+ break;
+ }
+ default:
+ {
+ throw std::exception("Unresolved Tag in Color Tables");
+ return;
+ }
- if (conversionInput->has_forwarddata)
- {
- A2BLUT = conversionInput->forwarddata.data;
- A2BLutsize = conversionInput->forwarddata.len;
- m_A2BTransform = new ColorTransf();
- m_A2BTransform->InitData(A2BLUT, A2BLutsize);
- SetnA2BnSepIn(m_A2BTransform->GetSeparationsIn());
- SetnA2BnSepOut(m_A2BTransform->GetSeparationsOut());
- if (m_nA2BnSepOut != 3)
+ }
+ }
+ for (int i = 0; i < tag_count; ++i)
{
- throw std::exception(" Wrong output dimensions in Ink to Lab transform");
- return;
+ delete[] TagNames[i];
+ delete[] TagSize[i];
}
+ delete[]TagNames;
+ delete[] TagSize;
+ delete[] TList;
}
- else
+
+
+ //Verify all relevant tags had been read
+ if (m_A2BTransform == NULL)
{
- if ((conversionInput->has_colorspace == COLOR_SPACE__CMYK) ||
- (conversionInput->has_colorspace == COLOR_SPACE__LAB) ||
- (conversionInput->colorspace == COLOR_SPACE__PANTON))
- throw std::exception("Missing necessary Ink to Lab Transform");
- return;
+ throw std::exception("Missing Forward Transform in Color Tables");
+ return;
}
- if (m_nB2AnSepIn != m_nA2BnSepOut ||
- m_nA2BnSepIn != m_nB2AnSepOut)
+ if (m_B2ATransform == NULL)
{
- throw std::exception("Forward and InverseTables dimensions do not match");
- return;
+ throw std::exception("Missing Inverse Transform in Color Tables");
+ return;
}
-
- if (A2BLUT != NULL)
+ if (m_GBD == NULL)
{
- delete[] A2BLUT;
- A2BLUT = NULL;
+ throw std::exception("Missing Gamut Boundary Descriptor in Color Tables");
+ return;
}
- if (B2ALUT != NULL)
+ if ((m_whitepointXYZ_CT.Get_x() ==-1) && (m_whitepointXYZ_CT.Get_y() == -1) && (m_whitepointXYZ_CT.Get_z() == -1))
{
- delete B2ALUT;
- B2ALUT = NULL;
+ throw std::exception("Missing Whitepoint in Color Tables");
+ return;
}
return; // OK
}
-void Tango::ColorLib::ColorConverter::readCalibrationTables(ConversionInput* conversionInput)
-{
- SetNumberofInks((int)(conversionInput->inputcoordinates->n_inputliquids));
- CalibData *CalibCurves = new CalibData[m_nInks];
- m_CalibCurves = new CalibData[m_nInks];
- for (int i = 0; i < m_nInks; ++i)
+ void Tango::ColorLib::ColorConverter::readCalibrationTables(ConversionInput* conversionInput)
{
- 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)
- {
- case LIQUID_TYPE__Cyan:
- case LIQUID_TYPE__Magenta:
- case LIQUID_TYPE__Yellow:
- case LIQUID_TYPE__Black:
+ SetNumberofInks((int)(conversionInput->inputcoordinates->n_inputliquids));
+ CalibData *CalibCurves = new CalibData[m_nInks];
+ m_CalibCurves = new CalibData[m_nInks];
+ for (int i = 0; i < m_nInks; ++i)
{
- // calibration data.
- CalibrationData* calibrationData = InkType->calibrationdata;
- SetCalibData(calibrationData, i, &m_CalibCurves[i]);
- break;
- }
- default:
- throw std::exception("could not fill all calibration tables");
- return;
+ 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)
+ {
+ case LIQUID_TYPE__Cyan:
+ case LIQUID_TYPE__Magenta:
+ case LIQUID_TYPE__Yellow:
+ case LIQUID_TYPE__Black:
+ {
+ // calibration data.
+ CalibrationData* calibrationData = InkType->calibrationdata;
+ SetCalibData(calibrationData, i, &m_CalibCurves[i]);
+ break;
+ }
+ default:
+ {
+ throw std::exception("could not fill all calibration tables");
+ return;
+ }
+ }
}
+ // m_CalibCurves=CalibCurves;
+ return;
}
- // m_CalibCurves=CalibCurves;
- return;
-}
+
void Tango::ColorLib::ColorConverter::SetCalibData(CalibrationData *calibrationData, int i, CalibData *tmpCurve)
{
if (calibrationData->calibrationpoints <= 0)
{
char msg[100];
- strcpy(msg, "No Calibration points in table ");
- char ai[10];
- strcat(msg, itoa(i, ai, 10));
+ int n =
+ strcpy_s (msg, 100, "No Calibration points in table ");
+
throw std::exception(msg);
return;
}
@@ -483,69 +569,62 @@ void Tango::ColorLib::ColorConverter::SetCalibData(CalibrationData *calibrationD
return;
}
-void Tango::ColorLib::ColorConverter::ConvertColorToLinearInks(ConversionInput* conversionInput, VectorXd &InkOut, VectorXd &RGBOut, VectorXd &LabOut, int &GamutRegion)
+void Tango::ColorLib::ColorConverter::ConvertColorToLinearInks(ConversionInput* conversionInput, VectorXd &InkOut, VectorXd &RGBOut,
+ VectorXd &LabOut, int &GamutRegion, bool &InGamut)
{
size_t nInks = 0;
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
- //if Strip whitepoint and Table whitepoint do not match, make the conversion:
- // RGB to XYZ (D65) -> Strip Thread (from D65 to Strip)
- //Convert from strip to Color table WP
- //Convert from Color Table WP to D65
- //Convert to Lab via RGB->Lab transformation
- //Convert to ink via B2A table
- //Convert to Lab via A2B table returns the actual Lab which maches the Gamut
- //Convert to RGB
+ // 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. 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
+
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 *LabIn;
double *RGBOutP = VectorToDouble(RGBOut);
+ //RGB to Lab
LabIn = CConvertD65.RGBtoLab(RGBOutP); //Values are in Relative Colorimetric, D65
+
double *LabInFinal = LabIn;
- //check if the thread to be used is the same as the one in the color tables
- if ((m_whitepointXYZ_Strip.Get_x() != m_whitepointXYZ_CT.Get_x()) ||
- (m_whitepointXYZ_Strip.Get_y() != m_whitepointXYZ_CT.Get_y()) ||
- (m_whitepointXYZ_Strip.Get_z() != m_whitepointXYZ_CT.Get_z()))
- {
- LabInFinal = CConvertD65.ToAbsoluteLab(LabInFinal, m_WP, m_whitepointXYZ_Strip);
- LabInFinal = CConvertD65.ToAbsoluteLab(LabInFinal, m_whitepointXYZ_Strip, m_whitepointXYZ_CT);
- LabInFinal = CConvertD65.ToAbsoluteLab(LabInFinal, m_whitepointXYZ_CT, m_WP);
- }
-
+ //Is In Gamut?
+ InGamut = IsInGamut(LabIn, sur);
//convert to inks
int GamutRegion;
double *InkOutP = 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
- //convert to Lab to get In-Gamut Lab
- double *LabInP = new double[3];
- m_A2BTransform->evalInkP2Lab(InkOutP, LabInP, GamutRegion);
InkOut = DoubleToVector(InkOutP, m_nInks);
- //Convert to Lab to get effective RGB
- //Lab is in D65
- double *LabOutFinal;
- LabOutFinal = LabInP;
- if ((m_whitepointXYZ_Strip.Get_x() != m_whitepointXYZ_CT.Get_x()) ||
- (m_whitepointXYZ_Strip.Get_y() != m_whitepointXYZ_CT.Get_y()) ||
- (m_whitepointXYZ_Strip.Get_z() != m_whitepointXYZ_CT.Get_z()))
+ //Convert to Lab to get the actual in Gamut Lab
+ double *LabInP = 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);
+ //check if the thread to be used is the same as the one in the color tables
+ if (m_AdaptWP)
{
- LabOutFinal = CConvertD65.ToAbsoluteLab(LabOutFinal, m_WP, m_whitepointXYZ_CT);
- LabOutFinal = CConvertD65.ToAbsoluteLab(LabOutFinal, m_whitepointXYZ_CT, m_whitepointXYZ_Strip);
- LabOutFinal = CConvertD65.ToAbsoluteLab(LabOutFinal, m_whitepointXYZ_Strip, m_WP);
+ //Convert to Strip White Point
+ LabInFinal = CConvertD65.ChangeWP(LabInFinal, m_whitepointXYZ_Strip, m_whitepointXYZ_CT);
}
- LabOut = DoubleToVector(LabOutFinal,3);
+
CConvertD65.SetReferenceWhite(D65);
//Get the Gamut Mapped RGB Based on Absolute Colorimetric Data
- RGBOutP = CConvertD65.LabtoRGB(LabOutFinal);
+ RGBOutP = CConvertD65.LabtoRGB(LabInFinal);
RGBOut = DoubleToVector(RGBOutP, 3);
if (LabInP != NULL)
{
@@ -571,21 +650,28 @@ void Tango::ColorLib::ColorConverter::ConvertColorToLinearInks(ConversionInput*
}
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. chack if there is a match between STRIP and Color 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
double *LabIn = 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
+ //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;
- //Check if Color Tables and Strip whitepoints are the same, otherwiae convert
- if ((m_whitepointXYZ_Strip.Get_x() != m_whitepointXYZ_CT.Get_x()) ||
- (m_whitepointXYZ_Strip.Get_y() != m_whitepointXYZ_CT.Get_y()) ||
- (m_whitepointXYZ_Strip.Get_z() != m_whitepointXYZ_CT.Get_z()))
+ // 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.ToAbsoluteLab(LabInFinal, m_whitepointXYZ_Strip, m_whitepointXYZ_CT);
- LabInFinal = CConvertD65.ToAbsoluteLab(LabInFinal, m_whitepointXYZ_Strip, m_WP);
+ LabInFinal = CConvertD65.ChangeWP(LabInFinal, m_whitepointXYZ_CT, m_whitepointXYZ_Strip); //to Color Tables
}
+ LabInFinal = CConvertD65.ChangeWP(LabInFinal, m_WP, m_whitepointXYZ_CT); //to Relative
+ InGamut = IsInGamut(LabInFinal, sur);
//convert to Inks
int GamutRegion;
double *InkOutP = new double[m_nB2AnSepOut];
@@ -593,13 +679,14 @@ void Tango::ColorLib::ColorConverter::ConvertColorToLinearInks(ConversionInput*
//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;
- if ((m_whitepointXYZ_Strip.Get_x() != m_whitepointXYZ_CT.Get_x()) ||
- (m_whitepointXYZ_Strip.Get_y() != m_whitepointXYZ_CT.Get_y()) ||
- (m_whitepointXYZ_Strip.Get_z() != m_whitepointXYZ_CT.Get_z()))
+ //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);
+ if (m_AdaptWP)
{
- LabOutFinal = CConvertD65.ToAbsoluteLab(LabOutFinal, m_WP, m_whitepointXYZ_CT);
- LabOutFinal = CConvertD65.ToAbsoluteLab(LabOutFinal, m_whitepointXYZ_CT, m_whitepointXYZ_Strip);
+ LabOutFinal = CConvertD65.ChangeWP(LabOutFinal, m_whitepointXYZ_Strip, m_whitepointXYZ_CT );
}
CConvertD65.SetReferenceWhite(D65);
//Convert to RGB
@@ -607,6 +694,11 @@ void Tango::ColorLib::ColorConverter::ConvertColorToLinearInks(ConversionInput*
RGBOutP = CConvertD65.LabtoRGB(LabOutFinal);
RGBOut = DoubleToVector(RGBOutP, 3);
+ if (InkOutP != NULL)
+ {
+ delete[] InkOutP;
+ InkOutP = NULL;
+ }
if (LabIn != NULL)
{
delete[] LabIn;
@@ -617,6 +709,7 @@ void Tango::ColorLib::ColorConverter::ConvertColorToLinearInks(ConversionInput*
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];
size_t CountSep = 0;
outData[0] = conversionInput->inputcoordinates->cyan;
@@ -645,19 +738,17 @@ void Tango::ColorLib::ColorConverter::ConvertColorToLinearInks(ConversionInput*
//LabOut is in relative colorimetric
ColorConvert CConvertD65(D65, D65);
double *LabOutFinal = LabOutP;
+ InGamut = true;
//Check if white points match
- if ((m_whitepointXYZ_Strip.Get_x() != m_whitepointXYZ_CT.Get_x()) ||
- (m_whitepointXYZ_Strip.Get_y() != m_whitepointXYZ_CT.Get_y()) ||
- (m_whitepointXYZ_Strip.Get_z() != m_whitepointXYZ_CT.Get_z()))
- {
- LabOutFinal = CConvertD65.ToAbsoluteLab(LabOutFinal, m_WP, m_whitepointXYZ_CT);
- LabOutFinal = CConvertD65.ToAbsoluteLab(LabOutFinal, m_whitepointXYZ_CT, m_whitepointXYZ_Strip);
- LabOutFinal = CConvertD65.ToAbsoluteLab(LabOutFinal, m_whitepointXYZ_Strip, m_WP);
+ LabOutFinal = CConvertD65.ChangeWP(LabOutFinal, m_whitepointXYZ_CT, m_WP);
+ if (m_AdaptWP)
+ {//check if this is needed
+ LabOutFinal = CConvertD65.ChangeWP(LabOutFinal, m_whitepointXYZ_Strip, m_whitepointXYZ_CT);
}
LabOut = DoubleToVector(LabOutFinal, 3);
CConvertD65.SetReferenceWhite(D65);
//Get RGB
- double *RGBOutP;
+ double *RGBOutP;
RGBOutP = CConvertD65.LabtoRGB(LabOutFinal);
RGBOut = DoubleToVector(RGBOutP, 3);
if (LabOutP != NULL)
@@ -665,6 +756,21 @@ void Tango::ColorLib::ColorConverter::ConvertColorToLinearInks(ConversionInput*
delete[] LabOutP;
LabOutP = NULL;
}
+ if (InkOutP != NULL)
+ {
+ delete[] InkOutP;
+ InkOutP = NULL;
+ }
+ if (LabOutFinal != NULL)
+ {
+ delete LabOutFinal;
+ LabOutFinal = NULL;
+ }
+ if (RGBOutP != NULL)
+ {
+ delete RGBOutP;
+ RGBOutP = NULL;
+ }
break;
}
case(COLOR_SPACE__PANTON):
@@ -683,9 +789,11 @@ void Tango::ColorLib::ColorConverter::ConvertColorToLinearInks(ConversionInput*
}
default:
+ {
throw std::exception(" Unsupported Color Space");
return;
}
+ }
//all data is now in linear ink format
return;
}
@@ -698,11 +806,12 @@ void Tango::ColorLib::ColorConverter::ConvertToNLInks(VectorXd InkIn, VectorXd
for (int i = 0; i < m_nVolumes; ++i)
{
- xValues = m_CalibCurves[i].getxCoords();
- yValues = m_CalibCurves[i].getyCoords();
+ xValues = m_CalibCurves[i].getyCoords();
+ yValues = m_CalibCurves[i].getxCoords();
LinInterp.Init(xValues, yValues, m_CalibCurves[i].getSize());
LinInterp.Eval(InkIn(i), InkOut(i));
}
+
return;
}
@@ -714,11 +823,12 @@ void Tango::ColorLib::ColorConverter::ConvertToLinearInks(VectorXd InkIn, Vecto
for (int i = 0; i < m_nVolumes; ++i)
{
- xValues = m_CalibCurves[i].getyCoords();
- yValues = m_CalibCurves[i].getxCoords();
- LinInterp.Init(yValues, xValues, m_CalibCurves[i].getSize());
+ xValues = m_CalibCurves[i].getxCoords();
+ yValues = m_CalibCurves[i].getyCoords();
+ LinInterp.Init(xValues, yValues, m_CalibCurves[i].getSize());
LinInterp.Eval(InkIn(i), InkOut(i));
}
+
return;
}
@@ -859,19 +969,16 @@ void Tango::ColorLib::ColorConverter::ConvertVolumeToRGBDisplay(ConversionInput*
double *LabOutP = new double[m_nA2BnSepOut];
for (int i = 0; i < m_nA2BnSepIn; ++i)
InkOutP[i] = InkOut(i);
- m_A2BTransform->evalInkP2Lab(InkOutP, LabOutP, GamutRegion);
+ m_A2BTransform->evalInkP2Lab(InkOutP, LabOutP, GamutRegion);
//LabOut is in Relative Colorimetric
ColorConvert CConvertD65(D65, D65);
double *LabOutFinal; //= new double[3];
LabOutFinal = LabOutP;
- if ((m_whitepointXYZ_Strip.Get_x() != m_whitepointXYZ_CT.Get_x()) ||
- (m_whitepointXYZ_Strip.Get_y() != m_whitepointXYZ_CT.Get_y()) ||
- (m_whitepointXYZ_Strip.Get_z() != m_whitepointXYZ_CT.Get_z()))
+ LabOutFinal = CConvertD65.ChangeWP(LabOutFinal, m_whitepointXYZ_CT, m_WP);
+ if (m_AdaptWP)
{
- LabOutFinal = CConvertD65.ToAbsoluteLab(LabOutFinal, m_WP, m_whitepointXYZ_Strip);
- LabOutFinal = CConvertD65.ToAbsoluteLab(LabOutFinal, m_whitepointXYZ_Strip, m_whitepointXYZ_CT);
- LabOutFinal = CConvertD65.ToAbsoluteLab(LabOutFinal, m_whitepointXYZ_CT, m_WP);
+ LabOutFinal = CConvertD65.ChangeWP(LabOutFinal, m_whitepointXYZ_Strip, m_whitepointXYZ_CT);
}
CConvertD65.SetReferenceWhite(D65);
double *RGBOutP; // = new double[3];
@@ -931,12 +1038,26 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i
conversion_output__init(conversionOutput);
// 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);
- // SetNumberOfInks(m_nB2AnSepOut);
+
+ //Initialize CIECAM02 transformation
+ Illum IL = D65;
+ SURROUND sur = average;
+ CAM02CS CS = UCS;
+ m_Conv02 = 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");
@@ -956,10 +1077,13 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i
int GamutRegion = 0;
//Convert input data to linear inks
if (conversionInput->colorspace == COLOR_SPACE__Volume)
+ {
ConvertVolumeToRGBDisplay(conversionInput, Volume, RGBOut, LabOut, GamutRegion);
+ InGamut = true;
+ }
else
{
- ConvertColorToLinearInks(conversionInput, InkOut, RGBOut, LabOut, GamutRegion);
+ ConvertColorToLinearInks(conversionInput, InkOut, RGBOut, LabOut, GamutRegion, InGamut);
//Convert to Nonlinear Inks
ConvertToNLInks(InkOut, NLInkOut);
//Convert to [nl/cm]
@@ -970,6 +1094,8 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i
output_coordinates__init(outputCoords);
fillRGB(outputCoords, RGBOut);
fillVolume(outputCoords, Volume);
+ conversionOutput->has_outofgamut = true;
+ conversionOutput->outofgamut = !(InGamut);
conversionOutput->singlecoordinates = outputCoords;
@@ -979,8 +1105,8 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i
// 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 = 22; // 18;
- int MatHive = 30; //25;
+ int nHive = 18; //22; // 18;
+ int MatHive = 25;// 30; //25;
MatrixXd RGBHive(MatHive, 3);
VectorXd RGBHive1(3);
@@ -1043,12 +1169,13 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i
conversionOutput->triplecoordinates[i] = TripletData[i];
}
- //Clean up
- /* if (GamutRegionV != NULL)
+/* //Clean up
+ if (GamutRegionV != NULL)
{
delete GamutRegionV;
GamutRegionV = NULL;
} */
+
//Pack output...
output_buffer = (uint8_t*)malloc(conversion_output__get_packed_size(conversionOutput));
@@ -1072,6 +1199,279 @@ int Tango::ColorLib::ColorConverter::CountNumberofInks(ConversionInput* conversi
return(numberofInks);
}
+bool Tango::ColorLib::ColorConverter::IsInGamut(double *InLab, SURROUND sur)
+{
+ int nInLab = sizeof(InLab);
+ double *xCoord = new double[nInLab];
+ //Convert InLab to CIECam02 coordinates
+ bool InGamut = true;
+ double ctr[3];
+ C_RGB_XYZ_Lab center = m_GBD->getCenter();
+ VectorXd JInLab(3);
+ JInLab << InLab[0], InLab[1], InLab[2];
+ VectorXd JLab = m_Conv02->LabToJab(JInLab, 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);
+ bool intersect = false;
+ m_GBD->TriangleRayIntersection(dJLab, ctr, intersect, xCoord);
+ if (intersect)
+ {
+ VectorXd V1(3);
+ VectorXd V2(3);
+ V1 << JLab[0], JLab[1], JLab[2];
+ V1 << xCoord[0], xCoord[1], xCoord[2];
+ double dECMC;
+ m_Conv02->SymmetricaldECMC(V1, V2, dECMC);
+ if (dECMC < dETol)
+ InGamut = true;
+ else
+ InGamut = false;
+ }
+ else
+ InGamut = true;
+ if (xCoord != NULL)
+ {
+ delete [] xCoord;
+ xCoord = NULL;
+ }
+ return(InGamut);
+}
+
+
+Tango::CT_Header Tango::ColorLib::ColorConverter::read_header(ConversionInput* conversionInput, int &bytesread)
+{
+ CT_Header *Header = new CT_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) ;
+ 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;
+ 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;
+ bytesread += 4;
+ tmp = Conv.ByteToInt(ColorTable, bytesread);
+ tmpC = Conv.getchar(tmp, n);
+ Header->ConnectionSpace = tmpC;
+ bytesread += 4;
+
+ bytesread += 12;
+ tmp = Conv.ByteToInt(ColorTable, bytesread);
+ tmpC = Conv.getchar(tmp, n);
+ Header->DeviceManufacturer = tmpC;
+ bytesread += 4;
+ //read illuminant
+ double xyz[3];
+ for (int j = 0; j < 3; ++j)
+ {
+ tmp = Conv.ByteToInt(ColorTable, bytesread);
+ xyz[j] = (double)(tmp) / 65536;
+ bytesread += 4;
+ }
+ Header->Illuminant.Set(xyz[0], xyz[1], xyz[2]);
+ if (bytesread < 128)
+ {
+ bytesread = 128;
+ return(*Header);
+ }
+ else
+ {
+ throw std::exception("could not read Color table Header");
+ }
+}
+
+void Tango::ColorLib::ColorConverter::read_lut_type(int offset, int data_size, ColorTransf *Transf, ConversionInput* conversionInput)
+{
+ /*
+ 0 - 3 'prec1', 'prec2'
+ 4 - 7 reserved, must be 0
+ 8 number of input channels, uint8
+ 9 number of output channels, uint8
+ 10 number of CLUT grid points, uint8
+ 11 number of Shift Bits
+ 12 Number of gamut regions
+ 13 - n CLUT values, uint16
+
+ 13 - n output tables, uint8
+ */
+ if (data_size < 32)
+ {
+ throw std::exception(" LUT size missmatch");
+ return;
+ }
+ int bytesread = 0;
+ // Check for signature
+ uint8_t *buff = &conversionInput->forwarddata.data[offset];
+ Transf->InitData(buff, data_size);
+ return;
+}
+
+void Tango::ColorLib::ColorConverter::read_xyz_type(int offset, int data_size, C_RGB_XYZ_Lab *XYZ, ConversionInput* conversionInput)
+{
+// 0 - 3 'XYZ '
+//4 - 7 reserved, must be 0
+// 8 - n array of XYZ numbers
+
+if (data_size < 8)
+{
+ throw std::exception("not enough data to read xyz");
+}
+uint8_t *buff = &(conversionInput->forwarddata.data[offset]);
+NumConversions Conv;
+int bytesread = 0;
+int tmpxyz = Conv.ByteToInt(buff, bytesread);
+char* tmpC;
+int n = 0;
+tmpC = Conv.getchar(tmpxyz, n);
+
+char *xyztype = new char[n+1];
+strncpy_s(xyztype, n+1,tmpC, n);
+if (strncmp(xyztype, "XYZ ",n) !=0)
+{
+ throw std::exception("Wrong Tag Type");
+ return;
+}
+delete[] xyztype;
+bytesread = 8;
+int num_values = (data_size - 8) / 4;
+if (floor((double)(num_values) / 3) * 3 != num_values)
+{
+ throw std::exception("not enough Data to read xyz");
+ return;
+}
+double xyz[3];
+int tmp;
+for (int j = 0; j < 3; ++j)
+{
+ tmp = Conv.ByteToInt(buff, bytesread);
+ xyz[j] = (double)(tmp) / 65536;
+ bytesread += 4;
+}
+XYZ->Set(xyz[0], xyz[1], xyz[2]);
+return;
+}
+
+void Tango::ColorLib::ColorConverter::read_text_type(int offset, int data_size, std::string *textstr,
+ ConversionInput* conversionInput)
+{
+ // 0 - 3 'text'
+ //4 - 7 reserved, must be 0
+ //8 - string of(data_size - 8) 7 - bit ASCII characters, including NULL
+
+ std::stringstream strstr;
+ if (data_size < 8)
+ {
+ throw std::exception("invalid Tag Name");
+ strstr << "";
+ *textstr = strstr.str();
+ return;
+ }
+
+ uint8_t *buff = &(conversionInput->forwarddata.data[offset]);
+ int bytesread = 0;
+ NumConversions Conv;
+ int tmp = Conv.ByteToInt(buff, bytesread);
+ int n = 0;
+ char *tmpC;
+ tmpC = Conv.getchar(tmp, n);
+ char *tagtype = new char[n+1];
+ strncpy_s(tagtype,n+1, tmpC, n);
+ if (strcmp(tagtype, "text") !=0)
+ {
+ throw std::exception("invalid Tag Name");
+ strstr << "";
+ *textstr = strstr.str();
+ return;
+ }
+ delete[] tagtype;
+ bytesread += 8;
+ uint8_t tmp1;
+ for (int i = bytesread; i < data_size; ++i)
+ {
+ tmp1 = buff[i];
+ strstr.put( tmp1);
+ }
+ *textstr = strstr.str();
+ return;
+}
+
+
+void Tango::ColorLib::ColorConverter::read_text_description_type(int offset, int data_size, std::string textdescstr,
+ ConversionInput* conversionInput)
+{
+ // 0 - 3 'desc'
+ // 4 - 7 reserved, must be 0
+ // 8 - 11 ASCII invariant description count, including terminating NULL
+ // 12 - ASCII invariant description
+
+ uint8_t *buff = &(conversionInput->forwarddata.data[offset]);
+ int bytesread = 0;
+ NumConversions Conv;
+ int tmp = Conv.ByteToInt(buff, bytesread);
+ int n = 0;
+ char *tmpC;
+ tmpC = Conv.getchar(tmp, n);
+ char *tagtype = new char[n+1];
+ strncpy_s(tagtype, n+1, tmpC, n);
+ std::stringstream strstr;
+ if (strcmp(tagtype, "desc") !=0)
+ {
+ throw std::exception("invalid Tag Name");
+ strstr << "";
+ textdescstr = strstr.str();
+ return;
+ }
+ delete[] tagtype;
+ bytesread += 8;
+ int count = Conv.ByteToInt(buff, bytesread);
+ bytesread += 4;
+ uint8_t tmp1;
+ for (int i = 0; i < count - 1; ++i)
+ {
+ tmp1 = buff[bytesread + i];
+ strstr << tmp1;
+ }
+ textdescstr = strstr.str();
+ return;
+}
+
+void Tango::ColorLib::ColorConverter::CompareWhitePoints()
+{
+ ColorConvert ColConv(D65, D65);
+ C_RGB_XYZ_Lab Lab_CT;
+ C_RGB_XYZ_Lab Lab_Strip;
+ Lab_CT = ColConv.XYZToLab(m_whitepointXYZ_CT);
+ Lab_Strip = ColConv.XYZToLab(m_whitepointXYZ_Strip);
+ VectorXd VLab_CT(3);
+ VectorXd VLab_Strip(3);
+ VLab_CT(0) = Lab_CT.Get_x();
+ VLab_CT(1) = Lab_CT.Get_y();
+ VLab_CT(2) = Lab_CT.Get_z();
+ VLab_Strip(0) = Lab_Strip.Get_x();
+ VLab_Strip(1) = Lab_Strip.Get_y();
+ VLab_Strip(2) = Lab_Strip.Get_z();
+ double dECMC;
+ ColConv.SymmetricaldECMC(VLab_CT, VLab_Strip, dECMC);
+ if (dECMC < WPTol)
+ m_AdaptWP = false;
+ return;
+}
+
//size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t input_buffer_size, uint8_t *& output_buffer)
//{
// //Unpack conversion input...
diff --git a/Software/Visual_Studio/Native/Tango.ColorLib/ColorConverter.h b/Software/Visual_Studio/Native/Tango.ColorLib/ColorConverter.h
index 3331199d7..1d61877fd 100644
--- a/Software/Visual_Studio/Native/Tango.ColorLib/ColorConverter.h
+++ b/Software/Visual_Studio/Native/Tango.ColorLib/ColorConverter.h
@@ -6,6 +6,8 @@
#include "protobuf-c\protobuf-c.h"
#include "CalibData.h"
#include "ColorTransf.h"
+#include "ColorConvert.h"
+#include "GBD.h"
#include "ConversionOutput.pb-c.h"
#include "CalibrationData.pb-c.h"
#include "ConversionInput.pb-c.h"
@@ -13,15 +15,44 @@
#pragma once
namespace Tango
{
+ typedef struct
+ {
+ unsigned int TblSIze;
+ unsigned int Version[3];
+ char * ColorSpace;
+ char * ConnectionSpace;
+ char * DeviceManufacturer;
+ C_RGB_XYZ_Lab Illuminant;
+ } CT_Header;
+
+ typedef enum {
+ XYZ,
+ Lab,
+ CMY,
+ CMYK
+ }ColorSpace;
+
+ typedef enum {
+ A2B,
+ B2A,
+ cprt,
+ gbd,
+ wtpt,
+ desc
+ }TagList;
+
namespace ColorLib
{
+
+
class ColorConverter
{
public:
ColorConverter();
~ColorConverter();
// size_t Convert(uint8_t * input_buffer, size_t input_buffer_size, uint8_t *& output_buffer);
- void ConvertColorToLinearInks(ConversionInput* conversionInput, VectorXd &InkOut, VectorXd &RGBOut, VectorXd &LabOut, int &GamutRegion);
+ void ConvertColorToLinearInks(ConversionInput* conversionInput, VectorXd &InkOut, VectorXd &RGBOut, VectorXd &LabOut,
+ int &GamutRegion, bool &InGamut);
void ConvertVolumeToRGBDisplay(ConversionInput* conversionInput, VectorXd &InkOut, VectorXd &RGBOut,
VectorXd &LabOut, int &GamutRegion);
size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t input_buffer_size, uint8_t *& output_buffer);
@@ -29,9 +60,12 @@ namespace Tango
void ConvertToLinearInks(VectorXd InkIn, VectorXd &InkOut);
void VolumeToNLInkP(VectorXd Volume, VectorXd &NLInkP);
void NLInkPToVolume(VectorXd NLInkP, VectorXd &Volume);
+ void SetMaxNLperCM(double maxNlPerCM, int i);
private:
ColorTransf *m_B2ATransform;
ColorTransf *m_A2BTransform;
+ GBD *m_GBD;
+ ColorConvert *m_Conv02;
C_RGB_XYZ_Lab m_whitepointLab;
C_RGB_XYZ_Lab m_whitepointXYZ_Strip;
C_RGB_XYZ_Lab m_whitepointXYZ_CT;
@@ -39,13 +73,13 @@ namespace Tango
int m_nB2AnSepOut;
int m_nA2BnSepIn;
int m_nA2BnSepOut;
+ bool m_AdaptWP;
CalibData *m_CalibCurves;
size_t *m_CalibDatasize;
int m_nInks;
- VectorXd m_maxNlPerCM;
int m_nVolumes;
C_RGB_XYZ_Lab m_WP;
-
+ VectorXd m_maxNlPerCM;
void SetnB2AnSepIn(int nB2AnSepIn) { m_nB2AnSepIn = nB2AnSepIn; };
void SetnB2AnSepOut(int nB2AnSepOut) { m_nB2AnSepOut = nB2AnSepOut; };
void SetnA2BnSepIn(int nA2BnSepIn) { m_nA2BnSepIn = nA2BnSepIn; };
@@ -54,7 +88,6 @@ namespace Tango
void readCalibrationTables(ConversionInput* conversionInput);
void SetCalibData(CalibrationData* calibrationData, int i, CalibData *tmpCurve);
void SetNumberofInks(int nInks) { m_nInks = nInks; };
- void SetMaxNLperCM(double maxNlPerCM, int i);
void SetNumberOfVolumes(int nVol) { m_nVolumes = nVol; };
void SetNumberOfInks(int nInks) { m_nInks = nInks; };
void fillRGB(OutputCoordinates *outputCoords, VectorXd RGBOut);
@@ -67,7 +100,15 @@ namespace Tango
int CountNumberofInks(ConversionInput* conversionInput);
double *VectorToDouble(VectorXd Vec);
VectorXd DoubleToVector(double *doub, int nSize);
-
+ void CompareWhitePoints();
+ bool IsInGamut(double *InLab, SURROUND sur);
+ CT_Header read_header(ConversionInput* conversionInput, int &bytesread);
+ void read_lut_type(int offset, int data_size, ColorTransf *Transf, ConversionInput* conversionInput);
+ void read_xyz_type(int offset, int data_size, C_RGB_XYZ_Lab *xyz, ConversionInput* conversionInput);
+ void read_text_type(int offset, int data_size, std::string *textstr,
+ ConversionInput* conversionInput);
+ void read_text_description_type(int offset, int data_size, std::string textdescstr,
+ ConversionInput* conversionInput);
};
}
}
diff --git a/Software/Visual_Studio/Native/Tango.ColorLib/Tango.ColorLib.vcxproj b/Software/Visual_Studio/Native/Tango.ColorLib/Tango.ColorLib.vcxproj
index 7fccc42b1..6aacdb863 100644
--- a/Software/Visual_Studio/Native/Tango.ColorLib/Tango.ColorLib.vcxproj
+++ b/Software/Visual_Studio/Native/Tango.ColorLib/Tango.ColorLib.vcxproj
@@ -176,8 +176,10 @@
<ClInclude Include="Utils\ColorConvert.h" />
<ClInclude Include="Utils\ColorTransf.h" />
<ClInclude Include="Utils\C_RGB_XYZ_Lab.h" />
+ <ClInclude Include="Utils\GBD.h" />
<ClInclude Include="Utils\Interp.h" />
<ClInclude Include="Utils\NDInterpUtils.h" />
+ <ClInclude Include="Utils\NumConversions.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="ColorConverter.cpp" />
@@ -197,8 +199,10 @@
<ClCompile Include="Utils\ColorConvert.cpp" />
<ClCompile Include="Utils\ColorTransf.cpp" />
<ClCompile Include="Utils\C_RGB_XYZ_Lab.cpp" />
+ <ClCompile Include="Utils\GBD.cpp" />
<ClCompile Include="Utils\Interp.cpp" />
<ClCompile Include="Utils\NDInterpUtils.cpp" />
+ <ClCompile Include="Utils\NumConversions.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
diff --git a/Software/Visual_Studio/Native/Tango.ColorLib/Tango.ColorLib.vcxproj.filters b/Software/Visual_Studio/Native/Tango.ColorLib/Tango.ColorLib.vcxproj.filters
index bcab0f096..38b89c2f3 100644
--- a/Software/Visual_Studio/Native/Tango.ColorLib/Tango.ColorLib.vcxproj.filters
+++ b/Software/Visual_Studio/Native/Tango.ColorLib/Tango.ColorLib.vcxproj.filters
@@ -93,6 +93,12 @@
<ClInclude Include="Exports.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="Utils\NumConversions.h">
+ <Filter>Utils</Filter>
+ </ClInclude>
+ <ClInclude Include="Utils\GBD.h">
+ <Filter>Utils</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Exports.cpp">
@@ -152,5 +158,11 @@
<ClCompile Include="Utils\ColorConvert.cpp">
<Filter>Utils</Filter>
</ClCompile>
+ <ClCompile Include="Utils\NumConversions.cpp">
+ <Filter>Utils</Filter>
+ </ClCompile>
+ <ClCompile Include="Utils\GBD.cpp">
+ <Filter>Utils</Filter>
+ </ClCompile>
</ItemGroup>
</Project> \ No newline at end of file
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 211dd0a34..25f035e0c 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
@@ -86,6 +86,30 @@ void C_RGB_XYZ_Lab::Clamp(C_RGB_XYZ_Lab &low, C_RGB_XYZ_Lab &high)
m_z = std::min(std::max(m_z, low.Get_z()), high.Get_z());;
}
+C_RGB_XYZ_Lab C_RGB_XYZ_Lab::labuint16_to_labdouble(uint16_t * LabShort)
+{
+ double tmp[3];
+ C_RGB_XYZ_Lab out;
+ tmp[0] = (double(LabShort[0]) * (100.0 + (25500.0 / 65280.0))) / 65535.0;
+ tmp[1] = ((double(LabShort[1]) * (255.0 + (255.0 / 256.0))) / 65535.0) - 128.0;
+ tmp[2] = ((double(LabShort[2]) * (255.0 + (255.0 / 256.0))) / 65535.0) - 128.0;
+ out.Set(tmp[0], tmp[1], tmp[2]);
+ return (out);
+}
+
+C_RGB_XYZ_Lab C_RGB_XYZ_Lab::labdouble_to_labuint16(double* LabDouble)
+{
+//Do the scale and offset and cast to uint16
+ C_RGB_XYZ_Lab out;
+ double tmp[3];
+tmp[0]= round(65535 * LabDouble[0] / (100 + (25500 / 65280)));
+tmp[1] = round(65535 * ((128 + LabDouble[1]) / (255 + (255 / 256))));
+tmp[2] = round(65535 * ((128 + LabDouble[2]) / (255 + (255 / 256))));
+for (int i = 0; i < 3; ++i)
+ tmp[0] = std::min(std::max(tmp[0], 0.0), 65535.0);
+out.Set((uint16_t)tmp[0], (uint16_t)tmp[1], (uint16_t)tmp[2]);
+return (out);
+}
// add to existing value (rgb += rhs)
C_RGB_XYZ_Lab &C_RGB_XYZ_Lab::operator += (C_RGB_XYZ_Lab &rhs)
@@ -141,3 +165,5 @@ bool operator != (C_RGB_XYZ_Lab &lhs, C_RGB_XYZ_Lab &rhs)
}
+
+
diff --git a/Software/Visual_Studio/Native/Tango.ColorLib/Utils/C_RGB_XYZ_Lab.h b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/C_RGB_XYZ_Lab.h
index 55062fc6a..875adc84c 100644
--- a/Software/Visual_Studio/Native/Tango.ColorLib/Utils/C_RGB_XYZ_Lab.h
+++ b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/C_RGB_XYZ_Lab.h
@@ -28,7 +28,8 @@ class C_RGB_XYZ_Lab
double Get_z() { return (m_z); };
// Clamp the elements to the range [low, high]
void Clamp (C_RGB_XYZ_Lab &low, C_RGB_XYZ_Lab &high);
-
+ C_RGB_XYZ_Lab labuint16_to_labdouble(uint16_t *LabShort);
+ C_RGB_XYZ_Lab labdouble_to_labuint16(double* LabDouble);
C_RGB_XYZ_Lab &operator += (C_RGB_XYZ_Lab &rhs);
C_RGB_XYZ_Lab &operator -= (C_RGB_XYZ_Lab &rhs);
C_RGB_XYZ_Lab &operator *= (C_RGB_XYZ_Lab &rhs);
diff --git a/Software/Visual_Studio/Native/Tango.ColorLib/Utils/ColorConvert.cpp b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/ColorConvert.cpp
index 1e4b60950..6014df298 100644
--- a/Software/Visual_Studio/Native/Tango.ColorLib/Utils/ColorConvert.cpp
+++ b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/ColorConvert.cpp
@@ -22,6 +22,8 @@ static const C_RGB_XYZ_Lab ZeroVal(0.0, 0.0, 0.0);
static bool m_MatricesInitialized = false;
static MatrixXd m_RGBtoXYZMatrix = MatrixXd(nXYZ, nRGB);
static MatrixXd m_XYZtoRGBMatrix = MatrixXd(nRGB, nXYZ);
+C_RGB_XYZ_Lab LowLab(0.0, -128.0, -128.0);
+C_RGB_XYZ_Lab HighLab(100.0, 127.0, 127.0);
// Default Constructor (defaults to reference white of D50, 2 degree)
ColorConvert::ColorConvert (void)
@@ -122,6 +124,8 @@ ColorConvert::ColorConvert(C_RGB_XYZ_Lab DDest, C_RGB_XYZ_Lab DSource)
ColorConvert::ColorConvert(Illum DDest, Illum DSource, double Y_b, double L_A, SURROUND sur, CAM02CS CS)
{
+ SetCAM02CS(CS);
+ SetSurround(sur);
switch (DDest)
{
case D50:
@@ -160,8 +164,10 @@ ColorConvert::ColorConvert(const ColorConvert &rhs) :
m_InvReferenceWhite(rhs.m_InvReferenceWhite),
m_SourceWhite(rhs.m_SourceWhite),
m_BradfordMatrix(rhs.m_BradfordMatrix),
- m_JabParams (rhs.m_JabParams),
- m_ParamsCIECam02(rhs.m_ParamsCIECam02)
+ m_JabParams(rhs.m_JabParams),
+ m_ParamsCIECam02(rhs.m_ParamsCIECam02),
+ m_CS(rhs.m_CS),
+ m_sur(rhs.m_sur)
{
}
@@ -377,8 +383,8 @@ const C_RGB_XYZ_Lab &ColorConvert::GetReferenceWhite(void) const
C_RGB_XYZ_Lab ColorConvert::RGBtoLab(C_RGB_XYZ_Lab& RGBVal)
{
C_RGB_XYZ_Lab DataXYZ;
- C_RGB_XYZ_Lab LowLab(0.0, -128.0, -128.0);
- C_RGB_XYZ_Lab HighLab(100.0, 127.0, 127.0);
+ //C_RGB_XYZ_Lab LowLab(0.0, -128.0, -128.0);
+ // C_RGB_XYZ_Lab HighLab(100.0, 127.0, 127.0);
DataXYZ = RGBtoXYZ(RGBVal);
C_RGB_XYZ_Lab DataLab;
@@ -388,7 +394,7 @@ const C_RGB_XYZ_Lab &ColorConvert::GetReferenceWhite(void) const
}
- double *ColorConvert::ToAbsoluteLab(double *LabIn, C_RGB_XYZ_Lab SourceWhite, C_RGB_XYZ_Lab DestWhite)
+ double *ColorConvert::ChangeWP(double *LabIn, C_RGB_XYZ_Lab SourceWhite, C_RGB_XYZ_Lab DestWhite)
{
SetReferenceWhite(SourceWhite);
C_RGB_XYZ_Lab Lab;
@@ -397,15 +403,21 @@ const C_RGB_XYZ_Lab &ColorConvert::GetReferenceWhite(void) const
SetReferenceWhite(DestWhite);
C_RGB_XYZ_Lab LabOut1;
LabOut1 = XYZToLab(XYZ);
- SetReferenceWhite(SourceWhite);
- C_RGB_XYZ_Lab LabOut2;
- 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();
+ // SetReferenceWhite(SourceWhite);
+/* C_RGB_XYZ_Lab LabOut2;
+ LabOut2 = XYZToLab(XYZ);
double *LabD = new double[3];
double x = 100 - Lab.Get_x();
double f = 100.0 / (100.0 + pow(x, 3) / 100.0);
LabD[0] = f*LabOut1.Get_x() + (1-f) *LabOut2.Get_x();
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);
}
@@ -1004,7 +1016,18 @@ void ColorConvert::Jab_parameters(CAM02CS CS)
Jab = JMh_2_Jab(JMh);
return(Jab);
}
-
+
+ double *ColorConvert::LabToJab(double* pColor, SURROUND sur)
+ {
+ VectorXd Vec(3);
+ for (int i = 0; i < 3; ++i)
+ Vec(i) = pColor[i];
+ VectorXd OutVec = LabToJab(Vec, sur);
+ double Out[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);
diff --git a/Software/Visual_Studio/Native/Tango.ColorLib/Utils/ColorConvert.h b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/ColorConvert.h
index 5c7b125f8..f51ebc7f4 100644
--- a/Software/Visual_Studio/Native/Tango.ColorLib/Utils/ColorConvert.h
+++ b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/ColorConvert.h
@@ -75,7 +75,7 @@ class ColorConvert
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 *ToAbsoluteLab(double *LabIn, C_RGB_XYZ_Lab SourceWhite, C_RGB_XYZ_Lab DestWhite);
+ double *ChangeWP(double *LabIn, C_RGB_XYZ_Lab SourceWhite, C_RGB_XYZ_Lab DestWhite);
C_RGB_XYZ_Lab LabtoRGB(C_RGB_XYZ_Lab& LabVal);
double *RGBtoLab(double*RGB);
C_RGB_XYZ_Lab RGBtoLab(C_RGB_XYZ_Lab& RGB);
@@ -86,9 +86,13 @@ class ColorConvert
VectorXd XYZtoJab(VectorXd pColor, SURROUND sur);
VectorXd Jab_2_XYZ(VectorXd Jab, CAM02CS CS);
VectorXd LabToJab(VectorXd pColor, SURROUND sur);
+ double *LabToJab(double* pColor, SURROUND sur);
void InitCiecamParams(double Y_b, double L_A, SURROUND sur, CAM02CS CS);
void dEcmc(VectorXd refX, VectorXd samX, double &dE);
void SymmetricaldECMC(VectorXd refX, VectorXd samX, double &dECMC);
+ CAM02CS getCAM02CS() { return(m_CS); };
+ SURROUND getSurround() { return(m_sur); };
+
protected:
private:
@@ -107,10 +111,14 @@ class ColorConvert
C_RGB_XYZ_Lab m_ReferenceWhite; // Reference white
C_RGB_XYZ_Lab m_InvReferenceWhite; // 1.0 / Reference white
C_RGB_XYZ_Lab m_SourceWhite; // 1.0 / Reference white
+ CAM02CS m_CS;
+ SURROUND m_sur;
MatrixXd m_BradfordMatrix;
double GammaExpand_sRGB(double nonlinear);
double GammaCompress_sRGB(double linear);
void SetCIECamWhitePoint(C_RGB_XYZ_Lab ReferenceWhite);
+ void SetCAM02CS(CAM02CS CS) { m_CS = CS; };
+ void SetSurround(SURROUND sur) { m_sur = sur; };
};
diff --git a/Software/Visual_Studio/Native/Tango.ColorLib/Utils/ColorTransf.cpp b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/ColorTransf.cpp
index 63958cf2b..51d0dbd2d 100644
--- a/Software/Visual_Studio/Native/Tango.ColorLib/Utils/ColorTransf.cpp
+++ b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/ColorTransf.cpp
@@ -3,8 +3,11 @@
#endif
#include "ColorTransf.h"
+#include "C_RGB_XYZ_Lab.h"
#include <iostream>
#include <stdio.h>
+#include "NumConversions.h"
+
using namespace std;
#define LFactor 100
#define abFactor 255
@@ -37,94 +40,97 @@ using namespace std;
}
}
- void ColorTransf::InitData(unsigned char *colorTransformBuffer, long colorTransformFileSize)
+ void ColorTransf::InitData(unsigned char *colorTransformBuffer, long colorTransformSize)
{
- long lSize, lSizeHalf;
+ /* the whole file is now loaded in the memory buffer. */
+ /*Parse data*/
+ /*1st Element: Number of Separations In
+ 2nd Element: Number of Separations Out
+ 3rd Element: Number of gridpoints
+ 4th Element: Most Significant bits shift
+ 5th Element: Number of Gamut Regions N (number between 0 and 3)
+ */
+ //long lSize, lSizeHalf;
// obtain file size:
- lSize = colorTransformFileSize;
- lSizeHalf = lSize / 2;
+ int lSize = colorTransformSize;
+ //lSizeHalf = lSize / 2;
// allocate memory to contain the whole file:
unsigned char *buffer = colorTransformBuffer;
if (buffer == NULL)
{
throw std::exception("Memory Error, ColorTransf::InitData");
}
- //convert to usigned short
- unsigned short *tmpBuffer = new unsigned short[lSizeHalf];
- for (int i=0; i<lSizeHalf; ++i)
- tmpBuffer[i] = (buffer[2*i+1] << 8) | buffer[2*i];
+ NumConversions Conv;
+ int bytesread = 0;
+ int tmpB =Conv.ByteToInt(buffer, 0);
+ bytesread += 4;
+ char *tmpC;
+ int n = 0;
+ tmpC = Conv.getchar(tmpB, n);
+ char *luttype = new char[n+1];
+ strncpy_s(luttype, n+1,tmpC, n);
+ int TablePrecision;
+ if (strncmp(luttype, "prc1",n)==0)
+ TablePrecision = 1;
+ else if (strncmp(luttype, "prc2",n)==0)
+ TablePrecision = 2;
+ else
+ {
+ throw std::exception("Wrong precision in Color Tables");
+ return;
+ }
- /* the whole file is now loaded in the memory buffer. */
- /*Parse data*/
- /*1st Element: Number of Separations In
- 2nd Element: Number of Separations Out
- 3rd Element: Number of gridpoints
- 4th Element: Most Significant bits shift
- 5th Element: Number of Gamut Regions N (number between 0 and 3)
- 6th ELement: Gamut Region 1
- ...
- (5+N)th Element: Gamut Region N, N<=3
- */
- unsigned short tmp;
- tmp = tmpBuffer[0]; //does not need conversion
- SetSeparationsIn((int)tmp); //Numer of Separations In
- tmp = tmpBuffer[1]; //does not need conversion
- SetSeparationsOut((int)tmp); //Numer of Separations Out
- tmp = tmpBuffer[2]; //does not need conversion
- SetNGridpoints((int)tmp); //Number of Gridpoints
- tmp = tmpBuffer[3]; //does not need conversion
- unsigned short checkMSB = 256 >> (tmp);
- if (tmpBuffer[2] != (checkMSB + 1))
+ // Skip past reserved padding bytes
+ bytesread += 4;
+
+ uint8_t num_input_channels = buffer[ bytesread];
+ SetSeparationsIn((int)num_input_channels); //Numer of Separations In
+ bytesread += 1;
+ uint8_t num_output_channels = buffer[ bytesread];
+ SetSeparationsOut((int)num_output_channels); //Numer of Separations Out
+ bytesread += 1;
+ uint8_t num_clut_grid_points = buffer[ bytesread];
+ SetNGridpoints((int)num_clut_grid_points); //Number of Gridpoints
+ bytesread += 1;
+ uint8_t num_Sh4MSB = buffer[ bytesread];
+ bytesread += 1;
+ unsigned short checkMSB = 256 >> (num_Sh4MSB);
+ if (num_clut_grid_points != (checkMSB + 1))
{
throw std::exception("Wrong Number of MSB's, ColorTransf::InitData");
}
else
- SetMSBShift((int)tmp); //Number of MSB's
- unsigned short tmp1;
- tmp1 = tmpBuffer[4];
- if (tmp1 > 0)
- SetNGamutRegions((int)tmp1); //Number of Gamut Regions
+ SetMSBShift((int)num_Sh4MSB); //Number of MSB's
+ uint8_t GReg = buffer[ bytesread];
+ bytesread += 1;
+ if (GReg > 0)
+ SetNGamutRegions((int)GReg); //Number of Gamut Regions
else
{
throw std::exception("No Gamut Regions in table header, ColorTransf::InitData");
- }
- double *GamutLimitsNlperCM = new double[(int)m_NGamutRegions];
- for (int i = 0; i < (int)m_NGamutRegions; ++i)
- {
- tmp1 = tmpBuffer[5 + i];
- GamutLimitsNlperCM[i] = (double)tmp1;
- }
- SetGamutLimitsNlperCM(GamutLimitsNlperCM);
- /*Sanity check*/
- /*Check size parameters*/
- long tmpSize = (int)(pow((double)m_nGridPoints, (int)m_SeparationsIn))* m_SeparationsOut;
- int totHeader = 5 + m_NGamutRegions;
- if (tmpSize != lSizeHalf - totHeader)
- {
- throw std::exception("Wrong Parameters in header's table, ColorTransf::InitData");
}
+ int clut_size = (int)pow(double(num_clut_grid_points), num_input_channels);
+ // lut8Type and lut16Type
- int lsizeH4 = lSizeHalf - totHeader;
+ //convert to usigned short
+
+ int lsizeH4 =( lSize - bytesread + 1)/2;
+// int lsizeH4 = lSizeHalf - totHeader;
m_DataBuffer = new unsigned short[lsizeH4];
int lSizeperSep = lsizeH4 / m_SeparationsOut;
- int indReshape = 0;
+ int indR = 0;
for (int i = 0; i < lSizeperSep; ++i)
{
for (int j = 0; j < m_SeparationsOut; ++j)
{
- m_DataBuffer[indReshape] = tmpBuffer[j*lSizeperSep + i + totHeader];
- indReshape++;
+ m_DataBuffer[indR] = Conv.ByteToShort(buffer, bytesread);
+ bytesread += 2;
+ indR++;
}
}
// terminate reading data file
m_InterpColor.InitData(m_DataBuffer, m_SeparationsIn, m_SeparationsOut, m_nGridPoints, m_MSBShift);
- if (tmpBuffer != NULL)
- {
- delete[] tmpBuffer;
- tmpBuffer = NULL;
- }
-
return;
}
@@ -137,33 +143,34 @@ void ColorTransf::SetGamutLimitsNlperCM(double *GamutLimitsNlperCM)
void ColorTransf::evalLab2InkP(double *ColorIn, double *&ColorOut, int &GamutRegion)
{
- double *tmpColorOut = new double[m_SeparationsOut];
-
+ //double *tmpColorOut = new double[m_SeparationsOut];
+ C_RGB_XYZ_Lab tmpColorOut;
+ tmpColorOut = tmpColorOut.labdouble_to_labuint16(ColorIn);
/*Convert ColorIn to uint16 */
uint16_t *iColorIn = new uint16_t[m_SeparationsIn];
- iColorIn[0] = uint16_t(double(ColorIn[0] /LFactor)*Uint16Factor);
- iColorIn[1] = uint16_t(double((ColorIn[1] + abOffset) / abFactor)*Uint16Factor);
- iColorIn[2] = uint16_t(double((ColorIn[2] + abOffset) / abFactor)*Uint16Factor);
-
+ 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];
if (m_SeparationsIn == 3)
- m_InterpColor.ColorMap3(iColorIn, tmpColorOut);
+ m_InterpColor.ColorMap3(iColorIn, tmpColor);
else if (m_SeparationsIn == 4)
- m_InterpColor.ColorMap4(iColorIn, tmpColorOut);
+ m_InterpColor.ColorMap4(iColorIn, tmpColor);
else
throw std::exception("Unsupported Number of Separations in ColorTransf::evalLab2Ink");
//tmpColorOut between 0and 255
//normalize to [0-100]
for (int i = 0; i < m_SeparationsOut; ++i)
- ColorOut[i] = tmpColorOut[i] * InkFactor/ Uint16Factor;
+ ColorOut[i] = tmpColor[i] * InkFactor/ Uint16Factor;
GamutRegion = 0;
if(iColorIn !=NULL)
{
delete[] iColorIn;
iColorIn = NULL;
}
- if (tmpColorOut != NULL)
+ if (tmpColor != NULL)
{
- delete[] tmpColorOut;
+ delete[] tmpColor;
tmpColorOut = NULL;
}
@@ -185,9 +192,14 @@ void ColorTransf::evalInkP2Lab(double *ColorIn, double *&ColorOut, int &GamutReg
else
throw std::exception("Unsupported Number of Separations in ColorTransf::evalInkP2Lab");
//Normalize to Lab Space
- ColorOut[0] = (double)tmpColorOut[0] * LFactor / Uint16Factor;
- ColorOut[1] = ((double)tmpColorOut[1] * abFactor) / Uint16Factor - abOffset;
- ColorOut[2] = ((double)tmpColorOut[2] * abFactor) / Uint16Factor - abOffset;
+ 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);
+ ColorOut[0] = tmpLabOut.Get_x();
+ ColorOut[1] = tmpLabOut.Get_y();
+ ColorOut[2] = tmpLabOut.Get_z();
GamutRegion = 0;
if (iColorIn != NULL)
{
@@ -199,9 +211,15 @@ void ColorTransf::evalInkP2Lab(double *ColorIn, double *&ColorOut, int &GamutReg
delete[] tmpColorOut;
tmpColorOut = NULL;
}
+ if (UInt16ColorOut != NULL)
+ {
+ delete[] UInt16ColorOut;
+ UInt16ColorOut = NULL;
+ }
return;
}
+
/* __declspec(dllexport) int ColorTransf::evalCMY2RGB(double *ColorIn, double *ColorOut)
{
//Assumption: ColorIn is in the interval [0,100]
diff --git a/Software/Visual_Studio/Native/Tango.ColorLib/Utils/GBD.cpp b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/GBD.cpp
new file mode 100644
index 000000000..0a21d5f25
--- /dev/null
+++ b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/GBD.cpp
@@ -0,0 +1,311 @@
+#ifdef _MSC_VER
+#define _CRT_SECURE_NO_WARNINGS
+#endif
+
+#include "GBD.h"
+#include <iostream>
+#include <stdio.h>
+#include "NumConversions.h"
+#include "C_RGB_XYZ_Lab.h"
+
+using namespace std;
+
+#define eps 1.0e-05
+#define dE_Tol 2.0
+#define LargeNumber 1.0e+10
+
+typedef enum {
+ TwoSided,
+ OneSided
+}RTRI;
+
+typedef enum {
+ Line,
+ Ray,
+ Segment
+}LineType;
+
+GBD::GBD() :
+ m_prec(0), m_nPCSChan(0),
+ m_nDevChan(0), m_CenterLab(0), m_nVertices(0), m_Vertices(NULL)
+{
+
+}
+
+GBD::~GBD()
+{
+}
+
+void GBD::TriangleRayIntersection(double *origin, double *direction, bool intersect, double *xCoor)
+{
+ int i, j;
+
+ RTRI rtri = TwoSided;
+ LineType lt = Segment;
+ bool ok = false;
+ double border = eps;
+ double t = LargeNumber;
+ double u = t;
+ double v = t;
+ double *edge1 = new double[3];
+ double *edge2 = new double[3];
+ double *tvec = new double[3]; // vector from vert0 to ray origin
+ double *pvec = new double[3];
+ double *qvec = new double[3];
+ double det = 0;
+ bool angleOK = false;
+ for (i = 0; i < m_nTriangles; ++i)
+ {
+ for (j = 0; j < 3; ++j)
+ {
+ edge1[j] = m_vert1[i][j] - m_vert0[i][j];
+ edge2[j] = m_vert2[i][j] - m_vert0[i][j];
+ tvec[j] = origin[j] - m_vert0[i][j];
+ }
+ crossProduct(direction, edge2, pvec);
+ det = dotProduct(edge1, pvec);
+ switch (rtri)
+ {
+ case TwoSided:
+ if (std::abs(det) > eps)
+ angleOK = true;
+ break;
+ case OneSided:
+ if (det > eps)
+ angleOK = true;
+ break;
+ default:
+ throw std::exception("Wrong Parameterin Ray-TriageIntersetion");
+ }
+ if (std::abs(det) > eps)
+ {
+ u = dotProduct(tvec, pvec) / det;
+ crossProduct(tvec, edge1, qvec);
+ v = dotProduct(direction, qvec) / det;
+ t = dotProduct(edge2, qvec) / det;
+ ok = (angleOK && (u >= -eps) && (v >= -eps) && ((u + v) <= 1 + eps));
+ }
+ else
+ ok = false;
+
+ switch (lt)
+ {
+ case Line:
+ intersect = ok;
+ break;
+ case Ray:
+ intersect = ok && (t >= -eps);
+ break;
+ case Segment:
+ intersect = ok && (t >= -eps) && (t <= 1 + eps);
+ break;
+ default:
+ throw std::exception("Wrong Line Type");
+ break;
+ }
+ if (intersect)
+ {
+ for (j = 0; j < 3; ++j)
+ xCoor[j] = m_vert0[i][j] + edge1[j] * u + edge2[j] * v;
+ if (edge1 != NULL)
+ {
+ delete[]edge1;
+ edge1 = NULL;
+ }
+ if (edge2 != NULL)
+ {
+ delete[]edge2;
+ edge2 = NULL;
+ }
+ if (tvec != NULL)
+ {
+ delete[]tvec;
+ tvec = NULL;
+ }
+ if (qvec != NULL)
+ {
+ delete[]qvec;
+ qvec = NULL;
+ }
+ if (pvec != NULL)
+ {
+ delete[]pvec;
+ pvec = NULL;
+ }
+ return;
+ }
+ }
+ if (edge1 != NULL)
+ {
+ delete[]edge1;
+ edge1 = NULL;
+ }
+ if (edge2 != NULL)
+ {
+ delete[]edge2;
+ edge2 = NULL;
+ }
+ if (tvec != NULL)
+ {
+ delete[]tvec;
+ tvec = NULL;
+ }
+ if (qvec != NULL)
+ {
+ delete[]qvec;
+ qvec = NULL;
+ }
+ if (pvec != NULL)
+ {
+ delete[]pvec;
+ pvec = NULL;
+ }
+ return;
+}
+
+void GBD::InitData(unsigned char* colorTransformBuffer, long colorTransformFileSize)
+{
+ // 0-3 prec
+ //4-7 reserved, must be 0
+ // 8-9 number of vertices, uint16
+ // 10-11 number of triangles, uint16
+ // 12 number of PCS Channels, uint8
+ // 13 number of device channels (0, no device data)
+ // prec 2 (16bit)
+ // 14-n triangle vertices arranged as vert0 -> vert1->vert2
+ // each vert is a matrix of size (number of vertices)x3
+ // Gamut is stored in Ciecam02 color space
+ // prec 1
+ // 14-n CLUT values, uint8
+
+ if (colorTransformFileSize < 32)
+ {
+ throw std::exception("Init GB, invalid size");
+ }
+
+ // Check for signature
+ unsigned char *buffer = colorTransformBuffer;
+ if (buffer == NULL)
+ {
+ throw std::exception("Memory Error, ColorTransf::InitData");
+ }
+
+ int i, j;
+ NumConversions Conv;
+ int bytesread = 0;
+ int tmpB = Conv.ByteToInt(buffer, 0);
+ bytesread += 4;
+ char *tmpC;
+ int n = 0;
+ tmpC = Conv.getchar(tmpB, n);
+ char *tableType = new char[n + 1];
+ strncpy_s(tableType, n + 1, tmpC, n);
+ int TablePrecision;
+ if (strncmp(tableType, "prc1", n) == 0)
+ TablePrecision = 1;
+ else if (strncmp(tableType, "prc2", n) == 0)
+ TablePrecision = 2;
+ else
+ {
+ throw std::exception("Wrong precision in gbd tables");
+ return;
+ }
+ // Skip past reserved padding bytes
+ bytesread += 4;
+ uint16_t num_gbd_points = Conv.ByteToShort(buffer, bytesread);
+ bytesread += 2;
+ SetNVertices((int)num_gbd_points);
+ uint16_t num_triangles = Conv.ByteToShort(buffer, bytesread);
+ bytesread += 2;
+ SetNTriangles((int)num_triangles);
+ uint8_t num_PCSChan = buffer[bytesread];
+ bytesread += 1;
+ SetNPCS_Channels((int)num_PCSChan);
+ bytesread += 1;
+ uint8_t num_DevChan = buffer[bytesread];
+ SetNDev_Channels((int)num_DevChan);
+ uint16_t ILab[3];
+ for (j = 0; j < 3; ++j)
+ {
+ ILab[j] = (uint16_t)Conv.ByteToInt(buffer, bytesread);
+ bytesread += 4;
+ }
+ C_RGB_XYZ_Lab tmpCenter;
+ m_CenterLab = tmpCenter.labuint16_to_labdouble(ILab);
+
+ // lut8Type and lut16Type
+ int remsize = colorTransformFileSize - bytesread;
+ int Bsize = (int)((int)(num_gbd_points) * (int)num_PCSChan);
+ if (remsize != Bsize * (int)TablePrecision)
+ {
+ throw std::exception("GBD size missmatch");
+ return;
+ }
+ m_vert0 = new double*[m_nTriangles];
+ m_vert1 = new double*[m_nTriangles];
+ m_vert2 = 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];
+ for (j = 0; j < m_nPCSChan; ++j)
+ {
+ tmp[j] = Conv.ByteToShort(buffer, bytesread);
+ bytesread += 2;
+ }
+ tmp1 = tmp1.labuint16_to_labdouble(tmp);
+ m_vert0[i][0] = tmp1.Get_x();
+ m_vert0[i][1] = tmp1.Get_y();
+ m_vert0[i][2] = tmp1.Get_z();
+ }
+ for (i = 0; i < m_nTriangles; ++i)
+ {
+ m_vert1[i] = new double[m_nPCSChan];
+ for (j = 0; j < m_nPCSChan; ++j)
+ {
+ tmp[j] = Conv.ByteToShort(buffer, bytesread);
+ bytesread += 2;
+ }
+ tmp1 = tmp1.labuint16_to_labdouble(tmp);
+ m_vert1[i][0] = tmp1.Get_x();
+ m_vert1[i][1] = tmp1.Get_y();
+ m_vert1[i][2] = tmp1.Get_z();
+ }
+ for (i = 0; i < m_nTriangles; ++i)
+ {
+ m_vert2[i] = new double[m_nPCSChan];
+ for (j = 0; j < m_nPCSChan; ++j)
+ {
+ tmp[j] = Conv.ByteToShort(buffer, bytesread);
+ bytesread += 2;
+ }
+ tmp1 = tmp1.labuint16_to_labdouble(tmp);
+ m_vert2[i][0] = tmp1.Get_x();
+ m_vert2[i][1] = tmp1.Get_y();
+ m_vert2[i][2] = tmp1.Get_z();
+ }
+}
+
+
+// dot product of two vectors.
+double GBD::dotProduct(double *vect_A, double*vect_B)
+{
+ int product = 0;
+ // Loop for calculate dot product
+ int n = sizeof(vect_A);
+ for (int i = 0; i < n; i++)
+ product = product + vect_A[i] * vect_B[i];
+ return (product);
+}
+
+
+// cross product of two vectors
+void GBD::crossProduct(double *vect_A, double* vect_B,double *cross_P)
+{
+ cross_P[0] = vect_A[1] * vect_B[2] - vect_A[2] * vect_B[1];
+ cross_P[1] = vect_A[0] * vect_B[2] - vect_A[2] * vect_B[0];
+ cross_P[2] = vect_A[0] * vect_B[1] - vect_A[1] * vect_B[0];
+ return;
+}
+
diff --git a/Software/Visual_Studio/Native/Tango.ColorLib/Utils/GBD.h b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/GBD.h
new file mode 100644
index 000000000..6ef4d3a51
--- /dev/null
+++ b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/GBD.h
@@ -0,0 +1,38 @@
+#ifndef _GBD_H_
+#define _GBD_H_
+
+#include <stdlib.h>
+#include "C_RGB_XYZ_Lab.h"
+
+class GBD {
+public:
+ GBD();
+ ~GBD();
+ int GetNVertices() { return(m_nVertices); };
+ int GetNPCS_Channels() { return(m_nPCSChan); };
+ int GetDev_Channels() { return(m_nDevChan); };
+ int GetNTriangles() { return(m_nTriangles); };
+ C_RGB_XYZ_Lab getCenter(){ return(m_CenterLab);};
+ void InitData(unsigned char* colorTransformBuffer, long colorTransformFileSize);
+ void TriangleRayIntersection(double *origin, double *direction, bool intersect, double *xCoor);
+private:
+ int m_prec;
+ int m_nDevChan;
+ int m_nPCSChan;
+ int m_nVertices;
+ int m_nTriangles;
+ C_RGB_XYZ_Lab m_CenterLab;
+ C_RGB_XYZ_Lab *m_Vertices;
+ double **m_vert0;
+ double **m_vert1;
+ double **m_vert2;
+ void SetNVertices(int nVertices) { m_nVertices = nVertices; };
+ void SetNPCS_Channels(int nPCSChan) { m_nPCSChan = nPCSChan; };
+ void SetNDev_Channels(int nDevChan) { m_nDevChan = nDevChan; };
+ void SetNTriangles(int nTriangles) { m_nTriangles = nTriangles; };
+ //void SetCenter( C_RGB_XYZ_Lab CenterLab);
+ double dotProduct(double *vect_A, double*vect_B);
+ void crossProduct(double *vect_A, double* vect_B, double *cross_P);
+};
+
+#endif
diff --git a/Software/Visual_Studio/Native/Tango.ColorLib/Utils/Interp.h b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/Interp.h
index 6c1128b8a..cf733d45e 100644
--- a/Software/Visual_Studio/Native/Tango.ColorLib/Utils/Interp.h
+++ b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/Interp.h
@@ -15,6 +15,6 @@ class Interp
int m_length;
};
-#endif // __CALIBDATA_H__
+#endif // __INTERP_H__
diff --git a/Software/Visual_Studio/Native/Tango.ColorLib/Utils/NumConversions.cpp b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/NumConversions.cpp
new file mode 100644
index 000000000..2ec57149e
--- /dev/null
+++ b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/NumConversions.cpp
@@ -0,0 +1,46 @@
+#include "NumConversions.h"
+#include <cmath>
+#include <cstdlib>
+#include <cstdint>
+#include <iostream>
+#include <stdio.h>
+
+NumConversions::NumConversions(void)
+{
+}
+
+NumConversions::NumConversions(const NumConversions &rhs)
+{
+}
+
+int NumConversions::ByteToInt(uint8_t *byteN, int start)
+{
+int res;
+res = (int)((unsigned int)byteN[start] << 24 |
+ (unsigned int)byteN[start + 1] << 16 |
+ (unsigned int)byteN[start + 2] << 8 |
+ (unsigned int)byteN[start + 3]);
+ return(res);
+}
+
+uint16_t NumConversions::ByteToShort(uint8_t *byteN, int start)
+{
+uint16_t res;
+res = (uint16_t)((unsigned short)byteN[start] << 8 |
+ (unsigned short)byteN[start + 1]) ;
+ return(res);
+}
+
+char* NumConversions::getchar(uint32_t num,int &nlen)
+{
+ char *getChar;
+ getChar = (char*)&num;
+ nlen = sizeof(getChar);
+ //reverse order
+ char *tmp = new char[nlen];
+ for (int i = 0; i < nlen; ++i)
+ {
+ tmp[i] = getChar[nlen - 1 - i];
+ }
+ return(tmp);
+}
diff --git a/Software/Visual_Studio/Native/Tango.ColorLib/Utils/NumConversions.h b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/NumConversions.h
new file mode 100644
index 000000000..b5e9d28e5
--- /dev/null
+++ b/Software/Visual_Studio/Native/Tango.ColorLib/Utils/NumConversions.h
@@ -0,0 +1,16 @@
+#ifndef __NUMCONVER_H__
+#define __NUMCONVER_H__
+#include <stdlib.h>
+#include <stdint.h>
+
+class NumConversions
+{
+ public:
+ NumConversions(void);
+ NumConversions(const NumConversions &rhs);
+ int ByteToInt(uint8_t *byteN, int Start);
+ uint16_t ByteToShort(uint8_t *byteN, int Start);
+ char* getchar(uint32_t num, int &nlen);
+ private:
+};
+#endif //__NUMCONVERSIONS_H__ \ No newline at end of file
diff --git a/Software/Visual_Studio/Native/Tester/Tester.cpp b/Software/Visual_Studio/Native/Tester/Tester.cpp
index 2b1659463..584e40e4b 100644
--- a/Software/Visual_Studio/Native/Tester/Tester.cpp
+++ b/Software/Visual_Studio/Native/Tester/Tester.cpp
@@ -22,16 +22,16 @@ size_t InitData(uint8_t *&input_buffer, long &buffersize, char *ForwardName, cha
ConversionInput *conversionInput = (ConversionInput*)malloc(sizeof(ConversionInput));
conversion_input__init(conversionInput);//CONVERSION_INPUT__INIT;
//fill conversionInput
- conversionInput->colorspace = COLOR_SPACE__Volume;
+ conversionInput->colorspace = COLOR_SPACE__RGB;
conversionInput->has_colorspace = true;
conversionInput->has_forwarddata = true;
conversionInput->has_inversedata = true;
conversionInput->has_threadl = true;
conversionInput->has_threada = true;
conversionInput->has_threadb = true;
- conversionInput->threadl = 92.1815;
- conversionInput->threada = 2.2555;;
- conversionInput->threadb = -10.9325;
+ conversionInput->threadl = 90.5055;
+ conversionInput->threada = 2.8998;;
+ conversionInput->threadb = -11.4028;
conversionInput->segmentlength = 10;
uint8_t *buffer = NULL;
long lsize;
@@ -254,7 +254,8 @@ size_t ReadCalData(char *name, double **&CalData, long &nCalData)
int main()
{
char *ForwardName = new char[256];
- strcpy_s(ForwardName, 256, "..\\..\\..\\ColorData\\CCT\\A2B_Lin.cct");
+ strcpy_s(ForwardName, 256, "..\\..\\..\\ColorData\\CCT\\test.cct");
+
char *InverseName = new char[256];
strcpy_s(InverseName, 256, "..\\..\\..\\ColorData\\CCT\\B2A_Lin.cct");
diff --git a/Software/Visual_Studio/Native/Tester/Tester.vcxproj b/Software/Visual_Studio/Native/Tester/Tester.vcxproj
index 5b967f733..5cbed97c2 100644
--- a/Software/Visual_Studio/Native/Tester/Tester.vcxproj
+++ b/Software/Visual_Studio/Native/Tester/Tester.vcxproj
@@ -131,6 +131,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\Tango.ColorLib\EigenDir;..\Tango.ColorLib\EigenDir\Eigen;$(ProjectDir)protobuf-c;$(ProjectDir)PMR\ColorLab;..\Tango.ColorLib\Utils;..\Tango.ColorLib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>