Subversion Repositories Scribus

Compare Revisions

Ignore whitespace Rev 2454 → Rev 2453

/trunk/lprof/include/lcmsprf.h
File deleted
Property changes:
Deleted: svn:eol-style
## -1 +0,0 ##
-native
\ No newline at end of property
Deleted: svn:keywords
## -1 +0,0 ##
-Author Date Id Revision
\ No newline at end of property
Index: trunk/lprof/src/cmsmntr.c
===================================================================
--- trunk/lprof/src/cmsmntr.c (revision 2454)
+++ trunk/lprof/src/cmsmntr.c (nonexistent)
@@ -1,371 +0,0 @@
-//
-// Little cms - profiler construction set
-// Copyright (C) 1998-2001 Marti Maria
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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(register WORD In[], register WORD Out[], register 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(register WORD In[], register WORD Out[], register 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;
-}
/trunk/lprof/src/cmsmntr.c
Property changes:
Deleted: svn:eol-style
## -1 +0,0 ##
-native
\ No newline at end of property
Deleted: svn:keywords
## -1 +0,0 ##
-Author Date Id Revision
\ No newline at end of property
Index: trunk/lprof/src/cmsscn.c
===================================================================
--- trunk/lprof/src/cmsscn.c (revision 2454)
+++ trunk/lprof/src/cmsscn.c (nonexistent)
@@ -1,422 +0,0 @@
-//
-// Little cms - profiler construction set
-// Copyright (C) 1998-2001 Marti Maria
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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.08a
-
-
-#include "lcmsprf.h"
-#include <stdio.h>
-
-// The scanner profiler
-
-
-BOOL cdecl cmsxScannerProfilerInit(LPSCANNERPROFILERDATA sys);
-BOOL cdecl cmsxScannerProfilerDo(LPSCANNERPROFILERDATA sys);
-
-// ------------------------------------------------------------ Implementation
-
-
-
-// Does create regression matrix
-
-static
-void ComputeGlobalRegression(LPSCANNERPROFILERDATA sys)
-{
- BOOL lAllOk;
- int nTerms;
- MLRSTATISTICS Stat;
-
- nTerms = cmsxFindOptimumNumOfTerms(&sys ->hdr, 55, &lAllOk);
-
-
- if (!lAllOk) {
- if (sys -> hdr.printf)
- sys -> hdr.printf("*** WARNING: Inconsistence found, profile may be wrong. Check the target!");
- nTerms = 4;
- }
-
- // Create high terms matrix used by interpolation
- cmsxRegressionCreateMatrix(&sys -> hdr.m,
- sys -> hdr.m.Allowed,
- nTerms,
- sys -> hdr.PCSType,
- &sys -> HiTerms,
- &Stat);
-
- if (sys -> hdr.printf)
- sys -> hdr.printf("Global regression: %d terms, R2Adj = %g", nTerms, Stat.R2adj);
-
- // Create low terms matrix used by extrapolation
- cmsxRegressionCreateMatrix(&sys -> hdr.m,
- sys -> hdr.m.Allowed,
- (nTerms > 10 ? 10 : nTerms),
- sys -> hdr.PCSType,
- &sys -> LoTerms,
- &Stat);
- if (sys -> hdr.printf)
- sys -> hdr.printf("Extrapolation: R2Adj = %g", Stat.R2adj);
-
-}
-
-
-// Fill struct with default values
-
-BOOL cmsxScannerProfilerInit(LPSCANNERPROFILERDATA sys)
-{
-
-
- if (sys == NULL) return FALSE;
- ZeroMemory(sys, sizeof(SCANNERPROFILERDATA));
-
- sys->hdr.DeviceClass = icSigInputClass;
- sys->hdr.ColorSpace = icSigRgbData;
- sys->hdr.PCSType = PT_Lab;
- sys->hdr.Medium = MEDIUM_REFLECTIVE_D50;
-
- // Default values for generation
-
- sys -> hdr.lUseCIECAM97s = FALSE;
- sys -> hdr.CLUTPoints = 16;
-
-
- // Default viewing conditions for scanner
-
- sys -> hdr.device.Yb = 20;
- sys -> hdr.device.La = 20;
- sys -> hdr.device.surround = AVG_SURROUND;
- sys -> hdr.device.D_value = 1.0; // Complete adaptation
-
-
- // Viewing conditions of PCS
- cmsxInitPCSViewingConditions(&sys -> hdr);
-
-
- sys -> HiTerms = NULL;
- sys -> LoTerms = NULL;
-
- strcpy(sys -> hdr.Description, "no description");
- strcpy(sys -> hdr.Manufacturer, "little cms profiler construction set");
- strcpy(sys -> hdr.Copyright, "No copyright, use freely");
- strcpy(sys -> hdr.Model, "(unknown)");
-
- sys ->lLocalConvergenceExtrapolation = FALSE;
- sys ->hdr.ProfileVerbosityLevel = 0;
-
-
- return TRUE;
-}
-
-// Auxiliar: take RGB and update gauge
-static
-void GetRGB(LPPROFILERCOMMONDATA hdr, register WORD In[], double* r, double* g, double* b)
-{
- static int Count = 0, n_old = 0;
- double R, G, B;
- int n;
-
-
- R = _cmsxSaturate65535To255(In[0]); // Convert from the sheet notation
- G = _cmsxSaturate65535To255(In[1]); // 0..255.0, to our notation
- B = _cmsxSaturate65535To255(In[2]); // of 0..0xffff, 0xffff/255 = 257
-
- if (R == 0 && G == 0 && B == 0) {
- Count = 0; n_old = -1;
- }
-
- n = (int) (double) (100. * Count) / (hdr->CLUTPoints * hdr->CLUTPoints * hdr->CLUTPoints);
- Count++;
-
- if (n > n_old) {
- if (hdr->Gauger) hdr->Gauger("", 0, 100, (int) n);
- }
-
- n_old = n;
- *r = R; *g = G; *b = B;
-
-}
-
-
-
-
-
-// The sampler for Lab
-static
-int RegressionSamplerLab(register WORD In[], register WORD Out[], register LPVOID Cargo)
-{
- cmsCIEXYZ xyz;
- cmsCIELab Lab;
- double r, g, b;
- LPSCANNERPROFILERDATA sys = (LPSCANNERPROFILERDATA) Cargo;
- char code;
-
-
- GetRGB(&sys->hdr, In, &r, &g, &b);
-
-
- code = cmsxHullCheckpoint(sys->hdr.hRGBHull,
- (int) floor(r + .5),
- (int) floor(g + .5),
- (int) floor(b + .5));
-
-
- if (code == 'i') { // Inside gamut
-
- if (!cmsxRegressionRGB2Lab(r, g, b, sys -> HiTerms, &Lab)) return FALSE;
- }
- else
- if (!sys -> lLocalConvergenceExtrapolation && code == 'o') { // outside gamut
-
- if (!cmsxRegressionRGB2Lab(r, g, b, sys -> LoTerms, &Lab)) return FALSE;
- }
- else { // At gamut hull boundaries
-
- if (!cmsxRegressionInterpolatorRGB(&sys -> hdr.m,
- PT_Lab,
- 10,
- TRUE,
- 30,
- r, g, b,
- &Lab)) return FALSE;
- }
-
-
- // Regression CAN deliver wrong values. Clamp these.
- cmsClampLab(&Lab, 127.9961, -128, 127.9961, -128);
-
- // Normalize
- cmsLab2XYZ(cmsD50_XYZ(), &xyz, &Lab);
- cmsxChromaticAdaptationAndNormalization(&sys->hdr, &xyz, FALSE);
- cmsXYZ2Lab(cmsD50_XYZ(), &Lab, &xyz);
-
- // Clamping again, adaptation could move slightly values
- cmsClampLab(&Lab, 127.9961, -128, 127.9961, -128);
-
- // To PCS encoding
- cmsFloat2LabEncoded(Out, &Lab);
-
-
- return TRUE; // And done with success
-}
-
-
-
-
-
-// The sampler for XYZ
-static
-int RegressionSamplerXYZ(register WORD In[], register WORD Out[], register LPVOID Cargo)
-{
- cmsCIEXYZ xyz;
- double r, g, b;
- LPSCANNERPROFILERDATA sys = (LPSCANNERPROFILERDATA) Cargo;
- char code;
-
- GetRGB(&sys -> hdr, In, &r, &g, &b);
-
- code = cmsxHullCheckpoint(sys ->hdr.hRGBHull,
- (int) floor(r + .5),
- (int) floor(g + .5),
- (int) floor(b + .5));
-
- if (code == 'i') { // Inside gamut
-
- if (!cmsxRegressionRGB2XYZ(r, g, b, sys -> HiTerms, &xyz)) return FALSE;
- }
- else
- if (!sys -> lLocalConvergenceExtrapolation && code == 'o') { // outside gamut
-
- if (!cmsxRegressionRGB2XYZ(r, g, b, sys -> LoTerms, &xyz)) return FALSE;
- }
-
- else { // At gamut hull boundaries
-
- if (!cmsxRegressionInterpolatorRGB(&sys -> hdr.m,
- PT_XYZ,
- 10,
- TRUE,
- 30,
- r, g, b,
- &xyz)) return FALSE;
- }
-
-
- xyz.X /= 100.;
- xyz.Y /= 100.;
- xyz.Z /= 100.;
-
- cmsxChromaticAdaptationAndNormalization(&sys->hdr, &xyz, FALSE);
-
- // To PCS encoding. It also claps bad values
- cmsFloat2XYZEncoded(Out, &xyz);
-
- return TRUE; // And done witch success
-}
-
-
-
-// The main scanner profiler
-BOOL cmsxScannerProfilerDo(LPSCANNERPROFILERDATA sys)
-{
-
- LPLUT AToB0;
- DWORD dwNeedSamples;
-
-
- if (!*sys -> hdr.OutputProfileFile)
- return FALSE;
-
-
- if (!cmsxChoosePCS(&sys->hdr))
- return FALSE;
-
- dwNeedSamples = PATCH_HAS_RGB;
- if (sys ->hdr.PCSType == PT_Lab)
- dwNeedSamples |= PATCH_HAS_Lab;
- else
- dwNeedSamples |= PATCH_HAS_XYZ;
-
-
- 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 (!cmsxPCollBuildMeasurement(&sys->hdr.m,
- sys->hdr.ReferenceSheet,
- sys->hdr.MeasurementSheet,
- dwNeedSamples)) return FALSE;
-
-
-
- sys->hdr.hProfile = cmsCreateRGBProfile(NULL, NULL, NULL);
-
-
- cmsSetDeviceClass(sys->hdr.hProfile, sys->hdr.DeviceClass);
- cmsSetColorSpace(sys->hdr.hProfile, sys->hdr.ColorSpace);
- cmsSetPCS(sys->hdr. hProfile, _cmsICCcolorSpace(sys->hdr.PCSType));
-
- // Save char target tag
- if (sys->hdr.ProfileVerbosityLevel >= 2) {
-
- cmsxEmbedCharTarget(&sys ->hdr);
- }
-
- AToB0 = cmsAllocLUT();
-
- cmsAlloc3DGrid(AToB0, sys->hdr.CLUTPoints, 3, 3);
-
- cmsxComputeLinearizationTables(&sys-> hdr.m,
- sys -> hdr.PCSType,
- sys -> Prelinearization,
- 1024,
- MEDIUM_REFLECTIVE_D50);
-
- // Refresh RGB of all patches. This converts all regression into
- // near linear RGB->Lab or XYZ
-
- cmsxPCollLinearizePatches(&sys->hdr.m, sys -> hdr.m.Allowed, sys -> Prelinearization);
-
- cmsxComputeGamutHull(&sys->hdr);
- ComputeGlobalRegression(sys);
-
- cmsAllocLinearTable(AToB0, sys -> Prelinearization, 1);
-
- // 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.;
-
-
- sys->hdr.hDevice = cmsCIECAM97sInit(&sys->hdr.device);
- sys->hdr.hPCS = cmsCIECAM97sInit(&sys->hdr.PCS);
-
-
- if (sys -> hdr.PCSType == PT_Lab)
- cmsSample3DGrid(AToB0, RegressionSamplerLab, sys, 0);
- else
- cmsSample3DGrid(AToB0, RegressionSamplerXYZ, sys, 0);
-
- cmsCIECAM97sDone(sys->hdr.hDevice);
- cmsCIECAM97sDone(sys->hdr.hPCS);
-
- cmsAddTag(sys->hdr.hProfile, icSigAToB0Tag, AToB0);
-
-
- cmsxEmbedTextualInfo(&sys -> hdr);
-
- cmsAddTag(sys->hdr.hProfile, icSigMediaWhitePointTag, &sys->hdr.WhitePoint);
- cmsAddTag(sys->hdr.hProfile, icSigMediaBlackPointTag, &sys->hdr.BlackPoint);
-
-
- // Save primaries & gamma curves
- if (sys->hdr.ProfileVerbosityLevel >= 1) {
-
- cmsxEmbedMatrixShaper(&sys ->hdr);
- }
-
- _cmsSaveProfile(sys->hdr.hProfile, sys->hdr.OutputProfileFile);
-
- cmsCloseProfile(sys->hdr.hProfile);
- sys->hdr.hProfile = NULL;
-
- cmsxPCollFreeMeasurements(&sys->hdr.m);
-
- cmsFreeLUT(AToB0);
-
- if (sys -> HiTerms)
- MATNfree(sys -> HiTerms);
- sys -> HiTerms = NULL;
-
-
- if (sys -> LoTerms)
- MATNfree(sys -> LoTerms);
- sys -> LoTerms = NULL;
-
-
-
- if (sys ->Prelinearization[0])
- cmsFreeGammaTriple(sys -> Prelinearization);
-
- if (sys ->hdr.Gamma)
- cmsFreeGammaTriple(sys->hdr.Gamma);
-
- return TRUE;
-}
/trunk/lprof/src/cmsscn.c
Property changes:
Deleted: svn:eol-style
## -1 +0,0 ##
-native
\ No newline at end of property
Deleted: svn:keywords
## -1 +0,0 ##
-Author Date Id Revision
\ No newline at end of property
Index: trunk/lprof/src/cmsoutl.c
===================================================================
--- trunk/lprof/src/cmsoutl.c (revision 2454)
+++ trunk/lprof/src/cmsoutl.c (nonexistent)
@@ -1,284 +0,0 @@
-//
-// Little cms - profiler construction set
-// Copyright (C) 1998-2001 Marti Maria
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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
-//
-// Incremental Interpolator
-
-#include "lcmsprf.h"
-
-
-// Res points to a result in XYZ or Lab
-
-BOOL cdecl cmsxRegressionInterpolatorRGB(LPMEASUREMENT m,
- int ColorSpace,
- int RegressionTerms,
- BOOL lUseLocalPatches,
- int MinPatchesToCollect,
- double r, double g, double b,
- void* Res);
-
-
-// -------------------------------------------------------------- Implementation
-
-// #define DEBUG 1
-
-// Estimate regression matrix
-static
-void EstimateRegression(LPMEASUREMENT m, double r, double g, double b,
- int ColorSpace,
- LPMATN* ptfm,
- int nterms,
- BOOL lIncludeAllPatches,
- int MinPatchesToCollect)
-{
- int nCollected;
- MLRSTATISTICS maxAns;
- int ToCollect;
- SETOFPATCHES collected = cmsxPCollBuildSet(m, FALSE);
- SETOFPATCHES allowed = cmsxPCollBuildSet(m, TRUE);
- BOOL rc;
- BOOL lPatchesExhausted = FALSE;
-
-
- CopyMemory(allowed, m -> Allowed, m->nPatches*sizeof(BOOL));
-
- *ptfm = NULL;
-
- ToCollect = max(MinPatchesToCollect, (nterms + 1));
-
- do {
-
- if (lIncludeAllPatches) {
-
- CopyMemory(collected, allowed, m->nPatches*sizeof(BOOL));
- lPatchesExhausted = TRUE;
- ToCollect = nCollected = m->nPatches;
- }
- else
- {
-
- nCollected = cmsxPCollPatchesNearRGB(m, m -> Allowed,
- r, g, b,
- ToCollect, collected);
-
- if (nCollected < ToCollect) { // No more patches available
- lPatchesExhausted = TRUE;
- }
- else {
- ToCollect = nCollected + 1; // Start from here in next iteration
- }
- }
-
- // We are going always 3 -> 3 for now....
- rc = cmsxRegressionCreateMatrix(m, collected, nterms, ColorSpace, ptfm, &maxAns);
-
-
- // Does fit?
- if ((rc == FALSE) || maxAns.R2adj < 0.95 || maxAns.R2adj > 1.0) {
-
- maxAns.R2adj = -100; // No, repeat
- }
-
-
- } while (!lPatchesExhausted && maxAns.R2adj < 0.95);
-
-#ifdef DEBUG
- printf("R2adj: %g, F: %g\n", maxAns.R2adj, maxAns.F);
-#endif
-
- free(collected);
- free(allowed);
-}
-
-
-
-BOOL cmsxRegressionInterpolatorRGB(LPMEASUREMENT m,
- int ColorSpace,
- int RegressionTerms,
- BOOL lUseLocalPatches,
- int MinPatchesToCollect,
- double r, double g, double b,
- void* Res)
-{
- LPMATN tfm = NULL;
-
-
- EstimateRegression(m, r, g, b, ColorSpace, &tfm, RegressionTerms,
- !lUseLocalPatches, MinPatchesToCollect);
-
- if (tfm == NULL) return FALSE;
-
- switch (ColorSpace) {
-
- case PT_Lab:
-
- if (!cmsxRegressionRGB2Lab(r, g, b, tfm, (LPcmsCIELab) Res)) return FALSE;
- break;
-
- case PT_XYZ:
- if (!cmsxRegressionRGB2XYZ(r, g, b, tfm, (LPcmsCIEXYZ) Res)) return FALSE;
- break;
-
- default:
- return FALSE;
- }
-
- MATNfree(tfm);
-
-
-#ifdef DEBUG
- printf("INTERPOLATED RGB %g,%g,%g Lab %g, %g, %g \n", r , g, b,
- Lab->L, Lab->a, Lab->b);
-
-#endif
- return TRUE;
-}
-
-
-// Check the results of a given regression matrix
-
-static
-void CheckOneRegressionMatrix(LPPROFILERCOMMONDATA hdr, LPMATN Matrix,
- double* Mean, double* Std, double* Max)
-{
-
- cmsCIELab Lab;
- cmsCIEXYZ XYZ;
- double Hit, sum, sum2, n, dE;
- int i;
- cmsCIEXYZ D50;
-
-
- D50.X = cmsD50_XYZ() -> X* 100.;
- D50.Y = cmsD50_XYZ() -> Y* 100.;
- D50.Z = cmsD50_XYZ() -> Z* 100.;
-
- Hit = sum = sum2 = n = 0;
- for (i=0; i < hdr -> m.nPatches; i++) {
-
- if (hdr -> m.Allowed[i]) {
-
- LPPATCH p = hdr -> m.Patches + i;
-
- if (hdr -> PCSType == PT_Lab) {
-
- WORD ProfileLabEncoded[3];
-
- cmsxRegressionRGB2Lab(p -> Colorant.RGB[0],
- p -> Colorant.RGB[1],
- p -> Colorant.RGB[2],
- Matrix, &Lab);
-
- cmsFloat2LabEncoded(ProfileLabEncoded, &Lab);
- cmsLabEncoded2Float(&Lab, ProfileLabEncoded);
-
- dE = cmsDeltaE(&Lab, &p ->Lab);
- }
- else {
- cmsCIELab Lab2;
-
- cmsxRegressionRGB2XYZ(p -> Colorant.RGB[0],
- p -> Colorant.RGB[1],
- p -> Colorant.RGB[2],
- Matrix, &XYZ);
- _cmsxClampXYZ100(&XYZ);
-
- cmsXYZ2Lab(&D50, &Lab, &XYZ);
- cmsXYZ2Lab(&D50, &Lab2, &p ->XYZ);
-
- dE = cmsDeltaE(&Lab, &Lab2);
- }
-
-
- if (dE > Hit)
- Hit = dE;
-
- sum += dE;
- sum2 += dE * dE;
- n = n + 1;
-
- }
- }
-
- *Mean = sum / n;
- *Std = sqrt((n * sum2 - sum * sum) / (n*(n-1)));
- *Max = Hit;
-
-}
-
-
-// Trial-and-error in order to get best number of terms.
-
-int cmsxFindOptimumNumOfTerms(LPPROFILERCOMMONDATA hdr, int nMaxTerms, BOOL* lAllOk)
-{
- int i, BestTerms;
- BOOL rc;
- LPMATN Matrix = NULL;
- MLRSTATISTICS Stat;
- double dEmean, dEStd, dEHit, Best;
- BOOL lOneFound;
-
-
- BestTerms = 4;
- Best = 1000.;
- lOneFound = FALSE;
-
- for (i=4; i <= nMaxTerms; i++) { // 55
-
- rc = cmsxRegressionCreateMatrix(&hdr -> m, hdr -> m.Allowed,
- i, hdr -> PCSType, &Matrix, &Stat);
-
- if (rc && Stat.R2adj < 1 && Stat.R2adj > 0.6) {
-
- CheckOneRegressionMatrix(hdr, Matrix, &dEmean, &dEStd, &dEHit);
-
- if (dEStd < Best && dEHit < 50.) {
-
- Best = dEStd;
- BestTerms = i;
- lOneFound = TRUE;
- }
-
- }
- MATNfree(Matrix);
- Matrix = NULL;
- }
-
- *lAllOk = lOneFound;
-
- return BestTerms;
-}
-
-
/trunk/lprof/src/cmsoutl.c
Property changes:
Deleted: svn:eol-style
## -1 +0,0 ##
-native
\ No newline at end of property
Deleted: svn:keywords
## -1 +0,0 ##
-Author Date Id Revision
\ No newline at end of property
Index: trunk/lprof/src/cmshull.c
===================================================================
--- trunk/lprof/src/cmshull.c (revision 2454)
+++ trunk/lprof/src/cmshull.c (nonexistent)
@@ -1,1480 +0,0 @@
-//
-// Little cms - profiler construction set
-// Copyright (C) 1998-2001 Marti Maria
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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"
-
-// Convex hull management
-
-LCMSHANDLE cdecl cmsxHullInit(void);
-void cdecl cmsxHullDone(LCMSHANDLE hHull);
-BOOL cdecl cmsxHullAddPoint(LCMSHANDLE hHull, int x, int y, int z);
-BOOL cdecl cmsxHullComputeHull(LCMSHANDLE hHull);
-char cdecl cmsxHullCheckpoint(LCMSHANDLE hHull, int x, int y, int z);
-BOOL cdecl cmsxHullDumpVRML(LCMSHANDLE hHull, const char* fname);
-
-// ---------------------------------------------------------------------
-
-
-
-// This method is described in "Computational Geometry in C" Chapter 4.
-//
-// --------------------------------------------------------------------
-// This code is Copyright 1998 by Joseph O'Rourke. It may be freely
-// redistributed in its entirety provided that this copyright notice is
-// not removed.
-// --------------------------------------------------------------------
-
-#define SWAP(t,x,y) { t = x; x = y; y = t; }
-
-#define XFREE(p)
-// if (p) { free ((char *) p); p = NULL; }
-
-
-#define ADD( head, p ) if ( head ) { \
- p->Next = head; \
- p->Prev = head->Prev; \
- head->Prev = p; \
- p->Prev->Next = p; \
- } \
- else { \
- head = p; \
- head->Next = head->Prev = p; \
- }
-
-#define XDELETE( head, p ) if ( head ) { \
- if ( head == head->Next ) \
- head = NULL; \
- else if ( p == head ) \
- head = head->Next; \
- p->Next->Prev = p->Prev; \
- p->Prev->Next = p->Next; \
- XFREE( p ); \
- }
-
-// Define Vertex indices.
-#define X 0
-#define Y 1
-#define Z 2
-
-// Define structures for vertices, edges and faces
-
-typedef struct _vertex_struct VERTEX,FAR *LPVERTEX;
-typedef struct _edge_struct EDGE, FAR *LPEDGE;
-typedef struct _face_struct FACE, FAR *LPFACE;
-
-
-struct _edge_struct {
-
- LPFACE AdjFace[2];
- LPVERTEX EndPts[2];
- LPFACE NewFace; /* pointer to incident cone face. */
- BOOL DoDelete; /* T iff Edge should be delete. */
-
- LPEDGE Next, Prev;
-};
-
-struct _face_struct {
-
- LPEDGE Edge[3];
- LPVERTEX Vertex[3];
- BOOL Visible; /* T iff face Visible from new point. */
-
- LPFACE Next, Prev;
-};
-
-struct _vertex_struct {
-
- int v[3];
- int vnum;
- LPEDGE duplicate; /* pointer to incident cone Edge (or NULL) */
- BOOL onhull; /* T iff point on hull. */
- BOOL mark; /* T iff point already processed. */
-
- LPVERTEX Next, Prev;
-};
-
-// Define flags
-
-#define ONHULL TRUE
-#define REMOVED TRUE
-#define VISIBLE TRUE
-#define PROCESSED TRUE
-#define SAFE 1000000 /* Range of safe coord values. */
-
-#define DIM 3 /* Dimension of points */
-typedef int VEC3I[DIM]; /* Type integer point */
-
-#define PMAX 10000 /* Max # of pts */
-
-typedef struct {
-
- /* Global variable definitions */
- LPVERTEX vertices;
- LPEDGE edges;
- LPFACE faces;
-
- VEC3I Vertices[PMAX]; /* All the points */
- VEC3I Faces[PMAX]; /* Each triangle face is 3 indices */
- VEC3I Box[PMAX][2]; /* Box around each face */
-
-
- VEC3I bmin, bmax;
- int radius;
- int vnumCounter;
-
- int nfaces;
- int nvertex;
-
-} HULL, FAR* LPHULL;
-
-// static HULL Global;
-
-
-/*---------------------------------------------------------------------
-MakeNullVertex: Makes a Vertex, nulls out fields.
----------------------------------------------------------------------*/
-
-static
-LPVERTEX MakeNullVertex(LPHULL hull)
-{
- LPVERTEX v;
-
- v = (LPVERTEX) malloc(sizeof(VERTEX));
- if (!v) return NULL;
-
- v->duplicate = NULL;
- v->onhull = !ONHULL;
- v->mark = !PROCESSED;
- ADD( hull->vertices, v );
-
- return v;
-}
-
-
-
-/*---------------------------------------------------------------------
-MakeNullEdge creates a new cell and initializes all pointers to NULL
-and sets all flags to off. It returns a pointer to the empty cell.
----------------------------------------------------------------------*/
-static
-LPEDGE MakeNullEdge(LPHULL hull)
-{
- LPEDGE e;
-
- e = (LPEDGE) malloc(sizeof(EDGE));
- if (!e) return NULL;
-
- e->AdjFace[0] = e->AdjFace[1] = e->NewFace = NULL;
- e->EndPts[0] = e->EndPts[1] = NULL;
- e->DoDelete = !REMOVED;
- ADD( hull->edges, e );
- return e;
-}
-
-/*--------------------------------------------------------------------
-MakeNullFace creates a new face structure and initializes all of its
-flags to NULL and sets all the flags to off. It returns a pointer
-to the empty cell.
----------------------------------------------------------------------*/
-static
-LPFACE MakeNullFace(LPHULL hull)
-{
- LPFACE f;
- int i;
-
- f = (LPFACE) malloc(sizeof(FACE));
- if (!f) return NULL;
-
- for ( i=0; i < 3; ++i ) {
- f->Edge[i] = NULL;
- f->Vertex[i] = NULL;
- }
- f->Visible = !VISIBLE;
- ADD( hull->faces, f );
- return f;
-}
-
-
-
-/*---------------------------------------------------------------------
-MakeFace creates a new face structure from three vertices (in ccw
-order). It returns a pointer to the face.
----------------------------------------------------------------------*/
-static
-LPFACE MakeFace(LPHULL hull, LPVERTEX v0, LPVERTEX v1, LPVERTEX v2, LPFACE fold)
-{
- LPFACE f;
- LPEDGE e0, e1, e2;
-
- /* Create edges of the initial triangle. */
- if( !fold ) {
- e0 = MakeNullEdge(hull);
- e1 = MakeNullEdge(hull);
- e2 = MakeNullEdge(hull);
- }
- else { /* Copy from fold, in reverse order. */
- e0 = fold->Edge[2];
- e1 = fold->Edge[1];
- e2 = fold->Edge[0];
- }
- e0->EndPts[0] = v0; e0->EndPts[1] = v1;
- e1->EndPts[0] = v1; e1->EndPts[1] = v2;
- e2->EndPts[0] = v2; e2->EndPts[1] = v0;
-
- /* Create face for triangle. */
- f = MakeNullFace(hull);
- f->Edge[0] = e0; f->Edge[1] = e1; f->Edge[2] = e2;
- f->Vertex[0] = v0; f->Vertex[1] = v1; f->Vertex[2] = v2;
-
- /* Link edges to face. */
- e0->AdjFace[0] = e1->AdjFace[0] = e2->AdjFace[0] = f;
-
- return f;
-}
-
-/*---------------------------------------------------------------------
-Collinear checks to see if the three points given are collinear,
-by checking to see if each element of the cross product is zero.
----------------------------------------------------------------------*/
-static
-BOOL Collinear( LPVERTEX a, LPVERTEX b, LPVERTEX c )
-{
- return
- ( c->v[Z] - a->v[Z] ) * ( b->v[Y] - a->v[Y] ) -
- ( b->v[Z] - a->v[Z] ) * ( c->v[Y] - a->v[Y] ) == 0
- && ( b->v[Z] - a->v[Z] ) * ( c->v[X] - a->v[X] ) -
- ( b->v[X] - a->v[X] ) * ( c->v[Z] - a->v[Z] ) == 0
- && ( b->v[X] - a->v[X] ) * ( c->v[Y] - a->v[Y] ) -
- ( b->v[Y] - a->v[Y] ) * ( c->v[X] - a->v[X] ) == 0 ;
-}
-
-/*---------------------------------------------------------------------
-VolumeSign returns the sign of the volume of the tetrahedron determined by f
-and p. VolumeSign is +1 iff p is on the negative side of f,
-where the positive side is determined by the rh-rule. So the volume
-is positive if the ccw normal to f points outside the tetrahedron.
-The final fewer-multiplications form is due to Bob Williamson.
----------------------------------------------------------------------*/
-int VolumeSign( LPFACE f, LPVERTEX p )
-{
- double vol;
- double ax, ay, az, bx, by, bz, cx, cy, cz;
-
- ax = f->Vertex[0]->v[X] - p->v[X];
- ay = f->Vertex[0]->v[Y] - p->v[Y];
- az = f->Vertex[0]->v[Z] - p->v[Z];
- bx = f->Vertex[1]->v[X] - p->v[X];
- by = f->Vertex[1]->v[Y] - p->v[Y];
- bz = f->Vertex[1]->v[Z] - p->v[Z];
- cx = f->Vertex[2]->v[X] - p->v[X];
- cy = f->Vertex[2]->v[Y] - p->v[Y];
- cz = f->Vertex[2]->v[Z] - p->v[Z];
-
- vol = ax * (by*cz - bz*cy)
- + ay * (bz*cx - bx*cz)
- + az * (bx*cy - by*cx);
-
-
- /* The volume should be an integer. */
- if ( vol > 0.5 ) return 1;
- else if ( vol < -0.5 ) return -1;
- else return 0;
-}
-
-
-
-/*---------------------------------------------------------------------
-CleanEdges runs through the Edge list and cleans up the structure.
-If there is a NewFace then it will put that face in place of the
-Visible face and NULL out NewFace. It also deletes so marked edges.
----------------------------------------------------------------------*/
-static
-void CleanEdges(LPHULL hull)
-{
- LPEDGE e; /* Primary index into Edge list. */
- LPEDGE t; /* Temporary Edge pointer. */
-
- /* Integrate the NewFace's into the data structure. */
- /* Check every Edge. */
-
- e = hull ->edges;
- do {
- if ( e->NewFace ) {
-
- if ( e->AdjFace[0]->Visible )
- e->AdjFace[0] = e->NewFace;
- else
- e->AdjFace[1] = e->NewFace;
-
- e->NewFace = NULL;
- }
-
- e = e->Next;
-
- } while ( e != hull ->edges );
-
- /* Delete any edges marked for deletion. */
- while ( hull ->edges && hull ->edges->DoDelete ) {
-
- e = hull ->edges;
-
- XDELETE( hull ->edges, e );
- }
-
- e = hull ->edges->Next;
-
- do {
- if ( e->DoDelete ) {
-
- t = e;
- e = e->Next;
- XDELETE( hull ->edges, t );
- }
- else e = e->Next;
-
- } while ( e != hull ->edges );
-}
-
-/*---------------------------------------------------------------------
-CleanFaces runs through the face list and deletes any face marked Visible.
----------------------------------------------------------------------*/
-static
-void CleanFaces(LPHULL hull)
-{
- LPFACE f; /* Primary pointer into face list. */
- LPFACE t; /* Temporary pointer, for deleting. */
-
-
- while ( hull ->faces && hull ->faces->Visible ) {
-
- f = hull ->faces;
- XDELETE( hull ->faces, f );
- }
-
- f = hull ->faces->Next;
-
- do {
- if ( f->Visible ) {
-
- t = f;
- f = f->Next;
- XDELETE( hull ->faces, t );
- }
- else f = f->Next;
-
- } while ( f != hull ->faces );
-}
-
-
-
-/*---------------------------------------------------------------------
-CleanVertices runs through the Vertex list and deletes the
-vertices that are marked as processed but are not incident to any
-undeleted edges.
----------------------------------------------------------------------*/
-static
-void CleanVertices(LPHULL hull)
-{
- LPEDGE e;
- LPVERTEX v, t;
-
- /* Mark all vertices incident to some undeleted Edge as on the hull. */
-
- e = hull ->edges;
- do {
- e->EndPts[0]->onhull = e->EndPts[1]->onhull = ONHULL;
- e = e->Next;
-
- } while (e != hull ->edges);
-
-
- /* Delete all vertices that have been processed but
- are not on the hull. */
-
- while ( hull ->vertices && hull->vertices->mark && !hull ->vertices->onhull ) {
-
- v = hull ->vertices;
- XDELETE(hull ->vertices, v );
- }
-
-
- v = hull ->vertices->Next;
- do {
- if (v->mark && !v->onhull ) {
- t = v;
- v = v->Next;
- XDELETE(hull ->vertices, t )
- }
- else
- v = v->Next;
-
- } while ( v != hull ->vertices );
-
-
- /* Reset flags. */
-
- v = hull ->vertices;
- do {
- v->duplicate = NULL;
- v->onhull = !ONHULL;
- v = v->Next;
-
- } while (v != hull->vertices );
-
-}
-
-
-
-
-/*---------------------------------------------------------------------
-MakeCcw puts the vertices in the face structure in counterclock wise
-order. We want to store the vertices in the same
-order as in the Visible face. The third Vertex is always p.
-
-Although no specific ordering of the edges of a face are used
-by the code, the following condition is maintained for each face f:
-one of the two endpoints of f->Edge[i] matches f->Vertex[i].
-But note that this does not imply that f->Edge[i] is between
-f->Vertex[i] and f->Vertex[(i+1)%3]. (Thanks to Bob Williamson.)
----------------------------------------------------------------------*/
-
-static
-void MakeCcw(LPFACE f, LPEDGE e, LPVERTEX p)
-{
- LPFACE fv; /* The Visible face adjacent to e */
- int i; /* Index of e->endpoint[0] in fv. */
- LPEDGE s; /* Temporary, for swapping */
-
- if (e->AdjFace[0]->Visible)
-
- fv = e->AdjFace[0];
- else
- fv = e->AdjFace[1];
-
- /* Set Vertex[0] & [1] of f to have the same orientation
- as do the corresponding vertices of fv. */
-
- for ( i=0; fv->Vertex[i] != e->EndPts[0]; ++i )
- ;
-
- /* Orient f the same as fv. */
-
- if ( fv->Vertex[ (i+1) % 3 ] != e->EndPts[1] ) {
-
- f->Vertex[0] = e->EndPts[1];
- f->Vertex[1] = e->EndPts[0];
- }
- else {
- f->Vertex[0] = e->EndPts[0];
- f->Vertex[1] = e->EndPts[1];
- SWAP( s, f->Edge[1], f->Edge[2] );
- }
-
- /* This swap is tricky. e is Edge[0]. Edge[1] is based on endpt[0],
- Edge[2] on endpt[1]. So if e is oriented "forwards," we
- need to move Edge[1] to follow [0], because it precedes. */
-
- f->Vertex[2] = p;
-}
-
-/*---------------------------------------------------------------------
-MakeConeFace makes a new face and two new edges between the
-Edge and the point that are passed to it. It returns a pointer to
-the new face.
----------------------------------------------------------------------*/
-
-static
-LPFACE MakeConeFace(LPHULL hull, LPEDGE e, LPVERTEX p)
-{
- LPEDGE new_edge[2];
- LPFACE new_face;
- int i, j;
-
- /* Make two new edges (if don't already exist). */
-
- for ( i=0; i < 2; ++i )
- /* If the Edge exists, copy it into new_edge. */
- if ( !( new_edge[i] = e->EndPts[i]->duplicate) ) {
-
- /* Otherwise (duplicate is NULL), MakeNullEdge. */
- new_edge[i] = MakeNullEdge(hull);
- new_edge[i]->EndPts[0] = e->EndPts[i];
- new_edge[i]->EndPts[1] = p;
- e->EndPts[i]->duplicate = new_edge[i];
- }
-
- /* Make the new face. */
- new_face = MakeNullFace(hull);
- new_face->Edge[0] = e;
- new_face->Edge[1] = new_edge[0];
- new_face->Edge[2] = new_edge[1];
- MakeCcw( new_face, e, p );
-
- /* Set the adjacent face pointers. */
- for ( i=0; i < 2; ++i )
- for ( j=0; j < 2; ++j )
- /* Only one NULL link should be set to new_face. */
- if ( !new_edge[i]->AdjFace[j] ) {
- new_edge[i]->AdjFace[j] = new_face;
- break;
- }
-
- return new_face;
-}
-
-
-/*---------------------------------------------------------------------
-AddOne is passed a Vertex. It first determines all faces Visible from
-that point. If none are Visible then the point is marked as not
-onhull. Next is a loop over edges. If both faces adjacent to an Edge
-are Visible, then the Edge is marked for deletion. If just one of the
-adjacent faces is Visible then a new face is constructed.
----------------------------------------------------------------------*/
-static
-BOOL AddOne(LPHULL hull, LPVERTEX p)
-{
- LPFACE f;
- LPEDGE e, temp;
- int vol;
- BOOL vis = FALSE;
-
-
- /* Mark faces Visible from p. */
- f = hull -> faces;
-
- do {
-
- vol = VolumeSign(f, p);
-
- if ( vol < 0 ) {
- f->Visible = VISIBLE;
- vis = TRUE;
- }
-
- f = f->Next;
-
- } while ( f != hull ->faces );
-
- /* If no faces are Visible from p, then p is inside the hull. */
-
- if ( !vis ) {
-
- p->onhull = !ONHULL;
- return FALSE;
- }
-
- /* Mark edges in interior of Visible region for deletion.
- Erect a NewFace based on each border Edge. */
-
- e = hull ->edges;
-
- do {
-
- temp = e->Next;
-
- if ( e->AdjFace[0]->Visible && e->AdjFace[1]->Visible )
- /* e interior: mark for deletion. */
- e->DoDelete = REMOVED;
-
- else
- if ( e->AdjFace[0]->Visible || e->AdjFace[1]->Visible )
- /* e border: make a new face. */
- e->NewFace = MakeConeFace(hull, e, p );
-
- e = temp;
-
- } while ( e != hull ->edges );
-
- return TRUE;
-}
-
-
-/*---------------------------------------------------------------------
- DoubleTriangle builds the initial double triangle. It first finds 3
- noncollinear points and makes two faces out of them, in opposite order.
- It then finds a fourth point that is not coplanar with that face. The
- vertices are stored in the face structure in counterclockwise order so
- that the volume between the face and the point is negative. Lastly, the
- 3 newfaces to the fourth point are constructed and the data structures
- are cleaned up.
----------------------------------------------------------------------*/
-
-static
-BOOL DoubleTriangle(LPHULL hull)
-{
- LPVERTEX v0, v1, v2, v3;
- LPFACE f0, f1 = NULL;
- int vol;
-
- /* Find 3 noncollinear points. */
- v0 = hull ->vertices;
- while ( Collinear( v0, v0->Next, v0->Next->Next ) )
- if ( ( v0 = v0->Next ) == hull->vertices )
- return FALSE; // All points are Collinear!
-
- v1 = v0->Next;
- v2 = v1->Next;
-
- /* Mark the vertices as processed. */
- v0->mark = PROCESSED;
- v1->mark = PROCESSED;
- v2->mark = PROCESSED;
-
- /* Create the two "twin" faces. */
- f0 = MakeFace(hull, v0, v1, v2, f1 );
- f1 = MakeFace(hull, v2, v1, v0, f0 );
-
- /* Link adjacent face fields. */
- f0->Edge[0]->AdjFace[1] = f1;
- f0->Edge[1]->AdjFace[1] = f1;
- f0->Edge[2]->AdjFace[1] = f1;
- f1->Edge[0]->AdjFace[1] = f0;
- f1->Edge[1]->AdjFace[1] = f0;
- f1->Edge[2]->AdjFace[1] = f0;
-
- /* Find a fourth, noncoplanar point to form tetrahedron. */
- v3 = v2->Next;
- vol = VolumeSign( f0, v3 );
-
- while ( !vol ) {
-
- if ( ( v3 = v3->Next ) == v0 )
- return FALSE; // All points are coplanar!
-
- vol = VolumeSign( f0, v3 );
- }
-
- /* Insure that v3 will be the first added. */
- hull ->vertices = v3;
- return TRUE;
-}
-
-
-
-/*---------------------------------------------------------------------
-ConstructHull adds the vertices to the hull one at a time. The hull
-vertices are those in the list marked as onhull.
----------------------------------------------------------------------*/
-static
-void ConstructHull(LPHULL hull)
-{
- LPVERTEX v, vnext;
- BOOL changed; /* T if addition changes hull; not used. */
-
- v = hull->vertices;
-
- do {
- vnext = v->Next;
-
- changed = FALSE;
-
- if (!v->mark ) {
-
- v->mark = PROCESSED;
- changed = AddOne(hull, v );
-
- CleanEdges(hull);
- CleanFaces(hull);
- CleanVertices(hull);
- }
-
- v = vnext;
-
- } while (v != hull->vertices );
-
-}
-
-
-
-/*-------------------------------------------------------------------*/
-
-
-static
-void AddVec( VEC3I q, VEC3I ray )
-{
- int i;
-
- for( i = 0; i < DIM; i++ )
- ray[i] = q[i] + ray[i];
-}
-
-/*---------------------------------------------------------------------
-a - b ==> c.
----------------------------------------------------------------------*/
-static
-void SubVec( VEC3I a, VEC3I b, VEC3I c )
-{
- int i;
-
- for( i = 0; i < DIM; i++ )
- c[i] = a[i] - b[i];
-}
-
-
-/*---------------------------------------------------------------------
-Returns the dot product of the two input vectors.
----------------------------------------------------------------------*/
-static
-double Dot( VEC3I a, LPVEC3 b )
-{
- int i;
- double sum = 0.0;
-
- for( i = 0; i < DIM; i++ )
- sum += a[i] * b->n[i];
-
- return sum;
-}
-
-/*---------------------------------------------------------------------
-Compute the cross product of (b-a)x(c-a) and place into N.
----------------------------------------------------------------------*/
-static
-void NormalVec( VEC3I a, VEC3I b, VEC3I c, LPVEC3 N )
-{
- N->n[X] = ( c[Z] - a[Z] ) * ( b[Y] - a[Y] ) -
- ( b[Z] - a[Z] ) * ( c[Y] - a[Y] );
- N->n[Y] = ( b[Z] - a[Z] ) * ( c[X] - a[X] ) -
- ( b[X] - a[X] ) * ( c[Z] - a[Z] );
- N->n[Z] = ( b[X] - a[X] ) * ( c[Y] - a[Y] ) -
- ( b[Y] - a[Y] ) * ( c[X] - a[X] );
-}
-
-
-
-
-static
-int InBox( VEC3I q, VEC3I bmin, VEC3I bmax )
-{
-
- if( ( bmin[X] <= q[X] ) && ( q[X] <= bmax[X] ) &&
- ( bmin[Y] <= q[Y] ) && ( q[Y] <= bmax[Y] ) &&
- ( bmin[Z] <= q[Z] ) && ( q[Z] <= bmax[Z] ) )
- return TRUE;
-
- return FALSE;
-}
-
-
-
-/*
- This function returns a char:
- '0': the segment [ab] does not intersect (completely misses) the
- bounding box surrounding the n-th triangle T. It lies
- strictly to one side of one of the six supporting planes.
- '?': status unknown: the segment may or may not intersect T.
-*/
-
-static
-char BoxTest(LPHULL hull, int n, VEC3I a, VEC3I b)
-{
- int i; /* Coordinate index */
- int w;
-
- for ( i=0; i < DIM; i++ ) {
-
- w = hull ->Box[ n ][0][i]; /* min: lower left */
-
- if ( (a[i] < w) && (b[i] < w) ) return '0';
-
- w = hull ->Box[ n ][1][i]; /* max: upper right */
-
- if ( (a[i] > w) && (b[i] > w) ) return '0';
- }
-
- return '?';
-}
-
-
-
-/* Return a random ray endpoint */
-
-static
-void RandomRay( VEC3I ray, int radius )
-{
- double x, y, z, w, t;
-
- /* Generate a random point on a sphere of radius 1. */
- /* the sphere is sliced at z, and a random point at angle t
- generated on the circle of intersection. */
-
- z = 2.0 * (double) rand() / RAND_MAX - 1.0;
- t = 2.0 * M_PI * (double) rand() / RAND_MAX;
- w = sqrt( 1 - z*z );
- x = w * cos( t );
- y = w * sin( t );
-
- ray[X] = (int) ( radius * x );
- ray[Y] = (int) ( radius * y );
- ray[Z] = (int) ( radius * z );
-}
-
-
-
-static
-int ComputeBox(LPHULL hull, int F, VEC3I bmin, VEC3I bmax )
-{
- int i, j;
- double radius;
-
- for( i = 0; i < F; i++ )
- for( j = 0; j < DIM; j++ ) {
-
- if( hull ->Vertices[i][j] < bmin[j] )
- bmin[j] = hull ->Vertices[i][j];
-
- if( hull ->Vertices[i][j] > bmax[j] )
- bmax[j] = hull ->Vertices[i][j];
- }
-
- radius = sqrt( pow( (double)(bmax[X] - bmin[X]), 2.0 ) +
- pow( (double)(bmax[Y] - bmin[Y]), 2.0 ) +
- pow( (double)(bmax[Z] - bmin[Z]), 2.0 ) );
-
- return (int)( radius +1 ) + 1;
-}
-
-
-/*---------------------------------------------------------------------
-Computes N & D and returns index m of largest component.
----------------------------------------------------------------------*/
-static
-int PlaneCoeff(LPHULL hull, VEC3I T, LPVEC3 N, double *D )
-{
- int i;
- double t; /* Temp storage */
- double biggest = 0.0; /* Largest component of normal vector. */
- int m = 0; /* Index of largest component. */
-
- NormalVec(hull ->Vertices[T[0]], hull ->Vertices[T[1]], hull ->Vertices[T[2]], N );
- *D = Dot( hull ->Vertices[T[0]], N );
-
- /* Find the largest component of N. */
- for ( i = 0; i < DIM; i++ ) {
- t = fabs( N->n[i] );
- if ( t > biggest ) {
- biggest = t;
- m = i;
- }
- }
- return m;
-}
-
-/*---------------------------------------------------------------------
- 'p': The segment lies wholly within the plane.
- 'q': The q endpoint is on the plane (but not 'p').
- 'r': The r endpoint is on the plane (but not 'p').
- '0': The segment lies strictly to one side or the other of the plane.
- '1': The segement intersects the plane, and 'p' does not hold.
----------------------------------------------------------------------*/
-static
-char SegPlaneInt(LPHULL hull, VEC3I T, VEC3I q, VEC3I r, LPVEC3 p, int *m)
-{
- VEC3 N; double D;
- VEC3I rq;
- double num, denom, t;
- int i;
-
- *m = PlaneCoeff(hull, T, &N, &D );
- num = D - Dot( q, &N );
- SubVec( r, q, rq );
- denom = Dot( rq, &N );
-
- if ( denom == 0.0 ) { /* Segment is parallel to plane. */
- if ( num == 0.0 ) /* q is on plane. */
- return 'p';
- else
- return '0';
- }
- else
- t = num / denom;
-
- for( i = 0; i < DIM; i++ )
- p->n[i] = q[i] + t * ( r[i] - q[i] );
-
- if ( (0.0 < t) && (t < 1.0) )
- return '1';
- else if ( num == 0.0 ) /* t == 0 */
- return 'q';
- else if ( num == denom ) /* t == 1 */
- return 'r';
- else return '0';
-}
-
-
-
-static
-int AreaSign( VEC3I a, VEC3I b, VEC3I c )
-{
- double area2;
-
- area2 = ( b[0] - a[0] ) * (double)( c[1] - a[1] ) -
- ( c[0] - a[0] ) * (double)( b[1] - a[1] );
-
- /* The area should be an integer. */
- if ( area2 > 0.5 ) return 1;
- else if ( area2 < -0.5 ) return -1;
- else return 0;
-}
-
-
-static
-char InTri2D( VEC3I Tp[3], VEC3I pp )
-{
- int area0, area1, area2;
-
- /* compute three AreaSign() values for pp w.r.t. each Edge of the face in 2D */
- area0 = AreaSign( pp, Tp[0], Tp[1] );
- area1 = AreaSign( pp, Tp[1], Tp[2] );
- area2 = AreaSign( pp, Tp[2], Tp[0] );
-
- if ( (( area0 == 0 ) && ( area1 > 0 ) && ( area2 > 0 )) ||
- (( area1 == 0 ) && ( area0 > 0 ) && ( area2 > 0 )) ||
- (( area2 == 0 ) && ( area0 > 0 ) && ( area1 > 0 )) )
- return 'E';
-
- if ( (( area0 == 0 ) && ( area1 < 0 ) && ( area2 < 0 )) ||
- (( area1 == 0 ) && ( area0 < 0 ) && ( area2 < 0 )) ||
- (( area2 == 0 ) && ( area0 < 0 ) && ( area1 < 0 )))
- return 'E';
-
- if ( (( area0 > 0 ) && ( area1 > 0 ) && ( area2 > 0 )) ||
- (( area0 < 0 ) && ( area1 < 0 ) && ( area2 < 0 )))
- return 'F';
-
- if ( ( area0 == 0 ) && ( area1 == 0 ) && ( area2 == 0 ) )
- return '?'; // Error in InTriD
-
- if ( (( area0 == 0 ) && ( area1 == 0 )) ||
- (( area0 == 0 ) && ( area2 == 0 )) ||
- (( area1 == 0 ) && ( area2 == 0 )) )
- return 'V';
-
- else
- return '0';
-}
-
-/* Assumption: p lies in the plane containing T.
- Returns a char:
- 'V': the query point p coincides with a Vertex of triangle T.
- 'E': the query point p is in the relative interior of an Edge of triangle T.
- 'F': the query point p is in the relative interior of a Face of triangle T.
- '0': the query point p does not intersect (misses) triangle T.
-*/
-
-static
-char InTri3D(LPHULL hull, VEC3I T, int m, VEC3I p )
-{
- int i; /* Index for X,Y,Z */
- int j; /* Index for X,Y */
- int k; /* Index for triangle Vertex */
- VEC3I pp; /* projected p */
- VEC3I Tp[3]; /* projected T: three new vertices */
-
- /* Project out coordinate m in both p and the triangular face */
- j = 0;
- for ( i = 0; i < DIM; i++ ) {
- if ( i != m ) { /* skip largest coordinate */
- pp[j] = p[i];
- for ( k = 0; k < 3; k++ )
- Tp[k][j] = hull->Vertices[T[k]][i];
- j++;
- }
- }
- return( InTri2D( Tp, pp ) );
-}
-
-
-
-static
-int VolumeSign2( VEC3I a, VEC3I b, VEC3I c, VEC3I d )
-{
- double vol;
- double ax, ay, az, bx, by, bz, cx, cy, cz, dx, dy, dz;
- double bxdx, bydy, bzdz, cxdx, cydy, czdz;
-
- ax = a[X];
- ay = a[Y];
- az = a[Z];
- bx = b[X];
- by = b[Y];
- bz = b[Z];
- cx = c[X];
- cy = c[Y];
- cz = c[Z];
- dx = d[X];
- dy = d[Y];
- dz = d[Z];
-
- bxdx=bx-dx;
- bydy=by-dy;
- bzdz=bz-dz;
- cxdx=cx-dx;
- cydy=cy-dy;
- czdz=cz-dz;
- vol = (az-dz) * (bxdx*cydy - bydy*cxdx)
- + (ay-dy) * (bzdz*cxdx - bxdx*czdz)
- + (ax-dx) * (bydy*czdz - bzdz*cydy);
-
-
- /* The volume should be an integer. */
- if ( vol > 0.5 ) return 1;
- else if ( vol < -0.5 ) return -1;
- else return 0;
-}
-
-
-
-
-/*---------------------------------------------------------------------
-The signed volumes of three tetrahedra are computed, determined
-by the segment qr, and each Edge of the triangle.
-Returns a char:
- 'v': the open segment includes a Vertex of T.
- 'e': the open segment includes a point in the relative interior of an Edge
- of T.
- 'f': the open segment includes a point in the relative interior of a face
- of T.
- '0': the open segment does not intersect triangle T.
----------------------------------------------------------------------*/
-
-static
-char SegTriCross(LPHULL hull, VEC3I T, VEC3I q, VEC3I r )
-{
- int vol0, vol1, vol2;
-
- vol0 = VolumeSign2( q, hull->Vertices[ T[0] ], hull->Vertices[ T[1] ], r );
- vol1 = VolumeSign2( q, hull->Vertices[ T[1] ], hull->Vertices[ T[2] ], r );
- vol2 = VolumeSign2( q, hull->Vertices[ T[2] ], hull->Vertices[ T[0] ], r );
-
-
- /* Same sign: segment intersects interior of triangle. */
- if ( ( ( vol0 > 0 ) && ( vol1 > 0 ) && ( vol2 > 0 ) ) ||
- ( ( vol0 < 0 ) && ( vol1 < 0 ) && ( vol2 < 0 ) ) )
- return 'f';
-
- /* Opposite sign: no intersection between segment and triangle */
- if ( ( ( vol0 > 0 ) || ( vol1 > 0 ) || ( vol2 > 0 ) ) &&
- ( ( vol0 < 0 ) || ( vol1 < 0 ) || ( vol2 < 0 ) ) )
- return '0';
-
- else if ( ( vol0 == 0 ) && ( vol1 == 0 ) && ( vol2 == 0 ) )
- return '?'; // Error 1 in SegTriCross
-
- /* Two zeros: segment intersects Vertex. */
- else if ( ( ( vol0 == 0 ) && ( vol1 == 0 ) ) ||
- ( ( vol0 == 0 ) && ( vol2 == 0 ) ) ||
- ( ( vol1 == 0 ) && ( vol2 == 0 ) ) )
- return 'v';
-
- /* One zero: segment intersects Edge. */
- else if ( ( vol0 == 0 ) || ( vol1 == 0 ) || ( vol2 == 0 ) )
- return 'e';
-
- else
- return '?'; // Error 2 in SegTriCross
-}
-
-
-
-static
-char SegTriInt(LPHULL hull, VEC3I T, VEC3I q, VEC3I r, LPVEC3 p )
-{
- int code;
- int m = -1;
-
- code = SegPlaneInt(hull, T, q, r, p, &m );
-
- if ( code == '0') return '0';
- else if ( code == 'q') return InTri3D(hull, T, m, q );
- else if ( code == 'r') return InTri3D(hull, T, m, r );
- else if ( code == 'p') return 'p';
- else if ( code == '1' ) return SegTriCross(hull, T, q, r );
- else
- return code; // Error
-}
-
-
-
-
-/*
- This function returns a char:
- 'i': the query point a is strictly interior to polyhedron P.
- 'o': the query point a is strictly exterior to( or outside of) polyhedron P.
-*/
-char InPolyhedron(LPHULL hull, VEC3I q)
-{
- int F = hull->nfaces;
- VEC3I Ray; /* Ray endpoint. */
- VEC3 p; /* Intersection point; not used. */
- int f, k = 0, crossings = 0;
- char code = '?';
-
-
- /* If query point is outside bounding box, finished. */
- if ( !InBox( q, hull->bmin, hull->bmax ) )
- return 'o';
-
- LOOP:
- while( k++ < F ) {
-
- crossings = 0;
-
- RandomRay(Ray, hull->radius );
-
- AddVec( q, Ray );
-
-
- for ( f = 0; f < F; f++ ) { /* Begin check each face */
-
- if ( BoxTest(hull, f, q, Ray ) == '0' ) {
- code = '0';
-
- }
- else code = SegTriInt(hull, hull->Faces[f], q, Ray, &p );
-
-
- /* If ray is degenerate, then goto outer while to generate another. */
- if ( code == 'p' || code == 'v' || code == 'e' ) {
-
- goto LOOP;
- }
-
- /* If ray hits face at interior point, increment crossings. */
- else if ( code == 'f' ) {
- crossings++;
-
- }
-
- /* If query endpoint q sits on a V/E/F, return inside. */
- else if ( code == 'V' || code == 'E' || code == 'F' )
- return code; // 'i'; // MM2
-
- /* If ray misses triangle, do nothing. */
- else if ( code == '0' )
- ;
-
- else
- return '?'; // Error
-
- }
- /* No degeneracies encountered: ray is generic, so finished. */
- break;
-
- } /* End while loop */
-
-
- /* q strictly interior to polyhedron iff an odd number of crossings. */
- if( ( crossings % 2 ) == 1 )
- return 'i';
-
- else return 'o';
-}
-
-
-/// ----------------------------------------------------------------------------------
-
-
-
-
-static
-void StoreResults(LPHULL hull)
-{
-
- int i, w;
- LPVERTEX v;
- LPFACE f;
- int V = 0, F = 0;
- int j, k;
-
- // Vertices
-
- v = hull ->vertices;
- V = 0;
- do {
-
- v -> vnum = V;
- hull ->Vertices[V][X] = v -> v[X];
- hull ->Vertices[V][Y] = v -> v[Y];
- hull ->Vertices[V][Z] = v -> v[Z];
-
- v = v->Next;
- V++;
-
- } while ( v != hull ->vertices );
-
- hull ->nvertex = V;
-
- // Faces
- f = hull ->faces;
- F = 0;
- do {
-
- hull ->Faces[F][0] = f->Vertex[0]->vnum;
- hull ->Faces[F][1] = f->Vertex[1]->vnum;
- hull ->Faces[F][2] = f->Vertex[2]->vnum;
-
- for ( j=0; j < 3; j++ ) {
-
- hull ->Box[F][0][j] = hull ->Vertices[ hull ->Faces[F][0] ][j];
- hull ->Box[F][1][j] = hull ->Vertices[ hull ->Faces[F][0] ][j];
- }
-
- /* Check k=1,2 vertices of face. */
- for ( k=1; k < 3; k++ )
- for ( j=0; j < 3; j++ ) {
-
- w = hull ->Vertices[ hull ->Faces[F][k] ][j];
- if ( w < hull ->Box[F][0][j] ) hull ->Box[F][0][j] = w;
- if ( w > hull ->Box[F][1][j] ) hull ->Box[F][1][j] = w;
- }
-
-
- f = f->Next; F++;
-
- } while ( f != hull ->faces );
-
-
- hull ->nfaces = F;
-
-
- /* Initialize the bounding box */
- for ( i = 0; i < DIM; i++ )
- hull ->bmin[i] = hull ->bmax[i] = hull ->Vertices[0][i];
-
- hull ->radius = ComputeBox(hull, V, hull ->bmin, hull ->bmax );
-
-
-}
-
-
-LCMSHANDLE cmsxHullInit(void)
-{
- LPHULL hull = (LPHULL) malloc(sizeof(HULL));
-
- ZeroMemory(hull, sizeof(HULL));
-
- hull->vnumCounter = 0;
- hull->vertices = NULL;
- hull->edges = NULL;
- hull->faces = NULL;
- hull->nfaces = 0;
- hull->nvertex = 0;
-
- return (LCMSHANDLE) (LPSTR) hull;
-}
-
-
-void cmsxHullDone(LCMSHANDLE hHull)
-{
- LPHULL hull = (LPHULL) (LPSTR) hHull;
-
- if (hull)
- free((LPVOID) hull);
-}
-
-
-BOOL cmsxHullAddPoint(LCMSHANDLE hHull, int x, int y, int z)
-{
- LPVERTEX v;
- LPHULL hull = (LPHULL) (LPSTR) hHull;
-
-
- v = MakeNullVertex(hull);
- v->v[X] = x;
- v->v[Y] = y;
- v->v[Z] = z;
- v->vnum = hull->vnumCounter++;
-
- return TRUE;
-}
-
-BOOL cmsxHullComputeHull(LCMSHANDLE hHull)
-{
-
- LPHULL hull = (LPHULL) (LPSTR) hHull;
-
- if (!DoubleTriangle(hull)) return FALSE;
-
- ConstructHull(hull);
- StoreResults(hull);
-
- return TRUE;
-}
-
-
-char cmsxHullCheckpoint(LCMSHANDLE hHull, int x, int y, int z)
-{
- VEC3I q;
- LPHULL hull = (LPHULL) (LPSTR) hHull;
-
- q[X] = x; q[Y] = y; q[Z] = z;
-
- return InPolyhedron(hull, q ) ;
-}
-
-
-BOOL cmsxHullDumpVRML(LCMSHANDLE hHull, const char* fname)
-{
- FILE* fp;
- int i;
- LPHULL hull = (LPHULL) (LPSTR) hHull;
-
- fp = fopen (fname, "wt");
- if (fp == NULL)
- return FALSE;
-
- fprintf (fp, "#VRML V2.0 utf8\n");
-
- /* set the viewing orientation and distance */
- fprintf (fp, "DEF CamTest Group {\n");
- fprintf (fp, "\tchildren [\n");
- fprintf (fp, "\t\tDEF Cameras Group {\n");
- fprintf (fp, "\t\t\tchildren [\n");
- fprintf (fp, "\t\t\t\tDEF DefaultView Viewpoint {\n");
- fprintf (fp, "\t\t\t\t\tposition 0 0 340\n");
- fprintf (fp, "\t\t\t\t\torientation 0 0 1 0\n");
- fprintf (fp, "\t\t\t\t\tdescription \"default view\"\n");
- fprintf (fp, "\t\t\t\t}\n");
- fprintf (fp, "\t\t\t]\n");
- fprintf (fp, "\t\t},\n");
- fprintf (fp, "\t]\n");
- fprintf (fp, "}\n");
-
- /* Output the background stuff */
- fprintf (fp, "Background {\n");
- fprintf (fp, "\tskyColor [\n");
- fprintf (fp, "\t\t.5 .5 .5\n");
- fprintf (fp, "\t]\n");
- fprintf (fp, "}\n");
-
- /* Output the shape stuff */
- fprintf (fp, "Transform {\n");
- fprintf (fp, "\tscale 8 8 8\n");
- fprintf (fp, "\tchildren [\n");
-
- /* Draw the axes as a shape: */
- fprintf (fp, "\t\tShape {\n");
- fprintf (fp, "\t\t\tappearance Appearance {\n");
- fprintf (fp, "\t\t\t\tmaterial Material {\n");
- fprintf (fp, "\t\t\t\t\tdiffuseColor 0 0.8 0\n");
- fprintf (fp, "\t\t\t\t\temissiveColor 1.0 1.0 1.0\n");
- fprintf (fp, "\t\t\t\t\tshininess 0.8\n");
- fprintf (fp, "\t\t\t\t}\n");
- fprintf (fp, "\t\t\t}\n");
- fprintf (fp, "\t\t\tgeometry IndexedLineSet {\n");
- fprintf (fp, "\t\t\t\tcoord Coordinate {\n");
- fprintf (fp, "\t\t\t\t\tpoint [\n");
- fprintf (fp, "\t\t\t\t\t0.0 0.0 0.0,\n");
- fprintf (fp, "\t\t\t\t\t%f 0.0 0.0,\n", 255.0);
- fprintf (fp, "\t\t\t\t\t0.0 %f 0.0,\n", 255.0);
- fprintf (fp, "\t\t\t\t\t0.0 0.0 %f]\n", 255.0);
- fprintf (fp, "\t\t\t\t}\n");
- fprintf (fp, "\t\t\t\tcoordIndex [\n");
- fprintf (fp, "\t\t\t\t\t0, 1, -1\n");
- fprintf (fp, "\t\t\t\t\t0, 2, -1\n");
- fprintf (fp, "\t\t\t\t\t0, 3, -1]\n");
- fprintf (fp, "\t\t\t}\n");
- fprintf (fp, "\t\t}\n");
-
-
- /* Draw the triangles as a shape: */
- fprintf (fp, "\t\tShape {\n");
- fprintf (fp, "\t\t\tappearance Appearance {\n");
- fprintf (fp, "\t\t\t\tmaterial Material {\n");
- fprintf (fp, "\t\t\t\t\tdiffuseColor 0 0.8 0\n");
- fprintf (fp, "\t\t\t\t\temissiveColor 0 0 0\n");
- fprintf (fp, "\t\t\t\t\tshininess 0.8\n");
- fprintf (fp, "\t\t\t\t}\n");
- fprintf (fp, "\t\t\t}\n");
- fprintf (fp, "\t\t\tgeometry IndexedFaceSet {\n");
- fprintf (fp, "\t\t\t\tsolid FALSE\n");
-
- /* fill in the points here */
- fprintf (fp, "\t\t\t\tcoord Coordinate {\n");
- fprintf (fp, "\t\t\t\t\tpoint [\n");
-
- for (i = 0; i < hull->nvertex; ++i)
- {
- fprintf (fp, "\t\t\t\t\t%g %g %g%c\n",
- (double) hull->Vertices[i][X], (double) hull->Vertices[i][Y], (double) hull->Vertices[i][Z],
- i == hull->nvertex-1? ']': ',');
- }
- fprintf (fp, "\t\t\t\t}\n");
-
- /* fill in the Vertex indices (followed by -1) */
-
-
- fprintf (fp, "\t\t\t\tcoordIndex [\n");
- for (i = 0; i < hull->nfaces; ++i)
- {
- fprintf (fp, "\t\t\t\t\t%d, %d, %d, -1\n",
- hull->Faces[i][0], hull->Faces[i][1], hull->Faces[i][2]);
-
- }
- fprintf (fp, "]\n");
-
-
- /* fill in the face colors */
- fprintf (fp, "\t\t\t\tcolor Color {\n");
- fprintf (fp, "\t\t\t\t\tcolor [\n");
- for (i = 0; i < hull->nfaces; ++i)
- {
- int vx, vy, vz;
- double r, g, b;
-
- vx = hull->Faces[i][0]; vy = hull->Faces[i][1]; vz = hull->Faces[i][2];
- r = (double) (hull->Vertices[vx][X] + hull->Vertices[vy][X] + hull->Vertices[vz][X]) / (3* 255);
- g = (double) (hull->Vertices[vx][Y] + hull->Vertices[vy][Y] + hull->Vertices[vz][Y]) / (3* 255);
- b = (double) (hull->Vertices[vx][Z] + hull->Vertices[vy][Z] + hull->Vertices[vz][Z]) / (3* 255);
-
- fprintf (fp, "\t\t\t\t\t%g %g %g%c\n", r, g, b,
- i == hull->nfaces-1? ']': ',');
- }
- fprintf (fp, "\t\t\t}\n");
-
- fprintf (fp, "\t\t\tcolorPerVertex FALSE\n");
-
- fprintf (fp, "\t\t\t}\n");
- fprintf (fp, "\t\t}\n");
- fprintf (fp, "\t]\n");
- fprintf (fp, "}\n");
-
- fclose (fp);
-
- return TRUE;
-}
/trunk/lprof/src/cmshull.c
Property changes:
Deleted: svn:eol-style
## -1 +0,0 ##
-native
\ No newline at end of property
Deleted: svn:keywords
## -1 +0,0 ##
-Author Date Id Revision
\ No newline at end of property
Index: trunk/lprof/src/cmsprf.c
===================================================================
--- trunk/lprof/src/cmsprf.c (revision 2454)
+++ trunk/lprof/src/cmsprf.c (nonexistent)
@@ -1,439 +0,0 @@
-//
-// Little cms - profiler construction set
-// Copyright (C) 1998-2001 Marti Maria
-//
-// 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 library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2 of the License, or (at your option) any later version.
-//
-// This library 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
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-#include "lcmsprf.h"
-
-
-double cdecl _cmsxSaturate65535To255(double d);
-double cdecl _cmsxSaturate255To65535(double d);
-
-
-void cdecl _cmsxClampXYZ100(LPcmsCIEXYZ xyz);
-
-
-BOOL cdecl cmsxEmbedCharTarget(LPPROFILERCOMMONDATA hdr);
-BOOL cdecl cmsxEmbedMatrixShaper(LPPROFILERCOMMONDATA hdr);
-BOOL cdecl cmsxEmbedTextualInfo(LPPROFILERCOMMONDATA hdr);
-
-// ----------------------------------------------------------------- Implementation
-
-
-// Convert from 0.0..65535.0 to 0.0..255.0
-
-double _cmsxSaturate65535To255(double d)
-{
- double v;
-
- v = d / 257.0;
-
- if (v < 0) return 0;
- if (v > 255.0) return 255.0;
-
- return v;
-}
-
-
-double _cmsxSaturate255To65535(double d)
-{
- double v;
-
- v = d * 257.0;
-
- if (v < 0) return 0;
- if (v > 65535.0) return 65535.0;
-
- return v;
-}
-
-
-
-// Cut off absurd values
-
-void _cmsxClampXYZ100(LPcmsCIEXYZ xyz)
-{
-
- if (xyz->X > 199.996)
- xyz->X = 199.996;
-
- if (xyz->Y > 199.996)
- xyz->Y = 199.996;
-
- if (xyz->Z > 199.996)
- xyz->Z = 199.996;
-
- if (xyz->Y < 0)
- xyz->Y = 0;
-
- if (xyz->X < 0)
- xyz->X = 0;
-
- if (xyz->Z < 0)
- xyz->Z = 0;
-
-}
-
-static
-int xfilelength(int fd)
-{
-#ifdef _MSC_VER
- return _filelength(fd);
-#else
- struct stat sb;
- if (fstat(fd, &sb) < 0)
- return(-1);
- return(sb.st_size);
-#endif
-
-
-}
-
-
-BOOL cmsxEmbedCharTarget(LPPROFILERCOMMONDATA hdr)
-{
- LCMSHANDLE it8 = cmsxIT8Alloc();
- LPBYTE mem;
- size_t size, readed;
- FILE* f;
- BOOL lFreeOnExit = FALSE;
-
-
- if (!hdr->m.Patches) {
-
- if (!hdr ->ReferenceSheet[0] && !hdr->MeasurementSheet[0]) return FALSE;
-
- if (cmsxPCollBuildMeasurement(&hdr ->m,
- hdr->ReferenceSheet,
- hdr->MeasurementSheet,
- PATCH_HAS_RGB|PATCH_HAS_XYZ) == FALSE) return FALSE;
- lFreeOnExit = TRUE;
-
- }
-
- cmsxIT8SetSheetType(it8,"LCMSEMBED");
- cmsxIT8SetProperty(it8, "ORIGINATOR", (const char *) "Little cms");
- cmsxIT8SetProperty(it8, "DESCRIPTOR", (const char *) hdr -> Description);
- cmsxIT8SetProperty(it8, "MANUFACTURER", (const char *) hdr ->Manufacturer);
-
- cmsxPCollSaveToSheet(&hdr->m, it8);
- cmsxIT8SaveToFile(it8, "TMP00.IT8");
- cmsxIT8Free(it8);
-
- f = fopen("TMP00.IT8", "rb");
- size = xfilelength(fileno(f));
- mem = (char*) malloc(size + 1);
- readed = fread(mem, 1, size, f);
- fclose(f);
-
- mem[readed] = 0;
- unlink("TMP00.IT8");
-
- cmsAddTag(hdr->hProfile, icSigCharTargetTag, mem);
- free(mem);
-
- if (lFreeOnExit) {
-
- cmsxPCollFreeMeasurements(&hdr->m);
- }
-
- return TRUE;
-}
-
-
-static
-BOOL ComputeColorantMatrix(LPcmsCIEXYZTRIPLE Colorants,
- LPcmsCIExyY WhitePoint,
- LPcmsCIExyYTRIPLE Primaries)
-{
- MAT3 MColorants;
-
- if (!cmsBuildRGB2XYZtransferMatrix(&MColorants, WhitePoint, Primaries))
- {
- return FALSE;
- }
-
-
- cmsAdaptMatrixToD50(&MColorants, WhitePoint);
-
- Colorants->Red.X = MColorants.v[0].n[0];
- Colorants->Red.Y = MColorants.v[1].n[0];
- Colorants->Red.Z = MColorants.v[2].n[0];
-
- Colorants->Green.X = MColorants.v[0].n[1];
- Colorants->Green.Y = MColorants.v[1].n[1];
- Colorants->Green.Z = MColorants.v[2].n[1];
-
- Colorants->Blue.X = MColorants.v[0].n[2];
- Colorants->Blue.Y = MColorants.v[1].n[2];
- Colorants->Blue.Z = MColorants.v[2].n[2];
-
- return TRUE;
-
-}
-
-
-BOOL cmsxEmbedMatrixShaper(LPPROFILERCOMMONDATA hdr)
-{
- cmsCIEXYZTRIPLE Colorant;
- cmsCIExyY MediaWhite;
-
- cmsXYZ2xyY(&MediaWhite, &hdr ->WhitePoint);
-
- if (ComputeColorantMatrix(&Colorant, &MediaWhite, &hdr ->Primaries)) {
-
- cmsAddTag(hdr ->hProfile, icSigRedColorantTag, &Colorant.Red);
- cmsAddTag(hdr ->hProfile, icSigGreenColorantTag, &Colorant.Green);
- cmsAddTag(hdr ->hProfile, icSigBlueColorantTag, &Colorant.Blue);
- }
-
- cmsAddTag(hdr ->hProfile, icSigRedTRCTag, hdr ->Gamma[0]);
- cmsAddTag(hdr ->hProfile, icSigGreenTRCTag, hdr ->Gamma[1]);
- cmsAddTag(hdr ->hProfile, icSigBlueTRCTag, hdr ->Gamma[2]);
-
- return TRUE;
-}
-
-
-BOOL cmsxEmbedTextualInfo(LPPROFILERCOMMONDATA hdr)
-{
- if (*hdr ->Description)
- cmsAddTag(hdr ->hProfile, icSigProfileDescriptionTag, hdr ->Description);
-
- if (*hdr ->Copyright)
- cmsAddTag(hdr ->hProfile, icSigCopyrightTag, hdr ->Copyright);
-
- if (*hdr ->Manufacturer)
- cmsAddTag(hdr ->hProfile, icSigDeviceMfgDescTag, hdr ->Manufacturer);
-
- if (*hdr ->Model)
- cmsAddTag(hdr ->hProfile, icSigDeviceModelDescTag, hdr ->Model);
-
- return TRUE;
-}
-
-
-
-void cmsxChromaticAdaptationAndNormalization(LPPROFILERCOMMONDATA hdr, LPcmsCIEXYZ xyz, BOOL lReverse)
-{
-
- if (hdr->lUseCIECAM97s) {
-
- cmsJCh JCh;
-
- // Let's CIECAM97s to do the adaptation to D50
-
- xyz->X *= 100.;
- xyz->Y *= 100.;
- xyz->Z *= 100.;
-
- _cmsxClampXYZ100(xyz);
-
- if (lReverse) {
- cmsCIECAM97sForward(hdr->hPCS, xyz, &JCh);
- cmsCIECAM97sReverse(hdr->hDevice, &JCh, xyz);
- }
- else {
-
- cmsCIECAM97sForward(hdr->hDevice, xyz, &JCh);
- cmsCIECAM97sReverse(hdr->hPCS, &JCh, xyz);
- }
-
- _cmsxClampXYZ100(xyz);
-
- xyz -> X /= 100.;
- xyz -> Y /= 100.;
- xyz -> Z /= 100.;
-
- }
- else {
-
- // Else, use Bradford
-
- if (lReverse) {
- cmsAdaptToIlluminant(xyz, cmsD50_XYZ(), &hdr->WhitePoint, xyz);
- }
- else {
- cmsAdaptToIlluminant(xyz, &hdr->WhitePoint, cmsD50_XYZ(), xyz);
- }
-
- }
-
-}
-
-
-void cmsxInitPCSViewingConditions(LPPROFILERCOMMONDATA hdr)
-{
-
- hdr->PCS.whitePoint.X = cmsD50_XYZ()->X * 100.;
- hdr->PCS.whitePoint.Y = cmsD50_XYZ()->Y * 100.;
- hdr->PCS.whitePoint.Z = cmsD50_XYZ()->Z * 100.;
-
-
- hdr->PCS.Yb = 20; // 20% of surround
- hdr->PCS.La = 20; // Adapting field luminance
- hdr->PCS.surround = AVG_SURROUND;
- hdr->PCS.D_value = 1.0; // Complete adaptation
-
-}
-
-
-// Build gamut hull by geometric means
-void cmsxComputeGamutHull(LPPROFILERCOMMONDATA hdr)
-{
- int i;
- int x0, y0, z0;
- int Inside, Outside, Boundaries;
- char code;
-
-
- hdr -> hRGBHull = cmsxHullInit();
-
- // For all valid patches, mark RGB knots as 0
- for (i=0; i < hdr ->m.nPatches; i++) {
-
- if (hdr ->m.Allowed[i]) {
-
- LPPATCH p = hdr ->m.Patches + i;
-
-
- x0 = (int) floor(p->Colorant.RGB[0] + .5);
- y0 = (int) floor(p->Colorant.RGB[1] + .5);
- z0 = (int) floor(p->Colorant.RGB[2] + .5);
-
- cmsxHullAddPoint(hdr->hRGBHull, x0, y0, z0);
- }
- }
-
- cmsxHullComputeHull(hdr ->hRGBHull);
-
-// #ifdef DEBUG
- cmsxHullDumpVRML(hdr -> hRGBHull, "rgbhull.wrl");
-// #endif
-
-
-
- // A check
-
- Inside = Outside = Boundaries = 0;
- // For all valid patches, mark RGB knots as 0
- for (i=0; i < hdr ->m.nPatches; i++) {
-
- if (hdr ->m.Allowed[i]) {
-
- LPPATCH p = hdr ->m.Patches + i;
-
- x0 = (int) floor(p->Colorant.RGB[0] + .5);
- y0 = (int) floor(p->Colorant.RGB[1] + .5);
- z0 = (int) floor(p->Colorant.RGB[2] + .5);
-
- code = cmsxHullCheckpoint(hdr -> hRGBHull, x0, y0, z0);
-
- switch (code) {
-
- case 'i': Inside++; break;
- case 'o': Outside++; break;
- default: Boundaries++;
- }
-
- }
- }
-
- if (hdr ->printf)
- hdr ->printf("Gamut hull: %d inside, %d outside, %d on boundaries", Inside, Outside, Boundaries);
-
-}
-
-BOOL cmsxChoosePCS(LPPROFILERCOMMONDATA hdr)
-{
-
- double gamma_r, gamma_g, gamma_b;
- cmsCIExyY SourceWhite;
-
- // At first, compute aproximation on matrix-shaper
- if (!cmsxComputeMatrixShaper(hdr ->ReferenceSheet,
- hdr ->MeasurementSheet,
- hdr -> Medium,
- hdr ->Gamma,
- &hdr ->WhitePoint,
- &hdr ->BlackPoint,
- &hdr ->Primaries)) return FALSE;
-
-
-
- cmsXYZ2xyY(&SourceWhite, &hdr ->WhitePoint);
-
- gamma_r = cmsEstimateGamma(hdr ->Gamma[0]);
- gamma_g = cmsEstimateGamma(hdr ->Gamma[1]);
- gamma_b = cmsEstimateGamma(hdr ->Gamma[2]);
-
-
-
- if (gamma_r > 1.8 || gamma_g > 1.8 || gamma_b > 1.8 ||
- gamma_r == -1 || gamma_g == -1 || gamma_b == -1) {
-
- hdr ->PCSType = PT_Lab;
-
- if (hdr ->printf)
- hdr ->printf("I have choosen Lab as PCS");
-
- }
- else {
-
- hdr ->PCSType = PT_XYZ;
-
- if (hdr ->printf)
- hdr ->printf("I have choosen XYZ as PCS");
- }
-
-
-
- if (hdr ->printf) {
-
- char Buffer[256] = "Infered ";
-
- _cmsIdentifyWhitePoint(Buffer, &hdr ->WhitePoint);
- hdr ->printf("%s", Buffer);
- hdr ->printf("Primaries (x-y): [Red: %2.2f, %2.2f] [Green: %2.2f, %2.2f] [Blue: %2.2f, %2.2f]",
- hdr ->Primaries.Red.x, hdr ->Primaries.Red.y,
- hdr ->Primaries.Green.x, hdr ->Primaries.Green.y,
- hdr ->Primaries.Blue.x, hdr ->Primaries.Blue.y);
-
- if ((gamma_r != -1) && (gamma_g != -1) && (gamma_b != -1)) {
-
- hdr ->printf("Estimated gamma: [Red: %2.2f] [Green: %2.2f] [Blue: %2.2f]",
- gamma_r, gamma_g, gamma_b);
- }
-
-
- }
-
-
-
- return TRUE;
-}
/trunk/lprof/src/cmsprf.c
Property changes:
Deleted: svn:eol-style
## -1 +0,0 ##
-native
\ No newline at end of property
Deleted: svn:keywords
## -1 +0,0 ##
-Author Date Id Revision
\ No newline at end of property
Index: trunk/lprof/src/cmssheet.c
===================================================================
--- trunk/lprof/src/cmssheet.c (revision 2454)
+++ trunk/lprof/src/cmssheet.c (nonexistent)
@@ -1,1746 +0,0 @@
-//
-// Little cms - profiler construction set
-// Copyright (C) 1998-2001 Marti Maria
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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.08a
-
-
-#include "lcmsprf.h"
-
-// #define _DEBUG 1
-
-
-
-// IT8.7 / CGATS.17-200x handling
-LCMSHANDLE cdecl cmsxIT8Alloc(void);
-void cdecl cmsxIT8Free(LCMSHANDLE IT8);
-
-// Persistence
-LCMSHANDLE cdecl cmsxIT8LoadFromFile(const char* cFileName);
-LCMSHANDLE cdecl cmsxIT8LoadFromMem(void *Ptr, size_t len);
-BOOL cdecl cmsxIT8SaveToFile(LCMSHANDLE IT8, const char* cFileName);
-
-// Properties
-const char* cdecl cmsxIT8GetSheetType(LCMSHANDLE hIT8);
-BOOL cdecl cmsxIT8SetSheetType(LCMSHANDLE hIT8, const char* Type);
-
-BOOL cdecl cmsxIT8SetProperty(LCMSHANDLE hIT8, const char* cProp, const char *Str);
-BOOL cdecl cmsxIT8SetPropertyDbl(LCMSHANDLE hIT8, const char* cProp, double Val);
-
-const char* cdecl cmsxIT8GetProperty(LCMSHANDLE hIT8, const char* cProp);
-double cdecl cmsxIT8GetPropertyDbl(LCMSHANDLE hIT8, const char* cProp);
-int cdecl cmsxIT8EnumProperties(LCMSHANDLE IT8, char ***PropertyNames);
-
-
-// Datasets
-
-BOOL cdecl cmsxIT8GetDataSetByPos(LCMSHANDLE IT8, int col, int row, char* Val, int ValBufferLen);
-
-BOOL cdecl cmsxIT8GetDataSet(LCMSHANDLE IT8, const char* cPatch,
- const char* cSample,
- char* Val, int ValBufferLen);
-
-
-BOOL cdecl cmsxIT8GetDataSetDbl(LCMSHANDLE IT8, const char* cPatch, const char* cSample, double* d);
-
-BOOL cdecl cmsxIT8SetDataSet(LCMSHANDLE IT8, const char* cPatch,
- const char* cSample,
- char *Val);
-
-BOOL cdecl cmsxIT8SetDataFormat(LCMSHANDLE IT8, int n, const char *Sample);
-int cdecl cmsxIT8EnumDataFormat(LCMSHANDLE IT8, char ***SampleNames);
-
-const char *cdecl cmsxIT8GenericPatchName(int nPatch, char* buffer);
-int cdecl cmsxIT8GenericPatchNum(const char *Name);
-
-
-// ------------------------------------------------------------- Implementation
-
-
-#define MAXID 128 // Max lenght of identifier
-#define MAXSTR 255 // Max lenght of string
-
-#ifndef NON_WINDOWS
-#include <io.h>
-#endif
-
-// Symbols
-
-typedef enum { SNONE,
- SINUM, // Integer
- SDNUM, // Real
- SIDENT, // Identifier
- SSTRING, // string
- SCOMMENT, // comment
- SEOLN, // End of line
- SEOF, // End of stream
- SSYNERROR, // Syntax error found on stream
-
- // Keywords
-
- SBEGIN_DATA,
- SBEGIN_DATA_FORMAT,
- SEND_DATA,
- SEND_DATA_FORMAT,
- SKEYWORD,
- SSTRING_SY
-
- } SYMBOL;
-
-
-// Linked list of variable names
-
-typedef struct _KeyVal {
-
- struct _KeyVal* Next;
- char* Keyword; // Name of variable
- char* Value; // Points to value
-
- } KEYVALUE, FAR* LPKEYVALUE;
-
-// Linked list of values (Memory sink)
-
-typedef struct _OwnedMem {
-
- struct _OwnedMem* Next;
- void * Ptr; // Point to value
-
- } OWNEDMEM, FAR* LPOWNEDMEM;
-
-
-// This struct hold all information about an openened
-// IT8 handler. Only one dataset is allowed.
-
-typedef struct {
-
- int nSamples, nPatches; // Rows, Cols
- int SampleID; // Pos of ID
- LPKEYVALUE HeaderList; // The properties
- char* FileBuffer; // The ASCII stream
- char** DataFormat; // The binary stream descriptor
- char** Data; // The binary stream
- LPOWNEDMEM MemorySink; // The storage bakend
-
- // Parser state machine
-
- SYMBOL sy; // Current symbol
- int ch; // Current character
- char* Source; // Points to loc. being parsed
- int inum; // integer value
- double dnum; // real value
- char id[MAXID]; // identifier
- char str[MAXSTR]; // string
-
- // Allowed keywords & datasets
-
- LPKEYVALUE ValidKeywords;
- LPKEYVALUE ValidSampleID;
-
- char FileName[MAX_PATH];
- int lineno; // line counter for error reporting
-
- char SheetType[MAXSTR]; // New 1.09
-
- } IT8, FAR* LPIT8;
-
-
-
-// ------------------------------------------------------ IT8 parsing routines
-
-
-// A keyword
-typedef struct {
- const char *id;
- SYMBOL sy;
-
- } KEYWORD;
-
-// The keyword->symbol translation table. Sorting is required.
-static const KEYWORD TabKeys[] = {
-
- {"BEGIN_DATA", SBEGIN_DATA },
- {"BEGIN_DATA_FORMAT", SBEGIN_DATA_FORMAT },
- {"END_DATA", SEND_DATA},
- {"END_DATA_FORMAT", SEND_DATA_FORMAT},
- {"KEYWORD", SKEYWORD},
- {"STRING", SSTRING_SY}};
-
-#define NUMKEYS (sizeof(TabKeys)/sizeof(KEYWORD))
-
-// Predefined properties
-static char* PredefinedProperties[] = {
-
- "NUMBER_OF_FIELDS", // Required - NUMBER OF FIELDS
- "NUMBER_OF_SETS", // Required - NUMBER OF SETS
- "ORIGINATOR", // Required - Identifies the specific system, organization or individual that created the data file.
- "CREATED", // Required - Indicates date of creation of the data file.
- "DESCRIPTOR", // Required - Describes the purpose or contents of the data file.
- "DIFFUSE_GEOMETRY", // The diffuse geometry used. Allowed values are "sphere" or "opal".
- "MANUFACTURER",
- "MANUFACTURE", // Some broken Fuji targets does store this value
- "PROD_DATE", // Identifies year and month of production of the target in the form yyyy:mm.
- "SERIAL", // Uniquely identifies individual physical target.
-
- "MATERIAL", // Identifies the material on which the target was produced using a code
- // uniquely identifying th e material. Th is is intend ed to be used for IT8.7
- // physical targets only (i.e . IT8.7/1 a nd IT8.7/2).
-
- "INSTRUMENTATION", // Used to report the specific instrumentation used (manufacturer and
- // model number) to generate the data reported. This data will often
- // provide more information about the particular data collected than an
- // extensive list of specific details. This is particularly important for
- // spectral data or data derived from spectrophotometry.
-
- "MEASUREMENT_SOURCE", // Illumination used for spectral measurements. This data helps provide
- // a guide to the potential for issues of paper fluorescence, etc.
-
- "PRINT_CONDITIONS", // Used to define the ch aracteristics of the printed sheet being reported.
- // Where standard conditions have been defined (e.g., SW OP at nominal)
- // named conditions may suffice. Otherwise, detailed in formation is
- // needed.
-
- "SAMPLE_BACKING", // Identifies the backing material used behind the sample during
- // measurement. Allowed values are “black”, “white”, or "na".
-
- "CHISQ_DOF" // Degrees of freedom associated with the Chi squared statistic
- };
-
-#define NUMPREDEFINEDPROPS (sizeof(PredefinedProperties)/sizeof(char *))
-
-
-// Predefined sample types on dataset
-static char* PredefinedSampleID[] = {
-
- "CMYK_C", // Cyan component of CMYK data expressed as a percentage
- "CMYK_M", // Magenta component of CMYK data expressed as a percentage
- "CMYK_Y", // Yellow component of CMYK data expressed as a percentage
- "CMYK_K", // Black component of CMYK data expressed as a percentage
- "D_RED", // Red filter density
- "D_GREEN", // Green filter density
- "D_BLUE", // Blue filter density
- "D_VIS", // Visual filter density
- "D_MAJOR_FILTER", // Major filter d ensity
- "RGB_R", // Red component of RGB data
- "RGB_G", // Green component of RGB data
- "RGB_B", // Blue com ponent of RGB data
- "SPECTRAL_NM", // Wavelength of measurement expressed in nanometers
- "SPECTRAL_PCT", // Percentage reflectance/transmittance
- "SPECTRAL_DEC", // Reflectance/transmittance
- "XYZ_X", // X component of tristimulus data
- "XYZ_Y", // Y component of tristimulus data
- "XYZ_Z", // Z component of tristimulus data
- "XYY_X" // x component of chromaticity data
- "XYY_Y", // y component of chromaticity data
- "XYY_CAPY", // Y component of tristimulus data
- "LAB_L", // L* component of Lab data
- "LAB_A", // a* component of Lab data
- "LAB_B", // b* component of Lab data
- "LAB_C", // C*ab component of Lab data
- "LAB_H", // hab component of Lab data
- "LAB_DE" // CIE dE
- "LAB_DE_94", // CIE dE using CIE 94
- "LAB_DE_CMC", // dE using CMC
- "LAB_DE_2000", // CIE dE using CIE DE 2000
- "MEAN_DE", // Mean Delta E (LAB_DE) of samples compared to batch average
- // (Used for data files for ANSI IT8.7/1 and IT8.7/2 targets)
- "STDEV_X", // Standard deviation of X (tristimulus data)
- "STDEV_Y", // Standard deviation of Y (tristimulus data)
- "STDEV_Z", // Standard deviation of Z (tristimulus data)
- "STDEV_L", // Standard deviation of L*
- "STDEV_A" // Standard deviation of a*
- "STDEV_B", // Standard deviation of b*
- "STDEV_DE", // Standard deviation of CIE dE
- "CHI_SQD_PAR"}; // The average of the standard deviations of L*, a* and b*. It is
- // used to derive an estimate of the chi-squared parameter which is
- // recommended as the predictor of the variability of dE
-
-#define NUMPREDEFINEDSAMPLEID (sizeof(PredefinedSampleID)/sizeof(char *))
-
-
-// Checks whatsever if c is a valid identifier middle char.
-static
-BOOL isidchar(int c)
-{
- return (isalnum(c) || c == '$' || c == '%' || c == '&' || c == '/' || c == '.' || c == '_');
-
-}
-
-// Checks whatsever if c is a valid identifier first char.
-static
-BOOL isfirstidchar(int c)
-{
- return !isdigit(c) && isidchar(c);
-}
-
-// Checks if c is a separator
-static
-BOOL isseparator(int c)
-{
- return (c == ' ' || c == '\t' || c == '\r');
-}
-
-// a replacement for strupr(), just for compatiblity sake
-
-static
-void xstrupr(char *cp)
-{
- for (;*cp;cp++)
- if (*cp >= 'a' && *cp <= 'z')
- *cp += 'A'-'a';
-}
-
-// A replacement for (the nonstandard) filelenght
-
-static
-int xfilelength(int fd)
-{
-#ifdef _MSC_VER
- return _filelength(fd);
-#else
- struct stat sb;
- if (fstat(fd, &sb) < 0)
- return(-1);
- return(sb.st_size);
-#endif
-
-
-}
-
-static
-BOOL SynError(LPIT8 it8, const char *Txt, ...)
-{
- char Buffer[256], ErrMsg[1024];
- va_list args;
-
- va_start(args, Txt);
- vsprintf(Buffer, Txt, args);
- va_end(args);
-
- sprintf(ErrMsg, "%s: Line %d, %s", it8->FileName, it8->lineno, Buffer);
- it8->sy = SSYNERROR;
- cmsSignalError(LCMS_ERRC_ABORTED, ErrMsg);
- return FALSE;
-}
-
-static
-BOOL Check(LPIT8 it8, SYMBOL sy, const char* Err)
-{
- if (it8 -> sy != sy)
- return SynError(it8, Err);
- return TRUE;
-}
-
-
-
-// Read Next character from stream
-static
-void NextCh(LPIT8 it8)
-{
- it8->ch = *it8->Source;
- if (it8->ch) it8->Source++;
-}
-
-
-// Try to see if current identifier is a keyword, if so return the referred symbol
-static
-SYMBOL BinSrchKey(const char *id)
-{
- int l = 1;
- int r = NUMKEYS;
- int x, res;
-
- while (r >= l)
- {
- x = (l+r)/2;
- res = strcmp(id, TabKeys[x-1].id);
- if (res == 0) return TabKeys[x-1].sy;
- if (res < 0) r = x - 1;
- else l = x + 1;
- }
-
- return SNONE;
-}
-
-
-// 10 ^n
-static
-double pow10(int n)
-{
- return pow(10, n);
-}
-
-
-// Reads a Real number, tries to follow from integer number
-static
-void ReadReal(LPIT8 it8, int inum)
-{
- it8->dnum = (double) inum;
-
- while (isdigit(it8->ch)) {
-
- it8->dnum = it8->dnum * 10.0 + (it8->ch - '0');
- NextCh(it8);
- }
-
- if (it8->ch == '.') { // Decimal point
-
- double frac = 0.0; // fraction
- int prec = 0; // precission
-
- NextCh(it8); // Eats dec. point
-
- while (isdigit(it8->ch)) {
-
- frac = frac * 10.0 + (it8->ch - '0');
- prec++;
- NextCh(it8);
- }
-
- it8->dnum = it8->dnum + (frac / pow10(prec));
- }
-
- // Exponent, example 34.00E+20
- if (toupper(it8->ch) == 'E') {
-
- int e;
- int sgn;
-
- NextCh(it8); sgn = 1;
-
- if (it8->ch == '-') {
-
- sgn = -1; NextCh(it8);
- }
- else
- if (it8->ch == '+') {
-
- sgn = +1;
- NextCh(it8);
- }
-
-
- e = 0;
- while (isdigit(it8->ch)) {
-
- if ((double) e * 10L < INT_MAX)
- e = e * 10 + (it8->ch - '0');
-
- NextCh(it8);
- }
-
- e = sgn*e;
-
- it8 -> dnum = it8 -> dnum * pow10(e);
- }
-}
-
-
-
-// Reads next symbol
-static
-void InSymbol(LPIT8 it8)
-{
- register char *idptr;
- register int k;
- SYMBOL key;
- int sng;
-
- do {
-
- while (isseparator(it8->ch))
- NextCh(it8);
-
- if (isfirstidchar(it8->ch)) { // Identifier
-
-
- k = 0;
- idptr = it8->id;
-
- do {
-
- if (++k < MAXID) *idptr++ = (char) it8->ch;
-
- NextCh(it8);
-
- } while (isidchar(it8->ch));
-
- *idptr = '\0';
- xstrupr(it8->id);
-
- key = BinSrchKey(it8->id);
- if (key == SNONE) it8->sy = SIDENT;
- else it8->sy = key;
-
- }
- else // Is a number?
- if (isdigit(it8->ch) || it8->ch == '.' || it8->ch == '-' || it8->ch == '+')
- {
- int sign = 1;
-
- if (it8->ch == '-') {
- sign = -1;
- NextCh(it8);
- }
-
- it8->inum = 0;
- it8->sy = SINUM;
-
- while (isdigit(it8->ch))
- {
- if ((long) it8->inum * 10L > (long) INT_MAX)
- {
- ReadReal(it8, it8->inum);
- it8->sy = SDNUM;
- it8->dnum *= sign;
- return;
- }
-
- it8->inum = it8->inum * 10 + (it8->ch - '0');
- NextCh(it8);
- }
-
- if (it8->ch == '.') {
-
- ReadReal(it8, it8->inum);
- it8->sy = SDNUM;
- it8->dnum *= sign;
- return;
- }
-
- it8 -> inum *= sign;
- return;
-
- }
- else
- switch ((int) it8->ch) {
-
- case '\0':
- case '\x1a':
- it8->sy = SEOF;
- break;
-
-
-
- case '\n':
- NextCh(it8);
- it8->sy = SEOLN;
- it8->lineno++;
- break;
-
- // Comment
-
- case '#':
- NextCh(it8);
- while (it8->ch && it8->ch != '\n')
- NextCh(it8);
-
- it8->sy = SCOMMENT;
- break;
-
- // String. I will support \", \n, \t and \\.
- // But otherwise I hardly doubt these will be used ...
-
- case '\'':
- case '\"':
- idptr = it8->str;
- sng = it8->ch;
- k = 0;
- NextCh(it8);
-
- while (k < MAXSTR && it8->ch != sng) {
-
- if (it8->ch == '\n'|| it8->ch == '\r') k = MAXSTR+1;
- else {
-
- if (it8->ch == '\\')
- {
- NextCh(it8);
-
- switch (it8->ch) {
-
- case 'n': *idptr++ = '\n'; break;
- case 'r': *idptr++ = '\r'; break;
- case 't': *idptr++ = '\t'; break;
- case '\\': *idptr++ = '\\'; break;
-
- default:
- *idptr++ = (char) it8->ch;
- }
-
- NextCh(it8);
- }
- else
- {
- *idptr++ = (char) it8->ch;
- NextCh(it8);
- }
-
- k++;
- }
- }
-
- it8->sy = SSTRING;
- *idptr = '\0';
- NextCh(it8);
- break;
-
-
- default:
- it8->sy = SSYNERROR;
- NextCh(it8);
-
- }
-
- } while (it8->sy == SCOMMENT);
-}
-
-// Checks end of line separator
-static
-BOOL CheckEOLN(LPIT8 it8)
-{
- if (!Check(it8, SEOLN, "Expected separator")) return FALSE;
- while (it8 -> sy == SEOLN)
- InSymbol(it8);
- return TRUE;
-
-}
-
-// Skip a symbol
-
-static
-void Skip(LPIT8 it8, SYMBOL sy)
-{
- if (it8->sy == sy && it8->sy != SEOF)
- InSymbol(it8);
-}
-
-// Returns a string holding current value
-static
-BOOL GetVal(LPIT8 it8, char* Buffer)
-{
- switch (it8->sy) {
-
- case SIDENT: strncpy(Buffer, it8->id, MAXID-1); break;
- case SINUM: sprintf(Buffer, "%d", it8 -> inum); break;
- case SDNUM: sprintf(Buffer, "%g", it8 -> dnum); break;
- case SSTRING: strncpy(Buffer, it8->str, MAXSTR-1); break;
-
-
- default:
- return SynError(it8, "Sample data expected");
- }
-
- return TRUE;
-}
-
-// ---------------------------------------------------------- Memory management
-
-
-
-// Frees an allocator and owned memory
-void cmsxIT8Free(LCMSHANDLE hIT8)
-{
- LPIT8 it8 = (LPIT8) hIT8;
-
- if (it8 == NULL)
- return;
-
- if (it8->MemorySink) {
-
- LPOWNEDMEM p;
- LPOWNEDMEM n;
-
- for (p = it8->MemorySink; p != NULL; p = n) {
-
- n = p->Next;
- if (p->Ptr) free(p->Ptr);
- free(p);
- }
- }
-
- if (it8->FileBuffer)
- free(it8->FileBuffer);
-
- free(it8);
-}
-
-
-// Allocates a chunk of data, keep linked list
-static
-void* AllocChunk(LPIT8 it8, size_t size)
-{
- LPOWNEDMEM ptr1;
- void* ptr = malloc(size);
-
- if (ptr) {
-
- ZeroMemory(ptr, size);
- ptr1 = (LPOWNEDMEM) malloc(sizeof(OWNEDMEM));
-
- if (ptr1 == NULL) {
-
- free(ptr);
- return NULL;
- }
-
- ZeroMemory(ptr1, sizeof(OWNEDMEM));
-
- ptr1-> Ptr = ptr;
- ptr1-> Next = it8 -> MemorySink;
- it8 -> MemorySink = ptr1;
- }
-
- return ptr;
-}
-
-
-// Allocates a string
-static
-char *AllocString(LPIT8 it8, const char* str)
-{
- int Size = strlen(str)+1;
- char *ptr;
- ptr = (char *) AllocChunk(it8, Size);
- if (ptr) strncpy (ptr, str, Size);
- return ptr;
-}
-
-// Searches through linked list
-
-static
-BOOL IsAvailableOnList(LPKEYVALUE p, const char* Key, LPKEYVALUE* LastPtr)
-{
- for (; p != NULL; p = p->Next) {
-
- if (LastPtr) *LastPtr = p;
- if (stricmp(Key, p->Keyword) == 0)
- return TRUE;
- }
-
- return FALSE;
-}
-
-
-
-// Add a property into a linked list
-static
-BOOL AddToList(LPIT8 it8, LPKEYVALUE* Head, const char *Key, const char* Value)
-{
- LPKEYVALUE p;
- LPKEYVALUE last;
-
-
- // Check if property is already in list (this is an error)
-
- if (IsAvailableOnList(*Head, Key, &last)) {
- cmsSignalError(LCMS_ERRC_ABORTED, "duplicate key <%s>", Key);
- return FALSE;
- }
-
- // Allocate the container
- p = (LPKEYVALUE) AllocChunk(it8, sizeof(KEYVALUE));
- if (p == NULL)
- {
- cmsSignalError(LCMS_ERRC_ABORTED, "AddToList: out of memory");
- return FALSE;
- }
-
- // Store name and value
- p->Keyword = AllocString(it8, Key);
-
- if (Value)
- p->Value = AllocString(it8, Value);
- else
- p->Value = NULL;
-
- p->Next = NULL;
-
- // Keep the container in our list
- if (*Head == NULL)
- *Head = p;
- else
- last->Next = p;
-
- return TRUE;
-}
-
-static
-BOOL AddAvailableProperty(LPIT8 it8, const char* Key)
-{
- return AddToList(it8, &it8->ValidKeywords, Key, NULL);
-}
-
-
-static
-BOOL AddAvailableSampleID(LPIT8 it8, const char* Key)
-{
- return AddToList(it8, &it8->ValidSampleID, Key, NULL);
-}
-
-
-
-// Init an empty container
-LCMSHANDLE cmsxIT8Alloc(void)
-{
- LPIT8 it8;
- int i;
-
- it8 = (LPIT8) malloc(sizeof(IT8));
- if (it8 == NULL) return NULL;
-
- ZeroMemory(it8, sizeof(IT8));
-
- it8->HeaderList = NULL;
- it8->FileBuffer = NULL;
- it8->DataFormat = NULL;
- it8->Data = NULL;
- it8->MemorySink = NULL;
- it8->ValidKeywords = NULL;
- it8->ValidSampleID = NULL;
-
- it8 -> sy = SNONE;
- it8 -> ch = ' ';
- it8 -> Source = NULL;
- it8 -> inum = 0;
- it8 -> dnum = 0.0;
-
- it8 -> lineno = 1;
-
- strcpy(it8->SheetType, "IT8.7/2");
-
- // Initialize predefined properties & data
-
- for (i=0; i < NUMPREDEFINEDPROPS; i++)
- AddAvailableProperty(it8, PredefinedProperties[i]);
-
- for (i=0; i < NUMPREDEFINEDSAMPLEID; i++)
- AddAvailableSampleID(it8, PredefinedSampleID[i]);
-
-
- return (LCMSHANDLE) it8;
-}
-
-
-const char* cdecl cmsxIT8GetSheetType(LCMSHANDLE hIT8)
-{
- LPIT8 it8 = (LPIT8) hIT8;
-
- return it8 ->SheetType;
-
-}
-
-BOOL cmsxIT8SetSheetType(LCMSHANDLE hIT8, const char* Type)
-{
- LPIT8 it8 = (LPIT8) hIT8;
-
- strncpy(it8 ->SheetType, Type, MAXSTR-1);
- return TRUE;
-}
-
-
-
-// Sets a property
-BOOL cmsxIT8SetProperty(LCMSHANDLE hIT8, const char* Key, const char *Val)
-{
- LPIT8 it8 = (LPIT8) hIT8;
-
- if (!Val) return FALSE;
- if (!*Val) return FALSE;
-
- return AddToList(it8, &it8 -> HeaderList, Key, Val);
-}
-
-
-BOOL cmsxIT8SetPropertyDbl(LCMSHANDLE hIT8, const char* cProp, double Val)
-{
- char Buffer[256];
-
- sprintf(Buffer, "%g", Val);
- return cmsxIT8SetProperty(hIT8, cProp, Buffer);
-}
-
-// Gets a property
-const char* cmsxIT8GetProperty(LCMSHANDLE hIT8, const char* Key)
-{
- LPIT8 it8 = (LPIT8) hIT8;
- LPKEYVALUE p;
-
- if (IsAvailableOnList(it8 -> HeaderList, Key, &p))
- {
- return p -> Value;
- }
- return NULL;
-}
-
-
-double cmsxIT8GetPropertyDbl(LCMSHANDLE hIT8, const char* cProp)
-{
- const char *v = cmsxIT8GetProperty(hIT8, cProp);
- if (v) return atof(v);
- else return 0.0;
-}
-
-// ----------------------------------------------------------------- Datasets
-
-
-static
-void AllocateDataFormat(LPIT8 it8)
-{
- if (it8 -> DataFormat) return; // Already allocated
-
- it8 -> nSamples = atoi(cmsxIT8GetProperty(it8, "NUMBER_OF_FIELDS"));
-
- if (it8 -> nSamples <= 0) {
-
- cmsSignalError(LCMS_ERRC_WARNING, "AllocateDataFormat: Unknown NUMBER_OF_FIELDS, assuming 10");
- it8 -> nSamples = 10;
- }
-
- it8 -> DataFormat = (char**) AllocChunk (it8, (it8->nSamples + 1) * sizeof(char *));
- if (it8->DataFormat == NULL)
- {
- cmsSignalError(LCMS_ERRC_ABORTED, "AllocateDataFormat: Unable to allocate dataFormat array");
- }
-
-}
-
-static
-const char *GetDataFormat(LPIT8 it8, int n)
-{
- if (it8->DataFormat)
- return it8->DataFormat[n];
-
- return NULL;
-}
-
-static
-BOOL SetDataFormat(LPIT8 it8, int n, const char *label)
-{
- if (n > it8 -> nSamples) return FALSE;
-
- if (!it8->DataFormat)
- AllocateDataFormat(it8);
-
- if (it8->DataFormat) {
-
- it8->DataFormat[n] = AllocString(it8, label);
- }
-
- return TRUE;
-}
-
-
-BOOL cmsxIT8SetDataFormat(LCMSHANDLE h, int n, const char *Sample)
-{
- LPIT8 it8 = (LPIT8) h;
- return SetDataFormat(it8, n, Sample);
-}
-
-static
-void AllocateDataSet(LPIT8 it8)
-{
- if (it8 -> Data) return; // Already allocated
-
- it8-> nSamples = atoi(cmsxIT8GetProperty(it8, "NUMBER_OF_FIELDS"));
- it8-> nPatches = atoi(cmsxIT8GetProperty(it8, "NUMBER_OF_SETS"));
- it8-> Data = (char**)AllocChunk (it8, (it8->nSamples + 1) * (it8->nPatches + 1) *sizeof (char*));
- if (it8->Data == NULL)
- {
- cmsSignalError(-1, "AllocateDataSet: Unable to allocate data array");
- }
-
-}
-
-static
-char* GetData(LPIT8 it8, int nSet, int nField)
-{
- int nSamples = it8 -> nSamples;
- int nPatches = it8 -> nPatches;
-
- if (nSet >= nPatches || nField >= nSamples)
- return NULL;
-
- if (!it8->Data) return NULL;
- return it8->Data [nSet * nSamples + nField];
-}
-
-static
-BOOL SetData(LPIT8 it8, int nSet, int nField, char *Val)
-{
- if (!it8->Data)
- AllocateDataSet(it8);
-
- if (!it8->Data) return FALSE;
-
-
- if (nSet > it8 -> nPatches) {
-
- SynError(it8, "Patch %d out of range, there are %d datasets", nSet, it8 -> nPatches);
- return FALSE;
- }
-
- if (nField > it8 ->nSamples) {
- SynError(it8, "Sample %d out of range, there are %d datasets", nField, it8 ->nSamples);
- return FALSE;
- }
-
-
- it8->Data [nSet * it8 -> nSamples + nField] = AllocString(it8, Val);
- return TRUE;
-}
-
-
-// --------------------------------------------------------------- File I/O
-
-
-// Writes a string to file
-static
-void WriteStr(FILE *f, char *str)
-{
- if (str == NULL)
- fwrite(" ", 1, 1, f);
- else
- fwrite(str, 1, strlen(str), f);
-}
-
-
-// Writes full header
-static
-void WriteHeader(LPIT8 it8, FILE *fp)
-{
- LPKEYVALUE p;
-
- WriteStr(fp, it8->SheetType);
- WriteStr(fp, "\n");
- for (p = it8->HeaderList; (p != NULL); p = p->Next)
- {
- if (!IsAvailableOnList(it8-> ValidKeywords, p->Keyword, NULL)) {
-
- WriteStr(fp, "KEYWORD\t\"");
- WriteStr(fp, p->Keyword);
- WriteStr(fp, "\"\n");
-
- }
-
- WriteStr(fp, p->Keyword);
- if (p->Value) {
-
- WriteStr(fp, "\t\"");
- WriteStr(fp, p->Value);
- WriteStr(fp, "\"");
- }
- WriteStr (fp, "\n");
- }
-
-}
-
-
-// Writes the data format
-static
-void WriteDataFormat(FILE *fp, LPIT8 it8)
-{
- int i, nSamples;
-
- if (!it8 -> DataFormat) return;
-
- WriteStr(fp, "BEGIN_DATA_FORMAT\n");
- nSamples = atoi(cmsxIT8GetProperty(it8, "NUMBER_OF_FIELDS"));
-
- for (i = 0; i < nSamples; i++) {
-
- WriteStr(fp, it8->DataFormat[i]);
- WriteStr(fp, ((i == (nSamples-1)) ? "\n" : "\t"));
- }
-
- WriteStr (fp, "END_DATA_FORMAT\n");
-}
-
-
-// Writes data array
-static
-void WriteData(FILE *fp, LPIT8 it8)
-{
- int i, j;
-
- if (!it8->Data) return;
-
- WriteStr (fp, "BEGIN_DATA\n");
-
- it8->nPatches = atoi(cmsxIT8GetProperty(it8, "NUMBER_OF_SETS"));
-
- for (i = 0; i < it8-> nPatches; i++) {
-
- for (j = 0; j < it8->nSamples; j++) {
-
- char *ptr = it8->Data[i*it8->nSamples+j];
-
- WriteStr(fp, ((ptr == NULL) ? "0.00" : ptr));
- WriteStr(fp, ((j == (it8->nSamples-1)) ? "\n" : "\t"));
- }
- }
- WriteStr (fp, "END_DATA\n");
-}
-
-
-
-// Saves whole file
-BOOL cmsxIT8SaveToFile(LCMSHANDLE hIT8, const char* cFileName)
-{
- FILE *fp;
- LPIT8 it8 = (LPIT8) hIT8;
-
- fp = fopen(cFileName, "wt");
- if (!fp) return FALSE;
- WriteHeader(it8, fp);
- WriteDataFormat(fp, it8);
- WriteData(fp, it8);
- fclose(fp);
-
- return TRUE;
-}
-
-
-// Reads whole file in a memory block
-static
-BOOL ReadFileInMemory(const char *cFileName, char **Buffer, size_t *Len)
-{
- FILE *fp;
- size_t Size;
- char *Ptr;
-
- fp = fopen(cFileName, "rt");
- if (!fp) return FALSE;
-
- Size = xfilelength(fileno(fp));
- if (Size <= 0) {
- fclose(fp);
- return FALSE;
- }
-
- Ptr = malloc(Size+1);
-
- Size = fread(Ptr, 1, Size, fp);
- fclose(fp);
- Ptr[Size] = '\0';
-
- *Buffer = Ptr;
- *Len = Size;
- return TRUE;
-}
-
-
-// -------------------------------------------------------------- Higer lever parsing
-
-static
-BOOL DataFormatSection(LPIT8 it8)
-{
- int iField = 0;
- BOOL Ignoring = FALSE;
-
- InSymbol(it8); // Eats "BEGIN_DATA_FORMAT"
- CheckEOLN(it8);
-
- while (it8->sy != SEND_DATA_FORMAT &&
- it8->sy != SEOLN &&
- it8->sy != SEOF &&
- it8->sy != SSYNERROR)
- {
-
- if (it8->sy != SIDENT) {
-
- cmsSignalError(LCMS_ERRC_ABORTED, "Sample type expected");
- it8->sy = SSYNERROR;
- return FALSE;
- }
-
- if (!Ignoring && iField > it8->nSamples) {
- cmsSignalError(LCMS_ERRC_WARNING, "More than NUMBER_OF_FIELDS fields. Extra is ignored\n");
- Ignoring = TRUE;
- }
- else {
- if (!SetDataFormat(it8, iField, it8->id)) return FALSE;
- iField++;
- }
-
- InSymbol(it8);
- Skip(it8, SEOLN);
- }
-
- Skip(it8, SEOLN);
- Skip(it8, SEND_DATA_FORMAT);
- Skip(it8, SEOLN);
- return TRUE;
-}
-
-
-
-static
-BOOL DataSection (LPIT8 it8)
-{
- int iField = 0;
- int iSet = 0;
- char Buffer[256];
-
- InSymbol(it8); // Eats "BEGIN_DATA"
- CheckEOLN(it8);
-
- while (it8->sy != SEND_DATA && it8->sy != SEOF)
- {
- if (iField >= it8 -> nSamples) {
- iField = 0;
- iSet++;
- if (!CheckEOLN(it8))
- return FALSE;
- }
-
- if (it8->sy != SEND_DATA && it8->sy != SEOF) {
-
- if (!GetVal(it8, Buffer))
- return FALSE;
-
- if (!SetData(it8, iSet, iField, Buffer))
- return FALSE;
-
- iField++;
-
- Skip(it8, SEOLN);
- InSymbol(it8);
- }
- }
-
- Skip(it8, SEOLN);
- Skip(it8, SEND_DATA);
- Skip(it8, SEOLN);
- return TRUE;
-}
-
-
-
-
-
-
-static
-BOOL HeaderSection (LPIT8 it8)
-{
- char VarName[MAXID];
- char Buffer[MAXSTR];
-
- while (it8->sy != SEOF &&
- it8->sy != SSYNERROR &&
- it8->sy != SBEGIN_DATA_FORMAT &&
- it8->sy != SBEGIN_DATA) {
-
-
- switch (it8 -> sy) {
-
- case SKEYWORD:
- InSymbol(it8);
- if (!Check(it8, SSTRING, "Keyword expected")) return FALSE;
- if (!AddAvailableProperty(it8, it8 -> str)) return FALSE;
- InSymbol(it8);
- break;
-
-
- case SIDENT:
- strncpy(VarName, it8->id, MAXID-1);
- if (!IsAvailableOnList(it8-> ValidKeywords, VarName, NULL))
- return SynError(it8, "Undefined keyword '%s'", VarName);
-
- InSymbol(it8);
- GetVal(it8, Buffer);
- cmsxIT8SetProperty((LCMSHANDLE) it8, VarName, Buffer);
- InSymbol(it8);
- break;
-
-
- case SEOLN: break;
-
- default:
- return SynError(it8, "expected keyword or identifier");
- }
-
- Skip(it8, SEOLN);
- }
-
- return TRUE;
-
-}
-
-
-static
-BOOL ParseIT8(LPIT8 it8)
-{
-
- InSymbol(it8);
-
- if (it8->sy == SIDENT) {
-
- strncpy(it8->SheetType, it8->id, MAXSTR-1);
- InSymbol(it8);
-
- // if (!AddAvailableProperty(it8, it8 -> id)) return FALSE;
- // cmsxIT8SetProperty((LCMSHANDLE) it8, it8->id, NULL);
- }
-
- Skip(it8, SEOLN);
-
- while (it8-> sy != SEOF &&
- it8-> sy != SSYNERROR) {
-
- switch (it8 -> sy) {
-
- case SBEGIN_DATA_FORMAT:
- if (!DataFormatSection(it8)) return FALSE;
- break;
-
- case SBEGIN_DATA:
- if (!DataSection(it8)) return FALSE;
- break;
-
- case SEOLN:
- Skip(it8, SEOLN);
- break;
-
- default:
- if (!HeaderSection(it8)) return FALSE;
- }
-
- }
-
- return TRUE;
-}
-
-
-static
-void CleanPatchName(char *cell)
-{
- char cleaned[256], Buffer[256], ident[256];
- char *orig = cell, *id;
- int n, lOneNum;
-
-
- id = ident;
- while (*cell && isalpha(*cell))
- {
- *id++ = (char) toupper(*cell);
- cell++;
- }
- *id = 0;
- strcpy(cleaned, ident);
-
-
- n = 0;
- lOneNum = FALSE;
- while (*cell && isdigit(*cell))
- {
- n = n * 10 + (*cell -'0');
- cell++;
- lOneNum = TRUE;
- }
-
- if (lOneNum) {
-
- sprintf(Buffer, "%d", n);
- strcat(cleaned, Buffer);
- }
-
- if (strcmp(cleaned, "GS0") == 0)
- strcpy(orig, "DMIN");
- else
- if (strcmp(cleaned, "GS23") == 0)
- strcpy(orig, "DMAX");
- else
- strcpy(orig, cleaned);
-}
-
-
-// Init usefull pointers
-
-static
-void CookPointers(LPIT8 it8)
-{
- int idField, i;
- char* Fld;
-
- it8 -> SampleID = 0;
- for (idField = 0; idField < it8 -> nSamples; idField++)
- {
- Fld = it8->DataFormat[idField];
- if (!Fld) continue;
-
- if (strcmp(Fld, "SAMPLE_ID") == 0) {
- it8 -> SampleID = idField;
-
-
- for (i=0; i < it8 -> nPatches; i++) {
-
- char *Data = GetData(it8, i, idField);
- if (Data) {
- char Buffer[256];
-
- strncpy(Buffer, Data, 255);
- CleanPatchName(Buffer);
-
- if (strlen(Buffer) <= strlen(Data))
- strcpy(Data, Buffer);
- else
- SetData(it8, i, idField, Buffer);
-
- }
- }
-
- }
- }
-
-}
-
-
-// ---------------------------------------------------------- Exported routines
-
-
-LCMSHANDLE cmsxIT8LoadFromMem(void *Ptr, size_t len)
-{
- LCMSHANDLE hIT8 = cmsxIT8Alloc();
- LPIT8 it8 = (LPIT8) hIT8;
-
- if (!hIT8) return NULL;
- it8 ->FileBuffer = (char*) malloc(len + 1);
-
- strncpy(it8 ->FileBuffer, Ptr, len);
- strncpy(it8->FileName, "", MAX_PATH-1);
- it8-> Source = it8 -> FileBuffer;
-
- ParseIT8(it8);
- CookPointers(it8);
-
- free(it8->FileBuffer);
- it8 -> FileBuffer = NULL;
-
- return hIT8;
-
-
-}
-
-
-LCMSHANDLE cmsxIT8LoadFromFile(const char* cFileName)
-{
-
- LCMSHANDLE hIT8 = cmsxIT8Alloc();
- LPIT8 it8 = (LPIT8) hIT8;
- size_t Len;
-
- if (!hIT8) return NULL;
- if (!ReadFileInMemory(cFileName, &it8->FileBuffer, &Len)) return NULL;
-
- strncpy(it8->FileName, cFileName, MAX_PATH-1);
- it8-> Source = it8 -> FileBuffer;
-
- ParseIT8(it8);
- CookPointers(it8);
-
- free(it8->FileBuffer);
- it8 -> FileBuffer = NULL;
-
- return hIT8;
-
-}
-
-int cmsxIT8EnumDataFormat(LCMSHANDLE hIT8, char ***SampleNames)
-{
- LPIT8 it8 = (LPIT8) hIT8;
-
- *SampleNames = it8 -> DataFormat;
- return it8 -> nSamples;
-}
-
-
-int cmsxIT8EnumProperties(LCMSHANDLE hIT8, char ***PropertyNames)
-{
- LPIT8 it8 = (LPIT8) hIT8;
- LPKEYVALUE p;
- int n;
- char **Props;
-
- // Pass#1 - count properties
-
- n = 0;
- for (p = it8 -> HeaderList; p != NULL; p = p->Next) {
- n++;
- }
-
-
- Props = (char **) malloc(sizeof(char *) * n);
-
- // Pass#2 - Fill pointers
- n = 0;
- for (p = it8 -> HeaderList; p != NULL; p = p->Next) {
- Props[n++] = p -> Keyword;
- }
-
- *PropertyNames = Props;
- return n;
-}
-
-static
-int LocatePatch(LPIT8 it8, const char* cPatch)
-{
- int i;
- const char *data;
-
- for (i=0; i < it8-> nPatches; i++) {
-
- data = GetData(it8, i, it8->SampleID);
-
- if (data != NULL) {
-
- if (stricmp(data, cPatch) == 0)
- return i;
- }
- }
-
- return -1;
-}
-
-
-static
-int LocateEmptyPatch(LPIT8 it8, const char* cPatch)
-{
- int i;
- const char *data;
-
- for (i=0; i < it8-> nPatches; i++) {
-
- data = GetData(it8, i, it8->SampleID);
-
- if (data == NULL)
- return i;
-
- }
-
- return -1;
-}
-
-static
-int LocateSample(LPIT8 it8, const char* cSample)
-{
- int i;
- const char *fld;
-
- for (i=0; i < it8->nSamples; i++) {
-
- fld = GetDataFormat(it8, i);
- if (stricmp(fld, cSample) == 0)
- return i;
- }
-
- return -1;
-}
-
-
-BOOL cmsxIT8GetDataSetByPos(LCMSHANDLE hIT8, int col, int row, char* Val, int ValBufferLen)
-{
- LPIT8 it8 = (LPIT8) hIT8;
- const char *data = GetData(it8, row, col);
-
- if (!data)
- {
- *Val = '\0';
- return FALSE;
- }
-
- strncpy(Val, data, ValBufferLen-1);
- return TRUE;
-}
-
-
-
-BOOL cmsxIT8GetDataSet(LCMSHANDLE hIT8, const char* cPatch,
- const char* cSample,
- char* Val, int ValBuffLen)
-{
- LPIT8 it8 = (LPIT8) hIT8;
- int iField, iSet;
-
-
- iField = LocateSample(it8, cSample);
- if (iField < 0) {
- // cmsSignalError(LCMS_ERRC_ABORTED, "Couldn't find data field %s\n", cSample);
- return FALSE;
- }
-
-
- iSet = LocatePatch(it8, cPatch);
- if (iSet < 0) {
-
- // cmsSignalError(LCMS_ERRC_ABORTED, "Couldn't find patch '%s'\n", cPatch);
- return FALSE;
- }
-
- strncpy(Val, GetData(it8, iSet, iField), ValBuffLen-1);
- return TRUE;
-}
-
-
-BOOL cmsxIT8GetDataSetDbl(LCMSHANDLE it8, const char* cPatch, const char* cSample, double* v)
-{
- char Buffer[20];
-
- if (cmsxIT8GetDataSet(it8, cPatch, cSample, Buffer, 20)) {
-
- *v = atof(Buffer);
- return TRUE;
- } else
- return FALSE;
-}
-
-
-
-BOOL cmsxIT8SetDataSet(LCMSHANDLE hIT8, const char* cPatch,
- const char* cSample,
- char *Val)
-{
- LPIT8 it8 = (LPIT8) hIT8;
- int iField, iSet;
-
-
- iField = LocateSample(it8, cSample);
-
- if (iField < 0) {
-
- cmsSignalError(LCMS_ERRC_ABORTED, "Couldn't find data field %s\n", cSample);
- return FALSE;
- }
-
-
- if (it8-> nPatches == 0) {
-
- AllocateDataFormat(it8);
- AllocateDataSet(it8);
- CookPointers(it8);
- }
-
-
- if (stricmp(cSample, "SAMPLE_ID") == 0)
- {
-
- iSet = LocateEmptyPatch(it8, cPatch);
- if (iSet < 0) {
- cmsSignalError(LCMS_ERRC_ABORTED, "Couldn't add more patches '%s'\n", cPatch);
- return FALSE;
- }
- iField = it8 -> SampleID;
- }
- else {
- iSet = LocatePatch(it8, cPatch);
- if (iSet < 0) {
-
- cmsSignalError(LCMS_ERRC_ABORTED, "Couldn't find patch '%s'\n", cPatch);
- return FALSE;
- }
- }
-
- return SetData(it8, iSet, iField, Val);
-}
-
-
-BOOL cmsxIT8SetDataSetDbl(LCMSHANDLE hIT8, const char* cPatch,
- const char* cSample,
- double Val)
-{
- char Buff[256];
-
- sprintf(Buff, "%g", Val);
- return cmsxIT8SetDataSet(hIT8, cPatch, cSample, Buff);
-
-}
-
-
-const char* cmsxIT8GetPatchName(LCMSHANDLE hIT8, int nPatch, char* buffer)
-{
- LPIT8 it8 = (LPIT8) hIT8;
- char* Data = GetData(it8, nPatch, it8->SampleID);
- if (!Data) return NULL;
-
- strcpy(buffer, Data);
- return buffer;
-}
-
-
-const char* cmsxIT8GenericPatchName(int nPatch, char* buffer)
-{
- int row, col;
-
- if (nPatch >= cmsxIT8_NORMAL_PATCHES)
- return "$CUSTOM";
-
- if (nPatch >= (cmsxIT8_ROWS * cmsxIT8_COLS)) {
-
- nPatch -= cmsxIT8_ROWS * cmsxIT8_COLS;
- if (nPatch == 0)
- return "DMIN";
- else
- if (nPatch == cmsxIT8_GRAYCOLS - 1)
- return "DMAX";
- else
- sprintf(buffer, "GS%d", nPatch);
- return buffer;
- }
-
-
- row = nPatch / cmsxIT8_COLS;
- col = nPatch % cmsxIT8_COLS;
-
- sprintf (buffer, "%c%d", 'A'+row, col+1);
- return buffer;
-}
-
-
-
-
-int cmsxIT8GenericPatchNum(const char *name)
-{
- int i;
- char Buff[256];
-
-
- for (i=0; i < cmsxIT8_TOTAL_PATCHES; i++)
- if (stricmp(cmsxIT8GenericPatchName(i, Buff), name) == 0)
- return i;
-
- return -1;
-}
-
-
-
-
-
/trunk/lprof/src/cmssheet.c
Property changes:
Deleted: svn:eol-style
## -1 +0,0 ##
-native
\ No newline at end of property
Deleted: svn:keywords
## -1 +0,0 ##
-Author Date Id Revision
\ No newline at end of property
Index: trunk/lprof/src/cmslm.c
===================================================================
--- trunk/lprof/src/cmslm.c (revision 2454)
+++ trunk/lprof/src/cmslm.c (nonexistent)
@@ -1,288 +0,0 @@
-//
-// Little cms - profiler construction set
-// Copyright (C) 1998-2001 Marti Maria
-//
-// 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., 59 Temple Place - Suite 330, Boston, ma 02111-1307, 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"
-
-
-// From "numerical recipes in C"
-//
-// Levenberg-Marquardt method, attempting to reduce the value X2 of a
-// fit between a set of data points x[1..ndata], y[1..ndata] with individual
-// standard deviations sig[1..ndata], and a nonlinear function dependent
-// on ma coefficients a[1..ma]. The input array ia[1..ma]
-// indicates by nonzero entries those components of a that should be
-// fitted for, and by zero entries those components that should be held
-// fixed at their input values. The program returns current best-fitt
-// values for the parameters a[1..ma], and chisq. The arrays
-// covar[1..ma][1..ma], alpha[1..ma][1..ma] are used as
-// working space during most iterations. Supply a routine
-// funcs(x, a, yfit, dyda, ma)
-// that evaluates the fitting function yfit, and its derivatives dyda[1..ma]
-// with respect to the fitting parameters a at x. On the first call provide
-// an initial guess for the parameters a, and set alamda<0 for initialization
-// (which then sets alamda=.001). If a step succeeds chisq becomes smaller
-// and alamda decreases by a factor of 10. If a step fails alamda grows by
-// a factor of 10. You must call this routine repeatedly until convergence
-// is achieved. Then, make one final call with alamda=0, so that
-// covar[1..ma][1..ma] returns the covar matrix, and alpha the
-// alpha matrix. (Parameters held fixed will return zero covariances.)
-
-
-LCMSHANDLE cdecl cmsxLevenbergMarquardtInit(LPSAMPLEDCURVE x, LPSAMPLEDCURVE y, double sig,
- double a[],
- int ma,
- void (*funcs)(double, double[], double*, double[], int)
- );
-
-double cdecl cmsxLevenbergMarquardtAlamda(LCMSHANDLE hMRQ);
-double cdecl cmsxLevenbergMarquardtChiSq(LCMSHANDLE hMRQ);
-BOOL cdecl cmsxLevenbergMarquardtIterate(LCMSHANDLE hMRQ);
-BOOL cdecl cmsxLevenbergMarquardtFree(LCMSHANDLE hMRQ);
-
-// ----------------------------------------------------------------------------
-
-
-
-typedef struct {
-
- LPSAMPLEDCURVE x;
- LPSAMPLEDCURVE y;
- int ndata;
- double* a;
- int ma;
- LPMATN covar;
- LPMATN alpha;
- double* atry;
- LPMATN beta;
- LPMATN oneda;
- double* dyda;
- double ochisq;
- double sig;
-
-
- void (*funcs)(double, double[], double*, double[], int);
-
- double alamda;
- double chisq;
-
-} LMRQMIN, FAR* LPLMRQMIN;
-
-
-
-
-static
-void mrqcof(LPLMRQMIN pLM, double *a, LPMATN alpha, LPMATN beta, double *chisq)
-{
- int i, j, k;
- double ymod, wt, sig2i, dy;
-
- for(j = 0; j < pLM->ma; j++)
- {
- for(k = 0; k <= j; k++)
- alpha->Values[j][k] = 0.0;
-
- beta->Values[j][0] = 0.0;
- }
-
- *chisq = 0.0;
- sig2i = 1.0 / (pLM->sig * pLM->sig);
-
- for(i = 0; i < pLM->ndata; i++)
- {
- (*(pLM->funcs))(pLM->x ->Values[i], a, &ymod, pLM->dyda, pLM->ma);
-
- dy = pLM->y->Values[i] - ymod;
-
- for(j = 0; j < pLM->ma; j++)
- {
- wt = pLM->dyda[j] * sig2i;
-
- for(k = 0; k <= j; k++)
- alpha->Values[j][k] += wt * pLM->dyda[k];
-
- beta->Values[j][0] += dy * wt;
- }
-
- *chisq += dy * dy * sig2i;
- }
-
- for(j = 1; j < pLM->ma; j++) // Fill in the symmetric side.
- for(k = 0; k < j; k++)
- alpha->Values[k][j] = alpha->Values[j][k];
-}
-
-
-
-static
-void FreeStruct(LPLMRQMIN pLM)
-{
- if(pLM == NULL) return;
-
- if(pLM->covar) MATNfree (pLM->covar);
- if(pLM->alpha) MATNfree (pLM->alpha);
- if(pLM->atry) free(pLM->atry);
- if(pLM->beta) MATNfree (pLM->beta);
- if(pLM->oneda) MATNfree (pLM->oneda);
- if(pLM->dyda) free(pLM->dyda);
- free(pLM);
-}
-
-
-
-LCMSHANDLE cmsxLevenbergMarquardtInit(LPSAMPLEDCURVE x, LPSAMPLEDCURVE y, double sig,
- double a[],
- int ma,
- void (*funcs)(double, double[], double*, double[], int))
-
-{
- int i;
- LPLMRQMIN pLM;
-
- if (x ->nItems != y ->nItems) return NULL;
-
- pLM = (LPLMRQMIN) malloc(sizeof(LMRQMIN));
- if(!pLM)
- return NULL;
-
- ZeroMemory(pLM, sizeof(LMRQMIN));
-
- if((pLM->atry = (double*)malloc(ma * sizeof(double))) == NULL) goto failed;
- if((pLM->beta = MATNalloc (ma, 1)) == NULL) goto failed;
- if((pLM->oneda = MATNalloc (ma, 1)) == NULL) goto failed;
-
-
-
- if((pLM->covar = MATNalloc(ma, ma)) == NULL) goto failed;
- if((pLM->alpha = MATNalloc(ma, ma)) == NULL) goto failed;
- if((pLM->dyda = (double*)malloc(ma * sizeof(double))) == NULL) goto failed;
-
- pLM->alamda = 0.001;
-
- pLM->ndata = x ->nItems;
- pLM->x = x;
- pLM->y = y;
- pLM->ma = ma;
- pLM->a = a;
- pLM->funcs = funcs;
- pLM->sig = sig;
-
- mrqcof(pLM, a, pLM->alpha, pLM->beta, &pLM->chisq);
- pLM->ochisq = (pLM->chisq);
-
- for(i = 0; i < ma; i++) pLM->atry[i] = a[i];
-
- return (LCMSHANDLE) pLM;
-
-failed:
- FreeStruct(pLM);
- return NULL;
-}
-
-
-BOOL cmsxLevenbergMarquardtFree(LCMSHANDLE hMRQ)
-{
- LPLMRQMIN pLM = (LPLMRQMIN)hMRQ;
- if(!pLM)
- return FALSE;
-
- FreeStruct(pLM);
- return TRUE;
-}
-
-
-BOOL cmsxLevenbergMarquardtIterate(LCMSHANDLE hMRQ)
-{
- int j, k;
- BOOL sts;
- LPLMRQMIN pLM = (LPLMRQMIN)hMRQ;
- if(!pLM)
- return FALSE;
-
- for(j = 0; j < pLM->ma; j++) // Alter linearized fitting matrix, by augmenting diagonal elements.
- {
- for(k = 0; k < pLM->ma; k++)
- pLM->covar->Values[j][k] = pLM->alpha->Values[j][k];
-
- pLM->covar->Values[j][j] = pLM->alpha->Values[j][j] * (1.0 + pLM ->alamda);
- pLM->oneda->Values[j][0] = pLM->beta->Values[j][0];
- }
-
- if((sts = MATNsolve (pLM->covar, pLM->oneda)) != TRUE) // Matrix solution.
- return sts;
-
- for(j = 0; j < pLM->ma; j++) // Did the trial succeed?
- pLM->atry[j] = pLM->a[j] + pLM->oneda->Values[j][0];
-
- mrqcof(pLM, pLM->atry, pLM->covar, pLM->oneda, &pLM -> chisq);
-
- if (pLM->chisq < pLM->ochisq) { // Success, accept the new solution.
-
- pLM->alamda *= 0.1;
- pLM->ochisq = pLM->chisq;
-
- for(j = 0; j < pLM->ma; j++)
- {
- for(k = 0; k < pLM->ma; k++)
- pLM->alpha->Values[j][k] = pLM->covar->Values[j][k];
-
- pLM->beta->Values[j][0] = pLM->oneda->Values[j][0];
- }
-
- for (j=0; j < pLM ->ma; j++) pLM->a[j] = pLM->atry[j];
- }
- else // Failure, increase alamda and return.
- {
- pLM -> alamda *= 10.0;
- pLM->chisq = pLM->ochisq;
- }
-
- return TRUE;
-}
-
-
-double cmsxLevenbergMarquardtAlamda(LCMSHANDLE hMRQ)
-{
- LPLMRQMIN pLM = (LPLMRQMIN)hMRQ;
-
- return pLM ->alamda;
-}
-
-double cmsxLevenbergMarquardtChiSq(LCMSHANDLE hMRQ)
-{
- LPLMRQMIN pLM = (LPLMRQMIN)hMRQ;
-
- return pLM ->chisq;
-}
/trunk/lprof/src/cmslm.c
Property changes:
Deleted: svn:eol-style
## -1 +0,0 ##
-native
\ No newline at end of property
Deleted: svn:keywords
## -1 +0,0 ##
-Author Date Id Revision
\ No newline at end of property
Index: trunk/lprof/src/cmspcoll.c
===================================================================
--- trunk/lprof/src/cmspcoll.c (revision 2454)
+++ trunk/lprof/src/cmspcoll.c (nonexistent)
@@ -1,1045 +0,0 @@
-//
-// Little cms - profiler construction set
-// Copyright (C) 1998-2001 Marti Maria
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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.08a
-
-
-#include "lcmsprf.h"
-
-
-// ----------------------------------------------------------------- Patch collections
-
-BOOL cdecl cmsxPCollLoadFromSheet(LPMEASUREMENT m, LCMSHANDLE hSheet);
-
-BOOL cdecl cmsxPCollBuildMeasurement(LPMEASUREMENT m,
- const char *ReferenceSheet,
- const char *MeasurementSheet,
- DWORD dwNeededSamplesType);
-
-LPPATCH cdecl cmsxPCollGetPatch(LPMEASUREMENT m, int n);
-
-LPPATCH cdecl cmsxPCollGetPatchByName(LPMEASUREMENT m, const char* Name, int* lpPos);
-LPPATCH cdecl cmsxPCollGetPatchByPos(LPMEASUREMENT m, int row, int col);
-LPPATCH cdecl cmsxPCollAddPatchRGB(LPMEASUREMENT m, const char *Name,
- double r, double g, double b,
- LPcmsCIEXYZ XYZ, LPcmsCIELab Lab);
-
-// Sets of patches
-
-SETOFPATCHES cdecl cmsxPCollBuildSet(LPMEASUREMENT m, BOOL lDefault);
-int cdecl cmsxPCollCountSet(LPMEASUREMENT m, SETOFPATCHES Set);
-BOOL cdecl cmsxPCollValidatePatches(LPMEASUREMENT m, DWORD dwFlags);
-
-
-// Collect "need" patches of the specific kind, return the number of collected (that
-// could be less if set of patches is exhausted)
-
-
-void cdecl cmsxPCollPatchesGS(LPMEASUREMENT m, SETOFPATCHES Result);
-
-int cdecl cmsxPCollPatchesNearRGB(LPMEASUREMENT m, SETOFPATCHES Valids,
- double r, double g, double b, int need, SETOFPATCHES Result);
-
-int cdecl cmsxPCollPatchesNearNeutral(LPMEASUREMENT m, SETOFPATCHES Valids,
- int need, SETOFPATCHES Result);
-
-int cdecl cmsxPCollPatchesNearPrimary(LPMEASUREMENT m, SETOFPATCHES Valids,
- int nChannel, int need, SETOFPATCHES Result);
-
-int cdecl cmsxPCollPatchesInLabCube(LPMEASUREMENT m, SETOFPATCHES Valids,
- double Lmin, double LMax, double a, double b, SETOFPATCHES Result);
-
-int cdecl cmsxPCollPatchesInGamutLUT(LPMEASUREMENT m, SETOFPATCHES Valids,
- LPLUT Gamut, SETOFPATCHES Result);
-
-LPPATCH cdecl cmsxPCollFindWhite(LPMEASUREMENT m, SETOFPATCHES Valids, double* Distance);
-LPPATCH cdecl cmsxPCollFindBlack(LPMEASUREMENT m, SETOFPATCHES Valids, double* Distance);
-LPPATCH cdecl cmsxPCollFindPrimary(LPMEASUREMENT m, SETOFPATCHES Valids, int Channel, double* Distance);
-
-
-// ------------------------------------------------------------- Implementation
-
-#define IS(x) EqualsTo(c, x)
-
-// A wrapper on stricmp()
-
-static
-BOOL EqualsTo(const char* a, const char *b)
-{
- return (stricmp(a, b) == 0);
-}
-
-
-// Does return a bitwise mask holding the measurements contained in a Sheet
-
-static
-DWORD MaskOfDataSet(LCMSHANDLE hSheet)
-{
- char** Names;
- int i, n;
- DWORD dwMask = 0;
-
- n = cmsxIT8EnumDataFormat(hSheet, &Names);
-
- for (i=0; i < n; i++) {
-
- char *c = Names[i];
-
- if (IS("RGB_R") || IS("RGB_G") || IS("RGB_B"))
- dwMask |= PATCH_HAS_RGB;
- else
- if (IS("XYZ_X") || IS("XYZ_Y") || IS("XYZ_Z"))
- dwMask |= PATCH_HAS_XYZ;
- else
- if (IS("LAB_L") || IS("LAB_A") ||IS("LAB_B"))
- dwMask |= PATCH_HAS_Lab;
- else
- if (IS("STDEV_DE"))
- dwMask |= PATCH_HAS_STD_DE;
- }
-
- return dwMask;
-}
-
-
-// Addition of a patch programatically
-
-LPPATCH cmsxPCollAddPatchRGB(LPMEASUREMENT m, const char *Name,
- double r, double g, double b,
- LPcmsCIEXYZ XYZ, LPcmsCIELab Lab)
-{
- LPPATCH p;
-
- p = m->Patches + m->nPatches++;
-
- strcpy(p -> Name, Name);
-
- p -> Colorant.RGB[0] = r;
- p -> Colorant.RGB[1] = g;
- p -> Colorant.RGB[2] = b;
- p -> dwFlags = PATCH_HAS_RGB;
-
- if (XYZ) {
-
- p -> XYZ = *XYZ;
- p -> dwFlags |= PATCH_HAS_XYZ;
- }
-
- if (Lab) {
- p -> Lab = *Lab;
- p -> dwFlags |= PATCH_HAS_Lab;
- }
-
-
- return p;
-}
-
-// Some vendors does store colorant data in a non-standard way,
-// i.e, from 0.0..1.0 or from 0.0..100.0 This routine tries to
-// detect such situations
-
-static
-void NormalizeColorant(LPMEASUREMENT m)
-{
- int i, j;
- double MaxColorant=0;
- double Normalize;
-
-
- for (i=0; i < m -> nPatches; i++) {
-
-
- LPPATCH p = m -> Patches + i;
-
- for (j=0; j < MAXCHANNELS; j++) {
- if (p ->Colorant.Hexa[j] > MaxColorant)
- MaxColorant = p ->Colorant.Hexa[j];
- }
- }
-
- // Ok, some heuristics
-
- if (MaxColorant < 2)
- Normalize = 255.0; // goes 0..1
- else
- if (MaxColorant < 102)
- Normalize = 2.55; // goes 0..100
- else
- if (MaxColorant > 300)
- Normalize = (255.0 / 65535.0); // Goes 0..65535.0
- else
- return; // Is ok
-
-
- // Rearrange patches
- for (i=0; i < m -> nPatches; i++) {
-
-
- LPPATCH p = m -> Patches + i;
- for (j=0; j < MAXCHANNELS; j++)
- p ->Colorant.Hexa[j] *= Normalize;
- }
-
-}
-
-
-// Load a collection from a Sheet
-
-BOOL cmsxPCollLoadFromSheet(LPMEASUREMENT m, LCMSHANDLE hSheet)
-{
- int i;
- DWORD dwMask;
-
-
- if (m -> nPatches == 0) {
-
- m -> nPatches = (int) cmsxIT8GetPropertyDbl(hSheet, "NUMBER_OF_SETS");
- m -> Patches = calloc(m -> nPatches, sizeof(PATCH));
-
- if (m -> Patches == NULL) {
- cmsxIT8Free(hSheet);
- return FALSE;
- }
-
- for (i=0; i < m -> nPatches; i++) {
-
- LPPATCH p = m -> Patches + i;
- p -> dwFlags = 0;
- cmsxIT8GetPatchName(hSheet, i, p ->Name);
-
- }
-
- }
-
-
- // Build mask according to data format
-
- dwMask = MaskOfDataSet(hSheet);
-
-
- // Read items. Set flags accordly.
- for (i = 0; i < m->nPatches; i++) {
-
- LPPATCH Patch = m -> Patches + i;
-
- // Fill in data according to mask
-
- if (dwMask & PATCH_HAS_Lab) {
-
- if (cmsxIT8GetDataSetDbl(hSheet, Patch->Name, "LAB_L", &Patch -> Lab.L) &&
- cmsxIT8GetDataSetDbl(hSheet, Patch->Name, "LAB_A", &Patch -> Lab.a) &&
- cmsxIT8GetDataSetDbl(hSheet, Patch->Name, "LAB_B", &Patch -> Lab.b))
-
- Patch -> dwFlags |= PATCH_HAS_Lab;
- }
-
- if (dwMask & PATCH_HAS_XYZ) {
-
- if (cmsxIT8GetDataSetDbl(hSheet, Patch->Name, "XYZ_X", &Patch -> XYZ.X) &&
- cmsxIT8GetDataSetDbl(hSheet, Patch->Name, "XYZ_Y", &Patch -> XYZ.Y) &&
- cmsxIT8GetDataSetDbl(hSheet, Patch->Name, "XYZ_Z", &Patch -> XYZ.Z))
-
- Patch -> dwFlags |= PATCH_HAS_XYZ;
-
- }
-
- if (dwMask & PATCH_HAS_RGB) {
-
- if (cmsxIT8GetDataSetDbl(hSheet, Patch->Name, "RGB_R", &Patch -> Colorant.RGB[0]) &&
- cmsxIT8GetDataSetDbl(hSheet, Patch->Name, "RGB_G", &Patch -> Colorant.RGB[1]) &&
- cmsxIT8GetDataSetDbl(hSheet, Patch->Name, "RGB_B", &Patch -> Colorant.RGB[2]))
-
- Patch -> dwFlags |= PATCH_HAS_RGB;
- }
-
- if (dwMask & PATCH_HAS_STD_DE) {
-
- if (cmsxIT8GetDataSetDbl(hSheet, Patch->Name, "STDEV_DE", &Patch -> dEStd))
-
- Patch -> dwFlags |= PATCH_HAS_STD_DE;
-
- }
-
- }
-
- NormalizeColorant(m);
- return TRUE;
-}
-
-
-// Does save parameters to a empty sheet
-
-BOOL cmsxPCollSaveToSheet(LPMEASUREMENT m, LCMSHANDLE it8)
-{
- int nNumberOfSets = cmsxPCollCountSet(m, m->Allowed);
- int nNumberOfFields = 0;
- DWORD dwMask = 0;
- int i;
-
- // Find mask of fields
- for (i=0; i < m ->nPatches; i++) {
- if (m ->Allowed[i]) {
-
- LPPATCH p = m ->Patches + i;
- dwMask |= p ->dwFlags;
- }
- }
-
- nNumberOfFields = 1; // SampleID
-
- if (dwMask & PATCH_HAS_RGB)
- nNumberOfFields += 3;
-
- if (dwMask & PATCH_HAS_XYZ)
- nNumberOfFields += 3;
-
- if (dwMask & PATCH_HAS_Lab)
- nNumberOfFields += 3;
-
-
- cmsxIT8SetPropertyDbl(it8, "NUMBER_OF_SETS", nNumberOfSets);
- cmsxIT8SetPropertyDbl(it8, "NUMBER_OF_FIELDS", nNumberOfFields);
-
- nNumberOfFields = 0;
- cmsxIT8SetDataFormat(it8, nNumberOfFields++, "SAMPLE_ID");
-
- if (dwMask & PATCH_HAS_RGB) {
-
- cmsxIT8SetDataFormat(it8, nNumberOfFields++, "RGB_R");
- cmsxIT8SetDataFormat(it8, nNumberOfFields++, "RGB_G");
- cmsxIT8SetDataFormat(it8, nNumberOfFields++, "RGB_B");
- }
-
- if (dwMask & PATCH_HAS_XYZ) {
-
- cmsxIT8SetDataFormat(it8, nNumberOfFields++, "XYZ_X");
- cmsxIT8SetDataFormat(it8, nNumberOfFields++, "XYZ_Y");
- cmsxIT8SetDataFormat(it8, nNumberOfFields++, "XYZ_Z");
-
- }
-
-
- if (dwMask & PATCH_HAS_XYZ) {
-
- cmsxIT8SetDataFormat(it8, nNumberOfFields++, "LAB_L");
- cmsxIT8SetDataFormat(it8, nNumberOfFields++, "LAB_A");
- cmsxIT8SetDataFormat(it8, nNumberOfFields++, "LAB_B");
-
- }
-
- for (i=0; i < m ->nPatches; i++) {
- if (m ->Allowed[i]) {
-
- LPPATCH Patch = m ->Patches + i;
-
- cmsxIT8SetDataSet(it8, Patch->Name, "SAMPLE_ID", Patch->Name);
-
- if (dwMask & PATCH_HAS_RGB) {
- cmsxIT8SetDataSetDbl(it8, Patch->Name, "RGB_R", Patch ->Colorant.RGB[0]);
- cmsxIT8SetDataSetDbl(it8, Patch->Name, "RGB_G", Patch ->Colorant.RGB[1]);
- cmsxIT8SetDataSetDbl(it8, Patch->Name, "RGB_B", Patch ->Colorant.RGB[2]);
- }
-
- if (dwMask & PATCH_HAS_XYZ) {
- cmsxIT8SetDataSetDbl(it8, Patch->Name, "XYZ_X", Patch ->XYZ.X);
- cmsxIT8SetDataSetDbl(it8, Patch->Name, "XYZ_Y", Patch ->XYZ.Y);
- cmsxIT8SetDataSetDbl(it8, Patch->Name, "XYZ_Z", Patch ->XYZ.Z);
- }
-
- if (dwMask & PATCH_HAS_Lab) {
- cmsxIT8SetDataSetDbl(it8, Patch->Name, "LAB_L", Patch ->Lab.L);
- cmsxIT8SetDataSetDbl(it8, Patch->Name, "LAB_A", Patch ->Lab.a);
- cmsxIT8SetDataSetDbl(it8, Patch->Name, "LAB_B", Patch ->Lab.b);
-
- }
- }
- }
-
- return TRUE;
-}
-
-static
-void FixLabOnly(LPMEASUREMENT m)
-{
- int i;
-
- for (i=0; i < m ->nPatches; i++) {
-
- LPPATCH p = m ->Patches + i;
- if ((p ->dwFlags & PATCH_HAS_Lab) &&
- !(p ->dwFlags & PATCH_HAS_XYZ))
- {
- cmsLab2XYZ(cmsD50_XYZ(), &p->XYZ, &p ->Lab);
-
- p ->XYZ.X *= 100.;
- p ->XYZ.Y *= 100.;
- p ->XYZ.Z *= 100.;
-
- p ->dwFlags |= PATCH_HAS_XYZ;
- }
-
- }
-
-}
-
-
-// Higher level function. Does merge reference and measurement sheet into
-// a MEASUREMENT struct. Data to keep is described in dwNeededSamplesType
-// mask as follows:
-//
-// PATCH_HAS_Lab 0x00000001
-// PATCH_HAS_XYZ 0x00000002
-// PATCH_HAS_RGB 0x00000004
-// PATCH_HAS_CMY 0x00000008
-// PATCH_HAS_CMYK 0x00000010
-// PATCH_HAS_HEXACRM 0x00000020
-// PATCH_HAS_STD_Lab 0x00010000
-// PATCH_HAS_STD_XYZ 0x00020000
-// PATCH_HAS_STD_RGB 0x00040000
-// PATCH_HAS_STD_CMY 0x00080000
-// PATCH_HAS_STD_CMYK 0x00100000
-// PATCH_HAS_STD_HEXACRM 0x00100000
-// PATCH_HAS_MEAN_DE 0x01000000
-// PATCH_HAS_STD_DE 0x02000000
-// PATCH_HAS_CHISQ 0x04000000
-//
-// See lprof.h for further info
-
-
-BOOL cmsxPCollBuildMeasurement(LPMEASUREMENT m,
- const char *ReferenceSheet,
- const char *MeasurementSheet,
- DWORD dwNeededSamplesType)
-{
- LCMSHANDLE hSheet;
- BOOL rc = TRUE;
-
- ZeroMemory(m, sizeof(MEASUREMENT));
-
-
- if (ReferenceSheet != NULL && *ReferenceSheet) {
-
- hSheet = cmsxIT8LoadFromFile(ReferenceSheet);
- if (hSheet == NULL) return FALSE;
-
- rc = cmsxPCollLoadFromSheet(m, hSheet);
- cmsxIT8Free(hSheet);
- }
-
- if (!rc) return FALSE;
-
- if (MeasurementSheet != NULL && *MeasurementSheet) {
-
- hSheet = cmsxIT8LoadFromFile(MeasurementSheet);
- if (hSheet == NULL) return FALSE;
-
- rc = cmsxPCollLoadFromSheet(m, hSheet);
- cmsxIT8Free(hSheet);
- }
-
- if (!rc) return FALSE;
-
-
- // Fix up -- If only Lab is present, then compute
- // XYZ based on D50
-
- FixLabOnly(m);
-
- cmsxPCollValidatePatches(m, dwNeededSamplesType);
- return TRUE;
-}
-
-
-
-void cmsxPCollFreeMeasurements(LPMEASUREMENT m)
-{
- if (m->Patches)
- free(m->Patches);
-
- m->Patches = NULL;
- m->nPatches = 0;
-
- if (m -> Allowed)
- free(m -> Allowed);
-
-}
-
-// Retrieval functions
-
-LPPATCH cmsxPCollGetPatchByName(LPMEASUREMENT m, const char* name, int* lpPos)
-{
- int i;
- for (i=0; i < m->nPatches; i++)
- {
- if (m -> Allowed)
- if (!m -> Allowed[i])
- continue;
-
- if (EqualsTo(m->Patches[i].Name, name)) {
- if (lpPos) *lpPos = i;
- return m->Patches + i;
- }
- }
-
- return NULL;
-}
-
-
-
-
-// -------------------------------------------------------------------- Sets
-
-
-SETOFPATCHES cmsxPCollBuildSet(LPMEASUREMENT m, BOOL lDefault)
-{
- SETOFPATCHES Full = (SETOFPATCHES) malloc(m -> nPatches * sizeof(BOOL));
- int i;
-
- for (i=0; i < m -> nPatches; i++)
- Full[i] = lDefault;
-
- return Full;
-}
-
-int cmsxPCollCountSet(LPMEASUREMENT m, SETOFPATCHES Set)
-{
- int i, Count = 0;
-
- for (i = 0; i < m -> nPatches; i++) {
-
- if (Set[i])
- Count++;
- }
-
- return Count;
-}
-
-
-// Validate patches
-
-BOOL cmsxPCollValidatePatches(LPMEASUREMENT m, DWORD dwFlags)
-{
- int i, n;
-
- if (m->Allowed)
- free(m->Allowed);
-
- m -> Allowed = cmsxPCollBuildSet(m, TRUE);
-
- // Check for flags
- for (i=n=0; i < m -> nPatches; i++) {
-
- LPPATCH p = m -> Patches + i;
- m -> Allowed[i] = ((p -> dwFlags & dwFlags) == dwFlags);
-
- }
-
- return TRUE;
-}
-
-
-// Several filters
-
-
-// This filter does validate patches placed on 'radius' distance of a
-// device-color space. Currently only RGB is supported
-
-static
-void PatchesByRGB(LPMEASUREMENT m, SETOFPATCHES Valids,
- double R, double G, double B, double radius, SETOFPATCHES Result)
-{
- int i;
- double ra, rmax = sqrt(radius / 255.);
- double dR, dG, dB;
- LPPATCH p;
-
- for (i=0; i < m->nPatches; i++) {
-
-
- if (Valids[i]) {
-
- p = m->Patches + i;
-
- dR = fabs(R - p -> Colorant.RGB[0]) / 255.;
- dG = fabs(G - p -> Colorant.RGB[1]) / 255.;
- dB = fabs(B - p -> Colorant.RGB[2]) / 255.;
-
- ra = sqrt(dR*dR + dG*dG + dB*dB);
-
- if (ra <= rmax)
- Result[i] = TRUE;
- else
- Result[i] = FALSE;
-
- }
- }
-
-}
-
-
-// This filter does validate patches placed at dEmax radius
-// in the device-independent side.
-
-static
-void PatchesByLab(LPMEASUREMENT m, SETOFPATCHES Valids,
- double L, double a, double b, double dEmax, SETOFPATCHES Result)
-{
- int i;
- double dE, dEMaxSQR = sqrt(dEmax);
- double dL, da, db;
- LPPATCH p;
-
-
- for (i=0; i < m->nPatches; i++) {
-
-
- if (Valids[i]) {
-
- p = m->Patches + i;
-
- dL = fabs(L - p -> Lab.L);
- da = fabs(a - p -> Lab.a);
- db = fabs(b - p -> Lab.b);
-
- dE = sqrt(dL*dL + da*da + db*db);
-
- if (dE <= dEMaxSQR)
- Result[i] = TRUE;
- else
- Result[i] = FALSE;
- }
- }
-}
-
-
-// Restrict Lab in a cube of variable sides. Quick and dirty out-of-gamut
-// stripper used in estimations.
-
-static
-void PatchesInLabCube(LPMEASUREMENT m, SETOFPATCHES Valids,
- double Lmin, double Lmax, double da, double db, SETOFPATCHES Result)
-{
- int i;
-
- for (i=0; i < m -> nPatches; i++) {
-
-
- if (Valids[i]) {
-
- LPPATCH p = m -> Patches + i;
-
- if ((p->Lab.L >= Lmin && p->Lab.L <= Lmax) &&
- (fabs(p -> Lab.a) < da) &&
- (fabs(p -> Lab.b) < db))
-
- Result[i] = TRUE;
- else
- Result[i] = FALSE;
- }
- }
-
-}
-
-// Restrict to low colorfullness
-
-static
-void PatchesOfLowC(LPMEASUREMENT m, SETOFPATCHES Valids,
- double Cmax, SETOFPATCHES Result)
-{
- int i;
- cmsCIELCh LCh;
-
- for (i=0; i < m -> nPatches; i++) {
-
-
- if (Valids[i]) {
-
- LPPATCH p = m -> Patches + i;
-
- cmsLab2LCh(&LCh, &p->Lab);
-
-
- if (LCh.C < Cmax)
- Result[i] = TRUE;
- else
- Result[i] = FALSE;
- }
- }
-
-}
-
-
-
-// Primary can be -1 for specifying device gray. Does return patches
-// on device-space Colorants. dEMax is the maximum allowed ratio
-
-static
-void PatchesPrimary(LPMEASUREMENT m, SETOFPATCHES Valids,
- int nColorant, double dEMax, SETOFPATCHES Result)
-{
- int i, j;
- double n, dE;
-
- for (i=0; i < m -> nPatches; i++) {
-
-
- if (Valids[i]) {
-
- LPPATCH p = m -> Patches + i;
-
-
- if (nColorant < 0) // device-grey?
- {
- // cross.
-
- double drg = fabs(p -> Colorant.RGB[0] - p -> Colorant.RGB[1]) / 255.;
- double drb = fabs(p -> Colorant.RGB[0] - p -> Colorant.RGB[2]) / 255.;
- double dbg = fabs(p -> Colorant.RGB[1] - p -> Colorant.RGB[2]) / 255.;
-
- dE = (drg*drg + drb*drb + dbg*dbg);
-
-
- }
- else {
- dE = 0.;
- for (j=0; j < 3; j++) {
-
- if (j != nColorant) {
-
- n = p -> Colorant.RGB[j] / 255.;
- dE += (n * n);
-
-
- }
- }
- }
-
-
-
- if (sqrt(dE) < dEMax)
- Result[i] = TRUE;
- else
- Result[i] = FALSE;
- }
- }
-
-}
-
-
-// The high level extractors -----------------------------------------------------
-
-int cmsxPCollPatchesNearRGB(LPMEASUREMENT m, SETOFPATCHES Valids,
- double r, double g, double b,
- int need, SETOFPATCHES Result)
-{
- double radius;
- int nCollected;
-
- // Collect points inside of a sphere or radius 'radius' by RGB
-
- radius = 1;
- do {
- PatchesByRGB(m, Valids, r, g, b, radius, Result);
-
- nCollected = cmsxPCollCountSet(m, Result);
- if (nCollected <= need) {
-
- radius += 1.0;
- }
-
- } while (nCollected <= need && radius < 256.);
-
- return nCollected; // Can be less than needed!
-}
-
-
-int cmsxPCollPatchesNearNeutral(LPMEASUREMENT m, SETOFPATCHES Valids,
- int need, SETOFPATCHES Result)
-{
- int nGrays;
- double Cmax;
-
- Cmax = 1.;
- do {
-
-
- PatchesOfLowC(m, Valids, Cmax, Result);
-
- nGrays = cmsxPCollCountSet(m, Result);
- if (nGrays <= need) {
-
- Cmax += .2;
- }
-
- } while (nGrays <= need && Cmax < 10.);
-
- return nGrays;
-}
-
-
-int cmsxPCollPatchesInLabCube(LPMEASUREMENT m, SETOFPATCHES Valids,
- double Lmin, double Lmax, double a, double b,
- SETOFPATCHES Result)
-
-
-{
- PatchesInLabCube(m, Valids, Lmin, Lmax, a, b, Result);
- return cmsxPCollCountSet(m, Result);
-}
-
-
-
-
-int cmsxPCollPatchesNearPrimary(LPMEASUREMENT m,
- SETOFPATCHES Valids,
- int nChannel,
- int need,
- SETOFPATCHES Result)
-{
- double radius;
- int nCollected;
-
- // Collect points inside of a sphere or radius 'radius' by RGB
-
- radius = 0.05;
- do {
- PatchesPrimary(m, Valids, nChannel, radius, Result);
-
- nCollected = cmsxPCollCountSet(m, Result);
- if (nCollected <= need) {
-
- radius += 0.01;
- }
-
- } while (nCollected <= need && radius < 256.);
-
- return nCollected;
-
-}
-
-
-static
-void AddOneGray(LPMEASUREMENT m, int n, SETOFPATCHES Grays)
-{
- LPPATCH p;
- char Buffer[cmsxIT8_GRAYCOLS];
- int pos;
-
- if (n == 0) strcpy(Buffer, "DMIN");
- else
- if (n == cmsxIT8_GRAYCOLS - 1) strcpy(Buffer, "DMAX");
- else
- sprintf(Buffer, "GS%d", n);
-
- p = cmsxPCollGetPatchByName(m, Buffer, &pos);
-
- if (p)
- Grays[pos] = TRUE;
-}
-
-
-
-void cmsxPCollPatchesGS(LPMEASUREMENT m, SETOFPATCHES Result)
-{
-
- int i;
-
- for (i=0; i < cmsxIT8_GRAYCOLS; i++)
- AddOneGray(m, i, Result);
-}
-
-
-
-// Refresh RGB of all patches after prelinearization
-
-void cmsxPCollLinearizePatches(LPMEASUREMENT m, SETOFPATCHES Valids, LPGAMMATABLE Gamma[3])
-{
- int i;
-
- for (i=0; i < m -> nPatches; i++) {
-
- if (Valids[i]) {
-
- LPPATCH p = m -> Patches + i;
-
- cmsxApplyLinearizationTable(p -> Colorant.RGB, Gamma, p -> Colorant.RGB);
- }
- }
-
-}
-
-
-int cmsxPCollPatchesInGamutLUT(LPMEASUREMENT m, SETOFPATCHES Valids,
- LPLUT Gamut, SETOFPATCHES Result)
-{
- int i;
- int nCollected = 0;
-
- for (i=0; i < m -> nPatches; i++) {
-
- if (Valids[i]) {
-
- LPPATCH p = m -> Patches + i;
- WORD EncodedLab[3];
- WORD dE;
-
- cmsFloat2LabEncoded(EncodedLab, &p->Lab);
- cmsEvalLUT(Gamut, EncodedLab, &dE);
- Result[i] = (dE < 2) ? TRUE : FALSE;
- if (Result[i]) nCollected++;
- }
- }
-
- return nCollected;
-}
-
-LPPATCH cmsxPCollFindWhite(LPMEASUREMENT m, SETOFPATCHES Valids, double* TheDistance)
-{
- int i;
- LPPATCH Candidate = NULL;
- double Distance, CandidateDistance = 255;
- double dR, dG, dB;
-
- Candidate = cmsxPCollGetPatchByName(m, "DMIN", NULL);
- if (Candidate) {
-
- if (TheDistance) *TheDistance = 0.0;
- return Candidate;
- }
-
- for (i=0; i < m -> nPatches; i++) {
-
- if (Valids[i]) {
-
- LPPATCH p = m -> Patches + i;
-
- dR = fabs(255.0 - p -> Colorant.RGB[0]) / 255.0;
- dG = fabs(255.0 - p -> Colorant.RGB[1]) / 255.0;
- dB = fabs(255.0 - p -> Colorant.RGB[2]) / 255.0;
-
- Distance = sqrt(dR*dR + dG*dG + dB*dB);
-
- if (Distance < CandidateDistance) {
- Candidate = p;
- CandidateDistance = Distance;
- }
- }
- }
-
- if (TheDistance)
- *TheDistance = floor(CandidateDistance * 255.0 + .5);
-
- return Candidate;
-}
-
-LPPATCH cmsxPCollFindBlack(LPMEASUREMENT m, SETOFPATCHES Valids, double* TheDistance)
-{
- int i;
- LPPATCH Candidate = NULL;
- double Distance, CandidateDistance = 255;
- double dR, dG, dB;
-
-
- Candidate = cmsxPCollGetPatchByName(m, "DMAX", NULL);
- if (Candidate) {
-
- if (TheDistance) *TheDistance = 0.0;
- return Candidate;
- }
-
- for (i=0; i < m -> nPatches; i++) {
-
- if (Valids[i]) {
-
- LPPATCH p = m -> Patches + i;
-
- dR = (p -> Colorant.RGB[0]) / 255.0;
- dG = (p -> Colorant.RGB[1]) / 255.0;
- dB = (p -> Colorant.RGB[2]) / 255.0;
-
- Distance = sqrt(dR*dR + dG*dG + dB*dB);
-
- if (Distance < CandidateDistance) {
- Candidate = p;
- CandidateDistance = Distance;
- }
- }
- }
-
- if (TheDistance)
- *TheDistance = floor(CandidateDistance * 255.0 + .5);
-
- return Candidate;
-}
-
-
-LPPATCH cmsxPCollFindPrimary(LPMEASUREMENT m, SETOFPATCHES Valids, int Channel, double* TheDistance)
-{
- int i;
- LPPATCH Candidate = NULL;
- double Distance, CandidateDistance = 255;
- double dR, dG, dB;
- const struct {
- double r, g, b;
-
- } RGBPrimaries[3] = {
- { 255.0, 0, 0},
- { 0, 255.0, 0},
- { 0, 0, 255 }};
-
-
- for (i=0; i < m -> nPatches; i++) {
-
- if (Valids[i]) {
-
- LPPATCH p = m -> Patches + i;
-
- dR = fabs(RGBPrimaries[Channel].r - p -> Colorant.RGB[0]) / 255.0;
- dG = fabs(RGBPrimaries[Channel].g - p -> Colorant.RGB[1]) / 255.0;
- dB = fabs(RGBPrimaries[Channel].b - p -> Colorant.RGB[2]) / 255.0;
-
- Distance = sqrt(dR*dR + dG*dG + dB*dB);
-
- if (Distance < CandidateDistance) {
- Candidate = p;
- CandidateDistance = Distance;
- }
- }
- }
-
- if (TheDistance)
- *TheDistance = floor(CandidateDistance * 255.0 + .5);
-
- return Candidate;
-}
/trunk/lprof/src/cmspcoll.c
Property changes:
Deleted: svn:eol-style
## -1 +0,0 ##
-native
\ No newline at end of property
Deleted: svn:keywords
## -1 +0,0 ##
-Author Date Id Revision
\ No newline at end of property
Index: trunk/lprof/src/makefile
===================================================================
--- trunk/lprof/src/makefile (revision 2454)
+++ trunk/lprof/src/makefile (nonexistent)
@@ -1,34 +0,0 @@
-SHELL = /bin/sh
-
-CFLAGS = -g -O4 -I../include -fomit-frame-pointer -Wall
-BASEDIR = $(DESTDIR)/usr
-BINDIR = $(BASEDIR)/bin
-LIBDIR = $(BASEDIR)/lib
-INCDIR = $(BASEDIR)/include
-VERSION = 1.09
-
-.c.o:
- $(CC) $(CFLAGS) $(LDFLAGS) -c $<
-
-SRCS = cmshull.c cmslm.c cmslnr.c cmsmatn.c cmsmkmsh.c cmsmntr.c cmsoutl.c \
- cmspcoll.c cmsprf.c cmsreg.c cmsscn.c cmssheet.c
-
-OBJS = $(SRCS:.c=.o)
-
-all: liblprof.a
-
-liblprof.a: $(OBJS)
- ar -cru liblprof.a $(OBJS)
- ranlib liblprof.a
-
-install: liblprof.a
- mkdir -p $(BINDIR) $(LIBDIR) $(INCDIR)
- cp -a liblprof.a $(LIBDIR)
- cp ../include/lcmsprf.h $(INCDIR)
- chmod 644 $(INCDIR)/lcmsprf.h
-
-test:
- # we are doing nothing for the test target
-
-clean:
- -rm $(OBJS) liblprof.a
/trunk/lprof/src/makefile
Property changes:
Deleted: svn:eol-style
## -1 +0,0 ##
-native
\ No newline at end of property
Deleted: svn:keywords
## -1 +0,0 ##
-Author Date Id Revision
\ No newline at end of property
Index: trunk/lprof/src/cmslnr.c
===================================================================
--- trunk/lprof/src/cmslnr.c (revision 2454)
+++ trunk/lprof/src/cmslnr.c (nonexistent)
@@ -1,560 +0,0 @@
-//
-// Little cms - profiler construction set
-// Copyright (C) 1998-2001 Marti Maria
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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"
-
-
-LPGAMMATABLE cdecl cmsxEstimateGamma(LPSAMPLEDCURVE X, LPSAMPLEDCURVE Y, int nResultingPoints);
-void cdecl cmsxCompleteLabOfPatches(LPMEASUREMENT m, SETOFPATCHES Valids, int Medium);
-
-void cdecl cmsxComputeLinearizationTables(LPMEASUREMENT m,
- int ColorSpace,
- LPGAMMATABLE Lin[3],
- int nResultingPoints,
- int Medium);
-
-
-void cdecl cmsxApplyLinearizationTable(double In[3],
- LPGAMMATABLE Gamma[3],
- double Out[3]);
-
-void cdecl cmsxApplyLinearizationGamma(WORD In[3], LPGAMMATABLE Gamma[3], WORD Out[3]);
-
-
-
-// ------------------------------------------------------------- Implementation
-
-
-#define EPSILON 0.00005
-#define LEVENBERG_MARQUARDT_ITERATE_MAX 150
-
-// In order to track linearization tables, we use following procedure
-//
-// We first assume R', G' and B' does exhibit a non-linear behaviour
-// that can be separated for each channel as Yr(R'), Yg(G'), Yb(B')
-// This is the shaper step
-//
-// R = Lr(R')
-// G = Lg(G')
-// B = Lb(B') (0.0)
-//
-// After this step, RGB is converted to XYZ by a matrix multiplication
-//
-// |X| |R|
-// |Y| = [M]·|G|
-// |Z| |B| (1.0)
-//
-// In order to extract Lr,Lg,Lb tables, we are interested only on Y part
-//
-// Y = (m1 * R + m2 * G + m3 * B) (1.1)
-//
-// The total intensity for maximum RGB = (1, 1, 1) should be 1,
-//
-// 1 = m1 * 1 + m2 * 1 + m3 * 1, so
-//
-// m1 + m2 + m3 = 1.0 (1.2)
-//
-// We now impose that for neutral (gray) patches, RGB components must be equal
-//
-// R = G = B = Gray
-//
-// So, substituting in (1.1):
-//
-// Y = (m1 + m2 + m3) Gray
-//
-// and for (1.2), (m1+m2+m3) = 1, so
-//
-// Y = Gray = Lr(R') = Lg(G') = Lb(B')
-//
-// That is, after prelinearization, RGB of gray patches should give
-// same values for R, G and B. And this value is Y.
-//
-//
-
-
-static
-LPSAMPLEDCURVE NormalizeTo(LPSAMPLEDCURVE X, double N, BOOL lAddEndPoint)
-{
- int i, nItems;
- LPSAMPLEDCURVE XNorm;
-
- nItems = X ->nItems;
- if (lAddEndPoint) nItems++;
-
- XNorm = cmsAllocSampledCurve(nItems);
-
- for (i=0; i < X ->nItems; i++) {
-
- XNorm ->Values[i] = X ->Values[i] / N;
- }
-
- if (lAddEndPoint)
- XNorm -> Values[X ->nItems] = 1.0;
-
- return XNorm;
-}
-
-
-//
-// ------------------------------------------------------------------------------
-//
-// Our Monitor model. We assume gamma has a general expression of
-//
-// Fn(x) = (Gain * x + offset) ^ gamma | for x >= 0
-// Fn(x) = 0 | for x < 0
-//
-// First partial derivatives are
-//
-// dFn/dGamma = Fn * ln(Base)
-// dFn/dGain = gamma * x * ((Gain * x + Offset) ^ (gamma -1))
-// dFn/dOffset = gamma * ((Gain * x + Offset) ^ (gamma -1))
-//
-
-static
-void GammaGainOffsetFn(double x, double *a, double *y, double *dyda, int na)
-{
- double Gamma,Gain,Offset;
- double Base;
-
- Gamma = a[0];
- Gain = a[1];
- Offset = a[2];
-
- Base = Gain * x + Offset;
-
- if (Base < 0) {
-
- Base = 0.0;
- *y = 0.0;
- dyda[0] = 0.0;
- dyda[1] = 0.0;
- dyda[2] = 0.0;
-
-
- } else {
-
-
- // The function itself
- *y = pow(Base, Gamma);
-
- // dyda[0] is partial derivative across Gamma
- dyda[0] = *y * log(Base);
-
- // dyda[1] is partial derivative across gain
- dyda[1] = (x * Gamma) * pow(Base, Gamma-1.0);
-
- // dyda[2] is partial derivative across offset
- dyda[2] = Gamma * pow(Base, Gamma-1.0);
- }
-}
-
-
-// Fit curve to our gamma-gain-offset model.
-
-static
-BOOL OneTry(LPSAMPLEDCURVE XNorm, LPSAMPLEDCURVE YNorm, double a[])
-{
- LCMSHANDLE h;
- double ChiSq, OldChiSq;
- int i;
- BOOL Status = TRUE;
-
- // initial guesses
-
- a[0] = 3.0; // gamma
- a[1] = 4.0; // gain
- a[2] = 6.0; // offset
- a[3] = 0.0; // Thereshold
- a[4] = 0.0; // Black
-
-
- // Significance = 0.02 gives good results
-
- h = cmsxLevenbergMarquardtInit(XNorm, YNorm, 0.02, a, 3, GammaGainOffsetFn);
- if (h == NULL) return FALSE;
-
-
- OldChiSq = cmsxLevenbergMarquardtChiSq(h);
-
- for(i = 0; i < LEVENBERG_MARQUARDT_ITERATE_MAX; i++) {
-
- if (!cmsxLevenbergMarquardtIterate(h)) {
- Status = FALSE;
- break;
- }
-
- ChiSq = cmsxLevenbergMarquardtChiSq(h);
-
- if(OldChiSq != ChiSq && (OldChiSq - ChiSq) < EPSILON)
- break;
-
- OldChiSq = ChiSq;
- }
-
- cmsxLevenbergMarquardtFree(h);
-
- return Status;
-}
-
-// Tries to fit gamma as per IEC 61966-2.1 using Levenberg-Marquardt method
-//
-// Y = (aX + b)^Gamma | X >= d
-// Y = cX | X < d
-
-LPGAMMATABLE cmsxEstimateGamma(LPSAMPLEDCURVE X, LPSAMPLEDCURVE Y, int nResultingPoints)
-{
- double a[5];
- LPSAMPLEDCURVE XNorm, YNorm;
- double e, Max;
-
-
- // Coarse approximation, to find maximum.
- // We have only a portion of curve. It is likely
- // maximum will not fall on exactly 100.
-
- if (!OneTry(X, Y, a))
- return FALSE;
-
- // Got parameters. Compute maximum.
- e = a[1]* 255.0 + a[2];
- if (e < 0) return FALSE;
- Max = pow(e, a[0]);
-
-
- // Normalize values to maximum
- XNorm = NormalizeTo(X, 255.0, FALSE);
- YNorm = NormalizeTo(Y, Max, FALSE);
-
- // Do the final fitting
- if (!OneTry(XNorm, YNorm, a))
- return FALSE;
-
- // Type 3 = IEC 61966-2.1 (sRGB)
- // Y = (aX + b)^Gamma | X >= d
- // Y = cX | X < d
- return cmsBuildParametricGamma(nResultingPoints, 3, a);
-}
-
-
-
-
-
-// A dumb bubble sort
-
-static
-void Bubble(LPSAMPLEDCURVE C, LPSAMPLEDCURVE L)
-{
-#define SWAP(a, b) { tmp = (a); (a) = (b); (b) = tmp; }
-
- BOOL lSwapped;
- int i, nItems;
- double tmp;
-
- nItems = C -> nItems;
- do {
- lSwapped = FALSE;
-
- for (i= 0; i < nItems - 1; i++) {
-
- if (C->Values[i] > C->Values[i+1]) {
-
- SWAP(C->Values[i], C->Values[i+1]);
- SWAP(L->Values[i], L->Values[i+1]);
- lSwapped = TRUE;
- }
- }
-
- } while (lSwapped);
-
-#undef SWAP
-}
-
-
-
-// Check for monotonicity. Force it if is not the case.
-
-static
-void CheckForMonotonicSampledCurve(LPSAMPLEDCURVE t)
-{
- int n = t ->nItems;
- int i;
- double last;
-
- last = t ->Values[n-1];
- for (i = n-2; i >= 0; --i) {
-
- if (t ->Values[i] > last)
-
- t ->Values[i] = last;
- else
- last = t ->Values[i];
-
- }
-
-}
-
-// The main gamma inferer. Tries first by gamma-gain-offset,
-// if not proper reverts to curve guessing.
-
-static
-LPGAMMATABLE BuildGammaTable(LPSAMPLEDCURVE C, LPSAMPLEDCURVE L, int nResultingPoints)
-{
- LPSAMPLEDCURVE Cw, Lw, Cn, Ln;
- LPSAMPLEDCURVE out;
- LPGAMMATABLE Result;
- double Lmax, Lend, Cmax;
-
- // Try to see if it can be fitted
- Result = cmsxEstimateGamma(C, L, nResultingPoints);
- if (Result)
- return Result;
-
-
- // No... build curve from scratch. Since we have not
- // endpoints, a coarse linear extrapolation should be
- // applied in order to get the expected maximum.
-
- Cw = cmsDupSampledCurve(C);
- Lw = cmsDupSampledCurve(L);
-
- Bubble(Cw, Lw);
-
- // Get endpoint
- Lmax = Lw->Values[Lw ->nItems - 1];
- Cmax = Cw->Values[Cw ->nItems - 1];
-
- // Linearly extrapolate
- Lend = (255 * Lmax) / Cmax;
-
- Ln = NormalizeTo(Lw, Lend, TRUE);
- Cn = NormalizeTo(Cw, 255.0, TRUE);
-
- cmsFreeSampledCurve(Cw);
- cmsFreeSampledCurve(Lw);
-
- // Add endpoint
- out = cmsJoinSampledCurves(Cn, Ln, nResultingPoints);
-
- cmsFreeSampledCurve(Cn);
- cmsFreeSampledCurve(Ln);
-
- CheckForMonotonicSampledCurve(out);
-
- cmsSmoothSampledCurve(out, nResultingPoints*4.);
- cmsClampSampledCurve(out, 0, 1.0);
-
- Result = cmsConvertSampledCurveToGamma(out, 1.0);
-
- cmsFreeSampledCurve(out);
- return Result;
-}
-
-
-
-
-void cmsxCompleteLabOfPatches(LPMEASUREMENT m, SETOFPATCHES Valids, int Medium)
-{
- LPPATCH White;
- cmsCIEXYZ WhiteXYZ;
- int i;
-
- if (Medium == MEDIUM_REFLECTIVE_D50)
- {
- WhiteXYZ.X = D50X * 100.;
- WhiteXYZ.Y = D50Y * 100.;
- WhiteXYZ.Z = D50Z * 100.;
- }
- else {
-
- White = cmsxPCollFindWhite(m, Valids, NULL);
- if (!White) return;
-
- WhiteXYZ = White ->XYZ;
- }
-
- // For all patches with XYZ and without Lab, add Lab values.
- // Transmissive profiles does need to locate its own white
- // point for device gray. Reflective does use D50
-
- for (i=0; i < m -> nPatches; i++) {
-
- if (Valids[i]) {
-
- LPPATCH p = m -> Patches + i;
-
- if ((p ->dwFlags & PATCH_HAS_XYZ) &&
- (!(p ->dwFlags & PATCH_HAS_Lab) || (Medium == MEDIUM_TRANSMISSIVE))) {
-
- cmsXYZ2Lab(&WhiteXYZ, &p->Lab, &p->XYZ);
- p -> dwFlags |= PATCH_HAS_Lab;
- }
- }
- }
-}
-
-
-// Compute linearization tables, trying to fit in a pure
-// exponential gamma. If gamma cannot be accurately infered,
-// then does build a smooth, monotonic curve that does the job.
-
-void cmsxComputeLinearizationTables(LPMEASUREMENT m,
- int ColorSpace,
- LPGAMMATABLE Lin[3],
- int nResultingPoints,
- int Medium)
-
-{
- LPSAMPLEDCURVE R, G, B, L;
- LPGAMMATABLE gr, gg, gb;
- SETOFPATCHES Neutrals;
- int nGrays;
- int i;
-
- // We need Lab for grays.
- cmsxCompleteLabOfPatches(m, m->Allowed, Medium);
-
- // Add neutrals, normalize to max
- Neutrals = cmsxPCollBuildSet(m, FALSE);
- cmsxPCollPatchesNearNeutral(m, m ->Allowed, 15, Neutrals);
-
- nGrays = cmsxPCollCountSet(m, Neutrals);
-
- R = cmsAllocSampledCurve(nGrays);
- G = cmsAllocSampledCurve(nGrays);
- B = cmsAllocSampledCurve(nGrays);
- L = cmsAllocSampledCurve(nGrays);
-
- nGrays = 0;
-
- // Collect patches
- for (i=0; i < m -> nPatches; i++) {
-
- if (Neutrals[i]) {
-
- LPPATCH gr = m -> Patches + i;
-
-
- R -> Values[nGrays] = gr -> Colorant.RGB[0];
- G -> Values[nGrays] = gr -> Colorant.RGB[1];
- B -> Values[nGrays] = gr -> Colorant.RGB[2];
- L -> Values[nGrays] = gr -> XYZ.Y;
-
- nGrays++;
- }
-
- }
-
-
- gr = BuildGammaTable(R, L, nResultingPoints);
- gg = BuildGammaTable(G, L, nResultingPoints);
- gb = BuildGammaTable(B, L, nResultingPoints);
-
- cmsFreeSampledCurve(R);
- cmsFreeSampledCurve(G);
- cmsFreeSampledCurve(B);
- cmsFreeSampledCurve(L);
-
- if (ColorSpace == PT_Lab) {
-
- LPGAMMATABLE Gamma3 = cmsBuildGamma(nResultingPoints, 3.0);
-
- Lin[0] = cmsJoinGammaEx(gr, Gamma3, nResultingPoints);
- Lin[1] = cmsJoinGammaEx(gg, Gamma3, nResultingPoints);
- Lin[2] = cmsJoinGammaEx(gb, Gamma3, nResultingPoints);
-
- cmsFreeGamma(gr); cmsFreeGamma(gg); cmsFreeGamma(gb);
- cmsFreeGamma(Gamma3);
- }
- else {
-
-
- LPGAMMATABLE Gamma1 = cmsBuildGamma(nResultingPoints, 1.0);
-
- Lin[0] = cmsJoinGammaEx(gr, Gamma1, nResultingPoints);
- Lin[1] = cmsJoinGammaEx(gg, Gamma1, nResultingPoints);
- Lin[2] = cmsJoinGammaEx(gb, Gamma1, nResultingPoints);
-
- cmsFreeGamma(gr); cmsFreeGamma(gg); cmsFreeGamma(gb);
- cmsFreeGamma(Gamma1);
-
- }
-
-}
-
-
-
-// Apply linearization. WORD encoded version
-
-void cmsxApplyLinearizationGamma(WORD In[3], LPGAMMATABLE Gamma[3], WORD Out[3])
-{
- L16PARAMS Lut16;
-
- cmsCalcL16Params(Gamma[0] -> nEntries, &Lut16);
-
- Out[0] = cmsLinearInterpLUT16(In[0], Gamma[0] -> GammaTable, &Lut16);
- Out[1] = cmsLinearInterpLUT16(In[1], Gamma[1] -> GammaTable, &Lut16);
- Out[2] = cmsLinearInterpLUT16(In[2], Gamma[2] -> GammaTable, &Lut16);
-
-
-}
-
-
-
-// Apply linearization. double version
-
-void cmsxApplyLinearizationTable(double In[3], LPGAMMATABLE Gamma[3], double Out[3])
-{
- WORD rw, gw, bw;
- double rd, gd, bd;
- L16PARAMS Lut16;
-
-
- cmsCalcL16Params(Gamma[0] -> nEntries, &Lut16);
-
- rw = (WORD) floor(_cmsxSaturate255To65535(In[0]) + .5);
- gw = (WORD) floor(_cmsxSaturate255To65535(In[1]) + .5);
- bw = (WORD) floor(_cmsxSaturate255To65535(In[2]) + .5);
-
- rd = cmsLinearInterpLUT16(rw , Gamma[0] -> GammaTable, &Lut16);
- gd = cmsLinearInterpLUT16(gw, Gamma[1] -> GammaTable, &Lut16);
- bd = cmsLinearInterpLUT16(bw, Gamma[2] -> GammaTable, &Lut16);
-
- Out[0] = _cmsxSaturate65535To255(rd); // back to 0..255
- Out[1] = _cmsxSaturate65535To255(gd);
- Out[2] = _cmsxSaturate65535To255(bd);
-}
-
/trunk/lprof/src/cmslnr.c
Property changes:
Deleted: svn:eol-style
## -1 +0,0 ##
-native
\ No newline at end of property
Deleted: svn:keywords
## -1 +0,0 ##
-Author Date Id Revision
\ No newline at end of property
Index: trunk/lprof/src/cmsreg.c
===================================================================
--- trunk/lprof/src/cmsreg.c (revision 2454)
+++ trunk/lprof/src/cmsreg.c (nonexistent)
@@ -1,558 +0,0 @@
-//
-// Little cms - profiler construction set
-// Copyright (C) 1998-2001 Marti Maria
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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"
-
-
-// There are three kinds of lies:
-//
-// * lies
-// * damn lies
-// * statistics
-//
-// -Some Wag
-//
-//
-// This module handles multiple linear regression stuff
-
-
-/*
-// A measurement of error
-
-typedef struct {
-
- double SSE; // The error sum of squares
- double MSE; // The error mean sum of squares
- double SSR; // The regression sum of squares
- double MSR; // The regression mean sum of squares
- double SSTO; // Total sum of squares
- double F; // The Fisher-F value (MSR / MSE)
- double R2; // Proportion of variability explained by the regression
- // (root is Pearson correlation coefficient)
-
- double R2adj; // The adjusted coefficient of multiple determination.
- // R2-adjusted or R2adj. This is calculated as
- // R2adj = 1 - (1-R2)(N-n-1)/(N-1)
- // and used as multiple correlation coefficient
- // (really, it should be square root)
-
- } MLRSTATISTICS, FAR* LPMLRSTATISTICS;
-
-*/
-
-
-int cdecl cmsxRegressionCreateMatrix(LPMEASUREMENT m, SETOFPATCHES Allowed, int nterms,
- int ColorSpace,
- LPMATN* lpMat, LPMLRSTATISTICS Stat);
-
-BOOL cdecl cmsxRegressionRGB2Lab(double r, double g, double b,
- LPMATN tfm, LPcmsCIELab Lab);
-
-BOOL cdecl cmsxRegressionRGB2XYZ(double r, double g, double b,
- LPMATN tfm, LPcmsCIEXYZ XYZ);
-
-
-// -------------------------------------------------------------- Implementation
-
-// #define DEBUG 1
-
-
-// Multiple linear regression. Also keep track of error.
-// Returns FALSE if something goes wrong, or TRUE if all Ok.
-
-static
-BOOL MultipleLinearRegression(const LPMATN xi, // Dependent variable
- const LPMATN y, // Independent variable
- int nvar, // Number of samples
- int npar, // Number of parameters (terms)
- double* coeff, // Returned coefficients
- LPMATN vcb, // Variance-covariance array
- double *tvl, // T-Values
- LPMLRSTATISTICS ans) // The returned statistics
-{
- LPMATN bt, xt, a, xy, yt, b;
- double sum;
- LPMATN temp1, temp2;
- int i;
-
-
- // |xt| = |xi| T
- xt = MATNtranspose(xi);
- if (xt == NULL) return FALSE;
-
-
- // |a| = |xt|* |xi|
- a = MATNmult(xt, xi);
- if (a == NULL) return FALSE;
-
-
- // |xy| = |xy| * |y|
- xy = MATNmult (xt, y);
- if (xy == NULL) return FALSE;
-
-
- // solve system |a|*|xy| = 0
- if (!MATNsolve(a, xy)) return FALSE;
-
- // b will hold coefficients
- b = MATNalloc (xy->Rows, 1);
- if (b == NULL) return FALSE;
-
- for (i = 0; i < npar; i++)
- b->Values[i][0] = xy->Values[i][0];
-
- // Store a copy for later user
- for (i = 0; i < npar; i++)
- coeff[i] = b->Values[i][0];
-
- // Error analysis.
-
- // SSE and MSE.
- temp1 = MATNalloc (1,1);
- if ((temp1->Values[0][0] = MATNcross(y)) == 0) return FALSE;
-
- // |bt| = |b| T
- bt = MATNtranspose (b);
- if (bt == FALSE) return FALSE;
-
- // |yt| = |bt| * |xt|
- yt = MATNmult (bt, xt);
- if (yt == NULL) return FALSE;
-
-
- // |temp2| = |yt|* |y|
- temp2 = MATNmult (yt, y);
- if (temp2 == NULL) return FALSE;
-
- // SSE, MSE
- ans->SSE = temp1 -> Values[0][0] - temp2 -> Values[0][0];
- ans->MSE = ans->SSE / (double) (nvar - npar);
-
- // SSTO
- sum = 0;
- for (i=0; i < nvar; i++)
- sum += y->Values[i][0];
-
- sum *= sum / (double) nvar;
- ans->SSTO = temp1->Values[0][0] - sum;
-
- // SSR, MSR, and Fisher-F
- ans->SSR = temp2->Values[0][0] - sum;
- ans->MSR = ans->SSR / (double) (npar - 1);
- ans->F = ans->MSR / ans->MSE;
-
- // Correlation coefficients.
- ans->R2 = ans->SSR/ans->SSTO;
- ans->R2adj = 1.0 - (ans->SSE/ans->SSTO)*((nvar-1.)/(nvar-npar));
-
- // Variance-covariance matrix
- //
- // In RGB->Lab, for example:
- //
- // Var(R) Cov(R,G) Cov(R,B)
- // |vcb| = Cov(R,G) Var(G) Cov(G,B)
- // Cov(R,B) Cov(G,B) Var(B)
- //
-
- MATNscalar(a, ans->MSE, vcb);
-
- // Determine the T-values
-
- for (i=0; i < npar; i++) {
-
- temp1->Values[0][0] = fabs(vcb->Values[i][0]);
- if ( temp1->Values[0][0] == 0)
- tvl[i] = 0; // This should never happen
- else
- tvl[i] = b->Values[i][0] / sqrt(temp1->Values[0][0]);
- }
-
-
- // Ok, done
-
- MATNfree(a); MATNfree(xy); MATNfree(yt); MATNfree(b);
- MATNfree(temp1); MATNfree(temp2); MATNfree(bt); MATNfree(xt);
-
-
- return TRUE;
-}
-
-
-
-// Does create (so, it allocates) the regression matrix,
-// keeping track of error as well.
-
-static
-BOOL CreateRegressionMatrix(const LPMATN Input, const LPMATN Output,
- LPMATN* ptrMatrix, LPMLRSTATISTICS maxErrorMeas)
-{
- double* coef;
- double* tval;
- LPMATN ivar, dvar, vcov;
- MLRSTATISTICS ErrorMeas, PeakErrorMeas;
- int i, j, nIn, nOut, NumOfPatches;
-
- nIn = Input -> Cols;
- nOut = Output -> Cols;
- NumOfPatches = Input -> Rows;
-
- // Checkpoint
- if (Output -> Rows != NumOfPatches) {
-
- cmsSignalError(LCMS_ERRC_ABORTED, "(internal) Regression matrix mismatch");
- return FALSE;
- }
-
- coef = (double*) malloc(nIn * sizeof(double));
- if (coef == NULL) return FALSE;
-
- tval = (double*) malloc(nIn * sizeof(double));
- if (tval == NULL) {
- free(coef);
- return FALSE;
- }
-
- ivar = MATNalloc(NumOfPatches, nIn);
- dvar = MATNalloc(NumOfPatches, 1);
-
- // Copy In to ivar,
- for (i = 0; i < NumOfPatches; i++) {
-
- for (j = 0; j < nIn; j++)
- ivar->Values[i][j] = Input->Values[i][j];
- }
-
- // This is the (symmetric) Covariance matrix
- vcov = MATNalloc(nIn, nIn);
-
- // This is the regression matrix
- *ptrMatrix = MATNalloc(nIn, nOut);
-
- PeakErrorMeas.R2adj = 0;
- for (j = 0; j < nOut; ++j)
- {
- for (i = 0; i < NumOfPatches; ++i)
- dvar->Values[i][0] = Output->Values[i][j];
-
- if (MultipleLinearRegression(ivar, dvar, NumOfPatches, nIn, coef, vcov, tval, &ErrorMeas)) {
-
- // Ok so far... store values
- for (i = 0; i < nIn; i++)
- (*ptrMatrix)->Values[i][j] = coef[i];
- }
- else {
- // Boo... got error. Discard whole point.
- MATNfree(ivar); MATNfree(dvar); MATNfree(vcov);
- if (coef) free(coef);
- if (tval) free(tval);
- MATNfree(*ptrMatrix); *ptrMatrix = NULL;
- return FALSE;
- }
-
- // Did this colorant got higer error? If so, this is
- // the peak of all pixel
-
- if(fabs(ErrorMeas.R2adj) > fabs(PeakErrorMeas.R2adj))
- PeakErrorMeas = ErrorMeas;
- }
-
- // This is the peak error on all components
- *maxErrorMeas = PeakErrorMeas;
-
-
-#ifdef DEBUG
- MATNprintf("Variance-Covariance", vcov);
- printf("R2adj: %g, F: %g\n", PeakErrorMeas.R2adj, PeakErrorMeas.F);
-#endif
-
- // Free stuff.
- MATNfree(ivar); MATNfree(dvar); MATNfree(vcov);
- if (coef) free(coef);
- if (tval) free(tval);
-
- return TRUE;
-}
-
-
-// Does compute the term of regression based on inputs.
-
-static
-double Term(int n, double r, double g, double b)
-{
-
- switch (n) {
-
- // 0
- case 0 : return 255.0; // 0 0 0
-
- // 1
- case 1 : return r; // 1 0 0
- case 2 : return g; // 0 1 0
- case 3 : return b; // 0 0 1
-
- // 2
- case 4 : return r * g; // 1 1 0
- case 5 : return r * b; // 1 0 1
- case 6 : return g * b; // 0 1 1
- case 7 : return r * r; // 2 0 0
- case 8 : return g * g; // 0 2 0
- case 9 : return b * b; // 0 0 2
-
- // 3
- case 10: return r * g * b; // 1 1 1
- case 11: return r * r * r; // 3 0 0
- case 12: return g * g * g; // 0 3 0
- case 13: return b * b * b; // 0 0 3
- case 14: return r * g * g; // 1 2 0
- case 15: return r * r * g; // 2 1 0
- case 16: return g * g * b; // 0 2 1
- case 17: return b * r * r; // 2 0 1
- case 18: return b * b * r; // 1 0 2
-
- // 4
-
- case 19: return r * r * g * g; // 2 2 0
- case 20: return g * g * b * b; // 0 2 2
- case 21: return r * r * b * b; // 2 0 2
- case 22: return r * r * g * b; // 2 1 1
- case 23: return r * g * g * b; // 1 2 1
- case 24: return r * g * b * b; // 1 1 2
- case 25: return r * r * r * g; // 3 1 0
- case 26: return r * r * r * b; // 3 0 1
- case 27: return r * g * g * g; // 1 3 0
- case 28: return g * g * g * b; // 0 3 1
- case 29: return r * b * b * b; // 1 0 3
- case 30: return g * b * b * b; // 0 1 3
- case 31: return r * r * r * r; // 4 0 0
- case 32: return g * g * g * g; // 0 4 0
- case 33: return b * b * b * b; // 0 0 4
-
- // 5
-
- case 34: return r * r * g * g * b; // 2 2 1
- case 35: return r * g * g * b * b; // 1 2 2
- case 36: return r * r * g * b * b; // 2 1 2
- case 37: return r * r * r * g * g; // 3 2 0
- case 38: return r * r * r * g * b; // 3 1 1
- case 39: return r * r * r * b * b; // 3 0 2
- case 40: return g * g * g * b * b; // 0 3 2
- case 41: return r * r * g * g * g; // 2 3 0
- case 42: return r * g * g * g * b; // 1 3 1
- case 43: return r * r * b * b * b; // 2 0 3
- case 44: return g * g * b * b * b; // 0 2 3
- case 45: return r * g * b * b * b; // 1 1 3
- case 46: return r * r * r * r * g; // 4 1 0
- case 47: return r * r * r * r * b; // 4 0 1
- case 48: return r * g * g * g * g; // 1 4 0
- case 49: return g * g * g * g * b; // 0 4 1
- case 50: return r * b * b * b * b; // 1 0 4
- case 51: return g * b * b * b * b; // 0 1 4
- case 52: return r * r * r * r * r; // 5 0 0
- case 53: return g * g * g * g * g; // 0 5 0
- case 54: return b * b * b * b * b; // 0 0 5
-
-
- default: return 0;
- }
-}
-
-
-
-int cmsxRegressionCreateMatrix(LPMEASUREMENT m, SETOFPATCHES Allowed, int nterms,
- int ColorSpace,
- LPMATN* lpMat, LPMLRSTATISTICS Stat)
-{
- LPMATN Input, Output;
- int nCollected = cmsxPCollCountSet(m, Allowed);
- int i, j, n, rc;
-
- // We are going always 3 -> 3 for now....
-
- Input = MATNalloc(nCollected, nterms);
- Output = MATNalloc(nCollected, 3);
-
- // Set independent terms
-
- for (n = i = 0; i < m -> nPatches; i++)
- {
- if (Allowed[i]) {
-
- LPPATCH p = m -> Patches + i;
-
- for (j=0; j < nterms; j++)
- Input -> Values[n][j] = Term(j, p -> Colorant.RGB[0], p -> Colorant.RGB[1], p->Colorant.RGB[2]);
-
- switch (ColorSpace) {
-
- case PT_Lab:
-
- Output-> Values[n][0] = p -> Lab.L;
- Output-> Values[n][1] = p -> Lab.a;
- Output-> Values[n][2] = p -> Lab.b;
- break;
-
- case PT_XYZ:
- Output-> Values[n][0] = p -> XYZ.X;
- Output-> Values[n][1] = p -> XYZ.Y;
- Output-> Values[n][2] = p -> XYZ.Z;
- break;
-
-
- default:
- cmsSignalError(LCMS_ERRC_ABORTED, "Invalid colorspace");
- }
-
- n++;
- }
- }
-
-
- // Apply multiple linear regression
-
- if (*lpMat) MATNfree(*lpMat);
- rc = CreateRegressionMatrix(Input, Output, lpMat, Stat);
-
- // Free variables
-
- MATNfree(Input);
- MATNfree(Output);
-
-
-#ifdef DEBUG
- if (rc == TRUE)
- MATNprintf("tfm", *lpMat);
-#endif
-
- return rc;
-}
-
-
-// Convert a RGB triplet to Lab by using regression matrix
-
-BOOL cmsxRegressionRGB2Lab(double r, double g, double b, LPMATN tfm, LPcmsCIELab Lab)
-{
- LPMATN inVec, outVec;
- int i;
-
- inVec = MATNalloc(1, tfm->Rows);
- if (inVec == NULL)
- return FALSE;
-
- // Put terms
- for (i=0; i < tfm->Rows; i++)
- inVec -> Values[0][i] = Term(i, r, g, b);
-
- // Across regression matrix
- outVec = MATNmult(inVec, tfm);
-
- // Store result
- if (outVec != NULL) {
-
- Lab->L = outVec->Values[0][0];
- Lab->a = outVec->Values[0][1];
- Lab->b = outVec->Values[0][2];
- MATNfree(outVec);
- }
-
- MATNfree(inVec);
- return TRUE;
-}
-
-
-// Convert a RGB triplet to XYX by using regression matrix
-
-BOOL cmsxRegressionRGB2XYZ(double r, double g, double b, LPMATN tfm, LPcmsCIEXYZ XYZ)
-{
- LPMATN inVec, outVec;
- int i;
-
- inVec = MATNalloc(1, tfm->Rows);
- if (inVec == NULL)
- return FALSE;
-
- // Put terms
- for (i=0; i < tfm->Rows; i++)
- inVec -> Values[0][i] = Term(i, r, g, b);
-
- // Across regression matrix
- outVec = MATNmult(inVec, tfm);
-
- // Store result
- if (outVec != NULL) {
-
- XYZ->X = outVec->Values[0][0];
- XYZ->Y = outVec->Values[0][1];
- XYZ->Z = outVec->Values[0][2];
- MATNfree(outVec);
- }
-
- MATNfree(inVec);
- return TRUE;
-}
-
-
-// Convert a RGB triplet to XYX by using regression matrix
-
-BOOL cmsxRegressionXYZ2RGB(LPcmsCIEXYZ XYZ, LPMATN tfm, double RGB[3])
-{
- LPMATN inVec, outVec;
- int i;
-
- inVec = MATNalloc(1, tfm->Rows);
- if (inVec == NULL)
- return FALSE;
-
- // Put terms
- for (i=0; i < tfm->Rows; i++)
- inVec -> Values[0][i] = Term(i, XYZ->X, XYZ->Y, XYZ->Z);
-
- // Across regression matrix
- outVec = MATNmult(inVec, tfm);
-
- // Store result
- if (outVec != NULL) {
-
- RGB[0] = outVec->Values[0][0];
- RGB[1] = outVec->Values[0][1];
- RGB[2] = outVec->Values[0][2];
- MATNfree(outVec);
- }
-
- MATNfree(inVec);
- return TRUE;
-}
-
/trunk/lprof/src/cmsreg.c
Property changes:
Deleted: svn:eol-style
## -1 +0,0 ##
-native
\ No newline at end of property
Deleted: svn:keywords
## -1 +0,0 ##
-Author Date Id Revision
\ No newline at end of property
Index: trunk/lprof/src/cmsmkmsh.c
===================================================================
--- trunk/lprof/src/cmsmkmsh.c (revision 2454)
+++ trunk/lprof/src/cmsmkmsh.c (nonexistent)
@@ -1,346 +0,0 @@
-//
-// Little cms - profiler construction set
-// Copyright (C) 1998-2001 Marti Maria
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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.08a
-
-
-#include "lcmsprf.h"
-
-
-BOOL cdecl cmsxComputeMatrixShaper(const char* ReferenceSheet,
- const char* MeasurementSheet,
- int Medium,
- LPGAMMATABLE TransferCurves[3],
- LPcmsCIEXYZ WhitePoint,
- LPcmsCIEXYZ BlackPoint,
- LPcmsCIExyYTRIPLE Primaries);
-
-
-
-// ------------------------------------------------------------- Implementation
-
-
-static
-void Div100(LPcmsCIEXYZ xyz)
-{
- xyz -> X /= 100; xyz -> Y /= 100; xyz -> Z /= 100;
-}
-
-
-
-// Compute endpoints
-
-static
-BOOL ComputeWhiteAndBlackPoints(LPMEASUREMENT Linearized,
- LPGAMMATABLE TransferCurves[3],
- LPcmsCIEXYZ Black, LPcmsCIEXYZ White)
-{
-
- double Zeroes[3], Ones[3], lmin[3], lmax[3];
-
- SETOFPATCHES Neutrals = cmsxPCollBuildSet(Linearized, FALSE);
-
- cmsxPCollPatchesNearNeutral(Linearized, Linearized->Allowed,
- 15, Neutrals);
-
- Zeroes[0] = Zeroes[1] = Zeroes[2] = 0.0;
- Ones[0] = Ones[1] = Ones[2] = 255.0;
-
-
- cmsxApplyLinearizationTable(Zeroes, TransferCurves, lmin);
- cmsxApplyLinearizationTable(Ones, TransferCurves, lmax);
-
-
- // Global regression to find White & Black points
- if (!cmsxRegressionInterpolatorRGB(Linearized, PT_XYZ,
- 4,
- TRUE,
- 12,
- lmin[0], lmin[1], lmin[2],
- Black)) return FALSE;
-
- if (!cmsxRegressionInterpolatorRGB(Linearized, PT_XYZ,
- 4,
- TRUE,
- 12,
- lmax[0], lmax[1], lmax[2],
- White)) return FALSE;
-
- _cmsxClampXYZ100(White);
- _cmsxClampXYZ100(Black);
-
- return TRUE;
-
-}
-
-
-// Study convergence of primary axis
-
-static
-BOOL ComputePrimary(LPMEASUREMENT Linearized,
- LPGAMMATABLE TransferCurves[3],
- int n,
- LPcmsCIExyY Primary)
-{
-
- double Ones[3], lmax[3];
- cmsCIEXYZ PrimXYZ;
- SETOFPATCHES SetPrimary;
- int nR;
-
-
- // At first, try to see if primaries are already in measurement
-
- SetPrimary = cmsxPCollBuildSet(Linearized, FALSE);
- nR = cmsxPCollPatchesNearPrimary(Linearized, Linearized->Allowed,
- n, 32, SetPrimary);
-
- Ones[0] = Ones[1] = Ones[2] = 0;
- Ones[n] = 255.0;
-
- cmsxApplyLinearizationTable(Ones, TransferCurves, lmax);
-
- // Do incremental regression to find primaries
- if (!cmsxRegressionInterpolatorRGB(Linearized, PT_XYZ,
- 4,
- FALSE,
- 12,
- lmax[0], lmax[1], lmax[2],
- &PrimXYZ)) return FALSE;
-
- _cmsxClampXYZ100(&PrimXYZ);
- cmsXYZ2xyY(Primary, &PrimXYZ);
- return TRUE;
-
-
-}
-
-
-
-// Does compute a matrix-shaper based on patches.
-
-static
-double Clip(double d)
-{
- return d > 0 ? d: 0;
-}
-
-
-BOOL cmsxComputeMatrixShaper(const char* ReferenceSheet,
- const char* MeasurementSheet,
- int Medium,
- LPGAMMATABLE TransferCurves[3],
- LPcmsCIEXYZ WhitePoint,
- LPcmsCIEXYZ BlackPoint,
- LPcmsCIExyYTRIPLE Primaries)
-{
-
- MEASUREMENT Linearized;
- cmsCIEXYZ Black, White;
- cmsCIExyYTRIPLE PrimarySet;
- LPPATCH PatchWhite, PatchBlack;
- LPPATCH PatchRed, PatchGreen, PatchBlue;
- double Distance;
-
- // Load sheets
-
- if (!cmsxPCollBuildMeasurement(&Linearized,
- ReferenceSheet,
- MeasurementSheet,
- PATCH_HAS_XYZ|PATCH_HAS_RGB)) return FALSE;
-
-
-
- // Any patch to deal of?
- if (cmsxPCollCountSet(&Linearized, Linearized.Allowed) <= 0) return FALSE;
-
-
- // Try to see if proper primaries, white and black already present
- PatchWhite = cmsxPCollFindWhite(&Linearized, Linearized.Allowed, &Distance);
- if (Distance != 0)
- PatchWhite = NULL;
-
- PatchBlack = cmsxPCollFindBlack(&Linearized, Linearized.Allowed, &Distance);
- if (Distance != 0)
- PatchBlack = NULL;
-
- PatchRed = cmsxPCollFindPrimary(&Linearized, Linearized.Allowed, 0, &Distance);
- if (Distance != 0)
- PatchRed = NULL;
-
- PatchGreen = cmsxPCollFindPrimary(&Linearized, Linearized.Allowed, 1, &Distance);
- if (Distance != 0)
- PatchGreen = NULL;
-
- PatchBlue = cmsxPCollFindPrimary(&Linearized, Linearized.Allowed, 2, &Distance);
- if (Distance != 0)
- PatchBlue= NULL;
-
- // If we got primaries, then we can also get prelinearization
- // by Levenberg-Marquardt. This applies on monitor profiles
-
- if (PatchWhite && PatchRed && PatchGreen && PatchBlue) {
-
- // Build matrix with primaries
-
- MAT3 Mat, MatInv;
- LPSAMPLEDCURVE Xr,Yr, Xg, Yg, Xb, Yb;
- int i, nRes, cnt;
-
- VEC3init(&Mat.v[0], PatchRed->XYZ.X, PatchGreen->XYZ.X, PatchBlue->XYZ.X);
- VEC3init(&Mat.v[1], PatchRed->XYZ.Y, PatchGreen->XYZ.Y, PatchBlue->XYZ.Y);
- VEC3init(&Mat.v[2], PatchRed->XYZ.Z, PatchGreen->XYZ.Z, PatchBlue->XYZ.Z);
-
- // Invert matrix
- MAT3inverse(&Mat, &MatInv);
-
- nRes = cmsxPCollCountSet(&Linearized, Linearized.Allowed);
-
- Xr = cmsAllocSampledCurve(nRes);
- Yr = cmsAllocSampledCurve(nRes);
- Xg = cmsAllocSampledCurve(nRes);
- Yg = cmsAllocSampledCurve(nRes);
- Xb = cmsAllocSampledCurve(nRes);
- Yb = cmsAllocSampledCurve(nRes);
-
- // Convert XYZ of all patches to RGB
- cnt = 0;
- for (i=0; i < Linearized.nPatches; i++) {
-
- if (Linearized.Allowed[i]) {
-
- VEC3 RGBprime, XYZ;
- LPPATCH p;
-
- p = Linearized.Patches + i;
- XYZ.n[0] = p -> XYZ.X;
- XYZ.n[1] = p -> XYZ.Y;
- XYZ.n[2] = p -> XYZ.Z;
-
- MAT3eval(&RGBprime, &MatInv, &XYZ);
-
- Xr ->Values[cnt] = p ->Colorant.RGB[0];
- Yr ->Values[cnt] = Clip(RGBprime.n[0]);
-
- Xg ->Values[cnt] = p ->Colorant.RGB[1];
- Yg ->Values[cnt] = Clip(RGBprime.n[1]);
-
- Xb ->Values[cnt] = p ->Colorant.RGB[2];
- Yb ->Values[cnt] = Clip(RGBprime.n[2]);
-
- cnt++;
-
- }
- }
-
- TransferCurves[0] = cmsxEstimateGamma(Xr, Yr, 1024);
- TransferCurves[1] = cmsxEstimateGamma(Xg, Yg, 1024);
- TransferCurves[2] = cmsxEstimateGamma(Xb, Yb, 1024);
-
- if (WhitePoint) {
-
- WhitePoint->X = PatchWhite->XYZ.X;
- WhitePoint->Y= PatchWhite ->XYZ.Y;
- WhitePoint->Z= PatchWhite ->XYZ.Z;
- }
-
- if (BlackPoint && PatchBlack) {
-
- BlackPoint->X = PatchBlack ->XYZ.X;
- BlackPoint->Y = PatchBlack ->XYZ.Y;
- BlackPoint->Z = PatchBlack ->XYZ.Z;
- }
-
- if (Primaries) {
-
- cmsXYZ2xyY(&Primaries->Red, &PatchRed ->XYZ);
- cmsXYZ2xyY(&Primaries->Green, &PatchGreen ->XYZ);
- cmsXYZ2xyY(&Primaries->Blue, &PatchBlue ->XYZ);
-
- }
-
-
- cmsFreeSampledCurve(Xr);
- cmsFreeSampledCurve(Yr);
- cmsFreeSampledCurve(Xg);
- cmsFreeSampledCurve(Yg);
- cmsFreeSampledCurve(Xb);
- cmsFreeSampledCurve(Yb);
-
- cmsxPCollFreeMeasurements(&Linearized);
-
- return TRUE;
- }
-
-
-
-
- // Compute prelinearization
- cmsxComputeLinearizationTables(&Linearized, PT_XYZ, TransferCurves, 1024, Medium);
-
- // Linearize measurements
- cmsxPCollLinearizePatches(&Linearized, Linearized.Allowed, TransferCurves);
-
-
- // Endpoints
- ComputeWhiteAndBlackPoints(&Linearized, TransferCurves, &Black, &White);
-
- // Primaries
- ComputePrimary(&Linearized, TransferCurves, 0, &PrimarySet.Red);
- ComputePrimary(&Linearized, TransferCurves, 1, &PrimarySet.Green);
- ComputePrimary(&Linearized, TransferCurves, 2, &PrimarySet.Blue);
-
-
- if (BlackPoint) {
- *BlackPoint = Black;
- Div100(BlackPoint);
- }
-
- if (WhitePoint) {
- *WhitePoint = White;
- Div100(WhitePoint);
- }
-
-
- if (Primaries) {
- *Primaries = PrimarySet;
- }
-
- cmsxPCollFreeMeasurements(&Linearized);
-
- return TRUE;
-}
-
-
-
/trunk/lprof/src/cmsmkmsh.c
Property changes:
Deleted: svn:eol-style
## -1 +0,0 ##
-native
\ No newline at end of property
Deleted: svn:keywords
## -1 +0,0 ##
-Author Date Id Revision
\ No newline at end of property
Index: trunk/lprof/src/cmsmatn.c
===================================================================
--- trunk/lprof/src/cmsmatn.c (revision 2454)
+++ trunk/lprof/src/cmsmatn.c (nonexistent)
@@ -1,323 +0,0 @@
-//
-// Little cms - profiler construction set
-// Copyright (C) 1998-2001 Marti Maria
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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"
-
-
-LPMATN cdecl MATNalloc(int Rows, int Cols);
-void cdecl MATNfree (LPMATN mat);
-LPMATN cdecl MATNmult(LPMATN a1, LPMATN a2);
-double cdecl MATNcross(LPMATN a);
-void cdecl MATNscalar (LPMATN a, double scl, LPMATN b);
-LPMATN cdecl MATNtranspose (LPMATN a);
-BOOL cdecl MATNsolve(LPMATN a, LPMATN b);
-
-
-// ------------------------------------------------------------ Implementation
-
-// Free matrix
-
-void MATNfree(LPMATN mat)
-{
- int i;
-
- if (mat == NULL) return;
-
- for (i = 0; i < mat->Rows; i++)
- {
- if (mat -> Values[i] != NULL)
- free (mat->Values[i]);
- }
-
- free(mat->Values);
- free(mat);
-}
-
-
-// Allocate (and Zero) a new matrix
-
-LPMATN MATNalloc(int Rows, int Cols)
-{
- int i;
-
- LPMATN mat = (LPMATN) malloc (sizeof (MATN));
- if (mat == NULL) return mat;
-
- ZeroMemory(mat, sizeof(MATN));
-
- mat->Rows = Rows;
- mat->Cols = Cols;
- mat->Values = (double**) malloc(Rows * sizeof (double*));
-
- if (mat->Values == NULL) {
- free(mat);
- return NULL;
- }
-
- ZeroMemory(mat -> Values, Rows * sizeof (double*));
-
- for (i = 0; i < Rows; i++)
- {
- mat-> Values [i] = (double*) malloc(Cols * sizeof (double));
- if (mat -> Values[i] == NULL) {
- MATNfree(mat);
- return NULL;
- }
-
- }
-
- return mat;
-}
-
-#define DO_SWAP(a, b, tmp) { tmp = (a); (a) = (b); (b) = tmp; }
-
-// Gauss-Jordan elimination. There is also a more
-// exahustive non-singular matrix checking part.
-
-BOOL MATNsolve(LPMATN a, LPMATN b)
-{
- BOOL status;
- int n = a->Rows;
- int i, iCol=0, iRow=0, j, k;
- double fMax, fAbs, fSave, fInf, temp;
- int* aiColIndex;
- int* aiRowIndex=0;
- int* aiPivoted=0;
-
-
- if (a->Rows != a->Cols) return FALSE;
-
- status = FALSE;
- if((aiColIndex = (int*) malloc(n * sizeof(int))) == NULL)
- goto GotError;
-
- if((aiRowIndex = (int*) malloc(n * sizeof(int))) == NULL)
- goto GotError;
-
- if((aiPivoted = (int*) malloc(n * sizeof(int))) == NULL)
- goto GotError;
-
- ZeroMemory(aiPivoted, n * sizeof(int));
-
-
- for(i = 0; i < n; i++) {
-
- // search matrix (excluding pivoted rows) for maximum absolute entry
-
- fMax = 0.0;
- for (j = 0; j < n; j++)
- if (aiPivoted[j] != 1)
- for (k = 0; k < n; k++)
- {
- fAbs = fabs(a->Values[j][k]);
- if (fAbs >= fMax) {
-
- fMax = fAbs;
- iRow = j;
- iCol = k;
- }
- else
- if (aiPivoted[k] > 1) {
-
- status = FALSE;
- goto GotError;
- }
- }
-
- aiPivoted[iCol]++;
-
- // swap rows so that A[iCol][iCol] contains the pivot entry
-
- if (iRow != iCol) {
-
- for(j = 0; j < n; j++)
- DO_SWAP(a->Values[iRow][j], a->Values[iCol][j], temp)
-
- DO_SWAP(b->Values[iRow][0], b->Values[iCol][0], temp)
- }
-
- // keep track of the permutations of the rows
-
- aiRowIndex[i] = iRow;
- aiColIndex[i] = iCol;
-
- if (a->Values[iCol][iCol] == 0.0)
- {
- status = FALSE;
- goto GotError;
- }
-
- // scale the row so that the pivot entry is 1
-
- fInf = 1.0 / a->Values[iCol][iCol];
- a->Values[iCol][iCol] = 1.0;
-
- for(j = 0; j < n; j++)
- a->Values[iCol][j] *= fInf;
-
- b->Values[iCol][0] *= fInf;
-
- // zero out the pivot column locations in the other rows
-
- for(j = 0; j < n; j++)
- if (j != iCol) {
-
- fSave = a->Values[j][iCol];
- a->Values[j][iCol] = 0.0;
-
- for(k = 0; k < n; k++)
- a->Values[j][k] -= a->Values[iCol][k] * fSave;
-
- b->Values[j][0] -= b->Values[iCol][0] * fSave;
- }
- }
-
- // reorder rows so that A[][] stores the inverse of the original matrix
-
- for(i = n - 1; i >= 0; i--) {
-
- if(aiRowIndex[i] != aiColIndex[i])
- for(j = 0; j < n; j++)
- DO_SWAP(a->Values[j][aiRowIndex[i]], a->Values[j][aiColIndex[i]], temp)
- }
-
- status = TRUE;
-
-GotError:
- if(aiColIndex) free(aiColIndex);
- if(aiRowIndex) free(aiRowIndex);
- if(aiPivoted) free(aiPivoted);
- return status;
-
-}
-
-#undef DO_SWAP
-
-
-LPMATN MATNmult(LPMATN a1, LPMATN a2)
-{
- int i, j, k;
- LPMATN b;
-
- if (a1->Cols != a2->Rows)
- return NULL;
-
- b = MATNalloc (a1->Rows, a2->Cols);
- if (b == NULL)
- return NULL;
-
- for (i = 0; i < b->Rows; i++) {
-
- for (j = 0; j < b->Cols; j++) {
-
- b->Values[i][j] = 0.0;
-
- for (k = 0; k < a1->Cols; k++) {
-
- b->Values[i][j] += a1->Values[i][k] * a2->Values[k][j];
- }
- }
- }
-
- return b;
-}
-
-
-double MATNcross(LPMATN a)
-{
- int i;
- double prod = 0.0;
-
- for (i = 0; i < a->Rows; i++) {
-
- prod += a->Values[i][0]*a->Values[i][0];
- }
- return prod;
-}
-
-
-void MATNscalar(LPMATN a, double scl, LPMATN b)
-{
- int i, j;
-
- if (a->Rows != b->Rows || a->Cols != b->Cols)
- return;
-
- for (i = 0; i < a->Rows; i++) {
-
- for (j = 0; j < a->Cols; j++)
- b->Values[i][j] = a->Values[i][j] * scl;
- }
-}
-
-
-LPMATN MATNtranspose(LPMATN a)
-{
- LPMATN b = MATNalloc(a->Cols, a->Rows);
- if (b != NULL) {
-
- int i, j;
-
- for (i = 0; i < a->Rows; i++)
- {
- for (j = 0; j < a->Cols; j++)
- b->Values[j][i] = a->Values [i][j];
- }
- }
- return b;
-}
-
-
-
-// Used for debug purposes
-#ifdef DEBUG
-void MATNprintf(char* name, LPMATN mat)
-{
- int i, j;
-
- printf ("%s:\n", name);
- for (i= 0; i < mat->Rows; i++) {
-
- printf ("%3d", i);
- for (j = 0; j < mat->Cols; j++)
- printf (" %.5f", mat->Values[i][j]);
- printf ("\n");
- }
-}
-#endif
-
-
/trunk/lprof/src/cmsmatn.c
Property changes:
Deleted: svn:eol-style
## -1 +0,0 ##
-native
\ No newline at end of property
Deleted: svn:keywords
## -1 +0,0 ##
-Author Date Id Revision
\ No newline at end of property
Index: trunk/lprof/COPYING
===================================================================
--- trunk/lprof/COPYING (revision 2454)
+++ trunk/lprof/COPYING (nonexistent)
@@ -1,340 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This program 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) year name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Library General
-Public License instead of this License.
/trunk/lprof/COPYING
Property changes:
Deleted: svn:eol-style
## -1 +0,0 ##
-native
\ No newline at end of property
Deleted: svn:keywords
## -1 +0,0 ##
-Author Date Id Revision
\ No newline at end of property
Index: trunk/lprof/manual.txt
===================================================================
--- trunk/lprof/manual.txt (revision 2454)
+++ trunk/lprof/manual.txt (nonexistent)
@@ -1,551 +0,0 @@
-
-
- little cms Engine
- http://www.littlecms.com
-
- lprof - A profile construction set library
-
- How to use the the sample profilers
-
- by Marti Maria
-
- Ver 1.09
-
- ---------------------------------------------------
-
-
- Welcome to this small guided tour on littlecms sample profilers.
- The goal of this document is to show how these programs can be
- used to generate ICC profiles for your monitor, scanner, digital
- camera, film projector or input device. It has also some advice
- on color management in general, as well as some guidelines on
- how to handle several littlecms utilities.
-
-
- Since the best way to see how it works seems to be by example, we
- will step by step make a whole calibration procedure for monitor
- and scanner.
-
- In all this tour, we will make extensive use of the measurement
- and proof utility: qtMeasurementTool. You will also need a IT8
- target, available from several vendors. If you plan to do scanner
- profiling, make sure to get one of these.
-
- qtMeasurementTool is a "virtual colorimeter" that used in
- conjunction with a proper scanner profile can be used as a cheap
- replacement of expensive hardware. It can also be used to proof
- an Image across two profiles. The most simple way to check if
- all is going fine is by visual inspection. You can load a Image
- in the measurement tool, and apply a transform between your
- input profile (AKA, scanner or camera) and your monitor profile.
- Since right now we have no profiles to check, we should first
- create a profile for our monitor.
-
- This is done by qtMonitorProfiler. This program can work in two
- different modes. The "advanced" mode, that gives accurate
- profiles by using hardware devices like X-Rite DP92 or EyeOne,
- and the "simple" mode, that allow to build reasonably accurate
- profiles without any additional hardware.
-
-
- Building a monitor profile: a coarse approximation
- ==================================================
-
- So, let's build our first monitor profile to check how all this
- stuff works. We don't need right now a big accuracy. We want to
- calibrate coarsely, just to visually check if is all going ok.
-
- After installing the package, type
-
- ./qtmonitorprofiler
-
- This will start the monitor profiler application. As said, we
- need only a coarse profile, so, we select the radio button
- labeled:
-
- "I want to build a coarse profile, giving approximate values"
-
- This is selected by default. We need not any measurement right
- now, only a few visual adjusts. Press the button labeled:
-
- "Enter monitor values"
-
- You will see the monitor values page. In order to obtain maximum
- performance, we need to adjust first the physical monitor
- controls.
-
- Set contrast to near maximum, (yes, near maximum. This is the
- gain of monitor and we need as many as monitor can deliver) and
- then adjust brightness until you can see all grays of a
- grayscale. Leave the monitor alone, and return to monitor
- profiler program.
-
- Now we will adjust gamma correction. This is by far the most
- important setting. On our first approach, we will try with only
- one gray channel (make sure "Link channels" is checked).
-
- Move the slide until the central frame seems to "fade" on background.
- Don't spend too much time adjust it, gamma varies with many factors.
- A coarse adjust will be enough right now.
-
- You should obtain a typical value of 2.1-2.4, in some cases it
- could be even lower.
-
- Now we go on the white point stuff. Some monitors refers white
- point as "temperature". Most users does have white point set to
- D93 in order to get more bright, unfortunately this restricts
- the gamut and adds a big quantity of blue, so my advice would be
- to select something lower.
-
- If you can switch temperature of your monitor, D65 (near 6500K)
- could be a good choice for multiuse. For proofing devices, D50
- is almost a must, but it adds too yellow for a unadapted used.
- D50 requires a dim or dark room to give the best results. If you
- don't know which temperature your monitor has, select D65 or
- D93. On our fist approach both these will give reasonable
- results.
-
-
-
- If your monitor has any other white point, you can select "User
- defined", the last option. You can then select your particular
- white point as a temperature in Kelvin degree.
-
- Don't use CIE illuminants. They are intended for workspace
- construction, and will be discussed latter.
-
- Next adjust is primaries set. For the primaries, select the
- default ITU/R BT.709 if you are profiling a CRT monitor. There
- are primaries for Samsung TFT and LCD, but these devices are not
- fully supported by the profiler. The reason to not support them
- is the angular dependence, which makes them unusable for color
- management tasks.
-
- Other primaries are for building workspaces. If you don't know
- the primaries, don't worry. Use the default ITU/R BT.709. There
- are 6 or 7 CRT tube manufacturers in the world, and all them
- does use this set.
-
- Now you can fill the info about your monitor. Although this is
- not strictly required, it could prevent a lot of pain when you
- have more than a couple of profiles. For filling the info field,
- select the "profile identification" tab, and be creative on your
- comments!
-
- Now we are ready to generate our profile. We must specify the
- output filename, so, select the "Main" tab, and press the "..."
- button on right side of the "output profile file" edit.
-
- Select "profiles" directory. This is where other tools will look
- for monitor profile. There are a couple of profiles there, leave
- them alone. For the name, we could use "CoarseMonitor.icm" So,
- type in the name and then proceed to generate the profile by
- pressing the "GO!" button. If all is ok, the status console will
- show "Profile DONE!"
-
- Let's now check how well is working our profile by eye. For
- that, we need another tool. So, close the monitor profile and
- start the measurement tool by typing
-
- ./qtMeasurementTool
-
- This utility has many usage. One would be to "proof" a color
- transform. Let's first configure the measurement tool. Select
- the "Options" tab. Adjust the default settings as following:
-
- On "Pick template" --> "Empty Picker"
-
- On "Input profile" --> "Tutorial Workspace"
-
- On "Monitor profile" should appear your profile. If you filled
- the info fields, here will be your description. If you didn't
- enter description it will be"(unknown) - Little cms construction
- set", which is the default string. Now you know why to fill
- information fields!
-
-
-
- We are going to check your profile with a highly tweaked sample
- Image This is a counterexample on what a good workspace should
- be. NEVER use this profile for practical purposes!
-
- Ok, let's see how a Image looks in this tweaked colorspace.
- Select the "Image" tab, and press "Load Image" button.
-
- Select "pics" directory. There is a "party_4s.png" Load it. You
- will see the raw, non color managed picture. Since the encoding
- space of this Image is quite different of any monitor, the
- images looks "flat" and "washed out" Now press the "Proof"
- button. The Image is shown using color management. Color
- changes should be noticeable, despite gamma of image is
- near gamma of monitor.
-
-
- Building scanner profile
- ========================
-
- We have now our monitor calibrated, and will try to generate a
- scanner profile. For this, we will also need the measurement
- tool.
-
- Scanner profiles are built by using a thing known as "IT8
- target". IT8 targets are just a photo with a set of color
- patches. There are known colorimetric measurements for each
- of these patches. There is also a standard way to specify
- these measurements, the IT8/CGATS format.
-
-
- IT8/CGATS is a way to encode data that is both, human and
- machine readable. You can open any of these IT8 reference sheets
- with your text editor to see it. You can even modify the
- contents. Since it is a standard, most color management systems
- does accept it. For these reasons, seems a good way to store
- measurement data.
-
-
- A IT8 file does contain measurements for a set of color patches.
- The measurement of each patch can be the device colorant values
- (the RGB or CMYK in 0..255 range) the tristimulous values (XYZ
- or Lab) and some statistic data.
-
-
-A IT8 sheet looks like:
-
------------------------------------------------------------
-IT8.7/2
-ORIGINATOR "Wolf Faust"
-DESCRIPTOR "L* a* b* Batch average data (light D50, viewing angle 2)"
-MANUFACTURER "Wolf Faust - http://www.coloraid.de"
-CREATED "January 07, 2002"
-PROD_DATE "2001:12"
-SERIAL "DIN A4 R012020"
-MATERIAL "Kodak Professional Digital 3 - Non-Glossy"
-NUMBER_OF_FIELDS 9
-BEGIN_DATA_FORMAT
-SAMPLE_ID XYZ_X XYZ_Y XYZ_Z LAB_L LAB_A LAB_B LAB_C LAB_H
-END_DATA_FORMAT
-NUMBER_OF_SETS 288
-BEGIN_DATA
-A1 3.25 2.71 1.94 18.86 11.18 2.87 11.55 14.41
-A2 4.07 2.73 1.60 18.91 23.59 6.54 24.49 15.48
-A3 5.79 3.42 1.75 21.67 33.38 9.60 34.73 16.05
-A4 4.28 2.66 1.46 18.62 27.73 7.59 28.75 15.32
-A5 11.97 10.30 7.42 38.38 15.04 4.16 15.61 15.47
-.... etc ...
-------------------------------------------------------------
-
-
- The target manufacturer does provide a IT8 file containing these
- measurements for the target. So, the target is giving to us a set
- of KNOWN colors. We must then, tell to the profiler which RGB
- values our scanner returns for each of these patches.
-
- Measurement tool can generate sheets with the RGB values of each
- patch grabbing them from a Image. In order to generate a
- profile, we need the RGB and Lab values for each patch.
-
- let's outline the scanner profiling procedure:
-
- * First (and very important!) adjust controls of scanner to
- obtain a proper exchange space.
-
- * Scan by means of you scanning software a Image of your
- target.
-
- * By using measurement tool, grab the RGB values of each
- patch. Store them in a IT8 file
-
- * The scanner profile then will compare the RGB
- obtained by the scanner, with the known colorimetric
- measurement of target, as stored in vendor's reference
- sheet.
-
- * The scanner profiler will create a model for the
- translation RGB -> Lab or RGB -> XYZ and will store it in
- a profile.
-
-
- The math behind this model is not trivial. There is a big
- quantity of factors taken into account. Don't worry for the
- apparent missing of data. Yes, there are colors not present in
- target, however the scanner profiler is capable to "guess" or
- extrapolate them, and should produce a profile handling all
- gradients between these colors in a smooth and pleasant way.
-
- Lets' discuss each step in detail:
-
- * Step 1: Adjust controls of scanner.
-
- You will need 24 bits per pixel at least. Gray profiles
- are NOT supported in this revision.
-
- There is a big amount of controversy about how to set the
- scanner controls. Some people does advice to use linear gamma
- (gamma=1.0), which is a wrong advice unless you are working with
- 16 bits per sample (48 bits per pixel)
-
- If you are going to scan in 8 bits per sample (24 or 32 bits)
- your best choice is a gamma between 2.2 and 3.0
-
- Gamma 2.2 has the additional benefit of being close to sRGB, and
- this means the uncorrected Image will "look nice" on average
- monitors. It is also near to perceptual gamma.
-
- Gamma 2.4 has the additional benefit of being closest to
- perceptual space, and this is a very good reason to use this
- value.
-
- Less that 2.2 (and of course the infamous 1.0) can generate huge
- loss of detail in shadows, only to give a slight bettering of
- highlights. Don't use this unless your are using 16 bits per
- sample, and even in such case, don't do it unless you know what
- are you doing!
-
- More that 2.4 (up to 3.0) drops too much highlight to be safe,
- despite you will still see the Image quite correct.
-
- More on controls: Turn off all color management, color enhancing
- and tweaking on scanner driver. Set brightness contrast and hue
- (if available) to default values. It is supposed this will be your
- working scanning mode, so set all to reasonable defaults.
-
- IMPORTANT: The profile will only be valid with those settings!
-
-
- * Step 2: Scan the IT8 target.
-
- Store it in PNG, TIFF, BMP on depending of supported formats of
- your platform. DON'T use JPEG! Its lousy nature makes it
- unsuitable for this purpose. You could use JPEG on final images,
- but not in profiling process.
-
- * Step 3: Extract the RGB values for each patch.
-
- Without help, this could be a huge task. There are plenty of
- patches and taking each sample by hand would be tedious. With
- the help of measurement tool, this is a easy task.
-
- Start the measurement tool by typing
-
- ./qtMeasurementTool
-
- Press "Load Image" button. Select the Image of target you scanned
- in step 2. I will use the scandmo.png image sited on "pics"
- directory as sample. This is a Kodak film target, scanned with a
- scanner that adds a huge violet cast. Don't worry, the profile
- will turn this one to a nice looking Image.
-
- Since this is a Kodak target that has some additional patches
- (those on I,J,K,L - 20,21,22) we can choose a picker template
- according the nature of target. Press "Options" tab, and in the
- combo labeled "Pick template" select:
-
- "IT8.7 19+3 (Kodak) column picker"
-
- Press "Image" tab.
-
- You will see a lot of green rectangles. Using the mouse you
- must place the pick template over the patches. Use left button to
- move whole template and right button to resize it. Since this
- Image is not perfectly horizontal, you may want to "unshear" the
- layout: You can do it by pressing "Ctrl" key while dragging with
- left mouse button.
-
- The "hot area" is marked with green rectangle. Assure all green
- rectangles are inside patches. Failure to do so could result in
- wrong profile! You can also adjust the relative size of "hot
- areas" by setting the % in "safe frame" on "Options" tab.
- Normally there is no need to touch anything.
-
- Once you were happy with the location of patch grabber zones,
- press the "Pick" button, placed on left side of window.
-
- The measurement tool will build a IT8 sheet containing RGB
- values of each of your patches. Now you can save this sheet by
- pressing the "Save IT8 sheet" button. For our tutorial I will
- name this measurement "scandmo.it8" and will place it on
- "pics" directory. (There is already one scandmo.it8, that you
- can overwrite)
-
- Our work with measurement tool is now done. We have right now
- the reference sheet of target, which is given by Kodak, and the
- RGB values obtained by our scanner. Now we can compare these
- files to create a profile.
-
- * Step 4: Close the measurement tool, and launch the
- scanner profiler by typing:
-
- ./qtScannerProfiler
-
- From here is quite easy. First we must select the target
- reference. In this tutorial, we have used a film target of
- reference 1996-08, so, press the "Select target & vendor type"
- button and select "targets", "Kodak" folder, then "Emissive"
- folder (since it is film). Press Ok. The left combo will be
- filled with all target references. Then select 1996-08 (is on
- last part of list)
-
- Once selected, you need to specify your measurement. Press the
- "..." button placed on right side of "Measurement" edit. Select
- "picts" folder and "scandmo.it8" file.
-
- Now we have to specify the profile filename. Press the "..." button
- placed on right of "output profile file", select the "profiles"
- folder. The name could be "scandmo.icm"
-
- You can now, as we did in the monitor profile, fill some info to
- help us to locate the profile latter. Press the "profile
- identification" tab, and fill in the fields.
-
- You are ready to generate the profile. Press "GO!" button to
- launch the profiler process. After a few seconds, you will have
- a small profile for your scanner. In the demo, the obtained dE is
- about 1.24, which is reasonably. Now, we can better a lot the
- error level, but this will take more time to generate the profile.
- Press the "Parameters and tweaking" tab, and select on
- "Resolution" group "33 points". Then check the checkbox labeled
- "local convergence analysis". Press the "GO!" button. Now the
- generation will take a while, but the obtained profile has
- bettered a lot... maximum dE is about 0.7 and the peak value is
- as small as 3!!!
-
- * Step 5: Let's check how this profile does affect the
- original Image.
-
- Start the measurement tool, select "options" tab and make sure
- picker template is set to "empty picker", "input profile" should
- be set to this newly created scanner profile, and "monitor
- profile" should be the profile we have made for monitor. Press
- "Image" tab, press "Load Image" button, load the scanned Image
- (scandmo.png in our sample) and then press the "proof" button to
- see the results. The girl's Image is dark, this is normal.
- However, rest of patches are hugely modified, the grayscale
- should appear smooth and without any cast, as well as all violet
- tint should disappear.
-
-
-
- Making workspace profiles
- =========================
-
- Some applications, for example Adobe Photoshop, does use what is
- called "Workspaces". These are RGB color spaces, which are not
- intended to be representing any device, nor storage but a
- "working space". That is, Image processing operations are
- performed in such space, and also can be used as a way to
- interchange image data between applications.
-
-
- The monitor profiler, despite its name, can be effectively used
- to build such profiles.
-
- Just select the gamma, primaries set and white point. Press GO!
- and the workspace profile will be generated.
-
-
- Building accurate monitor profiles by hardware measurement devices
- ===================================================================
-
- To measure your monitor, you need to fill a IT8 sheet,
- containing XYZ measurements for several RGB combinations. A
- sample sheet of this kind can be found in "pics" directory. The
- file is called "sRGB.IT8" and it measures an ideal sRGB monitor.
-
- You need to change the XYZ values by those read by your
- measurement device. Don't put any Lab value, just RGB and XYZ.
-
- Please keep the RGB values the sRGB.IT8 has. Optionally, you can
- use more patches to assure consistent color reproduction, but make
- sure to include at least that ones.
-
- Note the big amount of gray patches needed. You can also add as
- many as you wish, on more gray patches, better linearization
- curves control. You must specify at least 16 gray patches.
-
- Now we will try this procedure, no matter you have not any
- hardware device. As we will see below, this method could be used
- to dissect profiles and do some tweaking.
-
- We are going to generate a sRGB profile, by using the sRGB.IT8
- measurement sheet. For that, we will use monitor profiler, so
- start it by typing:
-
- ./qtMonitorProfiler
-
- Now, we are going to use it in advanced mode. Select the radio
- button labeled:
-
- "I want to build accurate profile from measurement sheet"
-
-
- Then press the "..." button located at right of edit. Select in
- "pics" directory the file called "sRGB.IT8". In the "Output
- profile file", select a new profile in "profiles" directory.
- Call it "my_sRGB.icm".
-
- I will use this sample to present another utility, the profile
- checker. Since the profile checker can understand advanced tags,
- we want to include all information in the profile, so select the
- "parameters and tweaking" tab, and make sure to select "Verbose,
- store anything" in the "profile verbosity level" group.
-
- Now, fill the info fields if you want (again, I recommend to do
- that) and press the GO button. A new "my_srgb.icm" profile will
- be created.
-
- We will check now how accurate is this profile. Start the
- profile checker program by typing
-
- ./qtProfileChecker
-
- The profile checker is a tool for inspecting some of profile
- internals. In our case, we want to check the accurancy. For
- selecting the profile, press the ".." button on the right side
- of the "profile" edit. Select "pics" directory, and choose
- "my_srgb.icm" profile. Press "GO!" button.
-
- On "dE report tab" you will see the error statistics. (unless
- you forgot to set the profile verbosity to "store anything")
- Our sample scored 0.18, which is a incredibly low value, not
- to be even reached in real world cases, but this could give
- an idea of the precision the profiler can give with only a
- very few measurements.
-
-
- The profile checker has also the capability of draw chromaticity
- diagram, to show primaries, color displacements, to guess the
- gamma of the profile and many other functionality. Feel free to
- experiment, the profile checker will never write on your
- profile, so you can play with it in a safe way.
-
- Additional utilities
- ====================
-
- Finally, there is a additional command-line utility that can be
- used in conjunction of monitor profiler. It is called icc2it8
- and is placed on ICCtoIT8 directory. This utility is capable of
- generate IT8 measurements from profiles, so, it can be used as a
- "profile tweacker". You can generate a IT8 sheet from a given
- profile, then edit manually XYZ values and then build a new
- profile using the modified sheet. This right now is limited to
- matrix-shaper profiles, but even with this small limitation,
- it can become a valuable tool.
-
- Other useful tools are included in littlecms CMM package.
- You have TIFFICC that can be used to apply profile transforms
- to TIFF files, and JPEGICC that does same on JPEG. Also,
- you have ICCTRANS, that can be used to check profiles
- by numbers. See the littlecms documentation for more details.
-
-
- That's all for now. There are still many options that this small
- introduction don't cover, like the CIECAM97s appearance model,
- and a more advanced usage. However, you have now a basic
- knowledge of how this stuff works. There is a mailing list on
- littlecms for asking and sharing your tricks on how get the best
- from littlecms profilers. Feel free to ask.
-
- http://lists.sourceforge.net/lists/listinfo/lcms-user
-
-
- Enjoy!
/trunk/lprof/manual.txt
Property changes:
Deleted: svn:eol-style
## -1 +0,0 ##
-native
\ No newline at end of property
Deleted: svn:keywords
## -1 +0,0 ##
-Author Date Id Revision
\ No newline at end of property
Index: trunk/lprof/README
===================================================================
--- trunk/lprof/README (revision 2454)
+++ trunk/lprof/README (nonexistent)
@@ -1,122 +0,0 @@
-
-
- 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.
-
- The lprof library is distributed under
-
- GNU GENERAL PUBLIC LICENSE
-
-
- As a special exception, Klas Kalass and Marti Maria gives permission to link
- this program with Qt non-commercial edition, and distribute the resulting
- executable, without including the source code for the Qt non-commercial
- edition in the source distribution.
-
- See file COPYING. for details
-
-
- This is the 2nd. public release the profilers. It has not been
- tested extensively, so is possible some bugs still arises.
- If so, sorry for the inconvenience, and please feel free to submit
- any suggestion/solution (if you can find it) at:
-
- marti@littlecms.com
-
-
- The main site for the package is located at
-
- http://www.littlecms.com
- or
- http://www.lcms.coloraid.de
-
-
-
- Looking forward the lcms project would grow in future, I will
- welcome any contribution/optimization/enhancement.
-
- Enjoy!
-
-
- Requeriments
- ============
-
- In order to execute the profiling utilities, you will need:
-
- - Trolltech's Qt installed (www.trolltech.com)
- - Littlecms color engine installed (www.littlecms.com)
- - GNU C compiler gcc or equivalent installed. MS VC++ 6 in Windows
- systems required in order to use Qt.
- - A working make utility. (not required on windows)
-
- Additionaly, in order to calibrate scanner, you will need an IT8 target.
-
-
-
- Installation
- ============
-
- Untar the package (you already did it) and then type 'make'. The
- binaries will be placed on root of distribution. There are no files
- installed outside distribution directory. You will end with 5 programs:
-
- - Measurement tool
- - Monitor profiler
- - Scanner profiler
- - Profile checker
- - ICC2IT8 program
-
-
- if something goes wrong, try the gcc compiler by using
-
- make CC=gcc all
-
-
-
- KDE
- ===
-
- For obtainig KDE specific programs, type
-
- make USE_KDE=yes all
-
-
- After installation, see MANUAL.TXT for a guided tour.
-
-
-
- Installing new target reference files
- =====================================
- If the target vendor gives you a diskette, press the "..." button on right
- and select the floppy drive. You can add references by copying reference
- files into the directory.
-
- IMPORTANT: DON'T PLACE ANY SPARE FILES, ONLY TARGET REFERENCES.
-
-
-
- Final notes
- ===========
-
- Don't expect magic. These profilers does build ICC profiles for your
- devices, but is up to the application to use this profiles in order to
- accomplish color management. Adobe's PhotoShop, for example does
- understand these profiles. Littlecms comes also with a utility for
- converting tiff files. If you want to see how can better this system
- the color reproduction, convert a scanned image to monitor space
-
- tifficc /iscanner.icm /omonitor.icm image_in.tif image_out.tif
-
- Also note that Qt does not support any type of image, TIFF, for example
- is not supported. JPEG, BMP are generally available. The list of
- supported formats does vary on platform and Qt version.
-
-
\ No newline at end of file
/trunk/lprof/README
Property changes:
Deleted: svn:eol-style
## -1 +0,0 ##
-native
\ No newline at end of property
Deleted: svn:keywords
## -1 +0,0 ##
-Author Date Id Revision
\ No newline at end of property