diff options
5 files changed, 771 insertions, 371 deletions
diff --git a/Software/Embedded_SW/Embedded/DataDef.h b/Software/Embedded_SW/Embedded/DataDef.h index 348ed37f6..001303c88 100644 --- a/Software/Embedded_SW/Embedded/DataDef.h +++ b/Software/Embedded_SW/Embedded/DataDef.h @@ -20,7 +20,7 @@ #define NO_INITIAL_HEATING #define MAX_STRING_LEN 255 //Embedded version + filter.c -//#define WATCHDOG +#define WATCHDOG //#define DISPESER_TEST //#define FPGA_WATCHDOG_DISABLE diff --git a/Software/Embedded_SW/Embedded/Drivers/Uart_Comm/BTSR/BTSR.c b/Software/Embedded_SW/Embedded/Drivers/Uart_Comm/BTSR/BTSR.c index 12699a1fd..92337080d 100644 --- a/Software/Embedded_SW/Embedded/Drivers/Uart_Comm/BTSR/BTSR.c +++ b/Software/Embedded_SW/Embedded/Drivers/Uart_Comm/BTSR/BTSR.c @@ -77,7 +77,7 @@ void U4RX() void uart4_intHandler() { - static uint8_t nop = 0; + //static uint8_t nop = 0; //Get interrupt flags unsigned long status = UARTIntStatus(UART4_BASE, 1); @@ -626,5 +626,168 @@ uint8_t BTSR_Read_Status(uint8_t BTSR_Id, uint8_t Application, uint8_t Yarn_Type return ERROR; } +//---------------------------------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------------------------------- +//BTSR_ALARM_AND_ENABLING_STATUS_READ +typedef struct +{ + bool D0 : 1;//0 + bool D1 : 1;//1 + bool D2 : 1;//2 + bool D3 : 1;//3 + bool D4 : 1;//4 + bool D5 : 1;//5 + bool D6 : 1;//6 + bool D7 : 1;//7 +}BITS; + + +typedef union +{ + BITS Bit[4]; + uint8_t Byte[4]; +}BTSR_ALARM_AND_ENABLING_STATUS_READ; + +BTSR_ALARM_AND_ENABLING_STATUS_READ BTSR_Status; + +void BTSR_Configuration_Set(uint8_t UFeeder_ID) +{ + memset(BTSR_TX_Buff, 0, Max_BTSR_TX_Bytes); + + BTSR_TX_Buff[0] = UFeeder_ID; + BTSR_TX_Buff[1] = 0x36; + BTSR_TX_Buff[2] = 0x80;//CCW + BTSR_TX_Buff[3] = 0x01;//YYT OFF, UNICO OFF + BTSR_TX_Buff[4] = 0x40;//FLIP DISPLAY + + BTSR_Calculate_CheckSum(BTSR_TX_Buff,18); + + BTSR_Send_Buf(Typology_Set.Buf, 20); + +} + +void BTSR_Alarm_and_Enabling_Status_Read(uint8_t UFeeder_ID) +{ + memset(BTSR_TX_Buff, 0, Max_BTSR_TX_Bytes); + + BTSR_TX_Buff[0] = UFeeder_ID; + BTSR_TX_Buff[1] = 0x1C; + + BTSR_Calculate_CheckSum(BTSR_TX_Buff,2); + + BTSR_Send_Buf(Typology_Set.Buf, 4); +} + +typedef enum +{ + //BTSR_READ + DEVICE_INFORMATION_READ_10 , + ADVANCED_PROGRAMMING_READ_18 , + ADVANCED_TENSION_READ_23 , + APPLICATION_AND_YARN_TYPOLOGY_READ_28 , + ALARM_AND_ENABLING_STATUS_READ_30 , + PC_LINK_READ_32 , + METERS_TOTAL_COUNTER_READ_LOW_37 , + METERS_TOTAL_COUNTER_READ_HIGH_39 , + METER_TOTAL_COUNTER_READ_HIGHEST_41 , + MAX_BTSR_READ , + + //BTSR_SET + //return 0xFA/0xFB/0xF9 + DEVICE_CALIBRATION_11 , + BAUDRATE_SET_13 , + DISPLAY_LANGUAGE_SET_14 , + CONFIGURATION_SET_15 , + ADVANCED_CONFIGURATION_SET_17 , + INPUT_CURRENT_CONTROL_SET_20 , + ADVANCED_TENSION_PROGRAMMING_21 , + ADVANCED_STYLE_LOAD_25 , + APPLICATION_AND_YARN_TYPOLOGY_SET_27 , + WORK_TENSION_AND_OPERATION_STATUS_SET_29 , + ALARM_STATUS_RESET_35 , + RESETS_ALL_THE_COUNTERS_36 , + //return device + Function code + METERS_TOTAL_COUNTER_RESET_LOW_38 , + METERS_TOTAL_COUNTER_RESET_HIGH_40 , + METERS_TOTAL_COUNTER_RESET_HIGHEST_42 , + MAX_BTSR_SET +}BTSR_CMD; + +#define Get_Set_resp 5 +#define Set_Command 6 + +#define Get_Read_resp 7 +#define Read_Command 8 + +BTSR_CMD BTSR_command_Stage[MAX_BTSR_SET]; + +uint8_t BTSR_State_Machine(uint8_t UFeeder_ID) +{ + uint8_t status = OK; + uint8_t i; + + for(i = DEVICE_CALIBRATION_11; i < MAX_BTSR_SET; i++) + { + if(BTSR_command_Stage[i] == Get_Set_resp) + { + if((i >= DEVICE_CALIBRATION_11) && (i <= RESETS_ALL_THE_COUNTERS_36) /*&& (BTSR_RX_Buff[0] != BTSR_RISP_OK)*/) + { + status = ERROR; + BTSR_command_Stage[i] = BTSR_RX_Buff[0]; + //print response + command ID + } + else if(((i == METERS_TOTAL_COUNTER_RESET_LOW_38) && (BTSR_RX_Buff[1] != 0x06)) || + ((i == METERS_TOTAL_COUNTER_RESET_HIGH_40) && (BTSR_RX_Buff[1] != 0x1E)) || + ((i == METERS_TOTAL_COUNTER_RESET_HIGHEST_42) && (BTSR_RX_Buff[1] != 0x48)) ) + { + status = ERROR; + BTSR_command_Stage[i] = BTSR_RX_Buff[1]; + //print response + command ID + } + //print response + command ID + BTSR_command_Stage[i] = OK; + } + + if(BTSR_command_Stage[i] == Set_Command) + { + if(i == CONFIGURATION_SET_15) + { + BTSR_Configuration_Set(UFeeder_ID); + } + + BTSR_command_Stage[i] = Get_Set_resp; + return status;//Only one command in cycle + } + } + + + for(i = DEVICE_INFORMATION_READ_10; i < MAX_BTSR_READ; i++) + { + if(BTSR_command_Stage[i] == Get_Read_resp) + { + // Add CRC check + if(i == ALARM_AND_ENABLING_STATUS_READ_30) + { + for(i = 0; i < 4; i++) + BTSR_Status.Byte[i] = BTSR_RX_Buff[i]; + } + BTSR_command_Stage[i] = 0; + } + + if(BTSR_command_Stage[i] == Read_Command) + { + + if(i == ALARM_AND_ENABLING_STATUS_READ_30) + { + BTSR_Alarm_and_Enabling_Status_Read(UFeeder_ID); + } + BTSR_command_Stage[i] = Get_Read_resp; + return status;//Only one command in cycle + } + } + + return status; +} diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/ColorConverter.cpp b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/ColorConverter.cpp index 96d5108f2..a4f45ae19 100644 --- a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/ColorConverter.cpp +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/ColorConverter.cpp @@ -58,6 +58,8 @@ #define LowVolumeThreshold 0.5 #define LowVolHalf LowVolumeThreshold/2 #define GradientEndThr 0.95 +#define DilutionFactor 10 +#define LightInksThr 5 Tango::ColorLib::ColorConverter::ColorConverter() : @@ -65,8 +67,8 @@ Tango::ColorLib::ColorConverter::ColorConverter() : m_maxNlPerCM(NULL), m_nInks(0), m_nVolumes(0), m_GradStops(NULL), m_nGradStops(0), m_colortable(NULL), m_ProcessRangesMaxP(NULL), - m_nProcessRanges(0), m_NormGamutRegionMaxLim(NULL), m_LowVolThr_nlcm(NULL), - m_LowVolThrHalf_nlcm(NULL) + m_ProcessRangesMinP(NULL), m_nProcessRanges(0), m_NormGamutRegionMaxLim(NULL), + m_LowVolThr_nlcm(NULL), m_LowVolThrHalf_nlcm(NULL), m_hasLightInks(false), m_InkNames(NULL) { m_whitepointLab.Set(-1, -1, -1); m_whitepointXYZ_Strip.Set(-1, -1, -1); @@ -105,6 +107,11 @@ Tango::ColorLib::ColorConverter::~ColorConverter() delete[] m_ProcessRangesMaxP; m_ProcessRangesMaxP = NULL; } + if (m_ProcessRangesMinP != NULL) + { + delete[] m_ProcessRangesMinP; + m_ProcessRangesMaxP = NULL; + } if (m_LowVolThr_nlcm != NULL) { delete[]m_LowVolThr_nlcm; @@ -116,6 +123,11 @@ Tango::ColorLib::ColorConverter::~ColorConverter() delete[]m_LowVolThrHalf_nlcm; m_LowVolThrHalf_nlcm = NULL; } + if (m_InkNames != NULL) + { + delete[] m_InkNames; + m_InkNames = NULL; + } /* if (m_ProcessRangesMinP != NULL) { delete[] m_ProcessRangesMinP; @@ -203,7 +215,7 @@ void Tango::ColorLib::ColorConverter::ProcessHiveNeighbors(ConversionInput *conv } MatrixXd RGBTmpVec(nHive + 1, 3); - MatrixXd VolumeHive(nHive + 1, m_nVolumes); + MatrixXd VolumeHive(nHive + 1, m_TotalNumberofInks); MatrixXd LabHive(nHive + 1, 3); VectorXd xyz(3); C_RGB_XYZ_Lab xyzVal, LabVal; @@ -215,7 +227,7 @@ void Tango::ColorLib::ColorConverter::ProcessHiveNeighbors(ConversionInput *conv //int *GamutRegion = DBG_NEW int[nHive + 1]; double *Lab1P = new double[3]; //double *Lab1P = DBG_NEW double[3]; - VectorXd Vol(m_nVolumes); + VectorXd Vol(m_nInks); int j = 0; double * LabInFinal1 = new double[3]; //double * LabInFinal1 = DBG_NEW double[3]; @@ -223,11 +235,11 @@ void Tango::ColorLib::ColorConverter::ProcessHiveNeighbors(ConversionInput *conv double * LabOnGamut = new double[3]; double *InkOutP = new double[m_nInks]; bool InGamut = true; - for (int i = 0; i < nHive; ++i) + for (int iHive = 0; iHive < nHive; ++iHive) { //Get Lab's inGamut for (j = 0; j < 3; ++j) - Lab1P[j] = Lab1(i, j); + Lab1P[j] = Lab1(iHive, j); //Check if whitepoints match /* if (m_AdaptWP) { @@ -238,23 +250,32 @@ void Tango::ColorLib::ColorConverter::ProcessHiveNeighbors(ConversionInput *conv */ // ColConv.ChangeWP(Lab1P, Lab1P, m_WP, m_whitepointXYZ_CT); //to Relative ColConv.ChangeWP(Lab1P, Lab1P, m_WP, m_whitepointXYZ_Strip); //to Relative - m_colortable->m_B2ATransform->evalLab2InkP(Lab1P, InkOut, GamutRegion[i]); //InkOut is in units of 16 bits - for (int i = 0; i <m_nInks; ++i) + m_colortable->m_B2ATransform->evalLab2InkP(Lab1P, InkOut, GamutRegion[iHive]); //InkOut is in units of 16 bits + for (int iInk = 0; iInk <m_nInks; ++iInk) { - InkOut[i] *= m_colortable->GetNormFactor(); - if (InkOut[i] <= m_NormGamutRegionMaxLim[0]) + InkOut[iInk] *= m_colortable->GetNormFactor(); + if (InkOut[iInk] <= m_NormGamutRegionMaxLim[0]) { - m_colortable->m_LinCurves->m_InterpCurves[i].Eval(InkOut[i] * 655.35, InkOut[i]); - InkOut[i] /= 655.35; + m_colortable->m_LinCurves->m_InterpCurves[iInk].Eval(InkOut[iInk] * 655.35, InkOut[iInk]); + InkOut[iInk] /= 655.35; } } InGamut = IsInGamut(Lab1P, sur, CS, LabOnGamut); LimitLab(LabOnGamut); VectorXd NLInkOut(m_nInks); ConvertToNLInks(DoubleToVector(InkOut, m_nInks), NLInkOut); - - LimitNLInks2Volume(NLInkOut, GamutRegion[i], Vol); - + LimitNLInks2Volume(NLInkOut, GamutRegion[iHive], Vol); + ///////////////////////////////////// + VectorXd VolumeLI(m_TotalNumberofInks); + if (m_hasLightInks) + { + SplitVolume(Vol, VolumeLI, GamutRegion[iHive]); + } + else + { + for (int iVol = 0; iVol < m_TotalNumberofInks; ++iVol) + VolumeLI(iVol) = Vol(iVol); + } //m_A2BTransform->evalInkP2Lab(InkOut, Lab1P, GamutRegion[i]); //Convert to CT WP @@ -271,29 +292,36 @@ void Tango::ColorLib::ColorConverter::ProcessHiveNeighbors(ConversionInput *conv }*/ m_Conv02->SetReferenceWhite(D65); for (int j = 0; j < 3; ++j) - LabHive(i, j) = LabInFinal1[j]; + LabHive(iHive, j) = LabInFinal1[j]; //Convert to RGB, relative col is converted m_Conv02->LabtoRGB(LabOnGamut, 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); + RGBTmpVec(iHive, j) = std::min(std::max(tmpRGB[j], 0.0), 255.0); - //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 j = 0; j < m_TotalNumberofInks; ++j) + VolumeHive(iHive, j) = VolumeLI(j); } - for (int i = 0; i < 1; ++i) + + VectorXd VolumeLI_s(m_TotalNumberofInks); + if (m_hasLightInks) { - 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); - LabHive(nHive + i, j) = Lab(j); - } - GamutRegion[nHive + i] = InGamutRegion; + SplitVolume(Volume, VolumeLI_s, InGamutRegion); + } + else + { + for (int iVol = 0; iVol < m_TotalNumberofInks; ++iVol) + VolumeLI_s(iVol) = Volume(iVol); + } + for (j = 0; j < m_TotalNumberofInks; ++j) + VolumeHive(nHive , j) = VolumeLI_s(j); + for (j = 0; j < 3; ++j) + { + RGBTmpVec(nHive , j) = RGB(j); + LabHive(nHive , j) = Lab(j); } + GamutRegion[nHive ] = InGamutRegion; //Organize hive into 5x5 matrix //Hive Vector follows the ordering 0-(0,0) 1-(0,1) 2-(0,2),...., @@ -437,7 +465,7 @@ void Tango::ColorLib::ColorConverter::ArrangeHiveData(MatrixXd LabHive, MatrixX for (j = 0; j < 3; ++j) RGBHive(index, j) = RGBTmpVec(i, j); - for (j = 0; j < m_nVolumes; ++j) + for (j = 0; j < m_TotalNumberofInks; ++j) OVolumeHive(index, j) = VolumeHive(i, j); OGamutRegion[index] = GamutRegion[i]; @@ -448,22 +476,25 @@ void Tango::ColorLib::ColorConverter::ArrangeHiveData(MatrixXd LabHive, MatrixX void Tango::ColorLib::ColorConverter::fillVolume(OutputCoordinates *&outputCoords, VectorXd Volume) { int i = 0; - OutputLiquid** outputLiquids = (OutputLiquid**)malloc(sizeof(OutputLiquid*) * m_nVolumes); - for (i = 0; i < m_nVolumes; ++i) + OutputLiquid** outputLiquids = (OutputLiquid**)malloc(sizeof(OutputLiquid*) * m_TotalNumberofInks); + for (i = 0; i < m_TotalNumberofInks; ++i) { // *outputLiquids[0] = OUTPUT_LIQUID__INIT; outputLiquids[i] = (OutputLiquid*)malloc(sizeof(OutputLiquid)); output_liquid__init(outputLiquids[i]); - switch (m_CalibCurves[i].getInkName()) + switch (m_InkNames[i]) { case LIQUID_TYPE__Cyan: case LIQUID_TYPE__Magenta: case LIQUID_TYPE__Yellow: case LIQUID_TYPE__Black: + case LIQUID_TYPE__LightCyan: + case LIQUID_TYPE__LightMagenta: + case LIQUID_TYPE__LightYellow: { outputLiquids[i]->has_volume = true; outputLiquids[i]->has_liquidtype = true; - outputLiquids[i]->liquidtype = (LiquidType)(m_CalibCurves[i].getInkName()); + outputLiquids[i]->liquidtype = (LiquidType)(m_InkNames[i]); outputLiquids[i]->volume = Volume(i); break; } @@ -472,7 +503,7 @@ void Tango::ColorLib::ColorConverter::fillVolume(OutputCoordinates *&outputCoor } } outputCoords->outputliquids = outputLiquids; - outputCoords->n_outputliquids = m_nVolumes; + outputCoords->n_outputliquids = m_TotalNumberofInks; return; } @@ -1053,7 +1084,7 @@ void Tango::ColorLib::ColorConverter::ConvertColorToLinearInks(InputCoordinates* void Tango::ColorLib::ColorConverter::ConvertToNLInks(VectorXd InkIn, VectorXd &InkOut) { - for (int i = 0; i < m_nVolumes; ++i) + for (int i = 0; i < m_nInks; ++i) { if (InkIn(i) <= m_NormGamutRegionMaxLim[0]) m_CalibCurves[i].m_InvLinearInterp->Eval(InkIn(i), InkOut(i)); @@ -1065,7 +1096,7 @@ void Tango::ColorLib::ColorConverter::ConvertToNLInks(VectorXd InkIn, VectorXd void Tango::ColorLib::ColorConverter::ConvertToLinearInks(VectorXd InkIn, VectorXd &InkOut) { - for (int i = 0; i < m_nVolumes; ++i) + for (int i = 0; i < m_nInks; ++i) { m_CalibCurves[i].m_LinearInterp->Eval(InkIn(i), InkOut(i)); } @@ -1076,13 +1107,34 @@ void Tango::ColorLib::ColorConverter::ConvertToLinearInks(VectorXd InkIn, Vecto void Tango::ColorLib::ColorConverter::VolumeToNLInkP(VectorXd Volume, VectorXd &NLInkP) { //Volume is in %. In order to be compatible with NL to volume it has to be tranlated to nl/cm - VectorXd InkP(m_nVolumes); + VectorXd InkP(m_TotalNumberofInks); int MaxInd = -1; double InkMax = -1.; double InkSum = 0.; - for (int i = 0; i < m_nVolumes; ++i) + //Convert volume to Volume without Light Inks + VectorXd VolumeNoLI((int)(m_nInks)); + if (m_hasLightInks) { - InkP(i) = Volume(i)* m_maxNlPerCM(i)/100; //Volume is in %, InkP is in [nl/cm] + //Convert Light Ink Volumes to Ink Volumes + for (int i = 0; i < m_nInks; ++i) + VolumeNoLI(i) = Volume(i); + + for (int i = 4; i < m_nVolumes; ++i) + { + if ((Volume(i) > 0) & (Volume(i - 4) == 0)) + { + VolumeNoLI(i - 4) = Volume(i) / DilutionFactor; + } + } + } + else + { + for (int i = 0; i < m_nInks; ++i) + VolumeNoLI(i) = Volume(i); + } + for (int i = 0; i < m_nInks; ++i) + { + InkP(i) = VolumeNoLI(i)* m_maxNlPerCM(i)/100; //Volume is in %, InkP is in [nl/cm] if (InkMax < InkP(i)) { InkMax = InkP(i); @@ -1208,19 +1260,19 @@ void Tango::ColorLib::ColorConverter::SetMaxNLperCM(double maxNlPerCM, int i) m_maxNlPerCM(i) = maxNlPerCM; } -void Tango::ColorLib::ColorConverter::ConvertVolumeToRGBDisplay(InputCoordinates *inputcoordinates, int n_processRanges, - int colorspace, VectorXd &Volume, VectorXd &RGBOut, VectorXd &LabOut, int &GamutRegion) +void Tango::ColorLib::ColorConverter::ConvertVolumeToRGBDisplay(InputCoordinates *inputcoordinates, int n_processRanges, + int colorspace, VectorXd &VolumeNoLI, VectorXd &RGBOut, VectorXd &LabOut, int &GamutRegion) { - SetNumberOfVolumes((int)(inputcoordinates->n_inputliquids)); + //SetNumberOfVolumes((int)(inputcoordinates->n_inputliquids)); // Set Calibration Data LiquidType LQ; if (m_CalibCurves == NULL) { m_CalibCurves = new CalibData[m_nInks]; //m_CalibCurves = DBG_NEW CalibData[m_nInks]; - for (int i = 0; i < m_nVolumes; ++i) + for (int i = 0; i < m_nInks; ++i) { - LQ =inputcoordinates->inputliquids[i]->calibrationdata->liquidtype; + LQ = 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. @@ -1237,16 +1289,37 @@ void Tango::ColorLib::ColorConverter::ConvertVolumeToRGBDisplay(InputCoordinates //July 29 2020 //Limit inks based on m_maxNlpercm //Inks are limited in their nonlinear form - VectorXd NLInkP((int)(m_nVolumes)); - VectorXd InkOut((int)(m_nVolumes)); + VectorXd NLInkP((int)(m_nInks)); + VectorXd InkOut((int)(m_nInks)); + VectorXd Volume((int)(m_TotalNumberofInks)); + //Convert to Nonlinear Inks double SumVol_Ink = 0.0; //Get Gamut Region - for (int i = 0; i < m_nVolumes; ++i) - Volume(i) = inputcoordinates->inputliquids[i]->volume; //volume is given in % + for (int i = 0; i < m_TotalNumberofInks; ++i) + Volume(i) = inputcoordinates->inputliquids[i]->volume; - GamutRegion = GetGamutRegion(Volume, m_NormGamutRegionMaxLim); - VolumeToNLInkP(Volume, NLInkP); + if (m_hasLightInks) + { + //Convert Light Ink Volumes to Ink Volumes + for (int i = 0; i < m_nInks; ++i) + VolumeNoLI(i) = Volume(i); + + for (int i = 4; i < m_TotalNumberofInks; ++i) + { + if ((Volume(i) > 0) & (Volume(i - 4) == 0)) + { + VolumeNoLI(i - 4) = inputcoordinates->inputliquids[i]->volume / DilutionFactor; + } + } + } + else + { + for (int i = 0; i < m_nInks; ++i) + VolumeNoLI(i) = Volume(i); + } + GamutRegion = GetGamutRegion(VolumeNoLI, m_NormGamutRegionMaxLim); + VolumeToNLInkP(VolumeNoLI, NLInkP); //Limit Inks double *InkOutP = new double[m_nInks]; VectorToDouble(NLInkP, InkOutP); @@ -1266,7 +1339,7 @@ void Tango::ColorLib::ColorConverter::ConvertVolumeToRGBDisplay(InputCoordinates } } - for (int i = 0; i < (int)(m_nVolumes); ++i) + for (int i = 0; i < (int)(m_nInks); ++i) { if (NLInkP(i) <= m_NormGamutRegionMaxLim[0]) { @@ -1282,12 +1355,12 @@ void Tango::ColorLib::ColorConverter::ConvertVolumeToRGBDisplay(InputCoordinates //Inks are limited in their nonlinear form //Output Volume is in % LimitInks(NLInkP, InkOutP); - NLInkPToVolume(DoubleToVector(InkOutP, m_nInks), Volume); - GamutRegion = GetGamutRegion(Volume, m_ProcessRangesMaxP); + NLInkPToVolume(DoubleToVector(InkOutP, m_nInks), VolumeNoLI); + GamutRegion = GetGamutRegion(VolumeNoLI, m_ProcessRangesMaxP); // LimitLowVolume(Volume, GamutRegion, Volume); - NLcmtoPercentage(Volume, Volume); + NLcmtoPercentage(VolumeNoLI, VolumeNoLI); // LimitNLInks2Volume(NLInkP, GamutRegion, Volume); - VolumeToNLInkP(Volume, NLInkP); + VolumeToNLInkP(VolumeNoLI, NLInkP); VectorToDouble(NLInkP, InkOutP); //Convert to RGB //GamutRegion = 0; @@ -1312,12 +1385,6 @@ void Tango::ColorLib::ColorConverter::ConvertVolumeToRGBDisplay(InputCoordinates for (int i = 0; i < 3; ++i) LabOutFinal[i] = LabOutFinal1[i]; -/* - if (m_AdaptWP) - { - CConvertD65.ChangeWP(LabOutFinal, LabOutFinal, m_whitepointXYZ_Strip, m_whitepointXYZ_CT); - } - */ LabOut = DoubleToVector(LabOutFinal, 3); CConvertD65.SetReferenceWhite(D65); @@ -1370,13 +1437,6 @@ void Tango::ColorLib::ColorConverter::VectorToDouble(VectorXd VecIn, double * do doubOut[i] = VecIn(i); } -/*void Tango::ColorLib::ColorConverter::VectorToDouble(VectorXd VecIn, std::vector<double> &doubOut) -{ - int nSize = VecIn.size(); - for (int i = 0; i < nSize && i < doubOut.size(); ++i) - doubOut.push_back(VecIn(i)); -}*/ - VectorXd Tango::ColorLib::ColorConverter::DoubleToVector(double *doub, int nSize) { @@ -1407,15 +1467,19 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i 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 numofInks = CountNumberofInks(conversionInput); + int numofInks = 0; + int numLightInks = 0; + CountNumberofInks(conversionInput, numofInks, numLightInks); if (numofInks < 0) throw std::exception("Duplicate inks"); + if (numLightInks > 0) + m_hasLightInks = true; int expected_liquids = numofInks; + m_TotalNumberofInks = numofInks; original_input_liquids_count = conversionInput->inputcoordinates->n_inputliquids; original_input_liquids = conversionInput->inputcoordinates->inputliquids; - - InputLiquid** filteredInputLiquids = (InputLiquid**)malloc(sizeof(InputLiquid*) * expected_liquids); + m_InkNames = new LiquidType[m_TotalNumberofInks]; + InputLiquid** filteredInputLiquids = (InputLiquid**)malloc(sizeof(InputLiquid*) * m_TotalNumberofInks); for (size_t i = 0; i < conversionInput->inputcoordinates->n_inputliquids; i++) { @@ -1425,15 +1489,31 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i { case LIQUID_TYPE__Cyan: filteredInputLiquids[0] = liquid; + m_InkNames[0] = liquid->liquidtype; break; case LIQUID_TYPE__Magenta: filteredInputLiquids[1] = liquid; + m_InkNames[1] = liquid->liquidtype; break; case LIQUID_TYPE__Yellow: filteredInputLiquids[2] = liquid; + m_InkNames[2] = liquid->liquidtype; break; case LIQUID_TYPE__Black: filteredInputLiquids[3] = liquid; + m_InkNames[3] = liquid->liquidtype; + break; + case LIQUID_TYPE__LightCyan: + filteredInputLiquids[4] = liquid; + m_InkNames[4] = liquid->liquidtype; + break; + case LIQUID_TYPE__LightMagenta: + filteredInputLiquids[5] = liquid; + m_InkNames[5] = liquid->liquidtype; + break; + case LIQUID_TYPE__LightYellow: + filteredInputLiquids[6] = liquid; + m_InkNames[6] = liquid->liquidtype; break; } } @@ -1455,8 +1535,8 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i 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); + + if(m_colortable ==NULL) m_colortable = new ColorTable(); readColorTransformations(conversionInput); @@ -1471,7 +1551,8 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i m_NormGamutRegionMaxLim[i] = tmpVal[i]; //read calibration tables and store them in m_CalibCurves InputLiquid **inputliquids = conversionInput->inputcoordinates->inputliquids; - int n_inputliquids = conversionInput->inputcoordinates->n_inputliquids; + // int n_inputliquids = conversionInput->inputcoordinates->n_inputliquids; + int n_inputliquids = numofInks - numLightInks; readCalibrationTables(inputliquids, n_inputliquids); //Initialize CIECAM02 transformation @@ -1485,7 +1566,7 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i // Compare Strip White point to Color Table White Point //CompareWhitePoints(); - if (numofInks != m_nInks) + if (n_inputliquids != m_nInks) throw std::exception("Number of available inks does not match ink tables\0"); //Tables have been filled @@ -1499,8 +1580,8 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i for (int i = 1; i < m_nProcessRanges; ++i) { diff = conversionInput->processranges[i]->maxinkuptake - conversionInput->processranges[i - 1]->maxinkuptake; - if(diff<=0) - throw std::exception("Process Rangesare not monotonic\0"); + if(diff<0) + throw std::exception("Process Ranges are not monotonic\0"); } if(m_ProcessRangesMaxP == NULL) m_ProcessRangesMaxP = new double[m_nProcessRanges]; @@ -1508,6 +1589,12 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i { m_ProcessRangesMaxP[i] = conversionInput->processranges[i]->maxinkuptake; } + if (m_ProcessRangesMinP == NULL) + m_ProcessRangesMinP = new double[m_nProcessRanges]; + for (int i = 0; i < m_nProcessRanges; ++i) + { + m_ProcessRangesMinP[i] = conversionInput->processranges[i]->mininkuptake; + } SetLowVolThr_nlcm(); VectorXd InkOut(m_nInks); @@ -1540,14 +1627,18 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i // Right now calibration is in the [0-100] range, values exceeding [0-100] are not transformed ConvertToNLInks(InkOut, NLInkOut); - LimitNLInks2Volume(NLInkOut, GamutRegion, Volume); - //OutputCoordinates outputCoords = OUTPUT_COORDINATES__INIT; - /* if (InkOutP != NULL) - { - delete[] InkOutP; - InkOutP = NULL; - }*/ - + LimitNLInks2Volume(NLInkOut, GamutRegion, Volume); + } + //Split Volume into inks and Light Inks + VectorXd VolumeLI(m_TotalNumberofInks); + if (m_hasLightInks) + { + SplitVolume(Volume, VolumeLI, GamutRegion); + } + else + { + for (int i = 0; i < m_TotalNumberofInks; ++i) + VolumeLI(i) = Volume(i); } OutputCoordinates *outputCoords = (OutputCoordinates*)malloc(sizeof(OutputCoordinates)); output_coordinates__init(outputCoords); @@ -1555,7 +1646,7 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i fillLab(outputCoords, LabOut); outputCoords->has_processparameterstableindex = true; outputCoords->processparameterstableindex = GamutRegion; - fillVolume(outputCoords, Volume); + fillVolume(outputCoords, VolumeLI); conversionOutput->has_outofgamut = true; conversionOutput->outofgamut = !(InGamut); conversionOutput->singlecoordinates = outputCoords; @@ -1574,8 +1665,8 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i MatrixXd RGBHive(MatHive, 3); VectorXd RGBHive1(3); VectorXd LabHive1(3); - VectorXd VolumeHive1(m_nVolumes); - MatrixXd VolumeHive(MatHive, m_nVolumes); + VectorXd VolumeHive1(m_TotalNumberofInks); + MatrixXd VolumeHive(MatHive, m_TotalNumberofInks); MatrixXd LabHive(MatHive, 3); int *GamutRegionV = new int[MatHive]; @@ -1603,7 +1694,7 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i for (j = 0; j < 3; ++j) RGBHive1(j) = RGBHive(i, j); fillRGB(hiveData[i], RGBHive1); - for (j = 0; j < m_nVolumes; ++j) + for (j = 0; j < m_TotalNumberofInks; ++j) VolumeHive1(j) = VolumeHive(i, j); fillVolume(hiveData[i], VolumeHive1); for (j = 0; j < 3; ++j) @@ -1611,7 +1702,7 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i fillLab(hiveData[i], LabHive1); hiveData[i]->has_processparameterstableindex = true; hiveData[i]->processparameterstableindex = GamutRegionV[i]; - hiveData[i]->n_outputliquids = m_nInks; + hiveData[i]->n_outputliquids = m_TotalNumberofInks; } conversionOutput->hivecoordinates[i] = hiveData[i]; } @@ -1637,7 +1728,7 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i fillLab(TripletData[i], LabHive1); TripletData[i]->has_processparameterstableindex = true; TripletData[i]->processparameterstableindex = GamutRegionV[tripletIndex[i]]; - TripletData[i]->n_outputliquids = m_nInks; + TripletData[i]->n_outputliquids = m_TotalNumberofInks; conversionOutput->triplecoordinates[i] = TripletData[i]; } @@ -1721,13 +1812,106 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i InvLinearInterp[i].SetNPoints(npts); } }*/ +void Tango::ColorLib::ColorConverter::CountNumberofInks(GradientConversionInput* conversionInput, int &numInks, int &numLightInks) +{ + int nLiquids = conversionInput->n_inputliquids; + // int numberofInks = 0; + //Cyan + int nCyan = 0; + for (int i = 0; i < nLiquids; ++i) + { + if (conversionInput->inputliquids[i]->liquidtype == LIQUID_TYPE__Cyan) + nCyan++; + } + if (nCyan > 1) + { + numInks = -1; + numLightInks = -1; + return; + } + int nMagenta = 0; + for (int i = 0; i < nLiquids; ++i) + { + if (conversionInput->inputliquids[i]->liquidtype == LIQUID_TYPE__Magenta) + nMagenta++; + } + if (nMagenta > 1) + { + numInks = -1; + numLightInks = -1; + return; + } + int nYellow = 0; + for (int i = 0; i < nLiquids; ++i) + { + if (conversionInput->inputliquids[i]->liquidtype == LIQUID_TYPE__Yellow) + nYellow++; + } + if (nYellow > 1) + { + numInks = -1; + numLightInks = -1; + return; + } + int nBlack = 0; + for (int i = 0; i < nLiquids; ++i) + { + if (conversionInput->inputliquids[i]->liquidtype == LIQUID_TYPE__Black) + nBlack++; + } + if (nBlack > 1) + { + numInks = -1; + numLightInks = -1; + return; + } + int nLightCyan = 0; + for (int i = 0; i < nLiquids; ++i) + { + if (conversionInput->inputliquids[i]->liquidtype == LIQUID_TYPE__LightCyan) + nLightCyan++; + } + if (nLightCyan > 1) + { + numInks = -1; + numLightInks = -1; + return; + } + int nLightMagenta = 0; + for (int i = 0; i < nLiquids; ++i) + { + if (conversionInput->inputliquids[i]->liquidtype == LIQUID_TYPE__LightMagenta) + nLightMagenta++; + } + if (nLightMagenta > 1) + { + numInks = -1; + numLightInks = -1; + return; + } + int nLightYellow = 0; + for (int i = 0; i < nLiquids; ++i) + { + if (conversionInput->inputliquids[i]->liquidtype == LIQUID_TYPE__LightYellow) + nLightYellow++; + } + if (nLightYellow > 1) + { + numInks = -1; + numLightInks = -1; + return; + } + numInks = nCyan + nMagenta + nYellow + nBlack + nLightCyan + nLightMagenta + nLightYellow; + numLightInks = nLightCyan + nLightMagenta + nLightYellow;; + return; +} -int Tango::ColorLib::ColorConverter::CountNumberofInks(ConversionInput* conversionInput) +void Tango::ColorLib::ColorConverter::CountNumberofInks(ConversionInput* conversionInput, int &numInks, int &numLightInks) { int nLiquids = conversionInput->inputcoordinates->n_inputliquids; - int numberofInks = 0; +// int numberofInks = 0; //Cyan - int nCyan = 0;; + int nCyan = 0; for (int i = 0; i < nLiquids; ++i) { if (conversionInput->inputcoordinates->inputliquids[i]->liquidtype == LIQUID_TYPE__Cyan) @@ -1735,8 +1919,9 @@ int Tango::ColorLib::ColorConverter::CountNumberofInks(ConversionInput* conversi } if (nCyan > 1) { - numberofInks = -1; - return(numberofInks); + numInks = -1; + numLightInks = -1; + return; } int nMagenta = 0; for (int i = 0; i < nLiquids; ++i) @@ -1746,8 +1931,9 @@ int Tango::ColorLib::ColorConverter::CountNumberofInks(ConversionInput* conversi } if (nMagenta > 1) { - numberofInks = -1; - return(numberofInks); + numInks = -1; + numLightInks = -1; + return; } int nYellow = 0; for (int i = 0; i < nLiquids; ++i) @@ -1757,8 +1943,9 @@ int Tango::ColorLib::ColorConverter::CountNumberofInks(ConversionInput* conversi } if (nYellow > 1) { - numberofInks = -1; - return(numberofInks); + numInks = -1; + numLightInks = -1; + return; } int nBlack = 0; for (int i = 0; i < nLiquids; ++i) @@ -1768,11 +1955,49 @@ int Tango::ColorLib::ColorConverter::CountNumberofInks(ConversionInput* conversi } if (nBlack > 1) { - numberofInks = -1; - return(numberofInks); + numInks = -1; + numLightInks = -1; + return; + } + int nLightCyan = 0; + for (int i = 0; i < nLiquids; ++i) + { + if (conversionInput->inputcoordinates->inputliquids[i]->liquidtype == LIQUID_TYPE__LightCyan) + nLightCyan++; + } + if (nLightCyan > 1) + { + numInks = -1; + numLightInks = -1; + return; } - numberofInks = nCyan + nMagenta + nYellow + nBlack; - return(numberofInks); + int nLightMagenta = 0; + for (int i = 0; i < nLiquids; ++i) + { + if (conversionInput->inputcoordinates->inputliquids[i]->liquidtype == LIQUID_TYPE__LightMagenta) + nLightMagenta++; + } + if (nLightMagenta > 1) + { + numInks = -1; + numLightInks = -1; + return; + } + int nLightYellow = 0; + for (int i = 0; i < nLiquids; ++i) + { + if (conversionInput->inputcoordinates->inputliquids[i]->liquidtype == LIQUID_TYPE__LightYellow) + nLightYellow++; + } + if (nLightYellow > 1) + { + numInks = -1; + numLightInks = -1; + return; + } + numInks = nCyan + nMagenta + nYellow + nBlack + nLightCyan + nLightMagenta + nLightYellow; + numLightInks = nLightCyan + nLightMagenta + nLightYellow;; + return; } bool Tango::ColorLib::ColorConverter::IsInGamut(double *InLab, SURROUND sur, CAM02CS CS, double *LabCoord) @@ -2099,12 +2324,16 @@ size_t Tango::ColorLib::ColorConverter::P_IsInGamut(uint8_t * input_buffer, size bool InGamut = false; m_WP.Set(0.9505, 1.00, 1.0888); //D65 //count number if inks - int numofInks = CountNumberofInks(conversionInput); + int numofInks = 0; + int numLightInks = 0; + CountNumberofInks(conversionInput, numofInks, numLightInks); readColorTransformations(conversionInput); //read calibration tables and store them in m_CalibCurves - int n_inputliquids = conversionInput->inputcoordinates->n_inputliquids; + int n_inputliquids = numofInks - numLightInks; InputLiquid **inputliquid = conversionInput->inputcoordinates->inputliquids; + //Read CMYK Calibration Tables only. Light Inks have no calibration tables + readCalibrationTables(inputliquid, n_inputliquids); //Initialize CIECAM02 transformation @@ -2118,7 +2347,7 @@ size_t Tango::ColorLib::ColorConverter::P_IsInGamut(uint8_t * input_buffer, size // Compare Strip White point to Color Table White Point //CompareWhitePoints(); - if (numofInks != m_nInks) + if ((numofInks - numLightInks) != m_nInks) throw std::exception("Number of available inks does not match ink tables"); VectorXd InkOut(m_nInks); @@ -2295,31 +2524,7 @@ size_t Tango::ColorLib::ColorConverter::GenerateGradient(uint8_t * input_buffer, if (m_colortable == NULL) m_colortable = new ColorTable(); PrepareGradient(conversionInput, conversionOutput); - //Get liquid types info... - /* InputLiquid* cyan = NULL; - InputLiquid* magenta = NULL; - InputLiquid* yellow = NULL; - InputLiquid* black = NULL; - - for (size_t i = 0; i < conversionInput->n_inputliquids; i++) - { - switch (conversionInput->inputliquids[i]->liquidtype) - { - case LIQUID_TYPE__Cyan: - cyan = conversionInput->inputliquids[i]; - break; - case LIQUID_TYPE__Magenta: - magenta = conversionInput->inputliquids[i]; - break; - case LIQUID_TYPE__Yellow: - yellow = conversionInput->inputliquids[i]; - break; - case LIQUID_TYPE__Black: - black = conversionInput->inputliquids[i]; - break; - } - }*/ - + //Pack output... output_buffer = (uint8_t*)malloc(gradient_conversion_output__get_packed_size(conversionOutput)); int size = gradient_conversion_output__pack(conversionOutput, output_buffer); @@ -2388,10 +2593,10 @@ void Tango::ColorLib::ColorConverter::fillGradientStops(GradientConversionInput m_GradStops[i].Set_ColorSpace(COLOR_SPACE__LAB); m_GradStops[i].Set_Offset(conversionInput->stops[i]->offset); break; - case COLOR_SPACE__Volume: //Case Volume + case COLOR_SPACE__Volume: //Case Volume // No Light Inks implementation for Volume m_GradStops[i].Set_ColorSpace(COLOR_SPACE__Volume); m_GradStops[i].Set_Offset(conversionInput->stops[i]->offset); - for (int j = 0; j < (int)conversionInput->stops[i]->n_liquidvolumes; j++) + for (int j = 0; j < m_TotalNumberofInks; j++) { LiquidVolume* liquidVolume = conversionInput->stops[i]->liquidvolumes[j]; @@ -2776,12 +2981,18 @@ void Tango::ColorLib::ColorConverter::PrepareGradient(GradientConversionInput* c //fill input stops... //All calculations are done in Relative Colorimetric Color Space m_nGradStops = conversionInput->n_stops; - int nInks = conversionInput->n_inputliquids; - m_nVolumes = nInks; + int numofInks = 0; + int numLightInks = 0; + CountNumberofInks(conversionInput, numofInks, numLightInks); + if (numofInks < 0) + throw std::exception("Duplicate inks"); + m_hasLightInks = false; //Gradients do not use light inks + m_TotalNumberofInks = numofInks - numLightInks; + m_nVolumes = m_TotalNumberofInks; if(m_GradStops == NULL) m_GradStops = new Gradient[m_nGradStops]; for (int i = 0; i < m_nGradStops; ++i) - m_GradStops[i].SetVolumeSize(nInks); + m_GradStops[i].SetVolumeSize(m_TotalNumberofInks); InputCoordinates **inputcoordinates = (InputCoordinates**)malloc(sizeof(InputCoordinates*)*m_nGradStops); for (int i = 0; i < m_nGradStops; ++i) @@ -2805,9 +3016,9 @@ void Tango::ColorLib::ColorConverter::PrepareGradient(GradientConversionInput* c double *tmpVal = m_colortable->GetNormGamutRegionMaxLim(); for (int i = 0; i < m_nProcessRanges; ++i) m_NormGamutRegionMaxLim[i] = tmpVal[i]; - int n_inputliquids = conversionInput->n_inputliquids; + //int n_inputliquids = conversionInput->n_inputliquids; InputLiquid **inputliquid = conversionInput->inputliquids; - readCalibrationTables(inputliquid, n_inputliquids); + readCalibrationTables(inputliquid, m_TotalNumberofInks); if (m_colortable->GetTableVersion() <= 1) { throw std::exception("Color Table Version does not support gradients\0"); @@ -2836,7 +3047,7 @@ void Tango::ColorLib::ColorConverter::PrepareGradient(GradientConversionInput* c // Compare Strip White point to Color Table White Point //CompareWhitePoints(); ColorConvert CConvertD65(D65, D65); //Destination, source - if (n_inputliquids != m_nInks) + if (m_TotalNumberofInks != m_nInks) throw std::exception("Number of available inks does not match ink tables\0"); if (m_ProcessRangesMaxP == NULL) @@ -2845,6 +3056,12 @@ void Tango::ColorLib::ColorConverter::PrepareGradient(GradientConversionInput* c { m_ProcessRangesMaxP[i] = conversionInput->processranges[i]->maxinkuptake; } + if (m_ProcessRangesMinP == NULL) + m_ProcessRangesMinP = new double[m_nProcessRanges]; + for (int i = 0; i < m_nProcessRanges; ++i) + { + m_ProcessRangesMinP[i] = conversionInput->processranges[i]->mininkuptake; + } SetLowVolThr_nlcm(); VectorXd InkOut(m_nInks); VectorXd RGBOut(3); @@ -3150,14 +3367,14 @@ void Tango::ColorLib::ColorConverter::GradInput2InputCoords(GradientConversionI inputcoordinates[i]->has_b = true; break; case COLOR_SPACE__Volume: //Case Volume - int size= (int)conversionInput->stops[i]->n_liquidvolumes; - InputLiquid** InputLiquidsIC = (InputLiquid**)malloc(sizeof(InputLiquid*) *size); - for (int j = 0; j < size; j++) + //int size= (int)conversionInput->stops[i]->n_liquidvolumes; + InputLiquid** InputLiquidsIC = (InputLiquid**)malloc(sizeof(InputLiquid*) *m_TotalNumberofInks); + for (int j = 0; j < m_TotalNumberofInks; j++) { InputLiquidsIC[j] = (InputLiquid*)malloc(sizeof(InputLiquid)); input_liquid__init(InputLiquidsIC[j]); } - for (size_t j= 0; j< (int)conversionInput->stops[i]->n_liquidvolumes; j++) + for (size_t j= 0; j< (size_t)m_TotalNumberofInks; j++) { LiquidVolume* liquidVolume = conversionInput->stops[i]->liquidvolumes[j]; switch (liquidVolume->liquidtype) @@ -3183,7 +3400,7 @@ void Tango::ColorLib::ColorConverter::GradInput2InputCoords(GradientConversionI } inputcoordinates[i]->inputliquids = InputLiquidsIC; - inputcoordinates[i]->n_inputliquids = size; + inputcoordinates[i]->n_inputliquids = m_TotalNumberofInks; } } } @@ -3205,27 +3422,53 @@ void Tango::ColorLib::ColorConverter::NLcmtoPercentage(VectorXd InVolume, Vector void Tango::ColorLib::ColorConverter::LimitLowVolume(VectorXd InVolume, int &GamutRegion, VectorXd &OutVolume) { int indGR = 0; - //Find Gamut Region for (int i = 1; i < m_nProcessRanges; ++i) { if (GamutRegion == i) indGR = i; } - //Limit Volume based on Gamut Region + //InVolume is in [nl/cm] + double TotalVolume = 0.0; + for (int i = 0; i < m_nInks; ++i) + TotalVolume += InVolume(i); + + double low = 0.0; + double high = 0.0; + + if (TotalVolume <= m_ProcessRangesMinP[0]) + { + //Calculate minVolumeThreshold based on m_ProcessRangesMinP[0] + high = LowVolumeThreshold * m_ProcessRangesMinP[0]/100.0; + } + else if (TotalVolume <= m_ProcessRangesMaxP[0]) + { + //Calculate minVolumeThreshold based on Total Volume + high = LowVolumeThreshold * TotalVolume/100.0; + } + else if (TotalVolume <= m_ProcessRangesMinP[1]) + { + //Calculate minVolumeThreshold based on m_ProcessRangesMinP[1] + high = LightInksThr * m_ProcessRangesMinP[1]/100.0; + } + else + { + high = LightInksThr * TotalVolume/100.0; + } + //Limit Volume based on Total Ink Volume double sumVol = 0; for (int i = 0; i < m_nInks; ++i) { - if (InVolume(i) >= m_LowVolThr_nlcm[indGR]) + if (InVolume(i) >= high) OutVolume(i) = InVolume(i); - else if (InVolume(i) < m_LowVolThrHalf_nlcm[indGR]) + else if (InVolume(i) <(high/2.0)) OutVolume(i) = 0.0; else - OutVolume(i) = m_LowVolThr_nlcm[indGR]; + OutVolume(i) =high; sumVol += OutVolume(i); } //recalculate GamutRegion - if (indGR == 0) - return; + if (sumVol <= m_ProcessRangesMaxP[0]) + GamutRegion = 0; else { for (int i = 1; i < indGR+1; ++i) @@ -3238,6 +3481,7 @@ void Tango::ColorLib::ColorConverter::LimitLowVolume(VectorXd InVolume, int &Gam void Tango::ColorLib::ColorConverter::LimitLowVolumeP(VectorXd InVolume, int &GamutRegion, VectorXd &OutVolume) { + //InVolume is in % int indGR = 0; //Find Gamut Region for (int i = 1; i < m_nProcessRanges; ++i) @@ -3483,10 +3727,10 @@ void Tango::ColorLib::ColorConverter::LimitNLInks2VolumeThr(VectorXd NLInks, int double *InkOutL = new double[m_nInks]; // ConvertToNLInks(NLInks, NLInkOut); LimitInks(NLInks, InkOutL); // InkOutL in [nl/cm] - NLInkPToVolume(DoubleToVector(InkOutL, m_nInks), Volume); + NLInkPToVolume(DoubleToVector(InkOutL, m_nInks), Volume); // [nl/cm] GamutRegion = GetGamutRegion(Volume, m_ProcessRangesMaxP); - LimitLowVolume(Volume, GamutRegion, Volume); - NLcmtoPercentage(Volume, Volume); + LimitLowVolume(Volume, GamutRegion, Volume); // [nl/cm] + NLcmtoPercentage(Volume, Volume); // output volume in % if (InkOutL != NULL) { @@ -3665,4 +3909,104 @@ void Tango::ColorLib::ColorConverter::ConvertVolumeToLabRel(VectorXd &Volume, V } return; -}
\ No newline at end of file +} + +void Tango::ColorLib::ColorConverter::SplitVolume(VectorXd Volume, VectorXd &VolumeLI, int &GamutRegion) +{ +//mark split candidates + int ind = 0; + int *LISplitInd = new int[m_nInks - 1]; + VectorXd Vol_nlcm(m_nInks); + double TotalVolume = 0; + double low = 0; + double high = 0; + for (int i = 0; i < m_nInks ; ++i) + { + Vol_nlcm(i) = Volume(i)*m_maxNlPerCM(i)/100; + VolumeLI(i) = Vol_nlcm(i); + TotalVolume += Vol_nlcm(i); + } + int indGR = 0; + //Find Gamut Region + for (int i = 1; i < m_nProcessRanges; ++i) + { + if (GamutRegion == i) + indGR = i; + } + double lim1 = 0; + double lim2 = m_ProcessRangesMinP[0]; + double lim3 = m_ProcessRangesMaxP[0]; + for (int iReg = 0; iReg<m_nProcessRanges-1; ++iReg) + { + if ((TotalVolume >= lim1) & (TotalVolume <= lim2)) + { + //Calculate Ink Split Based on m_ProcessRangesMinP[iReg] + low = LowVolumeThreshold * m_ProcessRangesMinP[iReg] / 100.0; + high = LightInksThr * m_ProcessRangesMinP[iReg] / 100.0; + } + else if ((TotalVolume <= lim3) & (TotalVolume > lim2)) + { + //Calculate Ink Split Based on Total Volume + low = LowVolumeThreshold * TotalVolume / 100.0; + high = LightInksThr * TotalVolume / 100.0; + } + lim1 = m_ProcessRangesMaxP[iReg]; + lim2 = m_ProcessRangesMinP[iReg+1]; + lim3 = m_ProcessRangesMaxP[iReg+1]; + } + if ((TotalVolume >= lim1) & (TotalVolume <= lim2)) + { + //Calculate Ink Split Based on m_ProcessRangesMinP[iReg] + low = LowVolumeThreshold * m_ProcessRangesMinP[m_nProcessRanges-1] / 100.0; + high = LightInksThr * m_ProcessRangesMinP[m_nProcessRanges-1] / 100.0; + } + else if ((TotalVolume <= lim3) & (TotalVolume > lim2)) + { + //Calculate Ink Split Based on Total Volume + low = LowVolumeThreshold * TotalVolume / 100.0; + high = LightInksThr * TotalVolume / 100.0; + } + + for (int i = 0; i < m_nInks - 1; ++i) + { + if ((Vol_nlcm(i) >= low) & (Vol_nlcm(i) <= high)) + { + VolumeLI(i + m_nInks) = DilutionFactor * Vol_nlcm(i); + VolumeLI(i) = 0.0; + } + else + { + VolumeLI(i) = Vol_nlcm(i); + VolumeLI(i + m_nInks) = 0; + } + } + //Check if Split Volume exceeds MaxInkUptake[1] + double UpperLimit = m_ProcessRangesMaxP[m_nProcessRanges - 1]; + TotalVolume = 0.0; + for (int i = 0; i < m_TotalNumberofInks; ++i) + TotalVolume += VolumeLI(i); + if (TotalVolume > UpperLimit) + { + //go back to CMYK inks + for (int iBack = 0; iBack < m_nInks - 1; ++iBack) + { + if ((VolumeLI(iBack) == 0) & (VolumeLI(iBack + m_nInks) > 0)) + { + VolumeLI(iBack) = VolumeLI(iBack + m_nInks)/DilutionFactor; + TotalVolume += (VolumeLI(iBack) - VolumeLI(iBack + m_nInks)); + VolumeLI(iBack + m_nInks) = 0.0; + } + } + } + NLcmtoPercentage(VolumeLI, VolumeLI); + if (TotalVolume <= m_ProcessRangesMaxP[0]) + GamutRegion = 0; + else + { + for (int i = 1; i < indGR + 1; ++i) + { + if ((TotalVolume > m_ProcessRangesMaxP[i - 1]) & (TotalVolume <= m_ProcessRangesMaxP[i])) + GamutRegion = i; + } + } +} diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/ColorConverter.h b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/ColorConverter.h index 3c75124e5..3f84b9304 100644 --- a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/ColorConverter.h +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/ColorConverter.h @@ -79,6 +79,7 @@ namespace Tango VectorXd &InkOut, VectorXd &RGBOut, VectorXd &LabOut, int &GamutRegion); void ConvertVolumeToLabRel(VectorXd &Volume, VectorXd &LabOut, int GamutRegion); + void SplitVolume(VectorXd Volume, VectorXd &VolumeLI, int &GamutRegion); size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t input_buffer_size, uint8_t *& output_buffer); size_t Tango::ColorLib::ColorConverter::GenerateGradient(uint8_t * input_buffer, size_t input_buffer_size, uint8_t *& output_buffer); void ConvertToNLInks(VectorXd InkIn, VectorXd &InkOut); @@ -91,13 +92,17 @@ namespace Tango private: ColorTable *m_colortable; ColorConvert *m_Conv02; + LiquidType *m_InkNames; // Interp *m_LinInterp; // Interp *m_InvLinInterp; C_RGB_XYZ_Lab m_whitepointLab; C_RGB_XYZ_Lab m_whitepointXYZ_Strip; double *m_NormGamutRegionMaxLim; double *m_ProcessRangesMaxP; + double *m_ProcessRangesMinP; int m_nProcessRanges; + bool m_hasLightInks; + int m_TotalNumberofInks; void LimitLab(double* LabIn); int m_nGradStops; Gradient *m_GradStops; @@ -131,7 +136,8 @@ namespace Tango VectorXd xpos, VectorXd ypos, int nHive, MatrixXd &OLabHive, MatrixXd &ORGBHive, MatrixXd &OVolumeHive, int *&OGamutRegion); void FindTriplet(VectorXd Lab, MatrixXd Lab1, int nHive, int*indDataMax); - int CountNumberofInks(ConversionInput* conversionInput); + void CountNumberofInks(ConversionInput* conversionInput, int &numInks, int &numLightInks); + void CountNumberofInks(GradientConversionInput* conversionInput, int &numInks, int &numLightInks); void SetStripWhitepoint(double threadl, double threada, double threadb); void VectorToDouble(VectorXd Vec, double *doub); // void VectorToDouble(VectorXd VecIn, std::vector<double> &doubOut); diff --git a/Software/Visual_Studio/Tango.ColorLib.GradientTest.CLI/Program.cs b/Software/Visual_Studio/Tango.ColorLib.GradientTest.CLI/Program.cs index 82049fa37..2a8077669 100644 --- a/Software/Visual_Studio/Tango.ColorLib.GradientTest.CLI/Program.cs +++ b/Software/Visual_Studio/Tango.ColorLib.GradientTest.CLI/Program.cs @@ -18,9 +18,9 @@ namespace Tango.ColorLib.GradientTest.CLI GradientGenerator generator = new GradientGenerator(); //RGB, Gamut Region 0, In Gamut //TEST1 - // TestRGBGamutRegion0(generator); - // Console.WriteLine("Press enter to nextTestLABGamutRegion0 test..."); - // Console.ReadLine(); + TestRGBGamutRegion0(generator); + Console.WriteLine("Press enter to nextTestLABGamutRegion0 test..."); + Console.ReadLine(); // Lab, Gamut Region 0, In Gamut //TEST2 TestLABGamutRegion0(generator); @@ -28,32 +28,32 @@ namespace Tango.ColorLib.GradientTest.CLI Console.ReadLine(); //Volume, Gamut Region 0, In Gamut //TEST3 - // TestVolumeGamutRegion0(generator); - // Console.WriteLine("Press enter to next TestVolumeGamutRegion1 test..."); - // Console.ReadLine(); + TestVolumeGamutRegion0(generator); + Console.WriteLine("Press enter to next TestVolumeGamutRegion1 test..."); + Console.ReadLine(); //Volume, Gamut Region 1, In Gamut //TEST4 - // TestVolumeGamutRegion1(generator); - // Console.WriteLine("Press enter to next TestRGBMixedGamut test..."); - // Console.ReadLine(); + TestVolumeGamutRegion1(generator); + Console.WriteLine("Press enter to next TestRGBMixedGamut test..."); + Console.ReadLine(); //RGB, Mixed Gamut Regions, In Gamut //TEST5 - // TestRGBMixedGamut(generator); - // Console.WriteLine("Press enter to next TestLABOutOfGamut test..."); - // Console.ReadLine(); + TestRGBMixedGamut(generator); + Console.WriteLine("Press enter to next TestLABOutOfGamut test..."); + Console.ReadLine(); //LAB, Gamut Region 0, Out of Gamut //TEST6 - // TestLABOutOfGamut(generator); -// Console.WriteLine("Press enter to next TestLABMixedGamut test..."); -// Console.ReadLine(); + TestLABOutOfGamut(generator); + Console.WriteLine("Press enter to next TestLABMixedGamut test..."); + Console.ReadLine(); //7. Lab, Mixed Gamut Regions, In Gamut //TEST7 - // TestLABMixedGamut(generator); - // Console.WriteLine("Press enter to next TestMixedEnvironment test..."); - // Console.ReadLine(); + TestLABMixedGamut(generator); + Console.WriteLine("Press enter to next TestMixedEnvironment test..."); + Console.ReadLine(); //8. Mixed Environment //TEST8 @@ -114,184 +114,111 @@ namespace Tango.ColorLib.GradientTest.CLI //Segment length input.SegmentLength = 1000;*/ } - { - /* - input.Stops.Add(new GradientInputStop() - { - ColorSpace = ColorSpace.Rgb, - Offset = 0, - Red = 93, - Green = 123, - Blue = 95, - }); - //Lab Stop 2 - input.Stops.Add(new GradientInputStop() - { - ColorSpace = ColorSpace.Lab, - Offset = 0.6, - L = 50, - A = -10, - B = -10, - }); - //Volume Stop 3 - GradientInputStop c = new GradientInputStop() - { - ColorSpace = ColorSpace.Volume, - Offset = 1, - }; - c.LiquidVolumes.Add(new LiquidVolume() - { - LiquidType = LiquidType.Cyan, - Volume = 50 - }); - c.LiquidVolumes.Add(new LiquidVolume() - { - LiquidType = LiquidType.Magenta, - Volume = 0 - }); - c.LiquidVolumes.Add(new LiquidVolume() - { - LiquidType = LiquidType.Yellow, - Volume = 50 - }); - c.LiquidVolumes.Add(new LiquidVolume() - { - LiquidType = LiquidType.Black, - Volume = 0 - }); - input.Stops.Add(c); + { + /* + input.Stops.Add(new GradientInputStop() + { + ColorSpace = ColorSpace.Rgb, + Offset = 0, + Red = 93, + Green = 123, + Blue = 95, + }); + //Lab Stop 2 + input.Stops.Add(new GradientInputStop() + { + ColorSpace = ColorSpace.Lab, + Offset = 0.6, + L = 50, + A = -10, + B = -10, + }); + //Volume Stop 3 + GradientInputStop c = new GradientInputStop() + { + ColorSpace = ColorSpace.Volume, + Offset = 1, + }; + c.LiquidVolumes.Add(new LiquidVolume() + { + LiquidType = LiquidType.Cyan, + Volume = 50 + }); + c.LiquidVolumes.Add(new LiquidVolume() + { + LiquidType = LiquidType.Magenta, + Volume = 0 + }); + c.LiquidVolumes.Add(new LiquidVolume() + { + LiquidType = LiquidType.Yellow, + Volume = 50 + }); + c.LiquidVolumes.Add(new LiquidVolume() + { + LiquidType = LiquidType.Black, + Volume = 0 + }); + input.Stops.Add(c); - Console.WriteLine($"Testing input:\n{input.ToJsonString(nameof(input.ForwardData),nameof(CalibrationData))}"); + Console.WriteLine($"Testing input:\n{input.ToJsonString(nameof(input.ForwardData),nameof(CalibrationData))}"); - Console.WriteLine(); + Console.WriteLine(); - Console.WriteLine("Processing..."); + Console.WriteLine("Processing..."); - Stopwatch watch = new Stopwatch(); - watch.Start(); + Stopwatch watch = new Stopwatch(); + watch.Start(); - GradientConversionOutput output = generator.GenerateGradient(input); + GradientConversionOutput output = generator.GenerateGradient(input); - watch.Stop(); - Console.WriteLine($"Processing completed after: {watch.Elapsed.Milliseconds.ToString("00000.00")} mseconds."); + watch.Stop(); + Console.WriteLine($"Processing completed after: {watch.Elapsed.Milliseconds.ToString("00000.00")} mseconds."); - //watch.Elapsed.TotalSeconds.ToString("0.0")} + //watch.Elapsed.TotalSeconds.ToString("0.0")} - Console.WriteLine(); - Console.WriteLine($"Result:\n{output.ToJsonString()}"); - Console.WriteLine();*/ + Console.WriteLine(); + Console.WriteLine($"Result:\n{output.ToJsonString()}"); + Console.WriteLine();*/ } Console.WriteLine("Press return to exit..."); Console.ReadLine(); } - public static CalibrationData CreateCalibrationData(PMR.ColorLab.LiquidType liquidType, CalibrationData tmpData, int nsize) - { - CalibrationData data = new CalibrationData(); - data.LiquidType = liquidType; - - for (int i = 0; i < nsize; i++) - { - data.CalibrationPoints.Add(new CalibrationPoint() - { - X = tmpData.CalibrationPoints[i].X, - Y = tmpData.CalibrationPoints[i].Y, - }); - } - - return data; - } - static GradientConversionInput CreateBaseGradientConversionInput() { GradientConversionInput input = new GradientConversionInput(); - - //CCT - input.ForwardData = ByteString.CopyFrom(File.ReadAllBytes(@"Sylko_HV_IL400Bl95R_1.cct")); //TODO: Load CCT file from local drive. - CalibrationData tmpCyanData = new CalibrationData(); - tmpCyanData.LiquidType = LiquidType.Cyan; - double [] XValC = {0, 1, 2, 3, 7, 19, 47, 76, 86, 100 }; - double[] YValC = {0 ,6.9665 ,13.1381, 18.1474, 30.80, 50.7896, 73.1757, 89.37837, 94.20457, 100 }; - int nsizeC = XValC.Length; - - for (int i = 0; i < nsizeC; i++) - { - tmpCyanData.CalibrationPoints.Add(new CalibrationPoint() - { - X = XValC[i], - Y = YValC[i], - }); - } - CalibrationData tmpMagentaData = new CalibrationData(); - tmpMagentaData.LiquidType = LiquidType.Magenta; - double[] XValM = { 0, 1, 2, 4, 7, 10, 31, 63, 80, 100 }; - double[] YValM = { 0, 11.6638, 21.7132, 34.7811, 45.3282, 53.6154, 74.9858, 90.2901,94.5245,100}; - int nsizeM = XValM.Length; - - for (int i = 0; i < nsizeM; i++) - { - tmpMagentaData.CalibrationPoints.Add(new CalibrationPoint() - { - X = XValM[i], - Y = YValM[i], - }); - } - CalibrationData tmpYellowData = new CalibrationData(); - tmpYellowData.LiquidType = LiquidType.Yellow; - double[] XValY = {0, 1, 2, 4, 7, 11, 23, 39, 67, 100 }; - double[] YValY = { 0, 9.8895, 18.4570, 29.6694, 37.7121, 45.4408, 63.6478, 75.8076, 93.9226, 100 }; - int nsizeY = XValY.Length; - - for (int i = 0; i < nsizeY; i++) - { - tmpYellowData.CalibrationPoints.Add(new CalibrationPoint() - { - X = XValY[i], - Y = YValY[i], - }); - } - CalibrationData tmpBlackData = new CalibrationData(); - tmpBlackData.LiquidType = LiquidType.Yellow; - double[] XValK = { 0, 1, 2,4,7,10,20,30,50,75,80,85,100 }; - double[] YValK = { 0, 10.4656,19.5667, 31.6627, 40.6020, 46.9257, 63.1965, 70.9355, 83.4647, 94.4979, 95.7233, 96.3631,100 }; - int nsizeK = XValY.Length; + //CCT + input.ForwardData = ByteString.CopyFrom(File.ReadAllBytes(@"Sylko_HV_IL350R.cct")); //TODO: Load CCT file from local drive. - for (int i = 0; i < nsizeK; i++) - { - tmpBlackData.CalibrationPoints.Add(new CalibrationPoint() - { - X = XValK[i], - Y = YValK[i], - }); - } //RML Liquid Factors input.InputLiquids.Add(new InputLiquid() { LiquidType = LiquidType.Cyan, - CalibrationData = CreateCalibrationData(LiquidType.Cyan, tmpCyanData, nsizeC), + CalibrationData = BL.Entities.Cat.CreateDemoCalibrationData(LiquidType.Cyan), MaxNanoliterPerCentimeter = 200, }); input.InputLiquids.Add(new InputLiquid() { LiquidType = LiquidType.Magenta, - CalibrationData = CreateCalibrationData(LiquidType.Magenta, tmpMagentaData, nsizeM), + CalibrationData = BL.Entities.Cat.CreateDemoCalibrationData(LiquidType.Magenta), MaxNanoliterPerCentimeter = 200, }); input.InputLiquids.Add(new InputLiquid() { LiquidType = LiquidType.Yellow, - CalibrationData = CreateCalibrationData(LiquidType.Yellow, tmpYellowData, nsizeY), + CalibrationData = BL.Entities.Cat.CreateDemoCalibrationData(LiquidType.Yellow), MaxNanoliterPerCentimeter = 200, }); input.InputLiquids.Add(new InputLiquid() { LiquidType = LiquidType.Black, - CalibrationData = CreateCalibrationData(LiquidType.Black, tmpBlackData, nsizeK), + CalibrationData = BL.Entities.Cat.CreateDemoCalibrationData(LiquidType.Black), MaxNanoliterPerCentimeter = 200, }); @@ -374,65 +301,25 @@ namespace Tango.ColorLib.GradientTest.CLI { ColorSpace = ColorSpace.Lab, Offset = 0.0, - L = 52, - A =-40, - B = -48, - }); - input.Stops.Add(new GradientInputStop() - { - ColorSpace = ColorSpace.Lab, - Offset = 0.15, - L = 44, - A = 2.88, - B = -38.36, - }); - input.Stops.Add(new GradientInputStop() - { - ColorSpace = ColorSpace.Lab, - Offset = 0.30, - L = 47.21, - A = 63.70, - B = 2.57, + L = 44.75, + A = 15.14, + B = -32.5, }); input.Stops.Add(new GradientInputStop() { ColorSpace = ColorSpace.Lab, - Offset = 0.45, - L = 51.92, - A = 54.73, - B = 35.87, - }); - input.Stops.Add(new GradientInputStop() - { - ColorSpace = ColorSpace.Lab, - Offset = 0.60, - L = 56.34, - A = 50.22, - B = 49.18, - }); - input.Stops.Add(new GradientInputStop() - { - ColorSpace = ColorSpace.Lab, - Offset = 0.75, - L =82, - A =-0.52, - B = 85, - }); - input.Stops.Add(new GradientInputStop() - { - ColorSpace = ColorSpace.Lab, - Offset = 0.90, - L = 51, - A =-32, - B =18, + Offset = 0.5, + L = 39.70, + A = 25.0, + B = -4.8, }); input.Stops.Add(new GradientInputStop() { ColorSpace = ColorSpace.Lab, Offset = 1, - L = 52, - A = -40, - B = -48, + L = 53, + A = -15.0, + B = -35, }); Console.WriteLine($"TestLABGamutRegion0 input:\n{input.ToJsonString(nameof(input.ForwardData), nameof(CalibrationData))}"); @@ -456,7 +343,7 @@ namespace Tango.ColorLib.GradientTest.CLI static void TestVolumeGamutRegion0(GradientGenerator generator) { GradientConversionInput input = CreateBaseGradientConversionInput(); - + GradientInputStop gradientInputStop1 = new GradientInputStop() { ColorSpace = ColorSpace.Volume, @@ -483,7 +370,7 @@ namespace Tango.ColorLib.GradientTest.CLI Volume = 0 }); input.Stops.Add(gradientInputStop1); - + GradientInputStop gradientInputStop2 = new GradientInputStop() { ColorSpace = ColorSpace.Volume, @@ -559,7 +446,7 @@ namespace Tango.ColorLib.GradientTest.CLI static void TestVolumeGamutRegion1(GradientGenerator generator) { GradientConversionInput input = CreateBaseGradientConversionInput(); - + GradientInputStop gradientInputStop1 = new GradientInputStop() { ColorSpace = ColorSpace.Volume, @@ -815,7 +702,7 @@ namespace Tango.ColorLib.GradientTest.CLI Green = 123, Blue = 95, }); - + input.Stops.Add(new GradientInputStop() { ColorSpace = ColorSpace.Lab, @@ -824,7 +711,7 @@ namespace Tango.ColorLib.GradientTest.CLI A = -10, B = -10, }); - + GradientInputStop gradientInputStop1 = new GradientInputStop() { ColorSpace = ColorSpace.Volume, |
