799 DataCLUT ->Params,
800 Dest ->InputChannels,
801 DataSetIn,
802 Dest ->OutputChannels,
803 DataSetOut);
804
805 _cmsPipelineSetOptimizationParameters(Dest, PrelinEval16, (void*) p16, PrelinOpt16free, Prelin16dup);
806 }
807
808
809 // Don't fix white on absolute colorimetric
810 if (Intent == INTENT_ABSOLUTE_COLORIMETRIC)
811 *dwFlags |= cmsFLAGS_NOWHITEONWHITEFIXUP;
812
813 if (!(*dwFlags & cmsFLAGS_NOWHITEONWHITEFIXUP)) {
814
815 FixWhiteMisalignment(Dest, ColorSpace, OutputColorSpace);
816 }
817
818 *Lut = Dest;
819 return TRUE;
820
821 cmsUNUSED_PARAMETER(Intent);
822 }
823
824
825 // -----------------------------------------------------------------------------------------------------------------------------------------------
826 // Fixes the gamma balancing of transform. This is described in my paper "Prelinearization Stages on
827 // Color-Management Application-Specific Integrated Circuits (ASICs)" presented at NIP24. It only works
828 // for RGB transforms. See the paper for more details
829 // -----------------------------------------------------------------------------------------------------------------------------------------------
830
831
832 // Normalize endpoints by slope limiting max and min. This assures endpoints as well.
833 // Descending curves are handled as well.
834 static
835 void SlopeLimiting(cmsToneCurve* g)
836 {
837 int BeginVal, EndVal;
838 int AtBegin = (int) floor((cmsFloat64Number) g ->nEntries * 0.02 + 0.5); // Cutoff at 2%
839 int AtEnd = g ->nEntries - AtBegin - 1; // And 98%
840 cmsFloat64Number Val, Slope, beta;
841 int i;
1224 }
1225 }
1226
1227 // And return the obtained LUT
1228
1229 cmsPipelineFree(OriginalLut);
1230 *Lut = OptimizedLUT;
1231 return TRUE;
1232
1233 Error:
1234
1235 for (t = 0; t < OriginalLut ->InputChannels; t++) {
1236
1237 if (Trans[t]) cmsFreeToneCurve(Trans[t]);
1238 if (TransReverse[t]) cmsFreeToneCurve(TransReverse[t]);
1239 }
1240
1241 if (LutPlusCurves != NULL) cmsPipelineFree(LutPlusCurves);
1242 if (OptimizedLUT != NULL) cmsPipelineFree(OptimizedLUT);
1243
1244 return FALSE;
1245
1246 cmsUNUSED_PARAMETER(Intent);
1247 }
1248
1249
1250 // Curves optimizer ------------------------------------------------------------------------------------------------------------------
1251
1252 static
1253 void CurvesFree(cmsContext ContextID, void* ptr)
1254 {
1255 Curves16Data* Data = (Curves16Data*) ptr;
1256 int i;
1257
1258 for (i=0; i < Data -> nCurves; i++) {
1259
1260 _cmsFree(ContextID, Data ->Curves[i]);
1261 }
1262
1263 _cmsFree(ContextID, Data ->Curves);
1264 _cmsFree(ContextID, ptr);
1265 }
1266
1472 _cmsPipelineSetOptimizationParameters(Dest, FastIdentity16, (void*) Dest, NULL, NULL);
1473 }
1474
1475 // We are done.
1476 cmsPipelineFree(Src);
1477 *Lut = Dest;
1478 return TRUE;
1479
1480 Error:
1481
1482 if (ObtainedCurves != NULL) cmsStageFree(ObtainedCurves);
1483 if (GammaTables != NULL) {
1484 for (i=0; i < Src ->InputChannels; i++) {
1485 if (GammaTables[i] != NULL) cmsFreeToneCurve(GammaTables[i]);
1486 }
1487
1488 _cmsFree(Src ->ContextID, GammaTables);
1489 }
1490
1491 if (Dest != NULL) cmsPipelineFree(Dest);
1492 return FALSE;
1493
1494 cmsUNUSED_PARAMETER(Intent);
1495 cmsUNUSED_PARAMETER(InputFormat);
1496 cmsUNUSED_PARAMETER(OutputFormat);
1497 cmsUNUSED_PARAMETER(dwFlags);
1498 }
1499
1500 // -------------------------------------------------------------------------------------------------------------------------------------
1501 // LUT is Shaper - Matrix - Matrix - Shaper, which is very frequent when combining two matrix-shaper profiles
1502
1503
1504 static
1505 void FreeMatShaper(cmsContext ContextID, void* Data)
1506 {
1507 if (Data != NULL) _cmsFree(ContextID, Data);
1508 }
1509
1510 static
1511 void* DupMatShaper(cmsContext ContextID, const void* Data)
1512 {
1513 return _cmsDupMem(ContextID, Data, sizeof(MatShaper8Data));
1514 }
1515
1516
1517 // A fast matrix-shaper evaluator for 8 bits. This is a bit ticky since I'm using 1.14 signed fixed point
|
799 DataCLUT ->Params,
800 Dest ->InputChannels,
801 DataSetIn,
802 Dest ->OutputChannels,
803 DataSetOut);
804
805 _cmsPipelineSetOptimizationParameters(Dest, PrelinEval16, (void*) p16, PrelinOpt16free, Prelin16dup);
806 }
807
808
809 // Don't fix white on absolute colorimetric
810 if (Intent == INTENT_ABSOLUTE_COLORIMETRIC)
811 *dwFlags |= cmsFLAGS_NOWHITEONWHITEFIXUP;
812
813 if (!(*dwFlags & cmsFLAGS_NOWHITEONWHITEFIXUP)) {
814
815 FixWhiteMisalignment(Dest, ColorSpace, OutputColorSpace);
816 }
817
818 *Lut = Dest;
819
820 cmsUNUSED_PARAMETER(Intent);
821
822 return TRUE;
823
824 }
825
826
827 // -----------------------------------------------------------------------------------------------------------------------------------------------
828 // Fixes the gamma balancing of transform. This is described in my paper "Prelinearization Stages on
829 // Color-Management Application-Specific Integrated Circuits (ASICs)" presented at NIP24. It only works
830 // for RGB transforms. See the paper for more details
831 // -----------------------------------------------------------------------------------------------------------------------------------------------
832
833
834 // Normalize endpoints by slope limiting max and min. This assures endpoints as well.
835 // Descending curves are handled as well.
836 static
837 void SlopeLimiting(cmsToneCurve* g)
838 {
839 int BeginVal, EndVal;
840 int AtBegin = (int) floor((cmsFloat64Number) g ->nEntries * 0.02 + 0.5); // Cutoff at 2%
841 int AtEnd = g ->nEntries - AtBegin - 1; // And 98%
842 cmsFloat64Number Val, Slope, beta;
843 int i;
1226 }
1227 }
1228
1229 // And return the obtained LUT
1230
1231 cmsPipelineFree(OriginalLut);
1232 *Lut = OptimizedLUT;
1233 return TRUE;
1234
1235 Error:
1236
1237 for (t = 0; t < OriginalLut ->InputChannels; t++) {
1238
1239 if (Trans[t]) cmsFreeToneCurve(Trans[t]);
1240 if (TransReverse[t]) cmsFreeToneCurve(TransReverse[t]);
1241 }
1242
1243 if (LutPlusCurves != NULL) cmsPipelineFree(LutPlusCurves);
1244 if (OptimizedLUT != NULL) cmsPipelineFree(OptimizedLUT);
1245
1246 cmsUNUSED_PARAMETER(Intent);
1247 return FALSE;
1248
1249 }
1250
1251
1252 // Curves optimizer ------------------------------------------------------------------------------------------------------------------
1253
1254 static
1255 void CurvesFree(cmsContext ContextID, void* ptr)
1256 {
1257 Curves16Data* Data = (Curves16Data*) ptr;
1258 int i;
1259
1260 for (i=0; i < Data -> nCurves; i++) {
1261
1262 _cmsFree(ContextID, Data ->Curves[i]);
1263 }
1264
1265 _cmsFree(ContextID, Data ->Curves);
1266 _cmsFree(ContextID, ptr);
1267 }
1268
1474 _cmsPipelineSetOptimizationParameters(Dest, FastIdentity16, (void*) Dest, NULL, NULL);
1475 }
1476
1477 // We are done.
1478 cmsPipelineFree(Src);
1479 *Lut = Dest;
1480 return TRUE;
1481
1482 Error:
1483
1484 if (ObtainedCurves != NULL) cmsStageFree(ObtainedCurves);
1485 if (GammaTables != NULL) {
1486 for (i=0; i < Src ->InputChannels; i++) {
1487 if (GammaTables[i] != NULL) cmsFreeToneCurve(GammaTables[i]);
1488 }
1489
1490 _cmsFree(Src ->ContextID, GammaTables);
1491 }
1492
1493 if (Dest != NULL) cmsPipelineFree(Dest);
1494 cmsUNUSED_PARAMETER(Intent);
1495 cmsUNUSED_PARAMETER(InputFormat);
1496 cmsUNUSED_PARAMETER(OutputFormat);
1497 cmsUNUSED_PARAMETER(dwFlags);
1498
1499 return FALSE;
1500
1501 }
1502
1503 // -------------------------------------------------------------------------------------------------------------------------------------
1504 // LUT is Shaper - Matrix - Matrix - Shaper, which is very frequent when combining two matrix-shaper profiles
1505
1506
1507 static
1508 void FreeMatShaper(cmsContext ContextID, void* Data)
1509 {
1510 if (Data != NULL) _cmsFree(ContextID, Data);
1511 }
1512
1513 static
1514 void* DupMatShaper(cmsContext ContextID, const void* Data)
1515 {
1516 return _cmsDupMem(ContextID, Data, sizeof(MatShaper8Data));
1517 }
1518
1519
1520 // A fast matrix-shaper evaluator for 8 bits. This is a bit ticky since I'm using 1.14 signed fixed point
|