/tags/lprof109/lprof/manual.txt |
---|
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: lprof109/lprof/README |
=================================================================== |
--- lprof109/lprof/README (revision 2457) |
+++ lprof109/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 |
/lprof109/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 |
Index: lprof109/lprof/include/lcmsprf.h |
=================================================================== |
--- lprof109/lprof/include/lcmsprf.h (revision 2457) |
+++ lprof109/lprof/include/lcmsprf.h (nonexistent) |
@@ -1,479 +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 |
- |
-#ifndef __cmsprf_H |
- |
-#include "lcms.h" |
-#include <ctype.h> |
-#include <limits.h> |
-#include <stdarg.h> |
-#include <sys/stat.h> |
- |
- |
-#ifdef __cplusplus |
-extern "C" { |
-#endif |
- |
-#ifdef NON_WINDOWS |
-# ifndef stricmp |
-# define stricmp strcasecmp |
-# endif |
-#endif |
- |
-#ifndef max |
-#define max(a,b) ((a) > (b)?(a):(b)) |
-#endif |
- |
- |
-// Matrix operations - arbitrary size ----------------------------------------------------- |
- |
-typedef struct { |
- |
- int Cols, Rows; |
- double** Values; |
- |
- } MATN,FAR* LPMATN; |
- |
- |
-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); |
- |
- |
-// IT8.7 / CGATS.17-200x handling -------------------------------------------------------- |
- |
-#define cmsxIT8_ROWS 12 |
-#define cmsxIT8_COLS 22 |
-#define cmsxIT8_GRAYCOLS 24 |
-#define cmsxIT8_NORMAL_PATCHES (cmsxIT8_ROWS*cmsxIT8_COLS + cmsxIT8_GRAYCOLS) |
-#define cmsxIT8_CUSTOM_PATCHES 10 |
-#define cmsxIT8_TOTAL_PATCHES (cmsxIT8_NORMAL_PATCHES + cmsxIT8_CUSTOM_PATCHES) |
- |
- |
-LCMSHANDLE cdecl cmsxIT8Alloc(void); |
-void cdecl cmsxIT8Free(LCMSHANDLE cmsxIT8); |
-LCMSHANDLE cdecl cmsxIT8LoadFromFile(const char* cFileName); |
-LCMSHANDLE cdecl cmsxIT8LoadFromMem(void *Ptr, size_t len); |
-BOOL cdecl cmsxIT8SaveToFile(LCMSHANDLE cmsxIT8, const char* cFileName); |
-const char* cdecl cmsxIT8GetSheetType(LCMSHANDLE hIT8); |
-BOOL cdecl cmsxIT8SetSheetType(LCMSHANDLE hIT8, const char* Type); |
-const char* cdecl cmsxIT8GetPatchName(LCMSHANDLE hIT8, int nPatch, char* buffer); |
-BOOL cdecl cmsxIT8SetProperty(LCMSHANDLE hcmsxIT8, const char* cProp, const char *Str); |
-BOOL cdecl cmsxIT8SetPropertyDbl(LCMSHANDLE hcmsxIT8, const char* cProp, double Val); |
-const char* cdecl cmsxIT8GetProperty(LCMSHANDLE hcmsxIT8, const char* cProp); |
-double cdecl cmsxIT8GetPropertyDbl(LCMSHANDLE hcmsxIT8, const char* cProp); |
-int cdecl cmsxIT8EnumProperties(LCMSHANDLE cmsxIT8, char ***PropertyNames); |
-int cdecl cmsxIT8EnumDataFormat(LCMSHANDLE cmsxIT8, char ***SampleNames); |
-BOOL cdecl cmsxIT8SetDataFormat(LCMSHANDLE cmsxIT8, int n, const char *Sample); |
- |
-BOOL cdecl cmsxIT8GetDataSetByPos(LCMSHANDLE IT8, int col, int row, char* Val, int ValBufferLen); |
- |
-BOOL cdecl cmsxIT8GetDataSet(LCMSHANDLE cmsxIT8, const char* cPatch, |
- const char* cSample, |
- char* Val, int ValBuffLen); |
- |
-BOOL cdecl cmsxIT8GetDataSetDbl(LCMSHANDLE cmsxIT8, const char* cPatch, const char* cSample, double* v); |
- |
-BOOL cdecl cmsxIT8SetDataSet(LCMSHANDLE cmsxIT8, const char* cPatch, |
- const char* cSample, |
- char *Val); |
- |
-BOOL cdecl cmsxIT8SetDataSetDbl(LCMSHANDLE cmsxIT8, const char* cPatch, const char* cSample, double Val); |
- |
-const char *cdecl cmsxIT8GenericPatchName(int nPatch, char* buffer); |
- |
- |
- |
-// Patch collections (measurement lists) -------------------------------------------------- |
- |
-#define PATCH_HAS_Lab 0x00000001 |
-#define PATCH_HAS_XYZ 0x00000002 |
-#define PATCH_HAS_RGB 0x00000004 |
-#define PATCH_HAS_CMY 0x00000008 |
-#define PATCH_HAS_CMYK 0x00000010 |
-#define PATCH_HAS_HEXACRM 0x00000020 |
-#define PATCH_HAS_STD_Lab 0x00010000 |
-#define PATCH_HAS_STD_XYZ 0x00020000 |
-#define PATCH_HAS_XYZ_PROOF 0x00100000 |
-#define PATCH_HAS_MEAN_DE 0x01000000 |
-#define PATCH_HAS_STD_DE 0x02000000 |
-#define PATCH_HAS_CHISQ 0x04000000 |
- |
- |
-#define MAXPATCHNAMELEN 20 |
-// A patch in memory |
- |
-typedef struct { |
- |
- DWORD dwFlags; // Is quite possible to have colorant in only |
- // some patches of sheet, so mark each entry with |
- // the values it has. |
- |
- char Name[MAXPATCHNAMELEN]; |
- |
- cmsCIELab Lab; // The tristimulus values of target |
- cmsCIEXYZ XYZ; |
- |
- cmsCIEXYZ XYZProof; // The absolute XYZ value returned by profile |
- // (gamut constrained to device) |
- |
- union { // The possible colorants. Only one space is |
- // allowed...obviously only one set of |
- // device-dependent values per patch does make sense. |
- double RGB[3]; |
- double CMY[3]; |
- double CMYK[4]; |
- double Hexa[MAXCHANNELS]; |
- |
- } Colorant; |
- |
- double dEStd; // Standard deviation |
- double ChiSq; // Chi-square parameter (mean of STD of colorants) |
- double dEMean; // Mean dE |
- |
- } PATCH, FAR* LPPATCH; |
- |
- |
- |
-// A set of patches is simply an array of bools, TRUE if the patch |
-// belong to the set, false otherwise. |
- |
-typedef BOOL* SETOFPATCHES; |
- |
-// This struct holds whole Patches collection |
- |
-typedef struct _measurement { |
- |
- int nPatches; |
- LPPATCH Patches; |
- SETOFPATCHES Allowed; |
- |
- } MEASUREMENT,FAR *LPMEASUREMENT; |
- |
- |
-void cdecl cmsxPCollFreeMeasurements(LPMEASUREMENT m); |
-SETOFPATCHES cdecl cmsxPCollBuildSet(LPMEASUREMENT m, BOOL lDefault); |
- |
-BOOL cdecl cmsxPCollBuildMeasurement(LPMEASUREMENT m, |
- const char *ReferenceSheet, |
- const char *MeasurementSheet, |
- DWORD dwNeededSamplesType); |
- |
-int cdecl cmsxPCollCountSet(LPMEASUREMENT m, SETOFPATCHES Set); |
-BOOL cdecl cmsxPCollValidatePatches(LPMEASUREMENT m, DWORD dwFlags); |
- |
-BOOL cdecl cmsxPCollLoadFromSheet(LPMEASUREMENT m, LCMSHANDLE hSheet); |
-BOOL cdecl cmsxPCollSaveToSheet(LPMEASUREMENT m, LCMSHANDLE it8); |
- |
-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); |
- |
-void cdecl cmsxPCollLinearizePatches(LPMEASUREMENT m, SETOFPATCHES Valids, |
- LPGAMMATABLE Gamma[3]); |
- |
-// Extraction utilities |
- |
-// 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); |
- |
-// Find important values |
- |
-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); |
- |
-// 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); |
- |
-BOOL cdecl cmsxRegressionInterpolatorRGB(LPMEASUREMENT m, |
- int ColorSpace, |
- int RegressionTerms, |
- BOOL lUseLocalPatches, |
- int MinPatchesToCollect, |
- double r, double g, double b, |
- void* Res); |
- |
- |
- |
-// Levenberg-Marquardt ---------------------------------------------------------------------- |
- |
-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); |
- |
- |
-// Convex hull geometric routines ------------------------------------------------------------ |
- |
-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); |
- |
- |
-// Linearization ---------------------------------------------------------------------------- |
- |
- |
-#define MEDIUM_REFLECTIVE_D50 0 // Used for scanner targets |
-#define MEDIUM_TRANSMISSIVE 1 // Used for monitors & projectors |
- |
-void cdecl cmsxComputeLinearizationTables(LPMEASUREMENT m, |
- int ColorSpace, |
- LPGAMMATABLE Lin[3], |
- int nResultingPoints, |
- int Medium); |
- |
- |
-void cdecl cmsxCompleteLabOfPatches(LPMEASUREMENT m, SETOFPATCHES Valids, int Medium); |
-LPGAMMATABLE cdecl cmsxEstimateGamma(LPSAMPLEDCURVE X, LPSAMPLEDCURVE Y, int nResultingPoints); |
- |
-void cdecl cmsxApplyLinearizationTable(double In[3], LPGAMMATABLE Gamma[3], double Out[3]); |
-void cdecl cmsxApplyLinearizationGamma(WORD In[3], LPGAMMATABLE Gamma[3], WORD Out[3]); |
- |
-// Support routines ---------------------------------------------------------------------- |
- |
-double cdecl _cmsxSaturate65535To255(double d); |
-double cdecl _cmsxSaturate255To65535(double d); |
-void cdecl _cmsxClampXYZ100(LPcmsCIEXYZ xyz); |
- |
-// Matrix shaper profiler API ------------------------------------------------------------- |
- |
- |
-BOOL cdecl cmsxComputeMatrixShaper(const char* ReferenceSheet, |
- const char* MeasurementSheet, |
- int Medium, |
- LPGAMMATABLE TransferCurves[3], |
- LPcmsCIEXYZ WhitePoint, |
- LPcmsCIEXYZ BlackPoint, |
- LPcmsCIExyYTRIPLE Primaries); |
- |
- |
-// Common to all profilers ------------------------------------------------------------------- |
- |
-#define MAX_STR 256 |
- |
-typedef int (* cmsxGAUGER)(const char *Label, int nMin, int nMax, int Pos); |
-typedef int (* cmsxPRINTF)(const char *Frm, ...); |
- |
-typedef struct { |
- |
- // Files |
- char ReferenceSheet[MAX_PATH]; |
- char MeasurementSheet[MAX_PATH]; |
- char OutputProfileFile[MAX_PATH]; |
- |
- // Some infos |
- char Description[MAX_STR]; |
- char Manufacturer[MAX_STR]; |
- char Model[MAX_STR]; |
- char Copyright[MAX_STR]; |
- |
- // Callbacks |
- cmsxGAUGER Gauger; |
- cmsxPRINTF printf; |
- |
- // EndPoints |
- cmsCIEXYZ WhitePoint; // Black point in 0.xxx notation |
- cmsCIEXYZ BlackPoint; // Black point in 0.xxx notation |
- cmsCIExyYTRIPLE Primaries; // The primaries |
- LPGAMMATABLE Gamma[3]; // Gamma curves |
- |
- // Profile |
- cmsHPROFILE hProfile; // handle to profile |
- |
- icProfileClassSignature DeviceClass; |
- icColorSpaceSignature ColorSpace; |
- |
- int PCSType; // PT_XYZ or PT_Lab |
- int CLUTPoints; // Final CLUT resolution |
- int ProfileVerbosityLevel; // 0=minimum, 1=additional, 2=Verbose, 3=Any suitable |
- |
- |
- // Measurement |
- MEASUREMENT m; // Contains list of available patches |
- int Medium; |
- |
- |
- // RGB Gamut hull |
- LCMSHANDLE hRGBHull; // Contains bobbin of valid RGB values |
- |
- // CIECAM97s |
- BOOL lUseCIECAM97s; // Use CIECAM97s for chromatic adaptation? |
- |
- cmsViewingConditions device; // Viewing condition of source |
- cmsViewingConditions PCS; // Viewing condition of PCS |
- |
- LCMSHANDLE hDevice; // CIECAM97s models used for adaptation |
- LCMSHANDLE hPCS; // and viewing conditions |
- |
- |
- } PROFILERCOMMONDATA,FAR* LPPROFILERCOMMONDATA; |
- |
- |
-// Shared routines |
- |
-BOOL cdecl cmsxEmbedCharTarget(LPPROFILERCOMMONDATA hdr); |
-BOOL cdecl cmsxEmbedMatrixShaper(LPPROFILERCOMMONDATA hdr); |
-BOOL cdecl cmsxEmbedTextualInfo(LPPROFILERCOMMONDATA hdr); |
- |
-int cdecl cmsxFindOptimumNumOfTerms(LPPROFILERCOMMONDATA hdr, int nMaxTerms, BOOL* lAllOk); |
-void cdecl cmsxChromaticAdaptationAndNormalization(LPPROFILERCOMMONDATA hdr, LPcmsCIEXYZ xyz, BOOL lReverse); |
-void cdecl cmsxInitPCSViewingConditions(LPPROFILERCOMMONDATA hdr); |
-void cdecl cmsxComputeGamutHull(LPPROFILERCOMMONDATA hdr); |
-BOOL cdecl cmsxChoosePCS(LPPROFILERCOMMONDATA hdr); |
- |
-// Monitor profiler API ------------------------------------------------------------------- |
- |
-typedef struct { |
- |
- PROFILERCOMMONDATA hdr; |
- |
- |
- LPGAMMATABLE Prelinearization[3]; // Canonic gamma |
- LPGAMMATABLE ReverseTables[3]; // Reverse (direct) gamma |
- LPGAMMATABLE PreLab[3]; |
- LPGAMMATABLE PreLabRev[3]; |
- |
- |
- MAT3 PrimariesMatrix; |
- MAT3 PrimariesMatrixRev; |
- |
- |
- } MONITORPROFILERDATA,FAR* LPMONITORPROFILERDATA; |
- |
- |
- |
-BOOL cdecl cmsxMonitorProfilerInit(LPMONITORPROFILERDATA sys); |
-BOOL cdecl cmsxMonitorProfilerDo(LPMONITORPROFILERDATA sys); |
- |
- |
-// Scanner profiler API ------------------------------------------------------------------- |
- |
- |
-typedef struct { |
- |
- PROFILERCOMMONDATA hdr; |
- |
- LPGAMMATABLE Prelinearization[3]; |
- |
- LPMATN HiTerms; // Regression matrix of many terms |
- LPMATN LoTerms; // Low order regression matrix used for extrapolation |
- |
- BOOL lLocalConvergenceExtrapolation; |
- |
- |
- } SCANNERPROFILERDATA,FAR* LPSCANNERPROFILERDATA; |
- |
- |
- |
- |
-BOOL cdecl cmsxScannerProfilerInit(LPSCANNERPROFILERDATA sys); |
-BOOL cdecl cmsxScannerProfilerDo(LPSCANNERPROFILERDATA sys); |
- |
-// ----------------------------------------------------------- end of profilers |
- |
- |
-#ifdef __cplusplus |
-} |
-#endif |
- |
-#define __cmsprf_H |
-#endif |
/lprof109/lprof/include/lcmsprf.h |
---|
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: lprof109/lprof/src/cmssheet.c |
=================================================================== |
--- lprof109/lprof/src/cmssheet.c (revision 2457) |
+++ lprof109/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; |
-} |
- |
- |
- |
- |
- |
/lprof109/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: lprof109/lprof/src/cmslm.c |
=================================================================== |
--- lprof109/lprof/src/cmslm.c (revision 2457) |
+++ lprof109/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; |
-} |
/lprof109/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: lprof109/lprof/src/cmspcoll.c |
=================================================================== |
--- lprof109/lprof/src/cmspcoll.c (revision 2457) |
+++ lprof109/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; |
-} |
/lprof109/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: lprof109/lprof/src/makefile |
=================================================================== |
--- lprof109/lprof/src/makefile (revision 2457) |
+++ lprof109/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 |
/lprof109/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: lprof109/lprof/src/cmslnr.c |
=================================================================== |
--- lprof109/lprof/src/cmslnr.c (revision 2457) |
+++ lprof109/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); |
-} |
- |
/lprof109/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: lprof109/lprof/src/cmsreg.c |
=================================================================== |
--- lprof109/lprof/src/cmsreg.c (revision 2457) |
+++ lprof109/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; |
-} |
- |
/lprof109/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: lprof109/lprof/src/cmsmkmsh.c |
=================================================================== |
--- lprof109/lprof/src/cmsmkmsh.c (revision 2457) |
+++ lprof109/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; |
-} |
- |
- |
- |
/lprof109/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: lprof109/lprof/src/cmsmatn.c |
=================================================================== |
--- lprof109/lprof/src/cmsmatn.c (revision 2457) |
+++ lprof109/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 |
- |
- |
/lprof109/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: lprof109/lprof/src/cmsmntr.c |
=================================================================== |
--- lprof109/lprof/src/cmsmntr.c (revision 2457) |
+++ lprof109/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; |
-} |
/lprof109/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: lprof109/lprof/src/cmsscn.c |
=================================================================== |
--- lprof109/lprof/src/cmsscn.c (revision 2457) |
+++ lprof109/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; |
-} |
/lprof109/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: lprof109/lprof/src/cmsoutl.c |
=================================================================== |
--- lprof109/lprof/src/cmsoutl.c (revision 2457) |
+++ lprof109/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; |
-} |
- |
- |
/lprof109/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: lprof109/lprof/src/cmshull.c |
=================================================================== |
--- lprof109/lprof/src/cmshull.c (revision 2457) |
+++ lprof109/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; |
-} |
/lprof109/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: lprof109/lprof/src/cmsprf.c |
=================================================================== |
--- lprof109/lprof/src/cmsprf.c (revision 2457) |
+++ lprof109/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; |
-} |
/lprof109/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: lprof109/lprof/COPYING |
=================================================================== |
--- lprof109/lprof/COPYING (revision 2457) |
+++ lprof109/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. |
/lprof109/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 |