summaryrefslogtreecommitdiffstats
path: root/src/libs/lprof/cmsmntr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/lprof/cmsmntr.cpp')
-rw-r--r--src/libs/lprof/cmsmntr.cpp371
1 files changed, 371 insertions, 0 deletions
diff --git a/src/libs/lprof/cmsmntr.cpp b/src/libs/lprof/cmsmntr.cpp
new file mode 100644
index 00000000..ed14ed50
--- /dev/null
+++ b/src/libs/lprof/cmsmntr.cpp
@@ -0,0 +1,371 @@
+/* */
+/* Little cms - profiler construction set */
+/* Copyright (C) 1998-2001 Marti Maria <marti@littlecms.com> */
+/* */
+/* THIS SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY */
+/* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. */
+/* */
+/* IN NO EVENT SHALL MARTI MARIA BE LIABLE FOR ANY SPECIAL, INCIDENTAL, */
+/* INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, */
+/* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, */
+/* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF */
+/* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE */
+/* OF THIS SOFTWARE. */
+/* */
+/* This file is free software; you can redistribute it and/or modify it */
+/* under the terms of the GNU General Public License as published by */
+/* the Free Software Foundation; either version 2 of the License, or */
+/* (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, but */
+/* WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+/* */
+/* As a special exception to the GNU General Public License, if you */
+/* distribute this file as part of a program that contains a */
+/* configuration script generated by Autoconf, you may include it under */
+/* the same distribution terms that you use for the rest of that program. */
+/* */
+/* Version 1.09a */
+
+
+#include "lcmsprf.h"
+
+
+static
+void ClampRGB(LPVEC3 RGB)
+{
+ int i;
+
+ for (i=0; i < 3; i++) {
+
+ if (RGB->n[i] > 1.0)
+ RGB->n[i] = 1.0;
+ if (RGB->n[i] < 0)
+ RGB->n[i] = 0;
+ }
+}
+
+
+static
+int RegressionSamplerA2B(WORD In[], WORD Out[], LPVOID Cargo)
+{
+ cmsCIEXYZ xyz;
+ cmsCIELab Lab;
+ VEC3 RGB, RGBlinear, vxyz;
+ LPMONITORPROFILERDATA sys = (LPMONITORPROFILERDATA) Cargo;
+
+
+ RGB.n[0] = _cmsxSaturate65535To255(In[0]);
+ RGB.n[1] = _cmsxSaturate65535To255(In[1]);
+ RGB.n[2] = _cmsxSaturate65535To255(In[2]);
+
+ cmsxApplyLinearizationTable(RGB.n, sys->PreLab, RGBlinear.n);
+ cmsxApplyLinearizationTable(RGBlinear.n, sys->Prelinearization, RGBlinear.n);
+
+ RGBlinear.n[0] /= 255.;
+ RGBlinear.n[1] /= 255.;
+ RGBlinear.n[2] /= 255.;
+
+ MAT3eval(&vxyz, &sys->PrimariesMatrix, &RGBlinear);
+
+ xyz.X = vxyz.n[0];
+ xyz.Y = vxyz.n[1];
+ xyz.Z = vxyz.n[2];
+
+ cmsxChromaticAdaptationAndNormalization(&sys ->hdr, &xyz, false);
+
+
+ /* To PCS encoding */
+
+ cmsXYZ2Lab(NULL, &Lab, &xyz);
+ cmsFloat2LabEncoded(Out, &Lab);
+
+
+ return true; /* And done witch success */
+}
+
+
+
+
+static
+int RegressionSamplerB2A(WORD In[], WORD Out[], LPVOID Cargo)
+{
+ cmsCIELab Lab;
+ cmsCIEXYZ xyz;
+ VEC3 vxyz, RGB;
+ /* cmsJCh JCh; */
+ WORD Lin[3], Llab[3];
+ LPMONITORPROFILERDATA sys = (LPMONITORPROFILERDATA) Cargo;
+ double L;
+
+
+ /* Pass L back to 0..0xff00 domain */
+
+ L = (double) (In[0] * 65280.0) / 65535.0;
+ In[0] = (WORD) floor(L + .5);
+
+
+ /* To float values */
+ cmsLabEncoded2Float(&Lab, In);
+ cmsLab2XYZ(NULL, &xyz, &Lab);
+
+
+ cmsxChromaticAdaptationAndNormalization(&sys ->hdr, &xyz, true);
+ vxyz.n[0] = xyz.X;
+ vxyz.n[1] = xyz.Y;
+ vxyz.n[2] = xyz.Z;
+
+ MAT3eval(&RGB, &sys-> PrimariesMatrixRev, &vxyz);
+
+ /* Clamp RGB */
+ ClampRGB(&RGB);
+
+ /* Encode output */
+ Lin[0] = (WORD) ((double) RGB.n[0] * 65535. + .5);
+ Lin[1] = (WORD) ((double) RGB.n[1] * 65535. + .5);
+ Lin[2] = (WORD) ((double) RGB.n[2] * 65535. + .5);
+
+ cmsxApplyLinearizationGamma(Lin, sys ->ReverseTables, Llab);
+ cmsxApplyLinearizationGamma(Llab, sys ->PreLabRev, Out);
+
+
+ return true; /* And done witch success */
+}
+
+
+BOOL cmsxMonitorProfilerInit(LPMONITORPROFILERDATA sys)
+{
+
+
+ if (sys == NULL) return false;
+ ZeroMemory(sys, sizeof(MONITORPROFILERDATA));
+
+ sys->hdr.DeviceClass = icSigDisplayClass;
+ sys->hdr.ColorSpace = icSigRgbData;
+ sys->hdr.PCSType = PT_Lab;
+ sys->hdr.Medium = MEDIUM_TRANSMISSIVE;
+
+
+ /* Default values for generation */
+
+ sys -> hdr.lUseCIECAM97s = false;
+ sys -> hdr.CLUTPoints = 16;
+
+ /* Default viewing conditions */
+
+ sys -> hdr.device.Yb = 20;
+ sys -> hdr.device.La = 20;
+ sys -> hdr.device.surround = AVG_SURROUND;
+ sys -> hdr.device.D_value = 1; /* Complete adaptation */
+
+
+ /* Viewing conditions of PCS */
+ cmsxInitPCSViewingConditions(&sys ->hdr);
+
+ strcpy(sys -> hdr.Description, "unknown monitor");
+ strcpy(sys -> hdr.Manufacturer, "little cms profiler construction set");
+ strcpy(sys -> hdr.Copyright, "No copyright, use freely");
+ strcpy(sys -> hdr.Model, "(unknown)");
+
+ sys -> hdr.ProfileVerbosityLevel = 0;
+
+ return true;
+}
+
+
+static
+void CreatePrimaryMatrices(LPMONITORPROFILERDATA sys)
+{
+ cmsCIExyY White;
+ MAT3 tmp;
+
+
+ cmsXYZ2xyY(&White, &sys->hdr.WhitePoint);
+ cmsBuildRGB2XYZtransferMatrix(&sys -> PrimariesMatrix, &White, &sys->hdr.Primaries);
+
+ CopyMemory(&tmp, &sys -> PrimariesMatrix, sizeof(MAT3));
+ MAT3inverse(&tmp, &sys->PrimariesMatrixRev);
+
+}
+
+
+static
+BOOL CreateLUTS(LPMONITORPROFILERDATA sys, LPLUT* A2B, LPLUT* B2A)
+{
+ LPLUT AToB0 = cmsAllocLUT();
+ LPLUT BToA0 = cmsAllocLUT();
+ LPGAMMATABLE LabG;
+ cmsCIExyY xyY;
+
+
+ cmsAlloc3DGrid(AToB0, sys->hdr.CLUTPoints, 3, 3);
+ cmsAlloc3DGrid(BToA0, sys->hdr.CLUTPoints, 3, 3);
+
+ /* cmsAllocLinearTable(AToB0, sys -> Prelinearization, 1); */
+
+ sys->ReverseTables[0] = cmsReverseGamma(4096, sys ->Prelinearization[0]);
+ sys->ReverseTables[1] = cmsReverseGamma(4096, sys ->Prelinearization[1]);
+ sys->ReverseTables[2] = cmsReverseGamma(4096, sys ->Prelinearization[2]);
+
+ /* Prelinearization */
+
+ LabG = cmsBuildGamma(4096, 3.0);
+
+ sys -> PreLab[0] = cmsJoinGammaEx(LabG, sys ->Prelinearization[0], 4096);
+ sys -> PreLab[1] = cmsJoinGammaEx(LabG, sys ->Prelinearization[1], 4096);
+ sys -> PreLab[2] = cmsJoinGammaEx(LabG, sys ->Prelinearization[2], 4096);
+
+ sys -> PreLabRev[0] = cmsJoinGammaEx(sys ->Prelinearization[0], LabG, 4096);
+ sys -> PreLabRev[1] = cmsJoinGammaEx(sys ->Prelinearization[1], LabG, 4096);
+ sys -> PreLabRev[2] = cmsJoinGammaEx(sys ->Prelinearization[2], LabG, 4096);
+
+
+ cmsFreeGamma(LabG);
+
+
+ cmsAllocLinearTable(AToB0, sys->PreLabRev, 1);
+ cmsAllocLinearTable(BToA0, sys->PreLab, 2);
+
+
+ /* Set CIECAM97s parameters */
+
+ sys -> hdr.device.whitePoint.X = sys -> hdr.WhitePoint.X * 100.;
+ sys -> hdr.device.whitePoint.Y = sys -> hdr.WhitePoint.Y * 100.;
+ sys -> hdr.device.whitePoint.Z = sys -> hdr.WhitePoint.Z * 100.;
+
+
+ /* Normalize White point for CIECAM97s model */
+ cmsXYZ2xyY(&xyY, &sys -> hdr.device.whitePoint);
+ xyY.Y = 100.;
+ cmsxyY2XYZ(&sys -> hdr.device.whitePoint, &xyY);
+
+
+ sys->hdr.hDevice = cmsCIECAM97sInit(&sys->hdr.device);
+ sys->hdr.hPCS = cmsCIECAM97sInit(&sys->hdr.PCS);
+
+
+ cmsSample3DGrid(AToB0, RegressionSamplerA2B, sys, 0);
+ cmsSample3DGrid(BToA0, RegressionSamplerB2A, sys, 0);
+
+ cmsCIECAM97sDone(sys->hdr.hDevice);
+ cmsCIECAM97sDone(sys->hdr.hPCS);
+
+ cmsAddTag(sys->hdr.hProfile, icSigAToB0Tag, AToB0);
+ cmsAddTag(sys->hdr.hProfile, icSigBToA0Tag, BToA0);
+
+ /* This is the 0xff00 trick to map white at lattice point */
+ BToA0 ->Matrix.v[0].n[0] = DOUBLE_TO_FIXED((65535.0 / 65280.0));
+
+ *A2B = AToB0;
+ *B2A = BToA0;
+
+ cmsFreeGammaTriple(sys->ReverseTables);
+ cmsFreeGammaTriple(sys->PreLab);
+ cmsFreeGammaTriple(sys->PreLabRev);
+ return true;
+}
+
+
+
+BOOL cmsxMonitorProfilerDo(LPMONITORPROFILERDATA sys)
+{
+
+ cmsCIExyY White;
+ LPLUT AToB0, BToA0;
+
+ AToB0 = BToA0 = NULL;
+
+ if (!*sys -> hdr.OutputProfileFile)
+ return false;
+
+
+ if (sys->hdr.ReferenceSheet[0] || sys->hdr.MeasurementSheet[0]) {
+
+ if (sys->hdr.printf) {
+
+ sys->hdr.printf("Loading sheets...");
+
+ if (sys->hdr.ReferenceSheet[0])
+ sys->hdr.printf("Reference sheet: %s", sys->hdr.ReferenceSheet);
+ if (sys->hdr.MeasurementSheet[0])
+ sys->hdr.printf("Measurement sheet: %s", sys->hdr.MeasurementSheet);
+ }
+
+
+ if (!cmsxComputeMatrixShaper(sys -> hdr.ReferenceSheet,
+ sys -> hdr.MeasurementSheet,
+ MEDIUM_TRANSMISSIVE,
+ sys -> Prelinearization,
+ &sys -> hdr.WhitePoint,
+ &sys -> hdr.BlackPoint,
+ &sys -> hdr.Primaries)) return false;
+
+ if (sys->hdr.printf) {
+
+ char Buffer[1024];
+ _cmsIdentifyWhitePoint(Buffer, &sys ->hdr.WhitePoint);
+ sys->hdr.printf("%s", Buffer);
+
+ sys->hdr.printf("Primaries: R:%1.2g, %1.2g G:%1.2g, %1.2g B:%1.2g, %1.2g",
+ sys->hdr.Primaries.Red.x,sys->hdr.Primaries.Red.y,
+ sys->hdr.Primaries.Green.x, sys->hdr.Primaries.Green.y,
+ sys->hdr.Primaries.Blue.x, sys->hdr.Primaries.Blue.y);
+ }
+
+ }
+
+
+ CreatePrimaryMatrices(sys);
+
+
+ cmsXYZ2xyY(&White, &sys->hdr.WhitePoint);
+
+ sys->hdr.hProfile = cmsCreateRGBProfile(&White,
+ &sys-> hdr.Primaries,
+ sys -> Prelinearization);
+
+ cmsSetDeviceClass(sys->hdr.hProfile, sys->hdr.DeviceClass);
+
+ if (sys -> hdr.lUseCIECAM97s)
+ sys->hdr.PCSType = PT_Lab;
+ else
+ sys->hdr.PCSType = PT_XYZ;
+
+ cmsSetPCS(sys->hdr.hProfile, _cmsICCcolorSpace(sys->hdr.PCSType));
+
+ if (sys -> hdr.lUseCIECAM97s)
+ CreateLUTS(sys, &AToB0, &BToA0);
+
+
+ cmsxEmbedTextualInfo(&sys ->hdr);
+
+ cmsAddTag(sys->hdr.hProfile, icSigMediaWhitePointTag, &sys->hdr.WhitePoint);
+ cmsAddTag(sys->hdr.hProfile, icSigMediaBlackPointTag, &sys->hdr.BlackPoint);
+
+
+ if (sys->hdr.ProfileVerbosityLevel >= 2) {
+
+ cmsxEmbedCharTarget(&sys ->hdr);
+ }
+
+
+ _cmsSaveProfile(sys->hdr.hProfile, sys->hdr.OutputProfileFile);
+ cmsCloseProfile(sys->hdr.hProfile);
+ sys->hdr.hProfile = NULL;
+
+
+ if (AToB0) cmsFreeLUT(AToB0);
+ if (BToA0) cmsFreeLUT(BToA0);
+
+ if (sys ->Prelinearization[0])
+ cmsFreeGammaTriple(sys -> Prelinearization);
+
+ return true;
+}