6821031: Upgrade OpenJDK's LittleCMS version to 1.18

Reviewed-by: bae, igor
This commit is contained in:
Phil Race 2009-03-24 09:14:02 -07:00
parent 4db0a48b10
commit 312ee333ac
24 changed files with 1962 additions and 1193 deletions

View File

@ -374,6 +374,10 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagData
return; return;
} }
// Modify data for a tag in a profile
LCMSBOOL LCMSEXPORT _cmsModifyTagData(cmsHPROFILE hProfile,
icTagSignature sig, void *data, size_t size);
/* /*
* Class: sun_java2d_cmm_lcms_LCMS * Class: sun_java2d_cmm_lcms_LCMS
* Method: setTagData * Method: setTagData
@ -561,10 +565,10 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_initLCMS
PF_ID_fID = (*env)->GetFieldID (env, Pf, "ID", "J"); PF_ID_fID = (*env)->GetFieldID (env, Pf, "ID", "J");
} }
BOOL _cmsModifyTagData(cmsHPROFILE hProfile, icTagSignature sig, LCMSBOOL _cmsModifyTagData(cmsHPROFILE hProfile, icTagSignature sig,
void *data, size_t size) void *data, size_t size)
{ {
BOOL isNew; LCMSBOOL isNew;
int i, idx, delta, count; int i, idx, delta, count;
LPBYTE padChars[3] = {0, 0, 0}; LPBYTE padChars[3] = {0, 0, 0};
LPBYTE beforeBuf, afterBuf, ptr; LPBYTE beforeBuf, afterBuf, ptr;

View File

@ -29,7 +29,7 @@
// //
// //
// Little cms // Little cms
// Copyright (C) 1998-2006 Marti Maria // Copyright (C) 1998-2007 Marti Maria
// //
// Permission is hereby granted, free of charge, to any person obtaining // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
@ -51,7 +51,7 @@
// CIECAM 02 appearance model // CIECAM 02 appearance model. Many thanks to Jordi Vilar for the debugging.
#include "lcms.h" #include "lcms.h"
@ -196,6 +196,10 @@ CAM02COLOR NonlinearCompression(CAM02COLOR clr, LPcmsCIECAM02 pMod)
clr.RGBpa[i] = (400.0 * temp) / (temp + 27.13) + 0.1; clr.RGBpa[i] = (400.0 * temp) / (temp + 27.13) + 0.1;
} }
} }
clr.A = (((2.0 * clr.RGBpa[0]) + clr.RGBpa[1] +
(clr.RGBpa[2] / 20.0)) - 0.305) * pMod->Nbb;
return clr; return clr;
} }
@ -249,9 +253,6 @@ CAM02COLOR ComputeCorrelates(CAM02COLOR clr, LPcmsCIECAM02 pMod)
clr.H = 300 + ((100*((clr.h - 237.53)/1.2)) / temp); clr.H = 300 + ((100*((clr.h - 237.53)/1.2)) / temp);
} }
clr.A = (((2.0 * clr.RGBpa[0]) + clr.RGBpa[1] +
(clr.RGBpa[2] / 20.0)) - 0.305) * pMod->Nbb;
clr.J = 100.0 * pow((clr.A / pMod->adoptedWhite.A), clr.J = 100.0 * pow((clr.A / pMod->adoptedWhite.A),
(pMod->c * pMod->z)); (pMod->c * pMod->z));
@ -395,7 +396,7 @@ LCMSHANDLE LCMSEXPORT cmsCIECAM02Init(LPcmsViewingConditions pVC)
LPcmsCIECAM02 lpMod; LPcmsCIECAM02 lpMod;
if((lpMod = (LPcmsCIECAM02) malloc(sizeof(cmsCIECAM02))) == NULL) { if((lpMod = (LPcmsCIECAM02) _cmsMalloc(sizeof(cmsCIECAM02))) == NULL) {
return (LCMSHANDLE) NULL; return (LCMSHANDLE) NULL;
} }
@ -449,14 +450,19 @@ LCMSHANDLE LCMSEXPORT cmsCIECAM02Init(LPcmsViewingConditions pVC)
lpMod -> z = compute_z(lpMod); lpMod -> z = compute_z(lpMod);
lpMod -> Nbb = computeNbb(lpMod); lpMod -> Nbb = computeNbb(lpMod);
lpMod -> FL = computeFL(lpMod); lpMod -> FL = computeFL(lpMod);
if (lpMod -> D == D_CALCULATE ||
lpMod -> D == D_CALCULATE_DISCOUNT) {
lpMod -> D = computeD(lpMod); lpMod -> D = computeD(lpMod);
}
lpMod -> Ncb = lpMod -> Nbb; lpMod -> Ncb = lpMod -> Nbb;
lpMod -> adoptedWhite = XYZtoCAT02(lpMod -> adoptedWhite); lpMod -> adoptedWhite = XYZtoCAT02(lpMod -> adoptedWhite);
lpMod -> adoptedWhite = ChromaticAdaptation(lpMod -> adoptedWhite, lpMod); lpMod -> adoptedWhite = ChromaticAdaptation(lpMod -> adoptedWhite, lpMod);
lpMod -> adoptedWhite = CAT02toHPE(lpMod -> adoptedWhite); lpMod -> adoptedWhite = CAT02toHPE(lpMod -> adoptedWhite);
lpMod -> adoptedWhite = NonlinearCompression(lpMod -> adoptedWhite, lpMod); lpMod -> adoptedWhite = NonlinearCompression(lpMod -> adoptedWhite, lpMod);
lpMod -> adoptedWhite = ComputeCorrelates(lpMod -> adoptedWhite, lpMod);
return (LCMSHANDLE) lpMod; return (LCMSHANDLE) lpMod;
@ -465,7 +471,7 @@ LCMSHANDLE LCMSEXPORT cmsCIECAM02Init(LPcmsViewingConditions pVC)
void LCMSEXPORT cmsCIECAM02Done(LCMSHANDLE hModel) void LCMSEXPORT cmsCIECAM02Done(LCMSHANDLE hModel)
{ {
LPcmsCIECAM02 lpMod = (LPcmsCIECAM02) (LPSTR) hModel; LPcmsCIECAM02 lpMod = (LPcmsCIECAM02) (LPSTR) hModel;
if (lpMod) free(lpMod); if (lpMod) _cmsFree(lpMod);
} }
@ -510,3 +516,4 @@ void LCMSEXPORT cmsCIECAM02Reverse(LCMSHANDLE hModel, LPcmsJCh pIn, LPcmsCIEXYZ
pOut ->Z = clr.XYZ[2]; pOut ->Z = clr.XYZ[2];
} }

View File

@ -29,7 +29,7 @@
// //
// //
// Little cms // Little cms
// Copyright (C) 1998-2006 Marti Maria // Copyright (C) 1998-2007 Marti Maria
// //
// Permission is hereby granted, free of charge, to any person obtaining // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
@ -174,7 +174,7 @@ typedef struct {
LCMSAPI void LCMSEXPORT cmsCIECAM97sDone(LCMSHANDLE hModel) LCMSAPI void LCMSEXPORT cmsCIECAM97sDone(LCMSHANDLE hModel)
{ {
LPcmsCIECAM97s lpMod = (LPcmsCIECAM97s) (LPSTR) hModel; LPcmsCIECAM97s lpMod = (LPcmsCIECAM97s) (LPSTR) hModel;
if (lpMod) free(lpMod); if (lpMod) _cmsFree(lpMod);
} }
// Partial discounting for adaptation degree computation // Partial discounting for adaptation degree computation
@ -331,7 +331,7 @@ LCMSAPI LCMSHANDLE LCMSEXPORT cmsCIECAM97sInit(LPcmsViewingConditions pVC)
LPcmsCIECAM97s lpMod; LPcmsCIECAM97s lpMod;
VEC3 tmp; VEC3 tmp;
if((lpMod = (LPcmsCIECAM97s) malloc(sizeof(cmsCIECAM97s))) == NULL) { if((lpMod = (LPcmsCIECAM97s) _cmsMalloc(sizeof(cmsCIECAM97s))) == NULL) {
return (LCMSHANDLE) NULL; return (LCMSHANDLE) NULL;
} }
@ -449,7 +449,7 @@ LCMSAPI LCMSHANDLE LCMSEXPORT cmsCIECAM97sInit(LPcmsViewingConditions pVC)
// RGB_subw = [MlamRigg][WP/YWp] // RGB_subw = [MlamRigg][WP/YWp]
#ifdef USE_CIECAM97s2 #ifdef USE_CIECAM97s2
MAT3eval(&lpMod -> RGB_subw, &lpMod -> MlamRigg, (LPVEC3) &lpMod -> WP); MAT3eval(&lpMod -> RGB_subw, &lpMod -> MlamRigg, &lpMod -> WP);
#else #else
VEC3divK(&tmp, (LPVEC3) &lpMod -> WP, lpMod->WP.Y); VEC3divK(&tmp, (LPVEC3) &lpMod -> WP, lpMod->WP.Y);
MAT3eval(&lpMod -> RGB_subw, &lpMod -> MlamRigg, &tmp); MAT3eval(&lpMod -> RGB_subw, &lpMod -> MlamRigg, &tmp);

File diff suppressed because it is too large Load Diff

View File

@ -29,7 +29,7 @@
// //
// //
// Little cms // Little cms
// Copyright (C) 1998-2006 Marti Maria // Copyright (C) 1998-2007 Marti Maria
// //
// Permission is hereby granted, free of charge, to any person obtaining // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
@ -256,7 +256,7 @@ void ComputeBlackPointCompensationFactors(LPcmsCIEXYZ BlackPointIn,
// Return TRUE if both m and of are empy -- "m" being identity and "of" being 0 // Return TRUE if both m and of are empy -- "m" being identity and "of" being 0
static static
BOOL IdentityParameters(LPWMAT3 m, LPWVEC3 of) LCMSBOOL IdentityParameters(LPWMAT3 m, LPWVEC3 of)
{ {
WVEC3 wv0; WVEC3 wv0;
@ -661,3 +661,6 @@ int cmsChooseCnvrt(int Absolute,
return rc; return rc;
} }

View File

@ -29,7 +29,7 @@
// //
// //
// Little cms // Little cms
// Copyright (C) 1998-2006 Marti Maria // Copyright (C) 1998-2007 Marti Maria
// //
// Permission is hereby granted, free of charge, to any person obtaining // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
@ -57,6 +57,7 @@
// errors. // errors.
void cdecl cmsSignalError(int ErrorCode, const char *ErrorText, ...); void cdecl cmsSignalError(int ErrorCode, const char *ErrorText, ...);
int LCMSEXPORT cmsErrorAction(int lAbort); int LCMSEXPORT cmsErrorAction(int lAbort);
void LCMSEXPORT cmsSetErrorHandler(cmsErrorHandlerFunction Fn); void LCMSEXPORT cmsSetErrorHandler(cmsErrorHandlerFunction Fn);
@ -96,7 +97,7 @@ void cmsSignalError(int ErrorCode, const char *ErrorText, ...)
char Buffer[1024]; char Buffer[1024];
vsprintf(Buffer, ErrorText, args); vsnprintf(Buffer, 1023, ErrorText, args);
va_end(args); va_end(args);
if (UserErrorHandler(ErrorCode, Buffer)) { if (UserErrorHandler(ErrorCode, Buffer)) {
@ -118,8 +119,8 @@ void cmsSignalError(int ErrorCode, const char *ErrorText, ...)
char Buffer1[1024]; char Buffer1[1024];
char Buffer2[256]; char Buffer2[256];
sprintf(Buffer1, "Error #%x; ", ErrorCode); snprintf(Buffer1, 767, "Error #%x; ", ErrorCode);
vsprintf(Buffer2, ErrorText, args); vsnprintf(Buffer2, 255, ErrorText, args);
strcat(Buffer1, Buffer2); strcat(Buffer1, Buffer2);
MessageBox(NULL, Buffer1, "Little cms", MessageBox(NULL, Buffer1, "Little cms",
MB_OK|MB_ICONSTOP|MB_TASKMODAL); MB_OK|MB_ICONSTOP|MB_TASKMODAL);

View File

@ -29,7 +29,7 @@
// //
// //
// Little cms // Little cms
// Copyright (C) 1998-2006 Marti Maria // Copyright (C) 1998-2007 Marti Maria
// //
// Permission is hereby granted, free of charge, to any person obtaining // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
@ -63,9 +63,9 @@ LPGAMMATABLE LCMSEXPORT cmsReverseGamma(int nResultSamples, LPGAMMATABLE InGamma
LPGAMMATABLE LCMSEXPORT cmsBuildParametricGamma(int nEntries, int Type, double Params[]); LPGAMMATABLE LCMSEXPORT cmsBuildParametricGamma(int nEntries, int Type, double Params[]);
LPGAMMATABLE LCMSEXPORT cmsJoinGamma(LPGAMMATABLE InGamma, LPGAMMATABLE OutGamma); LPGAMMATABLE LCMSEXPORT cmsJoinGamma(LPGAMMATABLE InGamma, LPGAMMATABLE OutGamma);
LPGAMMATABLE LCMSEXPORT cmsJoinGammaEx(LPGAMMATABLE InGamma, LPGAMMATABLE OutGamma, int nPoints); LPGAMMATABLE LCMSEXPORT cmsJoinGammaEx(LPGAMMATABLE InGamma, LPGAMMATABLE OutGamma, int nPoints);
BOOL LCMSEXPORT cmsSmoothGamma(LPGAMMATABLE Tab, double lambda); LCMSBOOL LCMSEXPORT cmsSmoothGamma(LPGAMMATABLE Tab, double lambda);
BOOL cdecl _cmsSmoothEndpoints(LPWORD Table, int nPoints); LCMSBOOL cdecl _cmsSmoothEndpoints(LPWORD Table, int nPoints);
// Sampled curves // Sampled curves
@ -74,7 +74,7 @@ LPSAMPLEDCURVE cdecl cmsAllocSampledCurve(int nItems);
void cdecl cmsFreeSampledCurve(LPSAMPLEDCURVE p); void cdecl cmsFreeSampledCurve(LPSAMPLEDCURVE p);
void cdecl cmsEndpointsOfSampledCurve(LPSAMPLEDCURVE p, double* Min, double* Max); void cdecl cmsEndpointsOfSampledCurve(LPSAMPLEDCURVE p, double* Min, double* Max);
void cdecl cmsClampSampledCurve(LPSAMPLEDCURVE p, double Min, double Max); void cdecl cmsClampSampledCurve(LPSAMPLEDCURVE p, double Min, double Max);
BOOL cdecl cmsSmoothSampledCurve(LPSAMPLEDCURVE Tab, double SmoothingLambda); LCMSBOOL cdecl cmsSmoothSampledCurve(LPSAMPLEDCURVE Tab, double SmoothingLambda);
void cdecl cmsRescaleSampledCurve(LPSAMPLEDCURVE p, double Min, double Max, int nPoints); void cdecl cmsRescaleSampledCurve(LPSAMPLEDCURVE p, double Min, double Max, int nPoints);
LPSAMPLEDCURVE cdecl cmsJoinSampledCurves(LPSAMPLEDCURVE X, LPSAMPLEDCURVE Y, int nResultingPoints); LPSAMPLEDCURVE cdecl cmsJoinSampledCurves(LPSAMPLEDCURVE X, LPSAMPLEDCURVE Y, int nResultingPoints);
@ -84,7 +84,6 @@ double LCMSEXPORT cmsEstimateGammaEx(LPWORD GammaTable, int nEntries, double The
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// #define DEBUG 1
#define MAX_KNOTS 4096 #define MAX_KNOTS 4096
typedef float vec[MAX_KNOTS+1]; typedef float vec[MAX_KNOTS+1];
@ -144,14 +143,14 @@ LPGAMMATABLE LCMSEXPORT cmsAllocGamma(int nEntries)
LPGAMMATABLE p; LPGAMMATABLE p;
size_t size; size_t size;
if (nEntries > 65530) { if (nEntries > 65530 || nEntries <= 0) {
cmsSignalError(LCMS_ERRC_WARNING, "Couldn't create gammatable of more than 65530 entries; 65530 assumed"); cmsSignalError(LCMS_ERRC_ABORTED, "Couldn't create gammatable of more than 65530 entries");
nEntries = 65530; return NULL;
} }
size = sizeof(GAMMATABLE) + (sizeof(WORD) * (nEntries-1)); size = sizeof(GAMMATABLE) + (sizeof(WORD) * (nEntries-1));
p = (LPGAMMATABLE) malloc(size); p = (LPGAMMATABLE) _cmsMalloc(size);
if (!p) return NULL; if (!p) return NULL;
ZeroMemory(p, size); ZeroMemory(p, size);
@ -164,7 +163,7 @@ LPGAMMATABLE LCMSEXPORT cmsAllocGamma(int nEntries)
void LCMSEXPORT cmsFreeGamma(LPGAMMATABLE Gamma) void LCMSEXPORT cmsFreeGamma(LPGAMMATABLE Gamma)
{ {
if (Gamma) free(Gamma); if (Gamma) _cmsFree(Gamma);
} }
@ -278,6 +277,15 @@ LPGAMMATABLE LCMSEXPORT cmsReverseGamma(int nResultSamples, LPGAMMATABLE InGamma
LPWORD InPtr; LPWORD InPtr;
LPGAMMATABLE p; LPGAMMATABLE p;
// Try to reverse it analytically whatever possible
if (InGamma -> Seed.Type > 0 && InGamma -> Seed.Type <= 5 &&
_cmsCrc32OfGammaTable(InGamma) == InGamma -> Seed.Crc32) {
return cmsBuildParametricGamma(nResultSamples, -(InGamma -> Seed.Type), InGamma ->Seed.Params);
}
// Nope, reverse the table
p = cmsAllocGamma(nResultSamples); p = cmsAllocGamma(nResultSamples);
if (!p) return NULL; if (!p) return NULL;
@ -528,7 +536,7 @@ void smooth2(vec w, vec y, vec z, float lambda, int m)
// Smooths a curve sampled at regular intervals // Smooths a curve sampled at regular intervals
BOOL LCMSEXPORT cmsSmoothGamma(LPGAMMATABLE Tab, double lambda) LCMSBOOL LCMSEXPORT cmsSmoothGamma(LPGAMMATABLE Tab, double lambda)
{ {
vec w, y, z; vec w, y, z;
@ -640,13 +648,13 @@ LPSAMPLEDCURVE cmsAllocSampledCurve(int nItems)
{ {
LPSAMPLEDCURVE pOut; LPSAMPLEDCURVE pOut;
pOut = (LPSAMPLEDCURVE) malloc(sizeof(SAMPLEDCURVE)); pOut = (LPSAMPLEDCURVE) _cmsMalloc(sizeof(SAMPLEDCURVE));
if (pOut == NULL) if (pOut == NULL)
return NULL; return NULL;
if((pOut->Values = (double *) malloc(nItems * sizeof(double))) == NULL) if((pOut->Values = (double *) _cmsMalloc(nItems * sizeof(double))) == NULL)
{ {
free(pOut); _cmsFree(pOut);
return NULL; return NULL;
} }
@ -659,8 +667,8 @@ LPSAMPLEDCURVE cmsAllocSampledCurve(int nItems)
void cmsFreeSampledCurve(LPSAMPLEDCURVE p) void cmsFreeSampledCurve(LPSAMPLEDCURVE p)
{ {
free((LPVOID) p -> Values); _cmsFree((LPVOID) p -> Values);
free((LPVOID) p); _cmsFree((LPVOID) p);
} }
@ -731,7 +739,7 @@ void cmsClampSampledCurve(LPSAMPLEDCURVE p, double Min, double Max)
// Smooths a curve sampled at regular intervals // Smooths a curve sampled at regular intervals
BOOL cmsSmoothSampledCurve(LPSAMPLEDCURVE Tab, double lambda) LCMSBOOL cmsSmoothSampledCurve(LPSAMPLEDCURVE Tab, double lambda)
{ {
vec w, y, z; vec w, y, z;
int i, nItems; int i, nItems;
@ -915,14 +923,11 @@ LPSAMPLEDCURVE cmsConvertGammaToSampledCurve(LPGAMMATABLE Gamma, int nPoints)
// Smooth endpoints (used in Black/White compensation) // Smooth endpoints (used in Black/White compensation)
BOOL _cmsSmoothEndpoints(LPWORD Table, int nEntries) LCMSBOOL _cmsSmoothEndpoints(LPWORD Table, int nEntries)
{ {
vec w, y, z; vec w, y, z;
int i, Zeros, Poles; int i, Zeros, Poles;
#ifdef DEBUG
ASAVE(Table, nEntries, "nonsmt.txt");
#endif
if (cmsIsLinear(Table, nEntries)) return FALSE; // Nothing to do if (cmsIsLinear(Table, nEntries)) return FALSE; // Nothing to do

View File

@ -29,7 +29,7 @@
// //
// //
// Little cms // Little cms
// Copyright (C) 1998-2006 Marti Maria // Copyright (C) 1998-2007 Marti Maria
// //
// Permission is hereby granted, free of charge, to any person obtaining // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
@ -66,7 +66,7 @@ to use highlights, then it will be lost.
*/ */
BOOL _cmsEndPointsBySpace(icColorSpaceSignature Space, WORD **White, WORD **Black, LCMSBOOL _cmsEndPointsBySpace(icColorSpaceSignature Space, WORD **White, WORD **Black,
int *nOutputs) int *nOutputs)
{ {
// Only most common spaces // Only most common spaces
@ -376,7 +376,6 @@ double LCMSEXPORT cmsCIE2000DeltaE(LPcmsCIELab Lab1, LPcmsCIELab Lab2,
double bs = Lab2 ->b; double bs = Lab2 ->b;
double Cs = sqrt( Sqr(as) + Sqr(bs) ); double Cs = sqrt( Sqr(as) + Sqr(bs) );
double G = 0.5 * ( 1 - sqrt(pow((C + Cs) / 2 , 7.0) / (pow((C + Cs) / 2, 7.0) + pow(25.0, 7.0) ) )); double G = 0.5 * ( 1 - sqrt(pow((C + Cs) / 2 , 7.0) / (pow((C + Cs) / 2, 7.0) + pow(25.0, 7.0) ) ));
double a_p = (1 + G ) * a1; double a_p = (1 + G ) * a1;
@ -390,15 +389,21 @@ double LCMSEXPORT cmsCIE2000DeltaE(LPcmsCIELab Lab1, LPcmsCIELab Lab2,
double C_ps = sqrt(Sqr(a_ps) + Sqr(b_ps)); double C_ps = sqrt(Sqr(a_ps) + Sqr(b_ps));
double h_ps = atan2deg(a_ps, b_ps); double h_ps = atan2deg(a_ps, b_ps);
double meanC_p =(C_p + C_ps) / 2; double meanC_p =(C_p + C_ps) / 2;
double meanh_p = fabs(h_ps-h_p) <= 180 ? (h_ps + h_p)/2 : (h_ps+h_p-360)/2; double hps_plus_hp = h_ps + h_p;
double hps_minus_hp = h_ps - h_p;
double meanh_p = fabs(hps_minus_hp) <= 180.000001 ? (hps_plus_hp)/2 :
(hps_plus_hp) < 360 ? (hps_plus_hp + 360)/2 :
(hps_plus_hp - 360)/2;
double delta_h = (hps_minus_hp) <= -180.000001 ? (hps_minus_hp + 360) :
(hps_minus_hp) > 180 ? (hps_minus_hp - 360) :
(hps_minus_hp);
double delta_L = (Ls - L1);
double delta_C = (C_ps - C_p );
double delta_h = fabs(h_p - h_ps) <= 180 ? fabs(h_p - h_ps) : 360 - fabs(h_p - h_ps);
double delta_L = fabs(L1 - Ls);
double delta_C = fabs(C_p - C_ps);
double delta_H =2 * sqrt(C_ps*C_p) * sin(RADIANES(delta_h) / 2); double delta_H =2 * sqrt(C_ps*C_p) * sin(RADIANES(delta_h) / 2);
@ -1065,7 +1070,7 @@ void SlopeLimiting(WORD Table[], int nEntries)
// Check for monotonicity. // Check for monotonicity.
static static
BOOL IsMonotonic(LPGAMMATABLE t) LCMSBOOL IsMonotonic(LPGAMMATABLE t)
{ {
int n = t -> nEntries; int n = t -> nEntries;
int i, last; int i, last;
@ -1088,7 +1093,7 @@ BOOL IsMonotonic(LPGAMMATABLE t)
// Check for endpoints // Check for endpoints
static static
BOOL HasProperEndpoints(LPGAMMATABLE t) LCMSBOOL HasProperEndpoints(LPGAMMATABLE t)
{ {
if (t ->GammaTable[0] != 0) return FALSE; if (t ->GammaTable[0] != 0) return FALSE;
if (t ->GammaTable[t ->nEntries-1] != 0xFFFF) return FALSE; if (t ->GammaTable[t ->nEntries-1] != 0xFFFF) return FALSE;
@ -1109,7 +1114,7 @@ void _cmsComputePrelinearizationTablesFromXFORM(cmsHTRANSFORM h[], int nTransfor
unsigned int t, i, v; unsigned int t, i, v;
int j; int j;
WORD In[MAXCHANNELS], Out[MAXCHANNELS]; WORD In[MAXCHANNELS], Out[MAXCHANNELS];
BOOL lIsSuitable; LCMSBOOL lIsSuitable;
_LPcmsTRANSFORM InputXForm = (_LPcmsTRANSFORM) h[0]; _LPcmsTRANSFORM InputXForm = (_LPcmsTRANSFORM) h[0];
_LPcmsTRANSFORM OutputXForm = (_LPcmsTRANSFORM) h[nTransforms-1]; _LPcmsTRANSFORM OutputXForm = (_LPcmsTRANSFORM) h[nTransforms-1];
@ -1126,10 +1131,10 @@ void _cmsComputePrelinearizationTablesFromXFORM(cmsHTRANSFORM h[], int nTransfor
} }
// Do nothing on all but RGB to RGB transforms // Do nothing on all but Gray/RGB to Gray/RGB transforms
if ((InputXForm ->EntryColorSpace != icSigRgbData) || if (((InputXForm ->EntryColorSpace != icSigRgbData) && (InputXForm ->EntryColorSpace != icSigGrayData)) ||
(OutputXForm->ExitColorSpace != icSigRgbData)) return; ((OutputXForm->ExitColorSpace != icSigRgbData) && (OutputXForm->ExitColorSpace != icSigGrayData))) return;
for (t = 0; t < Grid -> InputChan; t++) for (t = 0; t < Grid -> InputChan; t++)
@ -1169,10 +1174,13 @@ void _cmsComputePrelinearizationTablesFromXFORM(cmsHTRANSFORM h[], int nTransfor
if (!HasProperEndpoints(Trans[t])) if (!HasProperEndpoints(Trans[t]))
lIsSuitable = FALSE; lIsSuitable = FALSE;
/*
// Exclude if transfer function is not smooth enough // Exclude if transfer function is not smooth enough
// to be modelled as a gamma function, or the gamma is reversed // to be modelled as a gamma function, or the gamma is reversed
if (cmsEstimateGamma(Trans[t]) < 1.0) if (cmsEstimateGamma(Trans[t]) < 1.0)
lIsSuitable = FALSE; lIsSuitable = FALSE;
*/
} }

View File

@ -29,7 +29,7 @@
// //
// //
// Little cms // Little cms
// Copyright (C) 1998-2006 Marti Maria // Copyright (C) 1998-2007 Marti Maria
// //
// Permission is hereby granted, free of charge, to any person obtaining // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
@ -282,7 +282,7 @@ void Eval8Inputs(WORD StageABC[], WORD StageLMN[], WORD LutTable[], LPL16PARAMS
// Fills optimization parameters // Fills optimization parameters
void cmsCalcCLUT16ParamsEx(int nSamples, int InputChan, int OutputChan, void cmsCalcCLUT16ParamsEx(int nSamples, int InputChan, int OutputChan,
BOOL lUseTetrahedral, LPL16PARAMS p) LCMSBOOL lUseTetrahedral, LPL16PARAMS p)
{ {
int clutPoints; int clutPoints;
@ -579,7 +579,7 @@ WORD cmsReverseLinearInterpLUT16(WORD Value, WORD LutTable[], LPL16PARAMS p)
// Identify if value fall downto 0 or FFFF zone // Identify if value fall downto 0 or FFFF zone
if (Value == 0) return 0; if (Value == 0) return 0;
if (Value == 0xFFFF) return 0xFFFF; // if (Value == 0xFFFF) return 0xFFFF;
// else restrict to valid zone // else restrict to valid zone
@ -631,7 +631,7 @@ WORD cmsReverseLinearInterpLUT16(WORD Value, WORD LutTable[], LPL16PARAMS p)
a = (y1 - y0) / (x1 - x0); a = (y1 - y0) / (x1 - x0);
b = y0 - a * x0; b = y0 - a * x0;
if (a == 0) return (WORD) x; if (fabs(a) < 0.01) return (WORD) x;
f = ((Value - b) / a); f = ((Value - b) / a);
@ -1131,3 +1131,4 @@ void cmsTetrahedralInterp8(WORD Input[],
} }
#undef DENS #undef DENS

View File

@ -29,7 +29,7 @@
// //
// //
// Little cms // Little cms
// Copyright (C) 1998-2006 Marti Maria // Copyright (C) 1998-2007 Marti Maria
// //
// Permission is hereby granted, free of charge, to any person obtaining // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
@ -62,7 +62,7 @@
typedef struct { typedef struct {
LPBYTE Block; // Points to allocated memory LPBYTE Block; // Points to allocated memory
size_t Size; // Size of allocated memory size_t Size; // Size of allocated memory
int Pointer; // Points to current location size_t Pointer; // Points to current location
int FreeBlockOnClose; // As title int FreeBlockOnClose; // As title
} FILEMEM; } FILEMEM;
@ -70,18 +70,19 @@ typedef struct {
static static
LPVOID MemoryOpen(LPBYTE Block, size_t Size, char Mode) LPVOID MemoryOpen(LPBYTE Block, size_t Size, char Mode)
{ {
FILEMEM* fm = (FILEMEM*) malloc(sizeof(FILEMEM)); FILEMEM* fm = (FILEMEM*) _cmsMalloc(sizeof(FILEMEM));
if (fm == NULL) return NULL;
ZeroMemory(fm, sizeof(FILEMEM)); ZeroMemory(fm, sizeof(FILEMEM));
if (Mode == 'r') { if (Mode == 'r') {
fm ->Block = (LPBYTE) malloc(Size); fm ->Block = (LPBYTE) _cmsMalloc(Size);
if (fm ->Block == NULL) { if (fm ->Block == NULL) {
free(fm); _cmsFree(fm);
return NULL; return NULL;
} }
CopyMemory(fm->Block, Block, Size); CopyMemory(fm->Block, Block, Size);
fm ->FreeBlockOnClose = TRUE; fm ->FreeBlockOnClose = TRUE;
} }
@ -103,13 +104,27 @@ size_t MemoryRead(LPVOID buffer, size_t size, size_t count, struct _lcms_iccprof
FILEMEM* ResData = (FILEMEM*) Icc ->stream; FILEMEM* ResData = (FILEMEM*) Icc ->stream;
LPBYTE Ptr; LPBYTE Ptr;
size_t len = size * count; size_t len = size * count;
size_t extent = ResData -> Pointer + len;
if (len == 0) {
return 0;
}
if (ResData -> Pointer + len > ResData -> Size){ if (len / size != count) {
cmsSignalError(LCMS_ERRC_ABORTED, "Read from memory error. Integer overflow with count / size.");
return 0;
}
if (extent < len || extent < ResData -> Pointer) {
cmsSignalError(LCMS_ERRC_ABORTED, "Read from memory error. Integer overflow with len.");
return 0;
}
if (ResData -> Pointer + len > ResData -> Size) {
len = (ResData -> Size - ResData -> Pointer); len = (ResData -> Size - ResData -> Pointer);
cmsSignalError(LCMS_ERRC_WARNING, "Read from memory error. Got %d bytes, block should be of %d bytes", len * size, count * size); cmsSignalError(LCMS_ERRC_ABORTED, "Read from memory error. Got %d bytes, block should be of %d bytes", len * size, count * size);
return 0;
} }
Ptr = ResData -> Block; Ptr = ResData -> Block;
@ -123,7 +138,7 @@ size_t MemoryRead(LPVOID buffer, size_t size, size_t count, struct _lcms_iccprof
// SEEK_CUR is assumed // SEEK_CUR is assumed
static static
BOOL MemorySeek(struct _lcms_iccprofile_struct* Icc, size_t offset) LCMSBOOL MemorySeek(struct _lcms_iccprofile_struct* Icc, size_t offset)
{ {
FILEMEM* ResData = (FILEMEM*) Icc ->stream; FILEMEM* ResData = (FILEMEM*) Icc ->stream;
@ -147,10 +162,10 @@ size_t MemoryTell(struct _lcms_iccprofile_struct* Icc)
} }
// Writes data to memory, also keeps used space for further reference // Writes data to memory, also keeps used space for further reference. NO CHECK IS PERFORMED
static static
BOOL MemoryWrite(struct _lcms_iccprofile_struct* Icc, size_t size, void *Ptr) LCMSBOOL MemoryWrite(struct _lcms_iccprofile_struct* Icc, size_t size, void *Ptr)
{ {
FILEMEM* ResData = (FILEMEM*) Icc ->stream; FILEMEM* ResData = (FILEMEM*) Icc ->stream;
@ -167,11 +182,17 @@ BOOL MemoryWrite(struct _lcms_iccprofile_struct* Icc, size_t size, void *Ptr)
static static
BOOL MemoryGrow(struct _lcms_iccprofile_struct* Icc, size_t size) LCMSBOOL MemoryGrow(struct _lcms_iccprofile_struct* Icc, size_t size)
{ {
FILEMEM* ResData = (FILEMEM*) Icc->stream; FILEMEM* ResData = (FILEMEM*) Icc->stream;
void* newBlock = realloc(ResData->Block, ResData->Size + size); void* newBlock = NULL;
/* Follow same policies as functions in lcms.h */
if (ResData->Size + size < 0) return NULL;
if (ResData->Size + size > (size_t)1024*1024*500))) return NULL;
newBlock = realloc(ResData->Block, ResData->Size + size);
if (!newBlock) { if (!newBlock) {
return FALSE; return FALSE;
@ -183,15 +204,15 @@ BOOL MemoryGrow(struct _lcms_iccprofile_struct* Icc, size_t size)
static static
BOOL MemoryClose(struct _lcms_iccprofile_struct* Icc) LCMSBOOL MemoryClose(struct _lcms_iccprofile_struct* Icc)
{ {
FILEMEM* ResData = (FILEMEM*) Icc ->stream; FILEMEM* ResData = (FILEMEM*) Icc ->stream;
if (ResData ->FreeBlockOnClose) { if (ResData ->FreeBlockOnClose) {
if (ResData ->Block) free(ResData ->Block); if (ResData ->Block) _cmsFree(ResData ->Block);
} }
free(ResData); _cmsFree(ResData);
return 0; return 0;
} }
@ -209,7 +230,7 @@ size_t FileRead(void *buffer, size_t size, size_t count, struct _lcms_iccprofile
{ {
size_t nReaded = fread(buffer, size, count, (FILE*) Icc->stream); size_t nReaded = fread(buffer, size, count, (FILE*) Icc->stream);
if (nReaded != count) { if (nReaded != count) {
cmsSignalError(LCMS_ERRC_WARNING, "Read error. Got %d bytes, block should be of %d bytes", nReaded * size, count * size); cmsSignalError(LCMS_ERRC_ABORTED, "Read error. Got %d bytes, block should be of %d bytes", nReaded * size, count * size);
return 0; return 0;
} }
@ -218,7 +239,7 @@ size_t FileRead(void *buffer, size_t size, size_t count, struct _lcms_iccprofile
static static
BOOL FileSeek(struct _lcms_iccprofile_struct* Icc, size_t offset) LCMSBOOL FileSeek(struct _lcms_iccprofile_struct* Icc, size_t offset)
{ {
if (fseek((FILE*) Icc ->stream, (long) offset, SEEK_SET) != 0) { if (fseek((FILE*) Icc ->stream, (long) offset, SEEK_SET) != 0) {
@ -240,7 +261,7 @@ size_t FileTell(struct _lcms_iccprofile_struct* Icc)
static static
BOOL FileWrite(struct _lcms_iccprofile_struct* Icc, size_t size, LPVOID Ptr) LCMSBOOL FileWrite(struct _lcms_iccprofile_struct* Icc, size_t size, LPVOID Ptr)
{ {
if (size == 0) return TRUE; if (size == 0) return TRUE;
@ -256,14 +277,14 @@ BOOL FileWrite(struct _lcms_iccprofile_struct* Icc, size_t size, LPVOID Ptr)
static static
BOOL FileGrow(struct _lcms_iccprofile_struct* Icc, size_t size) LCMSBOOL FileGrow(struct _lcms_iccprofile_struct* Icc, size_t size)
{ {
return TRUE; return TRUE;
} }
static static
BOOL FileClose(struct _lcms_iccprofile_struct* Icc) LCMSBOOL FileClose(struct _lcms_iccprofile_struct* Icc)
{ {
return fclose((FILE*) Icc ->stream); return fclose((FILE*) Icc ->stream);
} }
@ -276,7 +297,7 @@ BOOL FileClose(struct _lcms_iccprofile_struct* Icc)
cmsHPROFILE _cmsCreateProfilePlaceholder(void) cmsHPROFILE _cmsCreateProfilePlaceholder(void)
{ {
LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) malloc(sizeof(LCMSICCPROFILE)); LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) _cmsMalloc(sizeof(LCMSICCPROFILE));
if (Icc == NULL) return NULL; if (Icc == NULL) return NULL;
// Empty values // Empty values
@ -314,7 +335,7 @@ icTagSignature LCMSEXPORT cmsGetTagSignature(cmsHPROFILE hProfile, icInt32Number
// Search for a specific tag in tag dictionary // Search for a specific tag in tag dictionary
// Returns position or -1 if tag not found // Returns position or -1 if tag not found
icInt32Number _cmsSearchTag(LPLCMSICCPROFILE Profile, icTagSignature sig, BOOL lSignalError) icInt32Number _cmsSearchTag(LPLCMSICCPROFILE Profile, icTagSignature sig, LCMSBOOL lSignalError)
{ {
icInt32Number i; icInt32Number i;
@ -335,7 +356,7 @@ icInt32Number _cmsSearchTag(LPLCMSICCPROFILE Profile, icTagSignature sig, BOOL l
// Check existance // Check existance
BOOL LCMSEXPORT cmsIsTag(cmsHPROFILE hProfile, icTagSignature sig) LCMSBOOL LCMSEXPORT cmsIsTag(cmsHPROFILE hProfile, icTagSignature sig)
{ {
LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile; LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
return _cmsSearchTag(Icc, sig, FALSE) >= 0; return _cmsSearchTag(Icc, sig, FALSE) >= 0;
@ -354,7 +375,7 @@ LPVOID _cmsInitTag(LPLCMSICCPROFILE Icc, icTagSignature sig, size_t size, const
if (i >=0) { if (i >=0) {
if (Icc -> TagPtrs[i]) free(Icc -> TagPtrs[i]); if (Icc -> TagPtrs[i]) _cmsFree(Icc -> TagPtrs[i]);
} }
else { else {
@ -365,11 +386,14 @@ LPVOID _cmsInitTag(LPLCMSICCPROFILE Icc, icTagSignature sig, size_t size, const
cmsSignalError(LCMS_ERRC_ABORTED, "Too many tags (%d)", MAX_TABLE_TAG); cmsSignalError(LCMS_ERRC_ABORTED, "Too many tags (%d)", MAX_TABLE_TAG);
Icc ->TagCount = MAX_TABLE_TAG-1; Icc ->TagCount = MAX_TABLE_TAG-1;
return NULL;
} }
} }
Ptr = malloc(size); Ptr = _cmsMalloc(size);
if (Ptr == NULL) return NULL;
CopyMemory(Ptr, Init, size); CopyMemory(Ptr, Init, size);
Icc ->TagNames[i] = sig; Icc ->TagNames[i] = sig;
@ -400,6 +424,8 @@ LPLCMSICCPROFILE _cmsCreateProfileFromFilePlaceholder(const char* FileName)
if (NewIcc == NULL) return NULL; if (NewIcc == NULL) return NULL;
strncpy(NewIcc -> PhysicalFile, FileName, MAX_PATH-1); strncpy(NewIcc -> PhysicalFile, FileName, MAX_PATH-1);
NewIcc -> PhysicalFile[MAX_PATH-1] = 0;
NewIcc ->stream = ICCfile; NewIcc ->stream = ICCfile;
NewIcc ->Read = FileRead; NewIcc ->Read = FileRead;
@ -502,7 +528,7 @@ void _cmsSetSaveToMemory(LPLCMSICCPROFILE Icc, LPVOID MemPtr, size_t dwSize)
BOOL LCMSEXPORT cmsTakeMediaWhitePoint(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile) LCMSBOOL LCMSEXPORT cmsTakeMediaWhitePoint(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile)
{ {
LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) hProfile; LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) hProfile;
*Dest = Icc -> MediaWhitePoint; *Dest = Icc -> MediaWhitePoint;
@ -510,14 +536,14 @@ BOOL LCMSEXPORT cmsTakeMediaWhitePoint(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile)
} }
BOOL LCMSEXPORT cmsTakeMediaBlackPoint(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile) LCMSBOOL LCMSEXPORT cmsTakeMediaBlackPoint(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile)
{ {
LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) hProfile; LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) hProfile;
*Dest = Icc -> MediaBlackPoint; *Dest = Icc -> MediaBlackPoint;
return TRUE; return TRUE;
} }
BOOL LCMSEXPORT cmsTakeIluminant(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile) LCMSBOOL LCMSEXPORT cmsTakeIluminant(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile)
{ {
LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) hProfile; LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) hProfile;
*Dest = Icc -> Illuminant; *Dest = Icc -> Illuminant;
@ -575,7 +601,7 @@ void LCMSEXPORT cmsSetProfileID(cmsHPROFILE hProfile, LPBYTE ProfileID)
} }
BOOL LCMSEXPORT cmsTakeCreationDateTime(struct tm *Dest, cmsHPROFILE hProfile) LCMSBOOL LCMSEXPORT cmsTakeCreationDateTime(struct tm *Dest, cmsHPROFILE hProfile)
{ {
LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile; LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
CopyMemory(Dest, &Icc ->Created, sizeof(struct tm)); CopyMemory(Dest, &Icc ->Created, sizeof(struct tm));
@ -596,23 +622,18 @@ void LCMSEXPORT cmsSetPCS(cmsHPROFILE hProfile, icColorSpaceSignature pcs)
Icc -> PCS = pcs; Icc -> PCS = pcs;
} }
icColorSpaceSignature LCMSEXPORT cmsGetColorSpace(cmsHPROFILE hProfile) icColorSpaceSignature LCMSEXPORT cmsGetColorSpace(cmsHPROFILE hProfile)
{ {
LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) hProfile; LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) hProfile;
return Icc -> ColorSpace; return Icc -> ColorSpace;
} }
void LCMSEXPORT cmsSetColorSpace(cmsHPROFILE hProfile, icColorSpaceSignature sig) void LCMSEXPORT cmsSetColorSpace(cmsHPROFILE hProfile, icColorSpaceSignature sig)
{ {
LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) hProfile; LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) hProfile;
Icc -> ColorSpace = sig; Icc -> ColorSpace = sig;
} }
icProfileClassSignature LCMSEXPORT cmsGetDeviceClass(cmsHPROFILE hProfile) icProfileClassSignature LCMSEXPORT cmsGetDeviceClass(cmsHPROFILE hProfile)
{ {
LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) hProfile; LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) hProfile;
@ -625,7 +646,6 @@ DWORD LCMSEXPORT cmsGetProfileICCversion(cmsHPROFILE hProfile)
return (DWORD) Icc -> Version; return (DWORD) Icc -> Version;
} }
void LCMSEXPORT cmsSetProfileICCversion(cmsHPROFILE hProfile, DWORD Version) void LCMSEXPORT cmsSetProfileICCversion(cmsHPROFILE hProfile, DWORD Version)
{ {
LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) hProfile; LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) hProfile;
@ -664,7 +684,7 @@ LPVOID DupBlock(LPLCMSICCPROFILE Icc, LPVOID Block, size_t size)
// This is tricky, since LUT structs does have pointers // This is tricky, since LUT structs does have pointers
BOOL LCMSEXPORT _cmsAddLUTTag(cmsHPROFILE hProfile, icTagSignature sig, const void* lut) LCMSBOOL LCMSEXPORT _cmsAddLUTTag(cmsHPROFILE hProfile, icTagSignature sig, const void* lut)
{ {
LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile; LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
LPLUT Orig, Stored; LPLUT Orig, Stored;
@ -692,7 +712,7 @@ BOOL LCMSEXPORT _cmsAddLUTTag(cmsHPROFILE hProfile, icTagSignature sig, const vo
} }
BOOL LCMSEXPORT _cmsAddXYZTag(cmsHPROFILE hProfile, icTagSignature sig, const cmsCIEXYZ* XYZ) LCMSBOOL LCMSEXPORT _cmsAddXYZTag(cmsHPROFILE hProfile, icTagSignature sig, const cmsCIEXYZ* XYZ)
{ {
LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile; LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
@ -701,7 +721,7 @@ BOOL LCMSEXPORT _cmsAddXYZTag(cmsHPROFILE hProfile, icTagSignature sig, const cm
} }
BOOL LCMSEXPORT _cmsAddTextTag(cmsHPROFILE hProfile, icTagSignature sig, const char* Text) LCMSBOOL LCMSEXPORT _cmsAddTextTag(cmsHPROFILE hProfile, icTagSignature sig, const char* Text)
{ {
LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile; LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
@ -709,7 +729,7 @@ BOOL LCMSEXPORT _cmsAddTextTag(cmsHPROFILE hProfile, icTagSignature sig, const c
return TRUE; return TRUE;
} }
BOOL LCMSEXPORT _cmsAddGammaTag(cmsHPROFILE hProfile, icTagSignature sig, LPGAMMATABLE TransferFunction) LCMSBOOL LCMSEXPORT _cmsAddGammaTag(cmsHPROFILE hProfile, icTagSignature sig, LPGAMMATABLE TransferFunction)
{ {
LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile; LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
@ -718,7 +738,7 @@ BOOL LCMSEXPORT _cmsAddGammaTag(cmsHPROFILE hProfile, icTagSignature sig, LPGAMM
} }
BOOL LCMSEXPORT _cmsAddChromaticityTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsCIExyYTRIPLE Chrm) LCMSBOOL LCMSEXPORT _cmsAddChromaticityTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsCIExyYTRIPLE Chrm)
{ {
LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile; LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
@ -727,7 +747,7 @@ BOOL LCMSEXPORT _cmsAddChromaticityTag(cmsHPROFILE hProfile, icTagSignature sig,
} }
BOOL LCMSEXPORT _cmsAddSequenceDescriptionTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsSEQ pseq) LCMSBOOL LCMSEXPORT _cmsAddSequenceDescriptionTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsSEQ pseq)
{ {
LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile; LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
@ -737,28 +757,40 @@ BOOL LCMSEXPORT _cmsAddSequenceDescriptionTag(cmsHPROFILE hProfile, icTagSignatu
} }
BOOL LCMSEXPORT _cmsAddNamedColorTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsNAMEDCOLORLIST nc) LCMSBOOL LCMSEXPORT _cmsAddNamedColorTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsNAMEDCOLORLIST nc)
{ {
LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile; LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
_cmsInitTag(Icc, sig, sizeof(cmsNAMEDCOLORLIST) + (nc ->nColors - 1) * sizeof(cmsNAMEDCOLOR), nc); _cmsInitTag(Icc, sig, sizeof(cmsNAMEDCOLORLIST) + (nc ->nColors - 1) * sizeof(cmsNAMEDCOLOR), nc);
return FALSE; return TRUE;
} }
BOOL LCMSEXPORT _cmsAddDateTimeTag(cmsHPROFILE hProfile, icTagSignature sig, struct tm *DateTime) LCMSBOOL LCMSEXPORT _cmsAddDateTimeTag(cmsHPROFILE hProfile, icTagSignature sig, struct tm *DateTime)
{ {
LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile; LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
_cmsInitTag(Icc, sig, sizeof(struct tm), DateTime); _cmsInitTag(Icc, sig, sizeof(struct tm), DateTime);
return FALSE; return TRUE;
} }
BOOL LCMSEXPORT _cmsAddColorantTableTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsNAMEDCOLORLIST nc) LCMSBOOL LCMSEXPORT _cmsAddColorantTableTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsNAMEDCOLORLIST nc)
{ {
LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile; LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
_cmsInitTag(Icc, sig, sizeof(cmsNAMEDCOLORLIST) + (nc ->nColors - 1) * sizeof(cmsNAMEDCOLOR), nc); _cmsInitTag(Icc, sig, sizeof(cmsNAMEDCOLORLIST) + (nc ->nColors - 1) * sizeof(cmsNAMEDCOLOR), nc);
return FALSE; return TRUE;
} }
LCMSBOOL LCMSEXPORT _cmsAddChromaticAdaptationTag(cmsHPROFILE hProfile, icTagSignature sig, const cmsCIEXYZ* mat)
{
LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
_cmsInitTag(Icc, sig, 3*sizeof(cmsCIEXYZ), mat);
return TRUE;
}

File diff suppressed because it is too large Load Diff

View File

@ -29,7 +29,7 @@
// //
// //
// Little cms // Little cms
// Copyright (C) 1998-2006 Marti Maria // Copyright (C) 1998-2007 Marti Maria
// //
// Permission is hereby granted, free of charge, to any person obtaining // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
@ -118,7 +118,7 @@ LPLUT LCMSEXPORT cmsAllocLUT(void)
{ {
LPLUT NewLUT; LPLUT NewLUT;
NewLUT = (LPLUT) malloc(sizeof(LUT)); NewLUT = (LPLUT) _cmsMalloc(sizeof(LUT));
if (NewLUT) if (NewLUT)
ZeroMemory(NewLUT, sizeof(LUT)); ZeroMemory(NewLUT, sizeof(LUT));
@ -171,9 +171,10 @@ void LCMSEXPORT cmsFreeLUT(LPLUT Lut)
static static
LPVOID DupBlockTab(LPVOID Org, size_t size) LPVOID DupBlockTab(LPVOID Org, size_t size)
{ {
LPVOID mem = malloc(size); LPVOID mem = _cmsMalloc(size);
if (mem != NULL)
CopyMemory(mem, Org, size); CopyMemory(mem, Org, size);
return mem; return mem;
} }
@ -211,6 +212,37 @@ unsigned int UIpow(unsigned int a, unsigned int b)
} }
LCMSBOOL _cmsValidateLUT(LPLUT NewLUT)
{
unsigned int calc = 1;
unsigned int oldCalc;
unsigned int power = NewLUT -> InputChan;
if (NewLUT -> cLutPoints > 100) return FALSE;
if (NewLUT -> InputChan > MAXCHANNELS) return FALSE;
if (NewLUT -> OutputChan > MAXCHANNELS) return FALSE;
if (NewLUT -> cLutPoints == 0) return TRUE;
for (; power > 0; power--) {
oldCalc = calc;
calc *= NewLUT -> cLutPoints;
if (calc / NewLUT -> cLutPoints != oldCalc) {
return FALSE;
}
}
oldCalc = calc;
calc *= NewLUT -> OutputChan;
if (NewLUT -> OutputChan && calc / NewLUT -> OutputChan != oldCalc) {
return FALSE;
}
return TRUE;
}
LPLUT LCMSEXPORT cmsAlloc3DGrid(LPLUT NewLUT, int clutPoints, int inputChan, int outputChan) LPLUT LCMSEXPORT cmsAlloc3DGrid(LPLUT NewLUT, int clutPoints, int inputChan, int outputChan)
{ {
DWORD nTabSize; DWORD nTabSize;
@ -220,12 +252,17 @@ LPLUT LCMSEXPORT cmsAlloc3DGrid(LPLUT NewLUT, int clutPoints, int inputChan, int
NewLUT -> InputChan = inputChan; NewLUT -> InputChan = inputChan;
NewLUT -> OutputChan = outputChan; NewLUT -> OutputChan = outputChan;
if (!_cmsValidateLUT(NewLUT)) {
return NULL;
}
nTabSize = (NewLUT -> OutputChan * UIpow(NewLUT->cLutPoints, nTabSize = NewLUT -> OutputChan * UIpow(NewLUT->cLutPoints,
NewLUT->InputChan) NewLUT->InputChan);
* sizeof(WORD));
NewLUT -> T = (LPWORD) _cmsCalloc(sizeof(WORD), nTabSize);
nTabSize *= sizeof(WORD);
if (NewLUT -> T == NULL) return NULL;
NewLUT -> T = (LPWORD) malloc(nTabSize);
ZeroMemory(NewLUT -> T, nTabSize); ZeroMemory(NewLUT -> T, nTabSize);
NewLUT ->Tsize = nTabSize; NewLUT ->Tsize = nTabSize;
@ -254,7 +291,9 @@ LPLUT LCMSEXPORT cmsAllocLinearTable(LPLUT NewLUT, LPGAMMATABLE Tables[], int nT
for (i=0; i < NewLUT -> InputChan; i++) { for (i=0; i < NewLUT -> InputChan; i++) {
PtrW = (LPWORD) malloc(sizeof(WORD) * NewLUT -> InputEntries); PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * NewLUT -> InputEntries);
if (PtrW == NULL) return NULL;
NewLUT -> L1[i] = PtrW; NewLUT -> L1[i] = PtrW;
CopyMemory(PtrW, Tables[i]->GammaTable, sizeof(WORD) * NewLUT -> InputEntries); CopyMemory(PtrW, Tables[i]->GammaTable, sizeof(WORD) * NewLUT -> InputEntries);
CopyMemory(&NewLUT -> LCurvesSeed[0][i], &Tables[i] -> Seed, sizeof(LCMSGAMMAPARAMS)); CopyMemory(&NewLUT -> LCurvesSeed[0][i], &Tables[i] -> Seed, sizeof(LCMSGAMMAPARAMS));
@ -268,7 +307,9 @@ LPLUT LCMSEXPORT cmsAllocLinearTable(LPLUT NewLUT, LPGAMMATABLE Tables[], int nT
NewLUT -> OutputEntries = Tables[0] -> nEntries; NewLUT -> OutputEntries = Tables[0] -> nEntries;
for (i=0; i < NewLUT -> OutputChan; i++) { for (i=0; i < NewLUT -> OutputChan; i++) {
PtrW = (LPWORD) malloc(sizeof(WORD) * NewLUT -> OutputEntries); PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * NewLUT -> OutputEntries);
if (PtrW == NULL) return NULL;
NewLUT -> L2[i] = PtrW; NewLUT -> L2[i] = PtrW;
CopyMemory(PtrW, Tables[i]->GammaTable, sizeof(WORD) * NewLUT -> OutputEntries); CopyMemory(PtrW, Tables[i]->GammaTable, sizeof(WORD) * NewLUT -> OutputEntries);
CopyMemory(&NewLUT -> LCurvesSeed[1][i], &Tables[i] -> Seed, sizeof(LCMSGAMMAPARAMS)); CopyMemory(&NewLUT -> LCurvesSeed[1][i], &Tables[i] -> Seed, sizeof(LCMSGAMMAPARAMS));
@ -285,7 +326,9 @@ LPLUT LCMSEXPORT cmsAllocLinearTable(LPLUT NewLUT, LPGAMMATABLE Tables[], int nT
for (i=0; i < NewLUT -> InputChan; i++) { for (i=0; i < NewLUT -> InputChan; i++) {
PtrW = (LPWORD) malloc(sizeof(WORD) * NewLUT -> L3Entries); PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * NewLUT -> L3Entries);
if (PtrW == NULL) return NULL;
NewLUT -> L3[i] = PtrW; NewLUT -> L3[i] = PtrW;
CopyMemory(PtrW, Tables[i]->GammaTable, sizeof(WORD) * NewLUT -> L3Entries); CopyMemory(PtrW, Tables[i]->GammaTable, sizeof(WORD) * NewLUT -> L3Entries);
CopyMemory(&NewLUT -> LCurvesSeed[2][i], &Tables[i] -> Seed, sizeof(LCMSGAMMAPARAMS)); CopyMemory(&NewLUT -> LCurvesSeed[2][i], &Tables[i] -> Seed, sizeof(LCMSGAMMAPARAMS));
@ -298,7 +341,9 @@ LPLUT LCMSEXPORT cmsAllocLinearTable(LPLUT NewLUT, LPGAMMATABLE Tables[], int nT
NewLUT -> L4Entries = Tables[0] -> nEntries; NewLUT -> L4Entries = Tables[0] -> nEntries;
for (i=0; i < NewLUT -> OutputChan; i++) { for (i=0; i < NewLUT -> OutputChan; i++) {
PtrW = (LPWORD) malloc(sizeof(WORD) * NewLUT -> L4Entries); PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * NewLUT -> L4Entries);
if (PtrW == NULL) return NULL;
NewLUT -> L4[i] = PtrW; NewLUT -> L4[i] = PtrW;
CopyMemory(PtrW, Tables[i]->GammaTable, sizeof(WORD) * NewLUT -> L4Entries); CopyMemory(PtrW, Tables[i]->GammaTable, sizeof(WORD) * NewLUT -> L4Entries);
CopyMemory(&NewLUT -> LCurvesSeed[3][i], &Tables[i] -> Seed, sizeof(LCMSGAMMAPARAMS)); CopyMemory(&NewLUT -> LCurvesSeed[3][i], &Tables[i] -> Seed, sizeof(LCMSGAMMAPARAMS));
@ -580,7 +625,7 @@ LPLUT _cmsBlessLUT8(LPLUT Lut)
LPL16PARAMS p = &Lut ->CLut16params; LPL16PARAMS p = &Lut ->CLut16params;
p8 = (LPL8PARAMS) malloc(sizeof(L8PARAMS)); p8 = (LPL8PARAMS) _cmsMalloc(sizeof(L8PARAMS));
if (p8 == NULL) return NULL; if (p8 == NULL) return NULL;
// values comes * 257, so we can safely take first byte (x << 8 + x) // values comes * 257, so we can safely take first byte (x << 8 + x)
@ -593,8 +638,8 @@ LPLUT _cmsBlessLUT8(LPLUT Lut)
if (Lut ->wFlags & LUT_HASTL1) { if (Lut ->wFlags & LUT_HASTL1) {
for (j=0; j < 3; j++) for (j=0; j < 3; j++)
StageABC[i] = cmsLinearInterpLUT16(StageABC[i], StageABC[j] = cmsLinearInterpLUT16(StageABC[j],
Lut -> L1[i], Lut -> L1[j],
&Lut -> In16params); &Lut -> In16params);
Lut ->wFlags &= ~LUT_HASTL1; Lut ->wFlags &= ~LUT_HASTL1;
} }
@ -822,3 +867,6 @@ LCMSAPI double LCMSEXPORT cmsEvalLUTreverse(LPLUT Lut, WORD Target[], WORD Resul
return LastError; return LastError;
} }

View File

@ -29,7 +29,7 @@
// //
// //
// Little cms // Little cms
// Copyright (C) 1998-2006 Marti Maria // Copyright (C) 1998-2007 Marti Maria
// //
// Permission is hereby granted, free of charge, to any person obtaining // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
@ -62,6 +62,7 @@
// data yet in fixed point, so no additional process is required. // data yet in fixed point, so no additional process is required.
// Then, we obtain data on 15.16, so we need to shift >> by 1 to // Then, we obtain data on 15.16, so we need to shift >> by 1 to
// obtain 1.15 PCS format. // obtain 1.15 PCS format.
// On OUTPUT profiles, things are inverse, we must first expand 1 bit // On OUTPUT profiles, things are inverse, we must first expand 1 bit
// by shifting left, and then convert result between 0 and 1.000 to // by shifting left, and then convert result between 0 and 1.000 to
// RGB, so FromFixedDomain() must be called before pass values to // RGB, so FromFixedDomain() must be called before pass values to
@ -71,6 +72,7 @@
// input is encoded from 0 to 0xffff, we must first use the shaper and // input is encoded from 0 to 0xffff, we must first use the shaper and
// then the matrix, an additional FromFixedDomain() must be used to // then the matrix, an additional FromFixedDomain() must be used to
// accomodate output values. // accomodate output values.
// For a sake of simplicity, I will handle this three behaviours // For a sake of simplicity, I will handle this three behaviours
// with different routines, so the flags MATSHAPER_INPUT and MATSHAPER_OUTPUT // with different routines, so the flags MATSHAPER_INPUT and MATSHAPER_OUTPUT
// can be conbined to signal smelted matrix-shapers // can be conbined to signal smelted matrix-shapers
@ -89,7 +91,7 @@ int ComputeTables(LPGAMMATABLE Table[3], LPWORD Out[3], LPL16PARAMS p16)
{ {
LPWORD PtrW; LPWORD PtrW;
PtrW = (LPWORD) malloc(sizeof(WORD) * p16 -> nSamples); PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * p16 -> nSamples);
if (PtrW == NULL) return -1; // Signal error if (PtrW == NULL) return -1; // Signal error
@ -119,7 +121,7 @@ LPMATSHAPER cmsAllocMatShaper2(LPMAT3 Matrix, LPGAMMATABLE In[], LPGAMMATABLE Ou
LPMATSHAPER NewMatShaper; LPMATSHAPER NewMatShaper;
int rc; int rc;
NewMatShaper = (LPMATSHAPER) malloc(sizeof(MATSHAPER)); NewMatShaper = (LPMATSHAPER) _cmsMalloc(sizeof(MATSHAPER));
if (NewMatShaper) if (NewMatShaper)
ZeroMemory(NewMatShaper, sizeof(MATSHAPER)); ZeroMemory(NewMatShaper, sizeof(MATSHAPER));
@ -171,7 +173,13 @@ LPMATSHAPER cmsAllocMatShaper(LPMAT3 Matrix, LPGAMMATABLE Tables[], DWORD Behavi
LPMATSHAPER NewMatShaper; LPMATSHAPER NewMatShaper;
int i, AllLinear; int i, AllLinear;
NewMatShaper = (LPMATSHAPER) malloc(sizeof(MATSHAPER)); if (Matrix == NULL) return NULL;
for (i=0; i < 3; i++) {
if (Tables[i] == NULL) return NULL;
}
NewMatShaper = (LPMATSHAPER) _cmsMalloc(sizeof(MATSHAPER));
if (NewMatShaper) if (NewMatShaper)
ZeroMemory(NewMatShaper, sizeof(MATSHAPER)); ZeroMemory(NewMatShaper, sizeof(MATSHAPER));
@ -187,17 +195,16 @@ LPMATSHAPER cmsAllocMatShaper(LPMAT3 Matrix, LPGAMMATABLE Tables[], DWORD Behavi
NewMatShaper -> dwFlags |= MATSHAPER_HASMATRIX; NewMatShaper -> dwFlags |= MATSHAPER_HASMATRIX;
// Now, on the table characteristics // Now, on the table characteristics
cmsCalcL16Params(Tables[0] -> nEntries, &NewMatShaper -> p16); cmsCalcL16Params(Tables[0] -> nEntries, &NewMatShaper -> p16);
// Copy tables // Copy tables
AllLinear = 0; AllLinear = 0;
for (i=0; i < 3; i++) for (i=0; i < 3; i++) {
{
LPWORD PtrW; LPWORD PtrW;
PtrW = (LPWORD) malloc(sizeof(WORD) * NewMatShaper -> p16.nSamples); PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * NewMatShaper -> p16.nSamples);
if (PtrW == NULL) { if (PtrW == NULL) {
cmsFreeMatShaper(NewMatShaper); cmsFreeMatShaper(NewMatShaper);
@ -235,11 +242,11 @@ void cmsFreeMatShaper(LPMATSHAPER MatShaper)
for (i=0; i < 3; i++) for (i=0; i < 3; i++)
{ {
if (MatShaper -> L[i]) free(MatShaper ->L[i]); if (MatShaper -> L[i]) _cmsFree(MatShaper ->L[i]);
if (MatShaper -> L2[i]) free(MatShaper ->L2[i]); if (MatShaper -> L2[i]) _cmsFree(MatShaper ->L2[i]);
} }
free(MatShaper); _cmsFree(MatShaper);
} }

View File

@ -29,7 +29,7 @@
// //
// //
// Little cms // Little cms
// Copyright (C) 1998-2006 Marti Maria // Copyright (C) 1998-2007 Marti Maria
// //
// Permission is hereby granted, free of charge, to any person obtaining // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
@ -74,7 +74,7 @@ double cdecl VEC3distance(LPVEC3 a, LPVEC3 b);
void cdecl MAT3identity(LPMAT3 a); void cdecl MAT3identity(LPMAT3 a);
void cdecl MAT3per(LPMAT3 r, LPMAT3 a, LPMAT3 b); void cdecl MAT3per(LPMAT3 r, LPMAT3 a, LPMAT3 b);
int cdecl MAT3inverse(LPMAT3 a, LPMAT3 b); int cdecl MAT3inverse(LPMAT3 a, LPMAT3 b);
BOOL cdecl MAT3solve(LPVEC3 x, LPMAT3 a, LPVEC3 b); LCMSBOOL cdecl MAT3solve(LPVEC3 x, LPMAT3 a, LPVEC3 b);
double cdecl MAT3det(LPMAT3 m); double cdecl MAT3det(LPMAT3 m);
void cdecl MAT3eval(LPVEC3 r, LPMAT3 a, LPVEC3 v); void cdecl MAT3eval(LPVEC3 r, LPMAT3 a, LPVEC3 v);
void cdecl MAT3toFix(LPWMAT3 r, LPMAT3 v); void cdecl MAT3toFix(LPWMAT3 r, LPMAT3 v);
@ -345,13 +345,13 @@ void VEC3minus(LPVEC3 r, LPVEC3 a, LPVEC3 b)
// Check id two vectors are the same, allowing tolerance // Check id two vectors are the same, allowing tolerance
static static
BOOL RangeCheck(double l, double h, double v) LCMSBOOL RangeCheck(double l, double h, double v)
{ {
return (v >= l && v <= h); return (v >= l && v <= h);
} }
BOOL VEC3equal(LPWVEC3 a, LPWVEC3 b, double Tolerance) LCMSBOOL VEC3equal(LPWVEC3 a, LPWVEC3 b, double Tolerance)
{ {
int i; int i;
double c; double c;
@ -367,7 +367,7 @@ BOOL VEC3equal(LPWVEC3 a, LPWVEC3 b, double Tolerance)
return TRUE; return TRUE;
} }
BOOL VEC3equalF(LPVEC3 a, LPVEC3 b, double Tolerance) LCMSBOOL VEC3equalF(LPVEC3 a, LPVEC3 b, double Tolerance)
{ {
int i; int i;
double c; double c;
@ -462,7 +462,7 @@ void MAT3identity(LPMAT3 a)
// Check if matrix is Identity. Allow a tolerance as % // Check if matrix is Identity. Allow a tolerance as %
BOOL MAT3isIdentity(LPWMAT3 a, double Tolerance) LCMSBOOL MAT3isIdentity(LPWMAT3 a, double Tolerance)
{ {
int i; int i;
MAT3 Idd; MAT3 Idd;
@ -545,7 +545,7 @@ int MAT3inverse(LPMAT3 a, LPMAT3 b)
// Solve a system in the form Ax = b // Solve a system in the form Ax = b
BOOL MAT3solve(LPVEC3 x, LPMAT3 a, LPVEC3 b) LCMSBOOL MAT3solve(LPVEC3 x, LPMAT3 a, LPVEC3 b)
{ {
MAT3 m, a_1; MAT3 m, a_1;
@ -839,3 +839,7 @@ void MAT3scaleAndCut(LPWMAT3 r, LPMAT3 v, double d)
VEC3scaleAndCut(&r -> v[1], &v -> v[1], d); VEC3scaleAndCut(&r -> v[1], &v -> v[1], d);
VEC3scaleAndCut(&r -> v[2], &v -> v[2], d); VEC3scaleAndCut(&r -> v[2], &v -> v[2], d);
} }

View File

@ -29,7 +29,7 @@
// //
// //
// Little cms // Little cms
// Copyright (C) 1998-2006 Marti Maria // Copyright (C) 1998-2007 Marti Maria
// //
// Permission is hereby granted, free of charge, to any person obtaining // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
@ -74,7 +74,7 @@ LPcmsNAMEDCOLORLIST GrowNamedColorList(LPcmsNAMEDCOLORLIST v, int ByElements)
NewElements *= 2; NewElements *= 2;
size = sizeof(cmsNAMEDCOLORLIST) + (sizeof(cmsNAMEDCOLOR) * NewElements); size = sizeof(cmsNAMEDCOLORLIST) + (sizeof(cmsNAMEDCOLOR) * NewElements);
TheNewList = (LPcmsNAMEDCOLORLIST) malloc(size); TheNewList = (LPcmsNAMEDCOLORLIST) _cmsMalloc(size);
if (TheNewList == NULL) { if (TheNewList == NULL) {
@ -86,7 +86,7 @@ LPcmsNAMEDCOLORLIST GrowNamedColorList(LPcmsNAMEDCOLORLIST v, int ByElements)
CopyMemory(TheNewList, v, sizeof(cmsNAMEDCOLORLIST) + (v ->nColors - 1) * sizeof(cmsNAMEDCOLOR)); CopyMemory(TheNewList, v, sizeof(cmsNAMEDCOLORLIST) + (v ->nColors - 1) * sizeof(cmsNAMEDCOLOR));
TheNewList -> Allocated = NewElements; TheNewList -> Allocated = NewElements;
free(v); _cmsFree(v);
return TheNewList; return TheNewList;
} }
} }
@ -99,7 +99,7 @@ LPcmsNAMEDCOLORLIST cmsAllocNamedColorList(int n)
{ {
size_t size = sizeof(cmsNAMEDCOLORLIST) + (n - 1) * sizeof(cmsNAMEDCOLOR); size_t size = sizeof(cmsNAMEDCOLORLIST) + (n - 1) * sizeof(cmsNAMEDCOLOR);
LPcmsNAMEDCOLORLIST v = (LPcmsNAMEDCOLORLIST) malloc(size); LPcmsNAMEDCOLORLIST v = (LPcmsNAMEDCOLORLIST) _cmsMalloc(size);
if (v == NULL) { if (v == NULL) {
@ -124,10 +124,10 @@ void cmsFreeNamedColorList(LPcmsNAMEDCOLORLIST v)
return; return;
} }
free(v); _cmsFree(v);
} }
BOOL cmsAppendNamedColor(cmsHTRANSFORM xform, const char* Name, WORD PCS[3], WORD Colorant[MAXCHANNELS]) LCMSBOOL cmsAppendNamedColor(cmsHTRANSFORM xform, const char* Name, WORD PCS[3], WORD Colorant[MAXCHANNELS])
{ {
_LPcmsTRANSFORM v = (_LPcmsTRANSFORM) xform; _LPcmsTRANSFORM v = (_LPcmsTRANSFORM) xform;
LPcmsNAMEDCOLORLIST List; LPcmsNAMEDCOLORLIST List;
@ -146,6 +146,7 @@ BOOL cmsAppendNamedColor(cmsHTRANSFORM xform, const char* Name, WORD PCS[3], WOR
List ->List[List ->nColors].PCS[i] = PCS[i]; List ->List[List ->nColors].PCS[i] = PCS[i];
strncpy(List ->List[List ->nColors].Name, Name, MAX_PATH-1); strncpy(List ->List[List ->nColors].Name, Name, MAX_PATH-1);
List ->List[List ->nColors].Name[MAX_PATH-1] = 0;
List ->nColors++; List ->nColors++;
return TRUE; return TRUE;
@ -164,18 +165,17 @@ int LCMSEXPORT cmsNamedColorCount(cmsHTRANSFORM xform)
} }
BOOL LCMSEXPORT cmsNamedColorInfo(cmsHTRANSFORM xform, int nColor, char* Name, char* Prefix, char* Suffix) LCMSBOOL LCMSEXPORT cmsNamedColorInfo(cmsHTRANSFORM xform, int nColor, char* Name, char* Prefix, char* Suffix)
{ {
_LPcmsTRANSFORM v = (_LPcmsTRANSFORM) xform; _LPcmsTRANSFORM v = (_LPcmsTRANSFORM) xform;
if (v ->NamedColorList == NULL) return FALSE; if (v ->NamedColorList == NULL) return FALSE;
if (nColor < 0 || nColor >= cmsNamedColorCount(xform)) return FALSE; if (nColor < 0 || nColor >= cmsNamedColorCount(xform)) return FALSE;
if (Name) strncpy(Name, v ->NamedColorList->List[nColor].Name, 31); if (Name) { strncpy(Name, v ->NamedColorList->List[nColor].Name, 31); Name[31] = 0; }
if (Prefix) strncpy(Prefix, v ->NamedColorList->Prefix, 31); if (Prefix) { strncpy(Prefix, v ->NamedColorList->Prefix, 31); Prefix[31] = 0; }
if (Suffix) strncpy(Suffix, v ->NamedColorList->Suffix, 31); if (Suffix) { strncpy(Suffix, v ->NamedColorList->Suffix, 31); Suffix[31] = 0; }
return TRUE; return TRUE;
} }
@ -196,3 +196,5 @@ int LCMSEXPORT cmsNamedColorIndex(cmsHTRANSFORM xform, const char* Name)
return -1; return -1;
} }

View File

@ -28,7 +28,7 @@
// file: // file:
// //
// Little cms // Little cms
// Copyright (C) 1998-2006 Marti Maria // Copyright (C) 1998-2007 Marti Maria
// //
// Permission is hereby granted, free of charge, to any person obtaining // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
@ -639,9 +639,81 @@ LPBYTE UnrollDouble(register _LPcmsTRANSFORM info, register WORD wIn[], register
static
LPBYTE UnrollDouble1Chan(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
{
double* Inks = (double*) accum;
double v;
v = floor(Inks[0] * 65535.0 + 0.5);
if (v > 65535.0) v = 65535.0;
if (v < 0) v = 0;
wIn[0] = wIn[1] = wIn[2] = (WORD) v;
return accum + sizeof(double);
}
// ----------------------------------------------------------- Packing routines // ----------------------------------------------------------- Packing routines
// Generic N-bytes plus dither 16-to-8 conversion. Currently is just a quick hack
static int err[MAXCHANNELS];
static
LPBYTE PackNBytesDither(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
{
int nChan = T_CHANNELS(info -> OutputFormat);
register int i;
unsigned int n, pe, pf;
for (i=0; i < nChan; i++) {
n = wOut[i] + err[i]; // Value
pe = (n / 257); // Whole part
pf = (n % 257); // Fractional part
err[i] = pf; // Store it for next pixel
*output++ = (BYTE) pe;
}
return output + T_EXTRA(info ->OutputFormat);
}
static
LPBYTE PackNBytesSwapDither(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
{
int nChan = T_CHANNELS(info -> OutputFormat);
register int i;
unsigned int n, pe, pf;
for (i=nChan-1; i >= 0; --i) {
n = wOut[i] + err[i]; // Value
pe = (n / 257); // Whole part
pf = (n % 257); // Fractional part
err[i] = pf; // Store it for next pixel
*output++ = (BYTE) pe;
}
return output + T_EXTRA(info ->OutputFormat);
}
// Generic chunky for byte // Generic chunky for byte
static static
@ -1486,6 +1558,9 @@ _cmsFIXFN _cmsIdentifyInputFormat(_LPcmsTRANSFORM xform, DWORD dwInput)
case PT_HSV: case PT_HSV:
case PT_HLS: case PT_HLS:
case PT_Yxy: case PT_Yxy:
if (T_CHANNELS(dwInput) == 1)
FromInput = UnrollDouble1Chan;
else
FromInput = UnrollDouble; FromInput = UnrollDouble;
break; break;
@ -1749,6 +1824,9 @@ _cmsFIXFN _cmsIdentifyOutputFormat(_LPcmsTRANSFORM xform, DWORD dwOutput)
switch (T_CHANNELS(dwOutput)) switch (T_CHANNELS(dwOutput))
{ {
case 1: case 1:
if (T_DITHER(dwOutput))
ToOutput = PackNBytesDither;
else
ToOutput = Pack1Byte; ToOutput = Pack1Byte;
if (T_EXTRA(dwOutput) == 1) { if (T_EXTRA(dwOutput) == 1) {
if (T_SWAPFIRST(dwOutput)) if (T_SWAPFIRST(dwOutput))
@ -1766,8 +1844,12 @@ _cmsFIXFN _cmsIdentifyOutputFormat(_LPcmsTRANSFORM xform, DWORD dwOutput)
else else
if (T_COLORSPACE(dwOutput) == PT_Lab) if (T_COLORSPACE(dwOutput) == PT_Lab)
ToOutput = Pack3BytesLab; ToOutput = Pack3BytesLab;
else {
if (T_DITHER(dwOutput))
ToOutput = PackNBytesDither;
else else
ToOutput = Pack3Bytes; ToOutput = Pack3Bytes;
}
break; break;
case 1: // TODO: ALab8 should be handled here case 1: // TODO: ALab8 should be handled here
@ -1793,12 +1875,22 @@ _cmsFIXFN _cmsIdentifyOutputFormat(_LPcmsTRANSFORM xform, DWORD dwOutput)
case 4: if (T_EXTRA(dwOutput) == 0) { case 4: if (T_EXTRA(dwOutput) == 0) {
if (T_DOSWAP(dwOutput)) { if (T_DOSWAP(dwOutput)) {
if (T_SWAPFIRST(dwOutput))
if (T_SWAPFIRST(dwOutput)) {
ToOutput = Pack4BytesSwapSwapFirst; ToOutput = Pack4BytesSwapSwapFirst;
else }
else {
if (T_DITHER(dwOutput)) {
ToOutput = PackNBytesSwapDither;
}
else {
ToOutput = Pack4BytesSwap; ToOutput = Pack4BytesSwap;
}
}
} }
else { else {
if (T_SWAPFIRST(dwOutput)) if (T_SWAPFIRST(dwOutput))
@ -1807,11 +1899,15 @@ _cmsFIXFN _cmsIdentifyOutputFormat(_LPcmsTRANSFORM xform, DWORD dwOutput)
if (T_FLAVOR(dwOutput)) if (T_FLAVOR(dwOutput))
ToOutput = Pack4BytesReverse; ToOutput = Pack4BytesReverse;
else {
if (T_DITHER(dwOutput))
ToOutput = PackNBytesDither;
else else
ToOutput = Pack4Bytes; ToOutput = Pack4Bytes;
} }
} }
} }
}
else { else {
if (!T_DOSWAP(dwOutput) && !T_SWAPFIRST(dwOutput)) if (!T_DOSWAP(dwOutput) && !T_SWAPFIRST(dwOutput))
ToOutput = PackNBytes; ToOutput = PackNBytes;
@ -1849,9 +1945,14 @@ _cmsFIXFN _cmsIdentifyOutputFormat(_LPcmsTRANSFORM xform, DWORD dwOutput)
{ {
if (T_DOSWAP(dwOutput)) if (T_DOSWAP(dwOutput))
ToOutput = PackNBytesSwap; ToOutput = PackNBytesSwap;
else {
if (T_DITHER(dwOutput))
ToOutput = PackNBytesDither;
else else
ToOutput = PackNBytes; ToOutput = PackNBytes;
} }
}
break; break;
default:; default:;

View File

@ -29,7 +29,7 @@
// //
// //
// Little cms // Little cms
// Copyright (C) 1998-2006 Marti Maria // Copyright (C) 1998-2007 Marti Maria
// //
// Permission is hereby granted, free of charge, to any person obtaining // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
@ -624,3 +624,7 @@ void LCMSEXPORT cmsXYZEncoded2Float(LPcmsCIEXYZ fXYZ, const WORD XYZ[3])
fXYZ -> Z = XYZ2float(XYZ[2]); fXYZ -> Z = XYZ2float(XYZ[2]);
} }

View File

@ -29,7 +29,7 @@
// //
// //
// Little cms // Little cms
// Copyright (C) 1998-2006 Marti Maria // Copyright (C) 1998-2007 Marti Maria
// //
// Permission is hereby granted, free of charge, to any person obtaining // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
@ -144,6 +144,8 @@ LCMSAPI DWORD LCMSEXPORT cmsGetPostScriptCRDEx(cmsHPROFILE hProfile, int Intent,
/Table [ p p p [<...>]] /Table [ p p p [<...>]]
/RangeABC [ 0 1 0 1 0 1] /RangeABC [ 0 1 0 1 0 1]
/DecodeABC[ <postlinearization> ] /DecodeABC[ <postlinearization> ]
/RangeLMN [ -0.236 1.254 0 1 -0.635 1.640 ]
% -128/500 1+127/500 0 1 -127/200 1+128/200
/MatrixABC [ 1 1 1 1 0 0 0 0 -1] /MatrixABC [ 1 1 1 1 0 0 0 0 -1]
/WhitePoint [D50] /WhitePoint [D50]
/BlackPoint [BP] /BlackPoint [BP]
@ -347,7 +349,8 @@ typedef struct {
static static
LPMEMSTREAM CreateMemStream(LPBYTE Buffer, DWORD dwMax, int MaxCols) LPMEMSTREAM CreateMemStream(LPBYTE Buffer, DWORD dwMax, int MaxCols)
{ {
LPMEMSTREAM m = (LPMEMSTREAM) malloc(sizeof(MEMSTREAM)); LPMEMSTREAM m = (LPMEMSTREAM) _cmsMalloc(sizeof(MEMSTREAM));
if (m == NULL) return NULL;
ZeroMemory(m, sizeof(MEMSTREAM)); ZeroMemory(m, sizeof(MEMSTREAM));
@ -387,7 +390,6 @@ BYTE L2Byte(WORD w)
static static
void WriteRawByte(LPMEMSTREAM m, BYTE b) void WriteRawByte(LPMEMSTREAM m, BYTE b)
{ {
if (m -> dwUsed + 1 > m -> dwMax) { if (m -> dwUsed + 1 > m -> dwMax) {
m -> HasError = 1; m -> HasError = 1;
} }
@ -422,7 +424,7 @@ void WriteByte(LPMEMSTREAM m, BYTE b)
} }
// Does write a formatted string // Does write a formatted string. Guaranteed to be 2048 bytes at most.
static static
void Writef(LPMEMSTREAM m, const char *frm, ...) void Writef(LPMEMSTREAM m, const char *frm, ...)
{ {
@ -432,7 +434,7 @@ void Writef(LPMEMSTREAM m, const char *frm, ...)
va_start(args, frm); va_start(args, frm);
vsprintf((char*) Buffer, frm, args); vsnprintf((char*) Buffer, 2048, frm, args);
for (pt = Buffer; *pt; pt++) { for (pt = Buffer; *pt; pt++) {
@ -562,7 +564,7 @@ void EmitLab2XYZ(LPMEMSTREAM m)
Writef(m, "{255 mul 128 sub 200 div } bind\n"); Writef(m, "{255 mul 128 sub 200 div } bind\n");
Writef(m, "]\n"); Writef(m, "]\n");
Writef(m, "/MatrixABC [ 1 1 1 1 0 0 0 0 -1]\n"); Writef(m, "/MatrixABC [ 1 1 1 1 0 0 0 0 -1]\n");
Writef(m, "/RangeLMN [ 0.0 0.9642 0.0 1.0000 0.0 0.8249 ]\n"); Writef(m, "/RangeLMN [ -0.236 1.254 0 1 -0.635 1.640 ]\n");
Writef(m, "/DecodeLMN [\n"); Writef(m, "/DecodeLMN [\n");
Writef(m, "{dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse 0.964200 mul} bind\n"); Writef(m, "{dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse 0.964200 mul} bind\n");
Writef(m, "{dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse } bind\n"); Writef(m, "{dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse } bind\n");
@ -584,7 +586,11 @@ void Emit1Gamma(LPMEMSTREAM m, LPWORD Table, int nEntries)
if (nEntries <= 0) return; // Empty table if (nEntries <= 0) return; // Empty table
// Suppress whole if identity // Suppress whole if identity
if (cmsIsLinear(Table, nEntries)) return; if (cmsIsLinear(Table, nEntries)) {
Writef(m, "{} ");
return;
}
// Check if is really an exponential. If so, emit "exp" // Check if is really an exponential. If so, emit "exp"
gamma = cmsEstimateGammaEx(Table, nEntries, 0.001); gamma = cmsEstimateGammaEx(Table, nEntries, 0.001);
@ -646,7 +652,7 @@ void Emit1Gamma(LPMEMSTREAM m, LPWORD Table, int nEntries)
// Compare gamma table // Compare gamma table
static static
BOOL GammaTableEquals(LPWORD g1, LPWORD g2, int nEntries) LCMSBOOL GammaTableEquals(LPWORD g1, LPWORD g2, int nEntries)
{ {
return memcmp(g1, g2, nEntries* sizeof(WORD)) == 0; return memcmp(g1, g2, nEntries* sizeof(WORD)) == 0;
} }
@ -676,7 +682,7 @@ void EmitNGamma(LPMEMSTREAM m, int n, LPWORD g[], int nEntries)
// Check whatever a profile has CLUT tables (only on input) // Check whatever a profile has CLUT tables (only on input)
static static
BOOL IsLUTbased(cmsHPROFILE hProfile, int Intent) LCMSBOOL IsLUTbased(cmsHPROFILE hProfile, int Intent)
{ {
icTagSignature Tag; icTagSignature Tag;
@ -718,10 +724,10 @@ int OutputValueSampler(register WORD In[], register WORD Out[], register LPVOID
if (sc -> FixWhite) { if (sc -> FixWhite) {
if (In[0] == 0xFFFF) { // Only in L* = 100 if (In[0] == 0xFFFF) { // Only in L* = 100, ab = [-8..8]
if ((In[1] >= 0x8000 && In[1] <= 0x87FF) || if ((In[1] >= 0x7800 && In[1] <= 0x8800) &&
(In[2] >= 0x8000 && In[2] <= 0x87FF)) { (In[2] >= 0x7800 && In[2] <= 0x8800)) {
WORD* Black; WORD* Black;
WORD* White; WORD* White;
@ -830,7 +836,7 @@ void WriteCLUT(LPMEMSTREAM m, LPLUT Lut, int bps, const char* PreMaj,
sc.PostMaj= PostMaj; sc.PostMaj= PostMaj;
sc.PreMin = PreMin; sc.PreMin = PreMin;
sc.PostMin= PostMin; sc.PostMin = PostMin;
sc.lIsInput = lIsInput; sc.lIsInput = lIsInput;
sc.FixWhite = FixWhite; sc.FixWhite = FixWhite;
sc.ColorSpace = ColorSpace; sc.ColorSpace = ColorSpace;
@ -1231,7 +1237,7 @@ DWORD LCMSEXPORT cmsGetPostScriptCSA(cmsHPROFILE hProfile,
if (!WriteNamedColorCSA(mem, hProfile, Intent)) { if (!WriteNamedColorCSA(mem, hProfile, Intent)) {
free((void*) mem); _cmsFree((void*) mem);
return 0; return 0;
} }
} }
@ -1246,7 +1252,7 @@ DWORD LCMSEXPORT cmsGetPostScriptCSA(cmsHPROFILE hProfile,
ColorSpace != icSigLabData) { ColorSpace != icSigLabData) {
cmsSignalError(LCMS_ERRC_ABORTED, "Invalid output color space"); cmsSignalError(LCMS_ERRC_ABORTED, "Invalid output color space");
free((void*) mem); _cmsFree((void*) mem);
return 0; return 0;
} }
@ -1256,7 +1262,7 @@ DWORD LCMSEXPORT cmsGetPostScriptCSA(cmsHPROFILE hProfile,
// Yes, so handle as LUT-based // Yes, so handle as LUT-based
if (!WriteInputLUT(mem, hProfile, Intent)) { if (!WriteInputLUT(mem, hProfile, Intent)) {
free((void*) mem); _cmsFree((void*) mem);
return 0; return 0;
} }
} }
@ -1266,7 +1272,7 @@ DWORD LCMSEXPORT cmsGetPostScriptCSA(cmsHPROFILE hProfile,
if (!WriteInputMatrixShaper(mem, hProfile)) { if (!WriteInputMatrixShaper(mem, hProfile)) {
free((void*) mem); // Something went wrong _cmsFree((void*) mem); // Something went wrong
return 0; return 0;
} }
} }
@ -1277,7 +1283,7 @@ DWORD LCMSEXPORT cmsGetPostScriptCSA(cmsHPROFILE hProfile,
dwBytesUsed = mem ->dwUsed; dwBytesUsed = mem ->dwUsed;
// Get rid of memory stream // Get rid of memory stream
free((void*) mem); _cmsFree((void*) mem);
// Finally, return used byte count // Finally, return used byte count
return dwBytesUsed; return dwBytesUsed;
@ -1350,27 +1356,40 @@ DWORD LCMSEXPORT cmsGetPostScriptCSA(cmsHPROFILE hProfile,
static static
void EmitPQRStage(LPMEMSTREAM m, int DoBPC, int lIsAbsolute) void EmitPQRStage(LPMEMSTREAM m, cmsHPROFILE hProfile, int DoBPC, int lIsAbsolute)
{ {
if (lIsAbsolute) {
// For absolute colorimetric intent, encode back to relative
// and generate a relative LUT
// Relative encoding is obtained across XYZpcs*(D50/WhitePoint)
cmsCIEXYZ White;
cmsTakeMediaWhitePoint(&White, hProfile);
Writef(m,"/MatrixPQR [1 0 0 0 1 0 0 0 1 ]\n");
Writef(m,"/RangePQR [ -0.5 2 -0.5 2 -0.5 2 ]\n");
Writef(m, "%% Absolute colorimetric -- encode to relative to maximize LUT usage\n"
"/TransformPQR [\n"
"{0.9642 mul %g div exch pop exch pop exch pop exch pop} bind\n"
"{1.0000 mul %g div exch pop exch pop exch pop exch pop} bind\n"
"{0.8249 mul %g div exch pop exch pop exch pop exch pop} bind\n]\n",
White.X, White.Y, White.Z);
return;
}
Writef(m,"%% Bradford Cone Space\n" Writef(m,"%% Bradford Cone Space\n"
"/MatrixPQR [0.8951 -0.7502 0.0389 0.2664 1.7135 -0.0685 -0.1614 0.0367 1.0296 ] \n"); "/MatrixPQR [0.8951 -0.7502 0.0389 0.2664 1.7135 -0.0685 -0.1614 0.0367 1.0296 ] \n");
Writef(m, "/RangePQR [ -0.5 2 -0.5 2 -0.5 2 ]\n"); Writef(m, "/RangePQR [ -0.5 2 -0.5 2 -0.5 2 ]\n");
if (lIsAbsolute) {
// For absolute colorimetric intent, do nothing
Writef(m, "%% Absolute colorimetric -- no transformation\n"
"/TransformPQR [\n"
"{exch pop exch pop exch pop exch pop} bind dup dup]\n");
return;
}
// No BPC // No BPC
if (!DoBPC) { if (!DoBPC) {
@ -1414,6 +1433,7 @@ void EmitPQRStage(LPMEMSTREAM m, int DoBPC, int lIsAbsolute)
static static
void EmitXYZ2Lab(LPMEMSTREAM m) void EmitXYZ2Lab(LPMEMSTREAM m)
{ {
Writef(m, "/RangeLMN [ -0.635 2.0 0 2 -0.635 2.0 ]\n");
Writef(m, "/EncodeLMN [\n"); Writef(m, "/EncodeLMN [\n");
Writef(m, "{ 0.964200 div dup 0.008856 le {7.787 mul 16 116 div add}{1 3 div exp} ifelse } bind\n"); Writef(m, "{ 0.964200 div dup 0.008856 le {7.787 mul 16 116 div add}{1 3 div exp} ifelse } bind\n");
Writef(m, "{ 1.000000 div dup 0.008856 le {7.787 mul 16 116 div add}{1 3 div exp} ifelse } bind\n"); Writef(m, "{ 1.000000 div dup 0.008856 le {7.787 mul 16 116 div add}{1 3 div exp} ifelse } bind\n");
@ -1423,18 +1443,11 @@ void EmitXYZ2Lab(LPMEMSTREAM m)
Writef(m, "/EncodeABC [\n"); Writef(m, "/EncodeABC [\n");
Writef(m, "{ 116 mul 16 sub 100 div } bind\n"); Writef(m, "{ 116 mul 16 sub 100 div } bind\n");
Writef(m, "{ 500 mul 128 add 255 div } bind\n"); Writef(m, "{ 500 mul 128 add 256 div } bind\n");
Writef(m, "{ 200 mul 128 add 255 div } bind\n"); Writef(m, "{ 200 mul 128 add 256 div } bind\n");
/*
Writef(m, "{ 116 mul 16 sub 256 mul 25700 div } bind\n");
Writef(m, "{ 500 mul 128 add 256 mul 65535 div } bind\n");
Writef(m, "{ 200 mul 128 add 256 mul 65535 div } bind\n");
*/
Writef(m, "]\n"); Writef(m, "]\n");
@ -1458,20 +1471,27 @@ int WriteOutputLUT(LPMEMSTREAM m, cmsHPROFILE hProfile, int Intent, DWORD dwFlag
LPLUT DeviceLink; LPLUT DeviceLink;
cmsHPROFILE Profiles[3]; cmsHPROFILE Profiles[3];
cmsCIEXYZ BlackPointAdaptedToD50; cmsCIEXYZ BlackPointAdaptedToD50;
BOOL lFreeDeviceLink = FALSE; LCMSBOOL lFreeDeviceLink = FALSE;
BOOL lDoBPC = (dwFlags & cmsFLAGS_BLACKPOINTCOMPENSATION); LCMSBOOL lDoBPC = (dwFlags & cmsFLAGS_BLACKPOINTCOMPENSATION);
LCMSBOOL lFixWhite = !(dwFlags & cmsFLAGS_NOWHITEONWHITEFIXUP);
int RelativeEncodingIntent;
// Trick our v4 profile as it were v2. This prevents the ajusting done
// in perceptual & saturation. We only neew v4 encoding!
hLab = cmsCreateLab4Profile(NULL); hLab = cmsCreateLabProfile(NULL);
cmsSetProfileICCversion(hLab, 0);
ColorSpace = cmsGetColorSpace(hProfile); ColorSpace = cmsGetColorSpace(hProfile);
nChannels = _cmsChannelsOf(ColorSpace); nChannels = _cmsChannelsOf(ColorSpace);
OutputFormat = CHANNELS_SH(nChannels) | BYTES_SH(2); OutputFormat = CHANNELS_SH(nChannels) | BYTES_SH(2);
// For absolute colorimetric, the LUT is encoded as relative
// in order to preserve precission.
RelativeEncodingIntent = Intent;
if (RelativeEncodingIntent == INTENT_ABSOLUTE_COLORIMETRIC)
RelativeEncodingIntent = INTENT_RELATIVE_COLORIMETRIC;
// Is a devicelink profile? // Is a devicelink profile?
if (cmsGetDeviceClass(hProfile) == icSigLinkClass) { if (cmsGetDeviceClass(hProfile) == icSigLinkClass) {
@ -1479,13 +1499,14 @@ int WriteOutputLUT(LPMEMSTREAM m, cmsHPROFILE hProfile, int Intent, DWORD dwFlag
if (ColorSpace == icSigLabData) { if (ColorSpace == icSigLabData) {
// adjust input to Lab to out v4 // adjust input to Lab to our v4
Profiles[0] = hLab; Profiles[0] = hLab;
Profiles[1] = hProfile; Profiles[1] = hProfile;
xform = cmsCreateMultiprofileTransform(Profiles, 2, TYPE_Lab_DBL, xform = cmsCreateMultiprofileTransform(Profiles, 2, TYPE_Lab_DBL,
OutputFormat, Intent, cmsFLAGS_NOPRELINEARIZATION); OutputFormat, RelativeEncodingIntent,
dwFlags|cmsFLAGS_NOWHITEONWHITEFIXUP|cmsFLAGS_NOPRELINEARIZATION);
} }
else { else {
@ -1499,7 +1520,7 @@ int WriteOutputLUT(LPMEMSTREAM m, cmsHPROFILE hProfile, int Intent, DWORD dwFlag
// This is a normal profile // This is a normal profile
xform = cmsCreateTransform(hLab, TYPE_Lab_DBL, hProfile, xform = cmsCreateTransform(hLab, TYPE_Lab_DBL, hProfile,
OutputFormat, Intent, cmsFLAGS_NOPRELINEARIZATION); OutputFormat, RelativeEncodingIntent, dwFlags|cmsFLAGS_NOWHITEONWHITEFIXUP|cmsFLAGS_NOPRELINEARIZATION);
} }
if (xform == NULL) { if (xform == NULL) {
@ -1515,7 +1536,7 @@ int WriteOutputLUT(LPMEMSTREAM m, cmsHPROFILE hProfile, int Intent, DWORD dwFlag
if (!DeviceLink) { if (!DeviceLink) {
DeviceLink = _cmsPrecalculateDeviceLink(xform, 0); DeviceLink = _cmsPrecalculateDeviceLink(xform, cmsFLAGS_NOPRELINEARIZATION);
lFreeDeviceLink = TRUE; lFreeDeviceLink = TRUE;
} }
@ -1527,7 +1548,7 @@ int WriteOutputLUT(LPMEMSTREAM m, cmsHPROFILE hProfile, int Intent, DWORD dwFlag
// Emit headers, etc. // Emit headers, etc.
EmitWhiteBlackD50(m, &BlackPointAdaptedToD50); EmitWhiteBlackD50(m, &BlackPointAdaptedToD50);
EmitPQRStage(m, lDoBPC, Intent == INTENT_ABSOLUTE_COLORIMETRIC); EmitPQRStage(m, hProfile, lDoBPC, Intent == INTENT_ABSOLUTE_COLORIMETRIC);
EmitXYZ2Lab(m); EmitXYZ2Lab(m);
if (DeviceLink ->wFlags & LUT_HASTL1) { if (DeviceLink ->wFlags & LUT_HASTL1) {
@ -1544,10 +1565,13 @@ int WriteOutputLUT(LPMEMSTREAM m, cmsHPROFILE hProfile, int Intent, DWORD dwFlag
// zero. This would sacrifice a bit of highlights, but failure to do so would cause // zero. This would sacrifice a bit of highlights, but failure to do so would cause
// scum dot. Ouch. // scum dot. Ouch.
if (Intent == INTENT_ABSOLUTE_COLORIMETRIC)
lFixWhite = FALSE;
Writef(m, "/RenderTable "); Writef(m, "/RenderTable ");
WriteCLUT(m, DeviceLink, 8, "<", ">\n", "", "", FALSE, WriteCLUT(m, DeviceLink, 8, "<", ">\n", "", "", FALSE,
(Intent != INTENT_ABSOLUTE_COLORIMETRIC), ColorSpace); lFixWhite, ColorSpace);
Writef(m, " %d {} bind ", nChannels); Writef(m, " %d {} bind ", nChannels);
@ -1582,6 +1606,9 @@ void BuildColorantList(char *Colorant, int nColorant, WORD Out[])
int j; int j;
Colorant[0] = 0; Colorant[0] = 0;
if (nColorant > MAXCHANNELS)
nColorant = MAXCHANNELS;
for (j=0; j < nColorant; j++) { for (j=0; j < nColorant; j++) {
sprintf(Buff, "%.3f", Out[j] / 65535.0); sprintf(Buff, "%.3f", Out[j] / 65535.0);
@ -1677,7 +1704,7 @@ DWORD LCMSEXPORT cmsGetPostScriptCRDEx(cmsHPROFILE hProfile,
if (!WriteNamedColorCRD(mem, hProfile, Intent, dwFlags)) { if (!WriteNamedColorCRD(mem, hProfile, Intent, dwFlags)) {
free((void*) mem); _cmsFree((void*) mem);
return 0; return 0;
} }
} }
@ -1687,7 +1714,7 @@ DWORD LCMSEXPORT cmsGetPostScriptCRDEx(cmsHPROFILE hProfile,
if (!WriteOutputLUT(mem, hProfile, Intent, dwFlags)) { if (!WriteOutputLUT(mem, hProfile, Intent, dwFlags)) {
free((void*) mem); _cmsFree((void*) mem);
return 0; return 0;
} }
} }
@ -1702,7 +1729,7 @@ DWORD LCMSEXPORT cmsGetPostScriptCRDEx(cmsHPROFILE hProfile,
dwBytesUsed = mem ->dwUsed; dwBytesUsed = mem ->dwUsed;
// Get rid of memory stream // Get rid of memory stream
free((void*) mem); _cmsFree((void*) mem);
// Finally, return used byte count // Finally, return used byte count
return dwBytesUsed; return dwBytesUsed;

View File

@ -29,7 +29,7 @@
// //
// //
// Little cms // Little cms
// Copyright (C) 1998-2006 Marti Maria // Copyright (C) 1998-2007 Marti Maria
// //
// Permission is hereby granted, free of charge, to any person obtaining // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
@ -120,7 +120,7 @@ int ComponentOf(int n, int clut, int nColorant)
// This routine does a sweep on whole input space, and calls its callback // This routine does a sweep on whole input space, and calls its callback
// function on knots. returns TRUE if all ok, FALSE otherwise. // function on knots. returns TRUE if all ok, FALSE otherwise.
BOOL LCMSEXPORT cmsSample3DGrid(LPLUT Lut, _cmsSAMPLER Sampler, LPVOID Cargo, DWORD dwFlags) LCMSBOOL LCMSEXPORT cmsSample3DGrid(LPLUT Lut, _cmsSAMPLER Sampler, LPVOID Cargo, DWORD dwFlags)
{ {
int i, t, nTotalPoints, Colorant, index; int i, t, nTotalPoints, Colorant, index;
WORD In[MAXCHANNELS], Out[MAXCHANNELS]; WORD In[MAXCHANNELS], Out[MAXCHANNELS];
@ -145,12 +145,16 @@ BOOL LCMSEXPORT cmsSample3DGrid(LPLUT Lut, _cmsSAMPLER Sampler, LPVOID Cargo, DW
&Lut -> In16params); &Lut -> In16params);
} }
// if (dwFlags & SAMPLER_INSPECT) {
for (t=0; t < (int) Lut -> OutputChan; t++) for (t=0; t < (int) Lut -> OutputChan; t++)
Out[t] = Lut->T[index + t]; Out[t] = Lut->T[index + t];
// }
if (dwFlags & SAMPLER_HASTL2) {
for (t=0; t < (int) Lut -> OutputChan; t++)
Out[t] = cmsLinearInterpLUT16(Out[t],
Lut -> L2[t],
&Lut -> Out16params);
}
if (!Sampler(In, Out, Cargo)) if (!Sampler(In, Out, Cargo))
@ -255,9 +259,11 @@ LPLUT _cmsPrecalculateDeviceLink(cmsHTRANSFORM h, DWORD dwFlags)
LPLUT Grid; LPLUT Grid;
int nGridPoints; int nGridPoints;
DWORD dwFormatIn, dwFormatOut; DWORD dwFormatIn, dwFormatOut;
DWORD SaveFormatIn, SaveFormatOut;
int ChannelsIn, ChannelsOut; int ChannelsIn, ChannelsOut;
LPLUT SaveGamutLUT; LPLUT SaveGamutLUT;
// Remove any gamut checking // Remove any gamut checking
SaveGamutLUT = p ->Gamut; SaveGamutLUT = p ->Gamut;
p ->Gamut = NULL; p ->Gamut = NULL;
@ -276,6 +282,11 @@ LPLUT _cmsPrecalculateDeviceLink(cmsHTRANSFORM h, DWORD dwFlags)
dwFormatIn = (CHANNELS_SH(ChannelsIn)|BYTES_SH(2)); dwFormatIn = (CHANNELS_SH(ChannelsIn)|BYTES_SH(2));
dwFormatOut = (CHANNELS_SH(ChannelsOut)|BYTES_SH(2)); dwFormatOut = (CHANNELS_SH(ChannelsOut)|BYTES_SH(2));
SaveFormatIn = p ->InputFormat;
SaveFormatOut = p ->OutputFormat;
p -> InputFormat = dwFormatIn;
p -> OutputFormat = dwFormatOut;
p -> FromInput = _cmsIdentifyInputFormat(p, dwFormatIn); p -> FromInput = _cmsIdentifyInputFormat(p, dwFormatIn);
p -> ToOutput = _cmsIdentifyOutputFormat(p, dwFormatOut); p -> ToOutput = _cmsIdentifyOutputFormat(p, dwFormatOut);
@ -289,7 +300,6 @@ LPLUT _cmsPrecalculateDeviceLink(cmsHTRANSFORM h, DWORD dwFlags)
_cmsComputePrelinearizationTablesFromXFORM(hOne, 1, Grid); _cmsComputePrelinearizationTablesFromXFORM(hOne, 1, Grid);
} }
// Attention to this typecast! we can take the luxury to // Attention to this typecast! we can take the luxury to
// do this since cmsHTRANSFORM is only an alias to a pointer // do this since cmsHTRANSFORM is only an alias to a pointer
// to the transform struct. // to the transform struct.
@ -297,11 +307,13 @@ LPLUT _cmsPrecalculateDeviceLink(cmsHTRANSFORM h, DWORD dwFlags)
if (!cmsSample3DGrid(Grid, XFormSampler, (LPVOID) p, Grid -> wFlags)) { if (!cmsSample3DGrid(Grid, XFormSampler, (LPVOID) p, Grid -> wFlags)) {
cmsFreeLUT(Grid); cmsFreeLUT(Grid);
return NULL; Grid = NULL;
} }
p ->Gamut = SaveGamutLUT; p ->Gamut = SaveGamutLUT;
p ->InputFormat = SaveFormatIn;
p ->OutputFormat = SaveFormatOut;
return Grid; return Grid;
} }
@ -348,7 +360,7 @@ int BlackPreservingGrayOnlySampler(register WORD In[], register WORD Out[], regi
// That is our K-preserving callback. // Preserve all K plane.
static static
int BlackPreservingSampler(register WORD In[], register WORD Out[], register LPVOID Cargo) int BlackPreservingSampler(register WORD In[], register WORD Out[], register LPVOID Cargo)
{ {
@ -469,6 +481,7 @@ int LCMSEXPORT cmsSetCMYKPreservationStrategy(int n)
return OldVal; return OldVal;
} }
#pragma warning(disable: 4550)
// Get a pointer to callback on depending of strategy // Get a pointer to callback on depending of strategy
static static
@ -504,11 +517,10 @@ LPLUT _cmsPrecalculateBlackPreservingDeviceLink(cmsHTRANSFORM hCMYK2CMYK, DWORD
if (p -> dwOriginalFlags & cmsFLAGS_BLACKPOINTCOMPENSATION) if (p -> dwOriginalFlags & cmsFLAGS_BLACKPOINTCOMPENSATION)
LocalFlags |= cmsFLAGS_BLACKPOINTCOMPENSATION; LocalFlags |= cmsFLAGS_BLACKPOINTCOMPENSATION;
// Fill in cargo struct // Fill in cargo struct
Cargo.cmyk2cmyk = hCMYK2CMYK; Cargo.cmyk2cmyk = hCMYK2CMYK;
// Compute tone curve // Compute tone curve.
Cargo.KTone = _cmsBuildKToneCurve(hCMYK2CMYK, 256); Cargo.KTone = _cmsBuildKToneCurve(hCMYK2CMYK, 256);
if (Cargo.KTone == NULL) return NULL; if (Cargo.KTone == NULL) return NULL;
cmsCalcL16Params(Cargo.KTone ->nEntries, &Cargo.KToneParams); cmsCalcL16Params(Cargo.KTone ->nEntries, &Cargo.KToneParams);
@ -654,7 +666,7 @@ void PatchLUT(LPLUT Grid, WORD At[], WORD Value[],
BOOL _cmsFixWhiteMisalignment(_LPcmsTRANSFORM p) LCMSBOOL _cmsFixWhiteMisalignment(_LPcmsTRANSFORM p)
{ {
WORD *WhitePointIn, *WhitePointOut, *BlackPointIn, *BlackPointOut; WORD *WhitePointIn, *WhitePointOut, *BlackPointIn, *BlackPointOut;
@ -682,3 +694,4 @@ BOOL _cmsFixWhiteMisalignment(_LPcmsTRANSFORM p)
return TRUE; return TRUE;
} }

View File

@ -29,7 +29,7 @@
// //
// //
// Little cms // Little cms
// Copyright (C) 1998-2006 Marti Maria // Copyright (C) 1998-2007 Marti Maria
// //
// Permission is hereby granted, free of charge, to any person obtaining // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
@ -320,7 +320,7 @@ cmsHPROFILE LCMSEXPORT cmsTransform2DeviceLink(cmsHTRANSFORM hTransform, DWORD d
cmsHPROFILE hICC; cmsHPROFILE hICC;
_LPcmsTRANSFORM v = (_LPcmsTRANSFORM) hTransform; _LPcmsTRANSFORM v = (_LPcmsTRANSFORM) hTransform;
LPLUT Lut; LPLUT Lut;
BOOL MustFreeLUT; LCMSBOOL MustFreeLUT;
LPcmsNAMEDCOLORLIST InputColorant = NULL; LPcmsNAMEDCOLORLIST InputColorant = NULL;
LPcmsNAMEDCOLORLIST OutputColorant = NULL; LPcmsNAMEDCOLORLIST OutputColorant = NULL;
@ -373,10 +373,8 @@ cmsHPROFILE LCMSEXPORT cmsTransform2DeviceLink(cmsHTRANSFORM hTransform, DWORD d
if (cmsGetDeviceClass(hICC) == icSigOutputClass) { if (cmsGetDeviceClass(hICC) == icSigOutputClass) {
cmsAddTag(hICC, icSigBToA0Tag, (LPVOID) Lut); cmsAddTag(hICC, icSigBToA0Tag, (LPVOID) Lut);
} }
else else
cmsAddTag(hICC, icSigAToB0Tag, (LPVOID) Lut); cmsAddTag(hICC, icSigAToB0Tag, (LPVOID) Lut);
@ -446,6 +444,7 @@ cmsHPROFILE LCMSEXPORT cmsCreateLinearizationDeviceLink(icColorSpaceSignature Co
// Creates a LUT with prelinearization step only // Creates a LUT with prelinearization step only
Lut = cmsAllocLUT(); Lut = cmsAllocLUT();
if (Lut == NULL) return NULL;
// Set up channels // Set up channels
Lut ->InputChan = Lut ->OutputChan = _cmsChannelsOf(ColorSpace); Lut ->InputChan = Lut ->OutputChan = _cmsChannelsOf(ColorSpace);
@ -548,6 +547,10 @@ cmsHPROFILE LCMSEXPORT cmsCreateInkLimitingDeviceLink(icColorSpaceSignature Colo
// Creates a LUT with 3D grid only // Creates a LUT with 3D grid only
Lut = cmsAllocLUT(); Lut = cmsAllocLUT();
if (Lut == NULL) {
cmsCloseProfile(hICC);
return NULL;
}
cmsAlloc3DGrid(Lut, 17, _cmsChannelsOf(ColorSpace), cmsAlloc3DGrid(Lut, 17, _cmsChannelsOf(ColorSpace),
@ -584,8 +587,9 @@ static
LPLUT Create3x3EmptyLUT(void) LPLUT Create3x3EmptyLUT(void)
{ {
LPLUT AToB0 = cmsAllocLUT(); LPLUT AToB0 = cmsAllocLUT();
AToB0 -> InputChan = AToB0 -> OutputChan = 3; if (AToB0 == NULL) return NULL;
AToB0 -> InputChan = AToB0 -> OutputChan = 3;
return AToB0; return AToB0;
} }
@ -597,8 +601,8 @@ cmsHPROFILE LCMSEXPORT cmsCreateLabProfile(LPcmsCIExyY WhitePoint)
cmsHPROFILE hProfile; cmsHPROFILE hProfile;
LPLUT Lut; LPLUT Lut;
hProfile = cmsCreateRGBProfile(WhitePoint == NULL ? cmsD50_xyY() : WhitePoint, NULL, NULL); hProfile = cmsCreateRGBProfile(WhitePoint == NULL ? cmsD50_xyY() : WhitePoint, NULL, NULL);
if (hProfile == NULL) return NULL;
cmsSetDeviceClass(hProfile, icSigAbstractClass); cmsSetDeviceClass(hProfile, icSigAbstractClass);
cmsSetColorSpace(hProfile, icSigLabData); cmsSetColorSpace(hProfile, icSigLabData);
@ -611,7 +615,10 @@ cmsHPROFILE LCMSEXPORT cmsCreateLabProfile(LPcmsCIExyY WhitePoint)
// An empty LUTs is all we need // An empty LUTs is all we need
Lut = Create3x3EmptyLUT(); Lut = Create3x3EmptyLUT();
if (Lut == NULL) return NULL; if (Lut == NULL) {
cmsCloseProfile(hProfile);
return NULL;
}
cmsAddTag(hProfile, icSigAToB0Tag, (LPVOID) Lut); cmsAddTag(hProfile, icSigAToB0Tag, (LPVOID) Lut);
cmsAddTag(hProfile, icSigBToA0Tag, (LPVOID) Lut); cmsAddTag(hProfile, icSigBToA0Tag, (LPVOID) Lut);
@ -628,8 +635,8 @@ cmsHPROFILE LCMSEXPORT cmsCreateLab4Profile(LPcmsCIExyY WhitePoint)
cmsHPROFILE hProfile; cmsHPROFILE hProfile;
LPLUT Lut; LPLUT Lut;
hProfile = cmsCreateRGBProfile(WhitePoint == NULL ? cmsD50_xyY() : WhitePoint, NULL, NULL); hProfile = cmsCreateRGBProfile(WhitePoint == NULL ? cmsD50_xyY() : WhitePoint, NULL, NULL);
if (hProfile == NULL) return NULL;
cmsSetProfileICCversion(hProfile, 0x4000000); cmsSetProfileICCversion(hProfile, 0x4000000);
@ -644,7 +651,10 @@ cmsHPROFILE LCMSEXPORT cmsCreateLab4Profile(LPcmsCIExyY WhitePoint)
// An empty LUTs is all we need // An empty LUTs is all we need
Lut = Create3x3EmptyLUT(); Lut = Create3x3EmptyLUT();
if (Lut == NULL) return NULL; if (Lut == NULL) {
cmsCloseProfile(hProfile);
return NULL;
}
Lut -> wFlags |= LUT_V4_INPUT_EMULATE_V2; Lut -> wFlags |= LUT_V4_INPUT_EMULATE_V2;
cmsAddTag(hProfile, icSigAToB0Tag, (LPVOID) Lut); cmsAddTag(hProfile, icSigAToB0Tag, (LPVOID) Lut);
@ -666,6 +676,7 @@ cmsHPROFILE LCMSEXPORT cmsCreateXYZProfile(void)
LPLUT Lut; LPLUT Lut;
hProfile = cmsCreateRGBProfile(cmsD50_xyY(), NULL, NULL); hProfile = cmsCreateRGBProfile(cmsD50_xyY(), NULL, NULL);
if (hProfile == NULL) return NULL;
cmsSetDeviceClass(hProfile, icSigAbstractClass); cmsSetDeviceClass(hProfile, icSigAbstractClass);
cmsSetColorSpace(hProfile, icSigXYZData); cmsSetColorSpace(hProfile, icSigXYZData);
@ -677,15 +688,16 @@ cmsHPROFILE LCMSEXPORT cmsCreateXYZProfile(void)
// An empty LUTs is all we need // An empty LUTs is all we need
Lut = Create3x3EmptyLUT(); Lut = Create3x3EmptyLUT();
if (Lut == NULL) return NULL; if (Lut == NULL) {
cmsCloseProfile(hProfile);
return NULL;
}
cmsAddTag(hProfile, icSigAToB0Tag, (LPVOID) Lut); cmsAddTag(hProfile, icSigAToB0Tag, (LPVOID) Lut);
cmsAddTag(hProfile, icSigBToA0Tag, (LPVOID) Lut); cmsAddTag(hProfile, icSigBToA0Tag, (LPVOID) Lut);
cmsAddTag(hProfile, icSigPreview0Tag, (LPVOID) Lut); cmsAddTag(hProfile, icSigPreview0Tag, (LPVOID) Lut);
cmsFreeLUT(Lut); cmsFreeLUT(Lut);
return hProfile; return hProfile;
} }
@ -723,6 +735,7 @@ LPGAMMATABLE Build_sRGBGamma(void)
return cmsBuildParametricGamma(1024, 4, Parameters); return cmsBuildParametricGamma(1024, 4, Parameters);
} }
// Create the ICC virtual profile for sRGB space
cmsHPROFILE LCMSEXPORT cmsCreate_sRGBProfile(void) cmsHPROFILE LCMSEXPORT cmsCreate_sRGBProfile(void)
{ {
cmsCIExyY D65; cmsCIExyY D65;
@ -739,6 +752,7 @@ cmsHPROFILE LCMSEXPORT cmsCreate_sRGBProfile(void)
hsRGB = cmsCreateRGBProfile(&D65, &Rec709Primaries, Gamma22); hsRGB = cmsCreateRGBProfile(&D65, &Rec709Primaries, Gamma22);
cmsFreeGamma(Gamma22[0]); cmsFreeGamma(Gamma22[0]);
if (hsRGB == NULL) return NULL;
cmsAddTag(hsRGB, icSigDeviceMfgDescTag, (LPVOID) "(lcms internal)"); cmsAddTag(hsRGB, icSigDeviceMfgDescTag, (LPVOID) "(lcms internal)");
@ -750,7 +764,6 @@ cmsHPROFILE LCMSEXPORT cmsCreate_sRGBProfile(void)
typedef struct { typedef struct {
double Brightness; double Brightness;
double Contrast; double Contrast;
@ -793,7 +806,6 @@ int bchswSampler(register WORD In[], register WORD Out[], register LPVOID Cargo)
cmsFloat2LabEncoded(Out, &LabOut); cmsFloat2LabEncoded(Out, &LabOut);
return TRUE; return TRUE;
} }
@ -839,7 +851,10 @@ cmsHPROFILE LCMSEXPORT cmsCreateBCHSWabstractProfile(int nLUTPoints,
// Creates a LUT with 3D grid only // Creates a LUT with 3D grid only
Lut = cmsAllocLUT(); Lut = cmsAllocLUT();
if (Lut == NULL) {
cmsCloseProfile(hICC);
return NULL;
}
cmsAlloc3DGrid(Lut, nLUTPoints, 3, 3); cmsAlloc3DGrid(Lut, nLUTPoints, 3, 3);
@ -890,7 +905,10 @@ cmsHPROFILE LCMSEXPORT cmsCreateNULLProfile(void)
// An empty LUTs is all we need // An empty LUTs is all we need
Lut = cmsAllocLUT(); Lut = cmsAllocLUT();
if (Lut == NULL) return NULL; if (Lut == NULL) {
cmsCloseProfile(hProfile);
return NULL;
}
Lut -> InputChan = 3; Lut -> InputChan = 3;
Lut -> OutputChan = 1; Lut -> OutputChan = 1;

View File

@ -29,7 +29,7 @@
// //
// //
// Little cms // Little cms
// Copyright (C) 1998-2006 Marti Maria // Copyright (C) 1998-2007 Marti Maria
// //
// Permission is hereby granted, free of charge, to any person obtaining // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
@ -51,10 +51,6 @@
#include "lcms.h" #include "lcms.h"
// Uncomment this line if you want lcms to use the black point tag in profile,
// if commented, lcms will compute the black point by its own.
// It is safer to leve it commented out
// #define HONOR_BLACK_POINT_TAG
// Conversions // Conversions
@ -79,10 +75,9 @@ void LCMSEXPORT cmsxyY2XYZ(LPcmsCIEXYZ Dest, const cmsCIExyY* Source)
} }
// Obtains WhitePoint from Temperature // Obtains WhitePoint from Temperature
BOOL LCMSEXPORT cmsWhitePointFromTemp(int TempK, LPcmsCIExyY WhitePoint) LCMSBOOL LCMSEXPORT cmsWhitePointFromTemp(int TempK, LPcmsCIExyY WhitePoint)
{ {
double x, y; double x, y;
double T, T2, T3; double T, T2, T3;
@ -147,7 +142,7 @@ BOOL LCMSEXPORT cmsWhitePointFromTemp(int TempK, LPcmsCIExyY WhitePoint)
// - Then, I apply these coeficients to the original matrix // - Then, I apply these coeficients to the original matrix
BOOL LCMSEXPORT cmsBuildRGB2XYZtransferMatrix(LPMAT3 r, LPcmsCIExyY WhitePt, LCMSBOOL LCMSEXPORT cmsBuildRGB2XYZtransferMatrix(LPMAT3 r, LPcmsCIExyY WhitePt,
LPcmsCIExyYTRIPLE Primrs) LPcmsCIExyYTRIPLE Primrs)
{ {
VEC3 WhitePoint, Coef; VEC3 WhitePoint, Coef;
@ -169,14 +164,12 @@ BOOL LCMSEXPORT cmsBuildRGB2XYZtransferMatrix(LPMAT3 r, LPcmsCIExyY WhitePt,
// Build Primaries matrix // Build Primaries matrix
VEC3init(&Primaries.v[0], xr, xg, xb); VEC3init(&Primaries.v[0], xr, xg, xb);
VEC3init(&Primaries.v[1], yr, yg, yb); VEC3init(&Primaries.v[1], yr, yg, yb);
VEC3init(&Primaries.v[2], (1-xr-yr), (1-xg-yg), (1-xb-yb)); VEC3init(&Primaries.v[2], (1-xr-yr), (1-xg-yg), (1-xb-yb));
// Result = Primaries ^ (-1) inverse matrix // Result = Primaries ^ (-1) inverse matrix
if (!MAT3inverse(&Primaries, &Result)) if (!MAT3inverse(&Primaries, &Result))
return FALSE; return FALSE;
@ -184,11 +177,9 @@ BOOL LCMSEXPORT cmsBuildRGB2XYZtransferMatrix(LPMAT3 r, LPcmsCIExyY WhitePt,
VEC3init(&WhitePoint, xn/yn, 1.0, (1.0-xn-yn)/yn); VEC3init(&WhitePoint, xn/yn, 1.0, (1.0-xn-yn)/yn);
// Across inverse primaries ... // Across inverse primaries ...
MAT3eval(&Coef, &Result, &WhitePoint); MAT3eval(&Coef, &Result, &WhitePoint);
// Give us the Coefs, then I build transformation matrix // Give us the Coefs, then I build transformation matrix
VEC3init(&r -> v[0], Coef.n[VX]*xr, Coef.n[VY]*xg, Coef.n[VZ]*xb); VEC3init(&r -> v[0], Coef.n[VX]*xr, Coef.n[VY]*xg, Coef.n[VZ]*xb);
VEC3init(&r -> v[1], Coef.n[VX]*yr, Coef.n[VY]*yg, Coef.n[VZ]*yb); VEC3init(&r -> v[1], Coef.n[VX]*yr, Coef.n[VY]*yg, Coef.n[VZ]*yb);
VEC3init(&r -> v[2], Coef.n[VX]*(1.0-xr-yr), Coef.n[VY]*(1.0-xg-yg), Coef.n[VZ]*(1.0-xb-yb)); VEC3init(&r -> v[2], Coef.n[VX]*(1.0-xr-yr), Coef.n[VY]*(1.0-xg-yg), Coef.n[VZ]*(1.0-xb-yb));
@ -246,7 +237,7 @@ void ComputeChromaticAdaptation(LPMAT3 Conversion,
// Returns the final chrmatic adaptation from illuminant FromIll to Illuminant ToIll // Returns the final chrmatic adaptation from illuminant FromIll to Illuminant ToIll
// The cone matrix can be specified in ConeMatrix. If NULL, Bradford is assumed // The cone matrix can be specified in ConeMatrix. If NULL, Bradford is assumed
BOOL cmsAdaptationMatrix(LPMAT3 r, LPMAT3 ConeMatrix, LPcmsCIEXYZ FromIll, LPcmsCIEXYZ ToIll) LCMSBOOL cmsAdaptationMatrix(LPMAT3 r, LPMAT3 ConeMatrix, LPcmsCIEXYZ FromIll, LPcmsCIEXYZ ToIll)
{ {
MAT3 LamRigg = {{ // Bradford matrix MAT3 LamRigg = {{ // Bradford matrix
{{ 0.8951, 0.2664, -0.1614 }}, {{ 0.8951, 0.2664, -0.1614 }},
@ -265,7 +256,7 @@ BOOL cmsAdaptationMatrix(LPMAT3 r, LPMAT3 ConeMatrix, LPcmsCIEXYZ FromIll, LPcms
// Same as anterior, but assuming D50 destination. White point is given in xyY // Same as anterior, but assuming D50 destination. White point is given in xyY
BOOL cmsAdaptMatrixToD50(LPMAT3 r, LPcmsCIExyY SourceWhitePt) LCMSBOOL cmsAdaptMatrixToD50(LPMAT3 r, LPcmsCIExyY SourceWhitePt)
{ {
cmsCIEXYZ Dn; cmsCIEXYZ Dn;
MAT3 Bradford; MAT3 Bradford;
@ -284,7 +275,7 @@ BOOL cmsAdaptMatrixToD50(LPMAT3 r, LPcmsCIExyY SourceWhitePt)
// Same as anterior, but assuming D50 source. White point is given in xyY // Same as anterior, but assuming D50 source. White point is given in xyY
BOOL cmsAdaptMatrixFromD50(LPMAT3 r, LPcmsCIExyY DestWhitePt) LCMSBOOL cmsAdaptMatrixFromD50(LPMAT3 r, LPcmsCIExyY DestWhitePt)
{ {
cmsCIEXYZ Dn; cmsCIEXYZ Dn;
MAT3 Bradford; MAT3 Bradford;
@ -304,7 +295,7 @@ BOOL cmsAdaptMatrixFromD50(LPMAT3 r, LPcmsCIExyY DestWhitePt)
// Adapts a color to a given illuminant. Original color is expected to have // Adapts a color to a given illuminant. Original color is expected to have
// a SourceWhitePt white point. // a SourceWhitePt white point.
BOOL LCMSEXPORT cmsAdaptToIlluminant(LPcmsCIEXYZ Result, LCMSBOOL LCMSEXPORT cmsAdaptToIlluminant(LPcmsCIEXYZ Result,
LPcmsCIEXYZ SourceWhitePt, LPcmsCIEXYZ SourceWhitePt,
LPcmsCIEXYZ Illuminant, LPcmsCIEXYZ Illuminant,
LPcmsCIEXYZ Value) LPcmsCIEXYZ Value)
@ -404,8 +395,6 @@ double Robertson(LPcmsCIExyY v)
dj = ((vs - vj) - tj * (us - uj)) / sqrt(1 + tj*tj); dj = ((vs - vj) - tj * (us - uj)) / sqrt(1 + tj*tj);
if ((j!=0) && (di/dj < 0.0)) { if ((j!=0) && (di/dj < 0.0)) {
Tc = 1000000.0 / (mi + (di / (di - dj)) * (mj - mi)); Tc = 1000000.0 / (mi + (di / (di - dj)) * (mj - mi));
break; break;
@ -423,7 +412,7 @@ double Robertson(LPcmsCIExyY v)
static static
BOOL InRange(LPcmsCIExyY a, LPcmsCIExyY b, double tolerance) LCMSBOOL InRange(LPcmsCIExyY a, LPcmsCIExyY b, double tolerance)
{ {
double dist_x, dist_y; double dist_x, dist_y;
@ -458,6 +447,7 @@ int FromD40toD150(LPWHITEPOINTS pts)
} }
// To be removed in future versions
void _cmsIdentifyWhitePoint(char *Buffer, LPcmsCIEXYZ WhitePt) void _cmsIdentifyWhitePoint(char *Buffer, LPcmsCIEXYZ WhitePt)
{ {
int i, n; int i, n;
@ -518,7 +508,6 @@ int BlackPointAsDarkerColorant(cmsHPROFILE hInput,
cmsCIEXYZ BlackXYZ, MediaWhite; cmsCIEXYZ BlackXYZ, MediaWhite;
// If the profile does not support input direction, assume Black point 0 // If the profile does not support input direction, assume Black point 0
if (!cmsIsIntentSupported(hInput, Intent, LCMS_USED_AS_INPUT)) { if (!cmsIsIntentSupported(hInput, Intent, LCMS_USED_AS_INPUT)) {
BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0; BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0;
@ -527,7 +516,6 @@ int BlackPointAsDarkerColorant(cmsHPROFILE hInput,
// Try to get black by using black colorant // Try to get black by using black colorant
Space = cmsGetColorSpace(hInput); Space = cmsGetColorSpace(hInput);
if (!_cmsEndPointsBySpace(Space, &White, &Black, &nChannels)) { if (!_cmsEndPointsBySpace(Space, &White, &Black, &nChannels)) {
@ -576,7 +564,7 @@ int BlackPointAsDarkerColorant(cmsHPROFILE hInput,
// Get a black point of output CMYK profile, discounting any ink-limiting embedded // Get a black point of output CMYK profile, discounting any ink-limiting embedded
// in the profile. Fou doing that, use perceptual intent in input direction: // in the profile. For doing that, use perceptual intent in input direction:
// Lab (0, 0, 0) -> [Perceptual] Profile -> CMYK -> [Rel. colorimetric] Profile -> Lab // Lab (0, 0, 0) -> [Perceptual] Profile -> CMYK -> [Rel. colorimetric] Profile -> Lab
static static
@ -651,6 +639,8 @@ int GetV4PerceptualBlack(LPcmsCIEXYZ BlackPoint, cmsHPROFILE hProfile, DWORD dwF
D50BlackPoint.X = PERCEPTUAL_BLACK_X; D50BlackPoint.X = PERCEPTUAL_BLACK_X;
D50BlackPoint.Y = PERCEPTUAL_BLACK_Y; D50BlackPoint.Y = PERCEPTUAL_BLACK_Y;
D50BlackPoint.Z = PERCEPTUAL_BLACK_Z; D50BlackPoint.Z = PERCEPTUAL_BLACK_Z;
// Obtain the absolute XYZ. Adapt perceptual black back from D50 to whatever media white
cmsAdaptToIlluminant(BlackPoint, cmsD50_XYZ(), &MediaWhite, &D50BlackPoint); cmsAdaptToIlluminant(BlackPoint, cmsD50_XYZ(), &MediaWhite, &D50BlackPoint);
} }
@ -662,26 +652,24 @@ int GetV4PerceptualBlack(LPcmsCIEXYZ BlackPoint, cmsHPROFILE hProfile, DWORD dwF
// This function shouldn't exist at all -- there is such quantity of broken // This function shouldn't exist at all -- there is such quantity of broken
// profiles on black point tag, that we must somehow fix chromaticity to // profiles on black point tag, that we must somehow fix chromaticity to
// avoid huge tint when doing Black point compensation. This function does // avoid huge tint when doing Black point compensation. This function does
// just that. If BP is specified, then forces it to neutral and uses only L // just that. There is a special flag for using black point tag, but turned
// component. If does not exist, computes it by taking 400% of ink or RGB=0 This // off by default because it is bogus on most profiles. The detection algorithm
// works well on relative intent and is undefined on perceptual & saturation. // involves to turn BP to neutral and to use only L component.
// However, I will support all intents for tricking & trapping.
int cmsDetectBlackPoint(LPcmsCIEXYZ BlackPoint, cmsHPROFILE hProfile, int Intent, DWORD dwFlags) int cmsDetectBlackPoint(LPcmsCIEXYZ BlackPoint, cmsHPROFILE hProfile, int Intent, DWORD dwFlags)
{ {
// v4 + perceptual & saturation intents does have its own black point // v4 + perceptual & saturation intents does have its own black point, and it is
// well specified enough to use it.
if ((cmsGetProfileICCversion(hProfile) >= 0x4000000) && if ((cmsGetProfileICCversion(hProfile) >= 0x4000000) &&
(Intent == INTENT_PERCEPTUAL || Intent == INTENT_SATURATION)) { (Intent == INTENT_PERCEPTUAL || Intent == INTENT_SATURATION)) {
// Matrix shaper share MRC & perceptual intents // Matrix shaper share MRC & perceptual intents
if (_cmsIsMatrixShaper(hProfile)) if (_cmsIsMatrixShaper(hProfile))
return BlackPointAsDarkerColorant(hProfile, INTENT_RELATIVE_COLORIMETRIC, BlackPoint, cmsFLAGS_NOTPRECALC); return BlackPointAsDarkerColorant(hProfile, INTENT_RELATIVE_COLORIMETRIC, BlackPoint, cmsFLAGS_NOTPRECALC);
// Get fixed value // CLUT based - Get perceptual black point (fixed value)
return GetV4PerceptualBlack(BlackPoint, hProfile, dwFlags); return GetV4PerceptualBlack(BlackPoint, hProfile, dwFlags);
} }
@ -701,7 +689,6 @@ int cmsDetectBlackPoint(LPcmsCIEXYZ BlackPoint, cmsHPROFILE hProfile, int Intent
cmsTakeMediaWhitePoint(&MediaWhite, hProfile); cmsTakeMediaWhitePoint(&MediaWhite, hProfile);
// Black point is absolute XYZ, so adapt to D50 to get PCS value // Black point is absolute XYZ, so adapt to D50 to get PCS value
cmsAdaptToIlluminant(&UntrustedBlackPoint, &MediaWhite, cmsD50_XYZ(), &BlackXYZ); cmsAdaptToIlluminant(&UntrustedBlackPoint, &MediaWhite, cmsD50_XYZ(), &BlackXYZ);
// Force a=b=0 to get rid of any chroma // Force a=b=0 to get rid of any chroma
@ -713,7 +700,6 @@ int cmsDetectBlackPoint(LPcmsCIEXYZ BlackPoint, cmsHPROFILE hProfile, int Intent
cmsLab2XYZ(NULL, &TrustedBlackPoint, &Lab); cmsLab2XYZ(NULL, &TrustedBlackPoint, &Lab);
// Return BP as D50 relative or absolute XYZ (depends on flags) // Return BP as D50 relative or absolute XYZ (depends on flags)
if (!(dwFlags & LCMS_BPFLAGS_D50_ADAPTED)) if (!(dwFlags & LCMS_BPFLAGS_D50_ADAPTED))
cmsAdaptToIlluminant(BlackPoint, cmsD50_XYZ(), &MediaWhite, &TrustedBlackPoint); cmsAdaptToIlluminant(BlackPoint, cmsD50_XYZ(), &MediaWhite, &TrustedBlackPoint);
else else
@ -724,15 +710,15 @@ int cmsDetectBlackPoint(LPcmsCIEXYZ BlackPoint, cmsHPROFILE hProfile, int Intent
#endif #endif
// If output profile, discount ink-limiting // That is about v2 profiles.
// If output profile, discount ink-limiting and that's all
if (Intent == INTENT_RELATIVE_COLORIMETRIC && if (Intent == INTENT_RELATIVE_COLORIMETRIC &&
(cmsGetDeviceClass(hProfile) == icSigOutputClass) && (cmsGetDeviceClass(hProfile) == icSigOutputClass) &&
(cmsGetColorSpace(hProfile) == icSigCmykData)) (cmsGetColorSpace(hProfile) == icSigCmykData))
return BlackPointUsingPerceptualBlack(BlackPoint, hProfile, dwFlags); return BlackPointUsingPerceptualBlack(BlackPoint, hProfile, dwFlags);
// Nope, compute BP using current intent. // Nope, compute BP using current intent.
return BlackPointAsDarkerColorant(hProfile, Intent, BlackPoint, dwFlags); return BlackPointAsDarkerColorant(hProfile, Intent, BlackPoint, dwFlags);
} }

View File

@ -29,7 +29,7 @@
// //
// //
// Little cms // Little cms
// Copyright (C) 1998-2006 Marti Maria // Copyright (C) 1998-2007 Marti Maria
// //
// Permission is hereby granted, free of charge, to any person obtaining // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
@ -52,7 +52,6 @@
#include "lcms.h" #include "lcms.h"
// #define DEBUG 1
// Transformations stuff // Transformations stuff
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@ -85,7 +84,7 @@ void LCMSEXPORT cmsDoTransform(cmsHTRANSFORM Transform,
void LCMSEXPORT cmsGetAlarmCodes(int *r, int *g, int *b); void LCMSEXPORT cmsGetAlarmCodes(int *r, int *g, int *b);
void LCMSEXPORT cmsSetAlarmCodes(int r, int g, int b); void LCMSEXPORT cmsSetAlarmCodes(int r, int g, int b);
BOOL LCMSEXPORT cmsIsIntentSupported(cmsHPROFILE hProfile, LCMSBOOL LCMSEXPORT cmsIsIntentSupported(cmsHPROFILE hProfile,
int Intent, int UsedDirection); int Intent, int UsedDirection);
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
@ -635,6 +634,8 @@ LPMATSHAPER cmsBuildGrayInputMatrixShaper(cmsHPROFILE hProfile)
MAT3 Scale; MAT3 Scale;
GrayTRC = cmsReadICCGamma(hProfile, icSigGrayTRCTag); // Y GrayTRC = cmsReadICCGamma(hProfile, icSigGrayTRCTag); // Y
if (GrayTRC == NULL) return NULL;
cmsTakeIluminant(&Illuminant, hProfile); cmsTakeIluminant(&Illuminant, hProfile);
if (cmsGetPCS(hProfile) == icSigLabData) { if (cmsGetPCS(hProfile) == icSigLabData) {
@ -789,6 +790,10 @@ LPMATSHAPER cmsBuildOutputMatrixShaper(cmsHPROFILE OutputProfile)
InverseShapes[1] = cmsReadICCGammaReversed(OutputProfile, icSigGreenTRCTag); InverseShapes[1] = cmsReadICCGammaReversed(OutputProfile, icSigGreenTRCTag);
InverseShapes[2] = cmsReadICCGammaReversed(OutputProfile, icSigBlueTRCTag); InverseShapes[2] = cmsReadICCGammaReversed(OutputProfile, icSigBlueTRCTag);
if (InverseShapes[0] == NULL ||
InverseShapes[1] == NULL ||
InverseShapes[2] == NULL) return NULL;
OutMatSh = cmsAllocMatShaper(&DoubleInv, InverseShapes, MATSHAPER_OUTPUT); OutMatSh = cmsAllocMatShaper(&DoubleInv, InverseShapes, MATSHAPER_OUTPUT);
cmsFreeGammaTriple(InverseShapes); cmsFreeGammaTriple(InverseShapes);
@ -801,7 +806,7 @@ LPMATSHAPER cmsBuildOutputMatrixShaper(cmsHPROFILE OutputProfile)
// This function builds a transform matrix chaining parameters // This function builds a transform matrix chaining parameters
static static
BOOL cmsBuildSmeltMatShaper(_LPcmsTRANSFORM p) LCMSBOOL cmsBuildSmeltMatShaper(_LPcmsTRANSFORM p)
{ {
MAT3 From, To, ToInv, Transfer; MAT3 From, To, ToInv, Transfer;
LPGAMMATABLE In[3], InverseOut[3]; LPGAMMATABLE In[3], InverseOut[3];
@ -814,7 +819,6 @@ BOOL cmsBuildSmeltMatShaper(_LPcmsTRANSFORM p)
if (!cmsReadICCMatrixRGB2XYZ(&To, p -> OutputProfile)) if (!cmsReadICCMatrixRGB2XYZ(&To, p -> OutputProfile))
return FALSE; return FALSE;
// invert dest // invert dest
if (MAT3inverse(&To, &ToInv) < 0) if (MAT3inverse(&To, &ToInv) < 0)
@ -838,10 +842,14 @@ BOOL cmsBuildSmeltMatShaper(_LPcmsTRANSFORM p)
InverseOut[1] = cmsReadICCGammaReversed(p -> OutputProfile, icSigGreenTRCTag); InverseOut[1] = cmsReadICCGammaReversed(p -> OutputProfile, icSigGreenTRCTag);
InverseOut[2] = cmsReadICCGammaReversed(p -> OutputProfile, icSigBlueTRCTag); InverseOut[2] = cmsReadICCGammaReversed(p -> OutputProfile, icSigBlueTRCTag);
if (!InverseOut[0] || !InverseOut[1] || !InverseOut[2]) {
cmsFreeGammaTriple(In);
return FALSE;
}
p -> SmeltMatShaper = cmsAllocMatShaper2(&Transfer, In, InverseOut, MATSHAPER_ALLSMELTED); p -> SmeltMatShaper = cmsAllocMatShaper2(&Transfer, In, InverseOut, MATSHAPER_ALLSMELTED);
cmsFreeGammaTriple(In); cmsFreeGammaTriple(In);
cmsFreeGammaTriple(InverseOut); cmsFreeGammaTriple(InverseOut);
return (p -> SmeltMatShaper != NULL); return (p -> SmeltMatShaper != NULL);
@ -1029,7 +1037,7 @@ void TakeConversionRoutines(_LPcmsTRANSFORM p, int DoBPC)
// Check colorspace // Check colorspace
static static
BOOL IsProperColorSpace(cmsHPROFILE hProfile, DWORD dwFormat, BOOL lUsePCS) LCMSBOOL IsProperColorSpace(cmsHPROFILE hProfile, DWORD dwFormat, LCMSBOOL lUsePCS)
{ {
int Space = T_COLORSPACE(dwFormat); int Space = T_COLORSPACE(dwFormat);
@ -1049,10 +1057,10 @@ _LPcmsTRANSFORM AllocEmptyTransform(void)
{ {
// Allocate needed memory // Allocate needed memory
_LPcmsTRANSFORM p = (_LPcmsTRANSFORM) malloc(sizeof(_cmsTRANSFORM)); _LPcmsTRANSFORM p = (_LPcmsTRANSFORM) _cmsMalloc(sizeof(_cmsTRANSFORM));
if (!p) { if (!p) {
cmsSignalError(LCMS_ERRC_ABORTED, "cmsCreateTransform: malloc() failed"); cmsSignalError(LCMS_ERRC_ABORTED, "cmsCreateTransform: _cmsMalloc() failed");
return NULL; return NULL;
} }
@ -1269,10 +1277,10 @@ _LPcmsTRANSFORM PickTransformRoutine(_LPcmsTRANSFORM p,
else { else {
// Can we optimize matrix-shaper only transform? // Can we optimize matrix-shaper only transform?
if (*FromTagPtr == 0 && if ((*FromTagPtr == 0) &&
*ToTagPtr == 0 && (*ToTagPtr == 0) &&
!p->PreviewProfile && (!p->PreviewProfile) &&
p -> Intent != INTENT_ABSOLUTE_COLORIMETRIC && (p -> Intent != INTENT_ABSOLUTE_COLORIMETRIC) &&
(p -> EntryColorSpace == icSigRgbData) && (p -> EntryColorSpace == icSigRgbData) &&
(p -> ExitColorSpace == icSigRgbData) && (p -> ExitColorSpace == icSigRgbData) &&
!(p -> dwOriginalFlags & cmsFLAGS_BLACKPOINTCOMPENSATION)) { !(p -> dwOriginalFlags & cmsFLAGS_BLACKPOINTCOMPENSATION)) {
@ -1530,7 +1538,6 @@ cmsHTRANSFORM LCMSEXPORT cmsCreateProofingTransform(cmsHPROFILE InputProfile,
TakeConversionRoutines(p, dwFlags & cmsFLAGS_BLACKPOINTCOMPENSATION); TakeConversionRoutines(p, dwFlags & cmsFLAGS_BLACKPOINTCOMPENSATION);
if (!(p -> dwOriginalFlags & cmsFLAGS_NOTPRECALC)) { if (!(p -> dwOriginalFlags & cmsFLAGS_NOTPRECALC)) {
LPLUT DeviceLink; LPLUT DeviceLink;
@ -1553,7 +1560,8 @@ cmsHTRANSFORM LCMSEXPORT cmsCreateProofingTransform(cmsHPROFILE InputProfile,
DeviceLink = _cmsPrecalculateDeviceLink((cmsHTRANSFORM) p, dwFlags); DeviceLink = _cmsPrecalculateDeviceLink((cmsHTRANSFORM) p, dwFlags);
} }
if (p -> dwOriginalFlags & cmsFLAGS_GAMUTCHECK) { // Allow to specify cmsFLAGS_GAMUTCHECK, even if no proofing profile is given
if ((p ->PreviewProfile != NULL) && (p -> dwOriginalFlags & cmsFLAGS_GAMUTCHECK)) {
GamutCheck = _cmsPrecalculateGamutCheck((cmsHTRANSFORM) p); GamutCheck = _cmsPrecalculateGamutCheck((cmsHTRANSFORM) p);
} }
@ -1561,7 +1569,6 @@ cmsHTRANSFORM LCMSEXPORT cmsCreateProofingTransform(cmsHPROFILE InputProfile,
// If input colorspace is Rgb, Cmy, then use tetrahedral interpolation // If input colorspace is Rgb, Cmy, then use tetrahedral interpolation
// for speed reasons (it only works well on spaces on Luma is diagonal, and // for speed reasons (it only works well on spaces on Luma is diagonal, and
// not if luma is in separate channel) // not if luma is in separate channel)
if (p ->EntryColorSpace == icSigRgbData || if (p ->EntryColorSpace == icSigRgbData ||
p ->EntryColorSpace == icSigCmyData) { p ->EntryColorSpace == icSigCmyData) {
@ -1668,7 +1675,7 @@ void LCMSEXPORT cmsDeleteTransform(cmsHTRANSFORM hTransform)
LCMS_FREE_LOCK(&p->rwlock); LCMS_FREE_LOCK(&p->rwlock);
free((void *) p); _cmsFree((void *) p);
} }
@ -1704,7 +1711,7 @@ void LCMSEXPORT cmsGetAlarmCodes(int *r, int *g, int *b)
// Returns TRUE if the profile is implemented as matrix-shaper // Returns TRUE if the profile is implemented as matrix-shaper
BOOL LCMSEXPORT _cmsIsMatrixShaper(cmsHPROFILE hProfile) LCMSBOOL LCMSEXPORT _cmsIsMatrixShaper(cmsHPROFILE hProfile)
{ {
switch (cmsGetColorSpace(hProfile)) { switch (cmsGetColorSpace(hProfile)) {
@ -1728,7 +1735,7 @@ BOOL LCMSEXPORT _cmsIsMatrixShaper(cmsHPROFILE hProfile)
} }
BOOL LCMSEXPORT cmsIsIntentSupported(cmsHPROFILE hProfile, LCMSBOOL LCMSEXPORT cmsIsIntentSupported(cmsHPROFILE hProfile,
int Intent, int UsedDirection) int Intent, int UsedDirection)
{ {
@ -1774,6 +1781,16 @@ int MultiprofileSampler(register WORD In[], register WORD Out[], register LPVOID
} }
static
int IsAllowedInSingleXform(icProfileClassSignature aClass)
{
return (aClass == icSigInputClass) ||
(aClass == icSigDisplayClass) ||
(aClass == icSigOutputClass) ||
(aClass == icSigColorSpaceClass);
}
// A multiprofile transform does chain several profiles into a single // A multiprofile transform does chain several profiles into a single
// devicelink. It couls also be used to merge named color profiles into // devicelink. It couls also be used to merge named color profiles into
// a single database. // a single database.
@ -1805,10 +1822,16 @@ cmsHTRANSFORM LCMSEXPORT cmsCreateMultiprofileTransform(cmsHPROFILE hProfiles[],
// There is a simple case with just two profiles, try to catch it in order of getting // There is a simple case with just two profiles, try to catch it in order of getting
// black preservation to work on this function, at least with two profiles. // black preservation to work on this function, at least with two profiles.
if (nProfiles == 2) { if (nProfiles == 2) {
if ((cmsGetDeviceClass(hProfiles[0]) != icSigLinkClass) && icProfileClassSignature Class1 = cmsGetDeviceClass(hProfiles[0]);
(cmsGetDeviceClass(hProfiles[1]) != icSigLinkClass)) icProfileClassSignature Class2 = cmsGetDeviceClass(hProfiles[1]);
// Only input, output and display are allowed
if (IsAllowedInSingleXform(Class1) &&
IsAllowedInSingleXform(Class2))
return cmsCreateTransform(hProfiles[0], dwInput, hProfiles[1], dwOutput, Intent, dwFlags); return cmsCreateTransform(hProfiles[0], dwInput, hProfiles[1], dwOutput, Intent, dwFlags);
} }
@ -1984,6 +2007,14 @@ cmsHTRANSFORM LCMSEXPORT cmsCreateMultiprofileTransform(cmsHPROFILE hProfiles[],
if (hLab) cmsCloseProfile(hLab); if (hLab) cmsCloseProfile(hLab);
if (hXYZ) cmsCloseProfile(hXYZ); if (hXYZ) cmsCloseProfile(hXYZ);
if (p ->EntryColorSpace == icSigRgbData ||
p ->EntryColorSpace == icSigCmyData) {
p->DeviceLink -> CLut16params.Interp3D = cmsTetrahedralInterp16;
}
if ((Intent != INTENT_ABSOLUTE_COLORIMETRIC) && if ((Intent != INTENT_ABSOLUTE_COLORIMETRIC) &&
!(dwFlags & cmsFLAGS_NOWHITEONWHITEFIXUP)) !(dwFlags & cmsFLAGS_NOWHITEONWHITEFIXUP))
_cmsFixWhiteMisalignment(p); _cmsFixWhiteMisalignment(p);

View File

@ -206,6 +206,11 @@ typedef __int32_t icInt64Number[2];
#if defined(__sun) || defined(__hpux) || defined (__MINGW) || defined(__MINGW32__) #if defined(__sun) || defined(__hpux) || defined (__MINGW) || defined(__MINGW32__)
#if defined (__MINGW) || defined(__MINGW32__)
#include <stdint.h>
#endif
typedef uint8_t icUInt8Number; typedef uint8_t icUInt8Number;
typedef uint16_t icUInt16Number; typedef uint16_t icUInt16Number;
typedef uint32_t icUInt32Number; typedef uint32_t icUInt32Number;

View File

@ -29,7 +29,7 @@
// //
// //
// Little cms // Little cms
// Copyright (C) 1998-2006 Marti Maria // Copyright (C) 1998-2007 Marti Maria
// //
// Permission is hereby granted, free of charge, to any person obtaining // Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"), // a copy of this software and associated documentation files (the "Software"),
@ -49,8 +49,8 @@
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// Version 1.16 // Version 1.18
#undef DEBUG
#ifndef __cms_H #ifndef __cms_H
// ********** Configuration toggles **************************************** // ********** Configuration toggles ****************************************
@ -62,13 +62,8 @@
// virtually any machine. // virtually any machine.
//#define USE_FLOAT 1 //#define USE_FLOAT 1
#ifdef _WIN64 // #define USE_C 1
#define USE_C 1
#undef USE_ASSEMBLER
#else
#undef USE_C
#define USE_ASSEMBLER 1 #define USE_ASSEMBLER 1
#endif
// Define this if you are using this package as a DLL (windows only) // Define this if you are using this package as a DLL (windows only)
@ -77,15 +72,11 @@
// Uncomment if you are trying the engine in a non-windows environment // Uncomment if you are trying the engine in a non-windows environment
// like linux, SGI, VAX, FreeBSD, BeOS, etc. // like linux, SGI, VAX, FreeBSD, BeOS, etc.
#if !defined(_WIN32) || !defined(_WIN64)
#define NON_WINDOWS 1 #define NON_WINDOWS 1
#endif
// Uncomment this one if you are using big endian machines (only meaningful // Uncomment this one if you are using big endian machines (only meaningful
// when NON_WINDOWS is used) // when NON_WINDOWS is used)
#ifndef _LITTLE_ENDIAN // #define USE_BIG_ENDIAN 1
#define USE_BIG_ENDIAN 1
#endif
// Uncomment this one if your compiler/machine does support the // Uncomment this one if your compiler/machine does support the
// "long long" type This will speedup fixed point math. (USE_C only) // "long long" type This will speedup fixed point math. (USE_C only)
@ -104,19 +95,25 @@
// Uncomment this line on multithreading environments // Uncomment this line on multithreading environments
// #define USE_PTHREADS 1 // #define USE_PTHREADS 1
// Uncomment this line if you want lcms to use the black point tag in profile,
// if commented, lcms will compute the black point by its own.
// It is safer to leve it commented out
// #define HONOR_BLACK_POINT_TAG 1
// ********** End of configuration toggles ****************************** // ********** End of configuration toggles ******************************
#define LCMS_VERSION 116 #define LCMS_VERSION 118
// Microsoft VisualC++ // Microsoft VisualC++
// Deal with Microsoft's attempt at deprecating C standard runtime functions // Deal with Microsoft's attempt at deprecating C standard runtime functions
#ifdef _MSC_VER #ifdef _MSC_VER
# undef NON_WINDOWS # undef NON_WINDOWS
# if (_MSC_VER >= 1400) # if (_MSC_VER >= 1400)
# ifndef _CRT_SECURE_NO_DEPRECATE
# define _CRT_SECURE_NO_DEPRECATE 1 # define _CRT_SECURE_NO_DEPRECATE 1
# endif # endif
# endif
#endif #endif
// Borland C // Borland C
@ -125,7 +122,6 @@
# undef NON_WINDOWS # undef NON_WINDOWS
#endif #endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <math.h> #include <math.h>
@ -134,11 +130,11 @@
#include <time.h> #include <time.h>
// Metroworks CodeWarrior // Metroworks CodeWarrior
#ifdef __MWERKS__ #ifdef __MWERKS__
# define unlink remove # define unlink remove
# if WIN32 # if WIN32
# define USE_CUSTOM_SWAB 1 # define USE_CUSTOM_SWAB 1
# undef NON_WINDOWS
# else # else
# define NON_WINDOWS 1 # define NON_WINDOWS 1
# endif # endif
@ -172,15 +168,21 @@ typedef pthread_rwlock_t LCMS_RWLOCK_T;
# define USE_BIG_ENDIAN 1 # define USE_BIG_ENDIAN 1
#endif #endif
#if defined(__sgi__) || defined(__sgi) || defined(__powerpc__) || defined(sparc) || defined(__ppc__) #if defined(__sgi__) || defined(__sgi) || defined(__powerpc__) || defined(sparc) || defined(__ppc__) || defined(__s390__) || defined(__s390x__)
# define USE_BIG_ENDIAN 1 # define USE_BIG_ENDIAN 1
#endif #endif
#ifdef TARGET_CPU_PPC #if TARGET_CPU_PPC
# define USE_BIG_ENDIAN 1 # define USE_BIG_ENDIAN 1
#endif #endif
#ifdef macintosh #if macintosh
# ifndef __LITTLE_ENDIAN__
# define USE_BIG_ENDIAN 1
# endif
#endif
#ifdef __BIG_ENDIAN__
# define USE_BIG_ENDIAN 1 # define USE_BIG_ENDIAN 1
#endif #endif
@ -217,11 +219,8 @@ typedef pthread_rwlock_t LCMS_RWLOCK_T;
typedef unsigned char BYTE, *LPBYTE; typedef unsigned char BYTE, *LPBYTE;
typedef unsigned short WORD, *LPWORD; typedef unsigned short WORD, *LPWORD;
typedef unsigned long DWORD, *LPDWORD; typedef unsigned long DWORD, *LPDWORD;
typedef int BOOL;
typedef char *LPSTR; typedef char *LPSTR;
typedef void *LPVOID; typedef void *LPVOID;
typedef void* LCMSHANDLE;
#define ZeroMemory(p,l) memset((p),0,(l)) #define ZeroMemory(p,l) memset((p),0,(l))
#define CopyMemory(d,s,l) memcpy((d),(s),(l)) #define CopyMemory(d,s,l) memcpy((d),(s),(l))
@ -263,8 +262,12 @@ typedef void* LCMSHANDLE;
#include <windows.h> #include <windows.h>
typedef HANDLE LCMSHANDLE; #ifdef _WIN64
# ifdef USE_ASSEMBLER
# undef USE_ASSEMBLER
# define USE_C 1
# endif
#endif
#ifdef USE_INT64 #ifdef USE_INT64
# ifndef LCMSULONGLONG # ifndef LCMSULONGLONG
@ -296,6 +299,10 @@ typedef int LCMS_RWLOCK_T;
# define LCMS_UNLOCK(x) # define LCMS_UNLOCK(x)
#endif #endif
// Base types
typedef int LCMSBOOL;
typedef void* LCMSHANDLE;
#include "icc34.h" // ICC header file #include "icc34.h" // ICC header file
@ -322,16 +329,10 @@ typedef int LCMS_RWLOCK_T;
#define icSigMCHEData ((icColorSpaceSignature) 0x4d434845L) // MCHE #define icSigMCHEData ((icColorSpaceSignature) 0x4d434845L) // MCHE
#define icSigMCHFData ((icColorSpaceSignature) 0x4d434846L) // MCHF #define icSigMCHFData ((icColorSpaceSignature) 0x4d434846L) // MCHF
#define icSigCAM97JABData ((icColorSpaceSignature) 0x4A616231L) // 'Jab1' H. Zeng
#define icSigCAM02JABData ((icColorSpaceSignature) 0x4A616232L) // 'Jab2' H. Zeng
#define icSigCAM02JCHData ((icColorSpaceSignature) 0x4A636A32L) // 'Jch2' H. Zeng
#define icSigChromaticityTag ((icTagSignature) 0x6368726dL) // As per Addendum 2 to Spec. ICC.1:1998-09 #define icSigChromaticityTag ((icTagSignature) 0x6368726dL) // As per Addendum 2 to Spec. ICC.1:1998-09
#define icSigChromaticAdaptationTag ((icTagSignature) 0x63686164L) // 'chad' #define icSigChromaticAdaptationTag ((icTagSignature) 0x63686164L) // 'chad'
#define icSigColorantTableTag ((icTagSignature) 0x636c7274L) // 'clrt' #define icSigColorantTableTag ((icTagSignature) 0x636c7274L) // 'clrt'
#define icSigColorantTableOutTag ((icTagSignature) 0x636c6f74L) // 'clot' #define icSigColorantTableOutTag ((icTagSignature) 0x636c6f74L) // 'clot'
#define icSigHPGamutDescTag ((icTagSignature) 0x676D7441L) // 'gmtA' H. Zeng
#define icSigParametricCurveType ((icTagTypeSignature) 0x70617261L) // parametric (ICC 4.0) #define icSigParametricCurveType ((icTagTypeSignature) 0x70617261L) // parametric (ICC 4.0)
#define icSigMultiLocalizedUnicodeType ((icTagTypeSignature) 0x6D6C7563L) #define icSigMultiLocalizedUnicodeType ((icTagTypeSignature) 0x6D6C7563L)
@ -340,7 +341,6 @@ typedef int LCMS_RWLOCK_T;
#define icSiglutAtoBType ((icTagTypeSignature) 0x6d414220L) // mAB #define icSiglutAtoBType ((icTagTypeSignature) 0x6d414220L) // mAB
#define icSiglutBtoAType ((icTagTypeSignature) 0x6d424120L) // mBA #define icSiglutBtoAType ((icTagTypeSignature) 0x6d424120L) // mBA
#define icSigColorantTableType ((icTagTypeSignature) 0x636c7274L) // clrt #define icSigColorantTableType ((icTagTypeSignature) 0x636c7274L) // clrt
#define icSigHPGamutDescType ((icTagTypeSignature) 0x676D7441L) // gmtA H. Zeng
typedef struct { typedef struct {
@ -438,9 +438,6 @@ extern "C" {
#ifndef itoa #ifndef itoa
# define itoa _itoa # define itoa _itoa
#endif #endif
#ifndef filelength
# define filelength _filelength
#endif
#ifndef fileno #ifndef fileno
# define fileno _fileno # define fileno _fileno
#endif #endif
@ -450,6 +447,14 @@ extern "C" {
#ifndef hypot #ifndef hypot
# define hypot _hypot # define hypot _hypot
#endif #endif
#ifndef snprintf
# define snprintf _snprintf
#endif
#ifndef vsnprintf
# define vsnprintf _vsnprintf
#endif
#endif #endif
@ -470,8 +475,9 @@ typedef LCMSHANDLE cmsHTRANSFORM;
// Format of pixel is defined by one DWORD, using bit fields as follows // Format of pixel is defined by one DWORD, using bit fields as follows
// //
// TTTTT U Y F P X S EEE CCCC BBB // D TTTTT U Y F P X S EEE CCCC BBB
// //
// D: Use dither (8 bits only)
// T: Pixeltype // T: Pixeltype
// F: Flavor 0=MinIsBlack(Chocolate) 1=MinIsWhite(Vanilla) // F: Flavor 0=MinIsBlack(Chocolate) 1=MinIsWhite(Vanilla)
// P: Planar? 0=Chunky, 1=Planar // P: Planar? 0=Chunky, 1=Planar
@ -483,6 +489,7 @@ typedef LCMSHANDLE cmsHTRANSFORM;
// Y: Swap first - changes ABGR to BGRA and KCMY to CMYK // Y: Swap first - changes ABGR to BGRA and KCMY to CMYK
#define DITHER_SH(s) ((s) << 22)
#define COLORSPACE_SH(s) ((s) << 16) #define COLORSPACE_SH(s) ((s) << 16)
#define SWAPFIRST_SH(s) ((s) << 14) #define SWAPFIRST_SH(s) ((s) << 14)
#define FLAVOR_SH(s) ((s) << 13) #define FLAVOR_SH(s) ((s) << 13)
@ -858,7 +865,7 @@ LCMSAPI LPcmsCIExyY LCMSEXPORT cmsD50_xyY(void);
LCMSAPI cmsHPROFILE LCMSEXPORT cmsOpenProfileFromFile(const char *ICCProfile, const char *sAccess); LCMSAPI cmsHPROFILE LCMSEXPORT cmsOpenProfileFromFile(const char *ICCProfile, const char *sAccess);
LCMSAPI cmsHPROFILE LCMSEXPORT cmsOpenProfileFromMem(LPVOID MemPtr, DWORD dwSize); LCMSAPI cmsHPROFILE LCMSEXPORT cmsOpenProfileFromMem(LPVOID MemPtr, DWORD dwSize);
LCMSAPI BOOL LCMSEXPORT cmsCloseProfile(cmsHPROFILE hProfile); LCMSAPI LCMSBOOL LCMSEXPORT cmsCloseProfile(cmsHPROFILE hProfile);
// Predefined run-time profiles // Predefined run-time profiles
@ -915,14 +922,14 @@ LCMSAPI double LCMSEXPORT cmsCIE2000DeltaE(LPcmsCIELab Lab1, LPcmsCIELab
LCMSAPI void LCMSEXPORT cmsClampLab(LPcmsCIELab Lab, double amax, double amin, double bmax, double bmin); LCMSAPI void LCMSEXPORT cmsClampLab(LPcmsCIELab Lab, double amax, double amin, double bmax, double bmin);
LCMSAPI BOOL LCMSEXPORT cmsWhitePointFromTemp(int TempK, LPcmsCIExyY WhitePoint); LCMSAPI LCMSBOOL LCMSEXPORT cmsWhitePointFromTemp(int TempK, LPcmsCIExyY WhitePoint);
LCMSAPI BOOL LCMSEXPORT cmsAdaptToIlluminant(LPcmsCIEXYZ Result, LCMSAPI LCMSBOOL LCMSEXPORT cmsAdaptToIlluminant(LPcmsCIEXYZ Result,
LPcmsCIEXYZ SourceWhitePt, LPcmsCIEXYZ SourceWhitePt,
LPcmsCIEXYZ Illuminant, LPcmsCIEXYZ Illuminant,
LPcmsCIEXYZ Value); LPcmsCIEXYZ Value);
LCMSAPI BOOL LCMSEXPORT cmsBuildRGB2XYZtransferMatrix(LPMAT3 r, LCMSAPI LCMSBOOL LCMSEXPORT cmsBuildRGB2XYZtransferMatrix(LPMAT3 r,
LPcmsCIExyY WhitePoint, LPcmsCIExyY WhitePoint,
LPcmsCIExyYTRIPLE Primaries); LPcmsCIExyYTRIPLE Primaries);
@ -976,7 +983,7 @@ LCMSAPI LPGAMMATABLE LCMSEXPORT cmsDupGamma(LPGAMMATABLE Src);
LCMSAPI LPGAMMATABLE LCMSEXPORT cmsReverseGamma(int nResultSamples, LPGAMMATABLE InGamma); LCMSAPI LPGAMMATABLE LCMSEXPORT cmsReverseGamma(int nResultSamples, LPGAMMATABLE InGamma);
LCMSAPI LPGAMMATABLE LCMSEXPORT cmsJoinGamma(LPGAMMATABLE InGamma, LPGAMMATABLE OutGamma); LCMSAPI LPGAMMATABLE LCMSEXPORT cmsJoinGamma(LPGAMMATABLE InGamma, LPGAMMATABLE OutGamma);
LCMSAPI LPGAMMATABLE LCMSEXPORT cmsJoinGammaEx(LPGAMMATABLE InGamma, LPGAMMATABLE OutGamma, int nPoints); LCMSAPI LPGAMMATABLE LCMSEXPORT cmsJoinGammaEx(LPGAMMATABLE InGamma, LPGAMMATABLE OutGamma, int nPoints);
LCMSAPI BOOL LCMSEXPORT cmsSmoothGamma(LPGAMMATABLE Tab, double lambda); LCMSAPI LCMSBOOL LCMSEXPORT cmsSmoothGamma(LPGAMMATABLE Tab, double lambda);
LCMSAPI double LCMSEXPORT cmsEstimateGamma(LPGAMMATABLE t); LCMSAPI double LCMSEXPORT cmsEstimateGamma(LPGAMMATABLE t);
LCMSAPI double LCMSEXPORT cmsEstimateGammaEx(LPWORD Table, int nEntries, double Thereshold); LCMSAPI double LCMSEXPORT cmsEstimateGammaEx(LPWORD Table, int nEntries, double Thereshold);
LCMSAPI LPGAMMATABLE LCMSEXPORT cmsReadICCGamma(cmsHPROFILE hProfile, icTagSignature sig); LCMSAPI LPGAMMATABLE LCMSEXPORT cmsReadICCGamma(cmsHPROFILE hProfile, icTagSignature sig);
@ -984,14 +991,14 @@ LCMSAPI LPGAMMATABLE LCMSEXPORT cmsReadICCGammaReversed(cmsHPROFILE hProfile, i
// Access to Profile data. // Access to Profile data.
LCMSAPI BOOL LCMSEXPORT cmsTakeMediaWhitePoint(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile); LCMSAPI LCMSBOOL LCMSEXPORT cmsTakeMediaWhitePoint(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile);
LCMSAPI BOOL LCMSEXPORT cmsTakeMediaBlackPoint(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile); LCMSAPI LCMSBOOL LCMSEXPORT cmsTakeMediaBlackPoint(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile);
LCMSAPI BOOL LCMSEXPORT cmsTakeIluminant(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile); LCMSAPI LCMSBOOL LCMSEXPORT cmsTakeIluminant(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile);
LCMSAPI BOOL LCMSEXPORT cmsTakeColorants(LPcmsCIEXYZTRIPLE Dest, cmsHPROFILE hProfile); LCMSAPI LCMSBOOL LCMSEXPORT cmsTakeColorants(LPcmsCIEXYZTRIPLE Dest, cmsHPROFILE hProfile);
LCMSAPI DWORD LCMSEXPORT cmsTakeHeaderFlags(cmsHPROFILE hProfile); LCMSAPI DWORD LCMSEXPORT cmsTakeHeaderFlags(cmsHPROFILE hProfile);
LCMSAPI DWORD LCMSEXPORT cmsTakeHeaderAttributes(cmsHPROFILE hProfile); LCMSAPI DWORD LCMSEXPORT cmsTakeHeaderAttributes(cmsHPROFILE hProfile);
LCMSAPI void LCMSEXPORT cmsSetLanguage(int LanguageCode, int CountryCode); LCMSAPI void LCMSEXPORT cmsSetLanguage(const char LanguageCode[4], const char CountryCode[4]);
LCMSAPI const char* LCMSEXPORT cmsTakeProductName(cmsHPROFILE hProfile); LCMSAPI const char* LCMSEXPORT cmsTakeProductName(cmsHPROFILE hProfile);
LCMSAPI const char* LCMSEXPORT cmsTakeProductDesc(cmsHPROFILE hProfile); LCMSAPI const char* LCMSEXPORT cmsTakeProductDesc(cmsHPROFILE hProfile);
LCMSAPI const char* LCMSEXPORT cmsTakeProductInfo(cmsHPROFILE hProfile); LCMSAPI const char* LCMSEXPORT cmsTakeProductInfo(cmsHPROFILE hProfile);
@ -1000,13 +1007,13 @@ LCMSAPI const char* LCMSEXPORT cmsTakeModel(cmsHPROFILE hProfile);
LCMSAPI const char* LCMSEXPORT cmsTakeCopyright(cmsHPROFILE hProfile); LCMSAPI const char* LCMSEXPORT cmsTakeCopyright(cmsHPROFILE hProfile);
LCMSAPI const BYTE* LCMSEXPORT cmsTakeProfileID(cmsHPROFILE hProfile); LCMSAPI const BYTE* LCMSEXPORT cmsTakeProfileID(cmsHPROFILE hProfile);
LCMSAPI BOOL LCMSEXPORT cmsTakeCreationDateTime(struct tm *Dest, cmsHPROFILE hProfile); LCMSAPI LCMSBOOL LCMSEXPORT cmsTakeCreationDateTime(struct tm *Dest, cmsHPROFILE hProfile);
LCMSAPI BOOL LCMSEXPORT cmsTakeCalibrationDateTime(struct tm *Dest, cmsHPROFILE hProfile); LCMSAPI LCMSBOOL LCMSEXPORT cmsTakeCalibrationDateTime(struct tm *Dest, cmsHPROFILE hProfile);
LCMSAPI BOOL LCMSEXPORT cmsIsTag(cmsHPROFILE hProfile, icTagSignature sig); LCMSAPI LCMSBOOL LCMSEXPORT cmsIsTag(cmsHPROFILE hProfile, icTagSignature sig);
LCMSAPI int LCMSEXPORT cmsTakeRenderingIntent(cmsHPROFILE hProfile); LCMSAPI int LCMSEXPORT cmsTakeRenderingIntent(cmsHPROFILE hProfile);
LCMSAPI BOOL LCMSEXPORT cmsTakeCharTargetData(cmsHPROFILE hProfile, char** Data, size_t* len); LCMSAPI LCMSBOOL LCMSEXPORT cmsTakeCharTargetData(cmsHPROFILE hProfile, char** Data, size_t* len);
LCMSAPI int LCMSEXPORT cmsReadICCTextEx(cmsHPROFILE hProfile, icTagSignature sig, char *Text, size_t size); LCMSAPI int LCMSEXPORT cmsReadICCTextEx(cmsHPROFILE hProfile, icTagSignature sig, char *Text, size_t size);
LCMSAPI int LCMSEXPORT cmsReadICCText(cmsHPROFILE hProfile, icTagSignature sig, char *Text); LCMSAPI int LCMSEXPORT cmsReadICCText(cmsHPROFILE hProfile, icTagSignature sig, char *Text);
@ -1038,50 +1045,18 @@ LCMSAPI LPcmsSEQ LCMSEXPORT cmsReadProfileSequenceDescription(cmsHPROFILE h
LCMSAPI void LCMSEXPORT cmsFreeProfileSequenceDescription(LPcmsSEQ pseq); LCMSAPI void LCMSEXPORT cmsFreeProfileSequenceDescription(LPcmsSEQ pseq);
// Extended gamut tag -- an HP extension
#define LCMSGAMUTMETHOD_SEGMENTMAXIMA 0
#define LCMSGAMUTMETHOD_CONVEXHULL 1
#define LCMSGAMUTMETHOD_ALPHASHAPE 2
#define LCMSGAMUT_PHYSICAL 0
#define LCMSGAMUT_HP1 1
#define LCMSGAMUT_HP2 2
typedef struct {
icColorSpaceSignature CoordSig; // Gamut coordinates signature
icUInt16Number Method; // Method used to generate gamut
icUInt16Number Usage; // Gamut usage or intent
char Description[LCMS_DESC_MAX]; // Textual description
cmsViewingConditions Vc; // The viewing conditions
icUInt32Number Count; // Number of entries
double Data[1]; // The current data
} cmsGAMUTEX, FAR* LPcmsGAMUTEX;
LCMSAPI LPcmsGAMUTEX LCMSEXPORT cmsReadExtendedGamut(cmsHPROFILE hProfile, int index);
LCMSAPI void LCMSEXPORT cmsFreeExtendedGamut(LPcmsGAMUTEX gex);
// Translate form/to our notation to ICC // Translate form/to our notation to ICC
LCMSAPI icColorSpaceSignature LCMSEXPORT _cmsICCcolorSpace(int OurNotation); LCMSAPI icColorSpaceSignature LCMSEXPORT _cmsICCcolorSpace(int OurNotation);
LCMSAPI int LCMSEXPORT _cmsLCMScolorSpace(icColorSpaceSignature ProfileSpace); LCMSAPI int LCMSEXPORT _cmsLCMScolorSpace(icColorSpaceSignature ProfileSpace);
LCMSAPI int LCMSEXPORT _cmsChannelsOf(icColorSpaceSignature ColorSpace); LCMSAPI int LCMSEXPORT _cmsChannelsOf(icColorSpaceSignature ColorSpace);
LCMSAPI BOOL LCMSEXPORT _cmsIsMatrixShaper(cmsHPROFILE hProfile); LCMSAPI LCMSBOOL LCMSEXPORT _cmsIsMatrixShaper(cmsHPROFILE hProfile);
// How profiles may be used
#define LCMS_USED_AS_INPUT 0 #define LCMS_USED_AS_INPUT 0
#define LCMS_USED_AS_OUTPUT 1 #define LCMS_USED_AS_OUTPUT 1
#define LCMS_USED_AS_PROOF 2 #define LCMS_USED_AS_PROOF 2
LCMSAPI BOOL LCMSEXPORT cmsIsIntentSupported(cmsHPROFILE hProfile, int Intent, int UsedDirection); LCMSAPI LCMSBOOL LCMSEXPORT cmsIsIntentSupported(cmsHPROFILE hProfile, int Intent, int UsedDirection);
LCMSAPI icColorSpaceSignature LCMSEXPORT cmsGetPCS(cmsHPROFILE hProfile); LCMSAPI icColorSpaceSignature LCMSEXPORT cmsGetPCS(cmsHPROFILE hProfile);
LCMSAPI icColorSpaceSignature LCMSEXPORT cmsGetColorSpace(cmsHPROFILE hProfile); LCMSAPI icColorSpaceSignature LCMSEXPORT cmsGetColorSpace(cmsHPROFILE hProfile);
@ -1141,7 +1116,7 @@ LCMSAPI void LCMSEXPORT cmsSetProfileID(cmsHPROFILE hProfile, LPBYTE Pr
// CRD special // CRD special
#define cmsFLAGS_NODEFAULTRESOURCEDEF 0x00010000 #define cmsFLAGS_NODEFAULTRESOURCEDEF 0x01000000
// Gridpoints // Gridpoints
@ -1221,7 +1196,7 @@ typedef struct {
// Named color support // Named color support
LCMSAPI int LCMSEXPORT cmsNamedColorCount(cmsHTRANSFORM xform); LCMSAPI int LCMSEXPORT cmsNamedColorCount(cmsHTRANSFORM xform);
LCMSAPI BOOL LCMSEXPORT cmsNamedColorInfo(cmsHTRANSFORM xform, int nColor, char* Name, char* Prefix, char* Suffix); LCMSAPI LCMSBOOL LCMSEXPORT cmsNamedColorInfo(cmsHTRANSFORM xform, int nColor, char* Name, char* Prefix, char* Suffix);
LCMSAPI int LCMSEXPORT cmsNamedColorIndex(cmsHTRANSFORM xform, const char* Name); LCMSAPI int LCMSEXPORT cmsNamedColorIndex(cmsHTRANSFORM xform, const char* Name);
// Colorant tables // Colorant tables
@ -1230,7 +1205,7 @@ LCMSAPI LPcmsNAMEDCOLORLIST LCMSEXPORT cmsReadColorantTable(cmsHPROFILE hProfile
// Profile creation // Profile creation
LCMSAPI BOOL LCMSEXPORT cmsAddTag(cmsHPROFILE hProfile, icTagSignature sig, const void* data); LCMSAPI LCMSBOOL LCMSEXPORT cmsAddTag(cmsHPROFILE hProfile, icTagSignature sig, const void* data);
// Converts a transform to a devicelink profile // Converts a transform to a devicelink profile
LCMSAPI cmsHPROFILE LCMSEXPORT cmsTransform2DeviceLink(cmsHTRANSFORM hTransform, DWORD dwFlags); LCMSAPI cmsHPROFILE LCMSEXPORT cmsTransform2DeviceLink(cmsHTRANSFORM hTransform, DWORD dwFlags);
@ -1240,8 +1215,8 @@ LCMSAPI void LCMSEXPORT _cmsSetLUTdepth(cmsHPROFILE hProfile, int depth);
// Save profile // Save profile
LCMSAPI BOOL LCMSEXPORT _cmsSaveProfile(cmsHPROFILE hProfile, const char* FileName); LCMSAPI LCMSBOOL LCMSEXPORT _cmsSaveProfile(cmsHPROFILE hProfile, const char* FileName);
LCMSAPI BOOL LCMSEXPORT _cmsSaveProfileToMem(cmsHPROFILE hProfile, void *MemPtr, LCMSAPI LCMSBOOL LCMSEXPORT _cmsSaveProfileToMem(cmsHPROFILE hProfile, void *MemPtr,
size_t* BytesNeeded); size_t* BytesNeeded);
@ -1286,6 +1261,7 @@ LCMSAPI double LCMSEXPORT cmsEvalLUTreverse(LPLUT Lut, WORD Target[], WORD Resul
LCMSAPI LPLUT LCMSEXPORT cmsReadICCLut(cmsHPROFILE hProfile, icTagSignature sig); LCMSAPI LPLUT LCMSEXPORT cmsReadICCLut(cmsHPROFILE hProfile, icTagSignature sig);
LCMSAPI LPLUT LCMSEXPORT cmsDupLUT(LPLUT Orig); LCMSAPI LPLUT LCMSEXPORT cmsDupLUT(LPLUT Orig);
// LUT Sampling // LUT Sampling
typedef int (* _cmsSAMPLER)(register WORD In[], typedef int (* _cmsSAMPLER)(register WORD In[],
@ -1325,35 +1301,37 @@ LCMSAPI int LCMSEXPORT cmsIT8SetTable(LCMSHANDLE IT8, int nTable);
// Persistence // Persistence
LCMSAPI LCMSHANDLE LCMSEXPORT cmsIT8LoadFromFile(const char* cFileName); LCMSAPI LCMSHANDLE LCMSEXPORT cmsIT8LoadFromFile(const char* cFileName);
LCMSAPI LCMSHANDLE LCMSEXPORT cmsIT8LoadFromMem(void *Ptr, size_t len); LCMSAPI LCMSHANDLE LCMSEXPORT cmsIT8LoadFromMem(void *Ptr, size_t len);
LCMSAPI BOOL LCMSEXPORT cmsIT8SaveToFile(LCMSHANDLE IT8, const char* cFileName); LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SaveToFile(LCMSHANDLE IT8, const char* cFileName);
LCMSAPI BOOL LCMSEXPORT cmsIT8SaveToMem(LCMSHANDLE hIT8, void *MemPtr, size_t* BytesNeeded); LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SaveToMem(LCMSHANDLE hIT8, void *MemPtr, size_t* BytesNeeded);
// Properties // Properties
LCMSAPI const char* LCMSEXPORT cmsIT8GetSheetType(LCMSHANDLE hIT8); LCMSAPI const char* LCMSEXPORT cmsIT8GetSheetType(LCMSHANDLE hIT8);
LCMSAPI BOOL LCMSEXPORT cmsIT8SetSheetType(LCMSHANDLE hIT8, const char* Type); LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SetSheetType(LCMSHANDLE hIT8, const char* Type);
LCMSAPI BOOL LCMSEXPORT cmsIT8SetComment(LCMSHANDLE hIT8, const char* cComment); LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SetComment(LCMSHANDLE hIT8, const char* cComment);
LCMSAPI BOOL LCMSEXPORT cmsIT8SetPropertyStr(LCMSHANDLE hIT8, const char* cProp, const char *Str); LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SetPropertyStr(LCMSHANDLE hIT8, const char* cProp, const char *Str);
LCMSAPI BOOL LCMSEXPORT cmsIT8SetPropertyDbl(LCMSHANDLE hIT8, const char* cProp, double Val); LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SetPropertyDbl(LCMSHANDLE hIT8, const char* cProp, double Val);
LCMSAPI BOOL LCMSEXPORT cmsIT8SetPropertyHex(LCMSHANDLE hIT8, const char* cProp, int Val); LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SetPropertyHex(LCMSHANDLE hIT8, const char* cProp, int Val);
LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SetPropertyMulti(LCMSHANDLE hIT8, const char* cProp, const char* cSubProp, const char *Val);
LCMSAPI BOOL LCMSEXPORT cmsIT8SetPropertyUncooked(LCMSHANDLE hIT8, const char* Key, const char* Buffer); LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SetPropertyUncooked(LCMSHANDLE hIT8, const char* Key, const char* Buffer);
LCMSAPI const char* LCMSEXPORT cmsIT8GetProperty(LCMSHANDLE hIT8, const char* cProp); LCMSAPI const char* LCMSEXPORT cmsIT8GetProperty(LCMSHANDLE hIT8, const char* cProp);
LCMSAPI double LCMSEXPORT cmsIT8GetPropertyDbl(LCMSHANDLE hIT8, const char* cProp); LCMSAPI double LCMSEXPORT cmsIT8GetPropertyDbl(LCMSHANDLE hIT8, const char* cProp);
LCMSAPI int LCMSEXPORT cmsIT8EnumProperties(LCMSHANDLE IT8, char ***PropertyNames); LCMSAPI const char* LCMSEXPORT cmsIT8GetPropertyMulti(LCMSHANDLE hIT8, const char* cProp, const char *cSubProp);
LCMSAPI int LCMSEXPORT cmsIT8EnumProperties(LCMSHANDLE hIT8, const char ***PropertyNames);
LCMSAPI int LCMSEXPORT cmsIT8EnumPropertyMulti(LCMSHANDLE hIT8, const char* cProp, const char*** SubpropertyNames);
// Datasets // Datasets
LCMSAPI const char* LCMSEXPORT cmsIT8GetDataRowCol(LCMSHANDLE IT8, int row, int col); LCMSAPI const char* LCMSEXPORT cmsIT8GetDataRowCol(LCMSHANDLE IT8, int row, int col);
LCMSAPI double LCMSEXPORT cmsIT8GetDataRowColDbl(LCMSHANDLE IT8, int row, int col); LCMSAPI double LCMSEXPORT cmsIT8GetDataRowColDbl(LCMSHANDLE IT8, int row, int col);
LCMSAPI BOOL LCMSEXPORT cmsIT8SetDataRowCol(LCMSHANDLE hIT8, int row, int col, LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SetDataRowCol(LCMSHANDLE hIT8, int row, int col,
const char* Val); const char* Val);
LCMSAPI BOOL LCMSEXPORT cmsIT8SetDataRowColDbl(LCMSHANDLE hIT8, int row, int col, LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SetDataRowColDbl(LCMSHANDLE hIT8, int row, int col,
double Val); double Val);
LCMSAPI const char* LCMSEXPORT cmsIT8GetData(LCMSHANDLE IT8, const char* cPatch, const char* cSample); LCMSAPI const char* LCMSEXPORT cmsIT8GetData(LCMSHANDLE IT8, const char* cPatch, const char* cSample);
@ -1361,25 +1339,28 @@ LCMSAPI const char* LCMSEXPORT cmsIT8GetData(LCMSHANDLE IT8, const char* cPa
LCMSAPI double LCMSEXPORT cmsIT8GetDataDbl(LCMSHANDLE IT8, const char* cPatch, const char* cSample); LCMSAPI double LCMSEXPORT cmsIT8GetDataDbl(LCMSHANDLE IT8, const char* cPatch, const char* cSample);
LCMSAPI BOOL LCMSEXPORT cmsIT8SetData(LCMSHANDLE IT8, const char* cPatch, LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SetData(LCMSHANDLE IT8, const char* cPatch,
const char* cSample, const char* cSample,
const char *Val); const char *Val);
LCMSAPI BOOL LCMSEXPORT cmsIT8SetDataDbl(LCMSHANDLE hIT8, const char* cPatch, LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SetDataDbl(LCMSHANDLE hIT8, const char* cPatch,
const char* cSample, const char* cSample,
double Val); double Val);
LCMSAPI int LCMSEXPORT cmsIT8GetDataFormat(LCMSHANDLE hIT8, const char* cSample); LCMSAPI int LCMSEXPORT cmsIT8GetDataFormat(LCMSHANDLE hIT8, const char* cSample);
LCMSAPI BOOL LCMSEXPORT cmsIT8SetDataFormat(LCMSHANDLE IT8, int n, const char *Sample); LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SetDataFormat(LCMSHANDLE IT8, int n, const char *Sample);
LCMSAPI int LCMSEXPORT cmsIT8EnumDataFormat(LCMSHANDLE IT8, char ***SampleNames); LCMSAPI int LCMSEXPORT cmsIT8EnumDataFormat(LCMSHANDLE IT8, char ***SampleNames);
LCMSAPI const char* LCMSEXPORT cmsIT8GetPatchName(LCMSHANDLE hIT8, int nPatch, char* buffer); LCMSAPI const char* LCMSEXPORT cmsIT8GetPatchName(LCMSHANDLE hIT8, int nPatch, char* buffer);
LCMSAPI int LCMSEXPORT cmsIT8GetPatchByName(LCMSHANDLE hIT8, const char *cSample);
// The LABEL extension // The LABEL extension
LCMSAPI int LCMSEXPORT cmsIT8SetTableByLabel(LCMSHANDLE hIT8, const char* cSet, const char* cField, const char* ExpectedType); LCMSAPI int LCMSEXPORT cmsIT8SetTableByLabel(LCMSHANDLE hIT8, const char* cSet, const char* cField, const char* ExpectedType);
LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SetIndexColumn(LCMSHANDLE hIT8, const char* cSample);
// Formatter for double // Formatter for double
LCMSAPI void LCMSEXPORT cmsIT8DefineDblFormat(LCMSHANDLE IT8, const char* Formatter); LCMSAPI void LCMSEXPORT cmsIT8DefineDblFormat(LCMSHANDLE IT8, const char* Formatter);
@ -1405,15 +1386,16 @@ LCMSAPI void LCMSEXPORT cmsFloat2XYZEncoded(WORD XYZ[3], const cmsCIEXY
// Profiling Extensions --- Would be removed from API in future revisions // Profiling Extensions --- Would be removed from API in future revisions
LCMSAPI BOOL LCMSEXPORT _cmsAddTextTag(cmsHPROFILE hProfile, icTagSignature sig, const char* Text); LCMSAPI LCMSBOOL LCMSEXPORT _cmsAddTextTag(cmsHPROFILE hProfile, icTagSignature sig, const char* Text);
LCMSAPI BOOL LCMSEXPORT _cmsAddXYZTag(cmsHPROFILE hProfile, icTagSignature sig, const cmsCIEXYZ* XYZ); LCMSAPI LCMSBOOL LCMSEXPORT _cmsAddXYZTag(cmsHPROFILE hProfile, icTagSignature sig, const cmsCIEXYZ* XYZ);
LCMSAPI BOOL LCMSEXPORT _cmsAddLUTTag(cmsHPROFILE hProfile, icTagSignature sig, const void* lut); LCMSAPI LCMSBOOL LCMSEXPORT _cmsAddLUTTag(cmsHPROFILE hProfile, icTagSignature sig, const void* lut);
LCMSAPI BOOL LCMSEXPORT _cmsAddGammaTag(cmsHPROFILE hProfile, icTagSignature sig, LPGAMMATABLE TransferFunction); LCMSAPI LCMSBOOL LCMSEXPORT _cmsAddGammaTag(cmsHPROFILE hProfile, icTagSignature sig, LPGAMMATABLE TransferFunction);
LCMSAPI BOOL LCMSEXPORT _cmsAddChromaticityTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsCIExyYTRIPLE Chrm); LCMSAPI LCMSBOOL LCMSEXPORT _cmsAddChromaticityTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsCIExyYTRIPLE Chrm);
LCMSAPI BOOL LCMSEXPORT _cmsAddSequenceDescriptionTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsSEQ PSeq); LCMSAPI LCMSBOOL LCMSEXPORT _cmsAddSequenceDescriptionTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsSEQ PSeq);
LCMSAPI BOOL LCMSEXPORT _cmsAddNamedColorTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsNAMEDCOLORLIST nc); LCMSAPI LCMSBOOL LCMSEXPORT _cmsAddNamedColorTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsNAMEDCOLORLIST nc);
LCMSAPI BOOL LCMSEXPORT _cmsAddDateTimeTag(cmsHPROFILE hProfile, icTagSignature sig, struct tm *DateTime); LCMSAPI LCMSBOOL LCMSEXPORT _cmsAddDateTimeTag(cmsHPROFILE hProfile, icTagSignature sig, struct tm *DateTime);
LCMSAPI BOOL LCMSEXPORT _cmsAddColorantTableTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsNAMEDCOLORLIST nc); LCMSAPI LCMSBOOL LCMSEXPORT _cmsAddColorantTableTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsNAMEDCOLORLIST nc);
LCMSAPI LCMSBOOL LCMSEXPORT _cmsAddChromaticAdaptationTag(cmsHPROFILE hProfile, icTagSignature sig, const cmsCIEXYZ* mat);
// --------------------------------------------------------------------------------------------------- Inline functions // --------------------------------------------------------------------------------------------------- Inline functions
@ -1455,6 +1437,38 @@ LCMS_INLINE WORD _cmsClampWord(int in)
return (WORD) in; return (WORD) in;
} }
#ifndef LCMS_USER_ALLOC
// Low-level alloc hook
LCMS_INLINE void* _cmsMalloc(size_t size)
{
if (size > ((size_t) 1024*1024*500)) return NULL; // Never allow over 500Mb
if (size < 0) return NULL; // Prevent signed size_t exploits
return (void*) malloc(size);
}
LCMS_INLINE void* _cmsCalloc(size_t nmemb, size_t size)
{
size_t alloc = nmemb * size;
if (size == 0) {
return _cmsMalloc(0);
}
if (alloc / size != nmemb) {
return NULL;
}
return _cmsMalloc(alloc);
}
LCMS_INLINE void _cmsFree(void *Ptr)
{
if (Ptr) free(Ptr);
}
#endif
// ------------------------------------------------------------------------------------------- end of inline functions // ------------------------------------------------------------------------------------------- end of inline functions
// Signal error from inside lcms code // Signal error from inside lcms code
@ -1541,8 +1555,8 @@ void cdecl VEC3divK(LPVEC3 r, LPVEC3 v, double d);
void cdecl VEC3perK(LPVEC3 r, LPVEC3 v, double d); void cdecl VEC3perK(LPVEC3 r, LPVEC3 v, double d);
void cdecl VEC3minus(LPVEC3 r, LPVEC3 a, LPVEC3 b); void cdecl VEC3minus(LPVEC3 r, LPVEC3 a, LPVEC3 b);
void cdecl VEC3perComp(LPVEC3 r, LPVEC3 a, LPVEC3 b); void cdecl VEC3perComp(LPVEC3 r, LPVEC3 a, LPVEC3 b);
BOOL cdecl VEC3equal(LPWVEC3 a, LPWVEC3 b, double Tolerance); LCMSBOOL cdecl VEC3equal(LPWVEC3 a, LPWVEC3 b, double Tolerance);
BOOL cdecl VEC3equalF(LPVEC3 a, LPVEC3 b, double Tolerance); LCMSBOOL cdecl VEC3equalF(LPVEC3 a, LPVEC3 b, double Tolerance);
void cdecl VEC3scaleAndCut(LPWVEC3 r, LPVEC3 v, double d); void cdecl VEC3scaleAndCut(LPWVEC3 r, LPVEC3 v, double d);
void cdecl VEC3cross(LPVEC3 r, LPVEC3 u, LPVEC3 v); void cdecl VEC3cross(LPVEC3 r, LPVEC3 u, LPVEC3 v);
void cdecl VEC3saturate(LPVEC3 v); void cdecl VEC3saturate(LPVEC3 v);
@ -1553,13 +1567,13 @@ void cdecl MAT3identity(LPMAT3 a);
void cdecl MAT3per(LPMAT3 r, LPMAT3 a, LPMAT3 b); void cdecl MAT3per(LPMAT3 r, LPMAT3 a, LPMAT3 b);
void cdecl MAT3perK(LPMAT3 r, LPMAT3 v, double d); void cdecl MAT3perK(LPMAT3 r, LPMAT3 v, double d);
int cdecl MAT3inverse(LPMAT3 a, LPMAT3 b); int cdecl MAT3inverse(LPMAT3 a, LPMAT3 b);
BOOL cdecl MAT3solve(LPVEC3 x, LPMAT3 a, LPVEC3 b); LCMSBOOL cdecl MAT3solve(LPVEC3 x, LPMAT3 a, LPVEC3 b);
double cdecl MAT3det(LPMAT3 m); double cdecl MAT3det(LPMAT3 m);
void cdecl MAT3eval(LPVEC3 r, LPMAT3 a, LPVEC3 v); void cdecl MAT3eval(LPVEC3 r, LPMAT3 a, LPVEC3 v);
void cdecl MAT3toFix(LPWMAT3 r, LPMAT3 v); void cdecl MAT3toFix(LPWMAT3 r, LPMAT3 v);
void cdecl MAT3fromFix(LPMAT3 r, LPWMAT3 v); void cdecl MAT3fromFix(LPMAT3 r, LPWMAT3 v);
void cdecl MAT3evalW(LPWVEC3 r, LPWMAT3 a, LPWVEC3 v); void cdecl MAT3evalW(LPWVEC3 r, LPWMAT3 a, LPWVEC3 v);
BOOL cdecl MAT3isIdentity(LPWMAT3 a, double Tolerance); LCMSBOOL cdecl MAT3isIdentity(LPWMAT3 a, double Tolerance);
void cdecl MAT3scaleAndCut(LPWMAT3 r, LPMAT3 v, double d); void cdecl MAT3scaleAndCut(LPWMAT3 r, LPMAT3 v, double d);
// Is a table linear? // Is a table linear?
@ -1608,7 +1622,7 @@ typedef struct _lcms_l16params_struc { // Used on 16 bits interpolations
void cdecl cmsCalcL16Params(int nSamples, LPL16PARAMS p); void cdecl cmsCalcL16Params(int nSamples, LPL16PARAMS p);
void cdecl cmsCalcCLUT16Params(int nSamples, int InputChan, int OutputChan, LPL16PARAMS p); void cdecl cmsCalcCLUT16Params(int nSamples, int InputChan, int OutputChan, LPL16PARAMS p);
void cdecl cmsCalcCLUT16ParamsEx(int nSamples, int InputChan, int OutputChan, void cdecl cmsCalcCLUT16ParamsEx(int nSamples, int InputChan, int OutputChan,
BOOL lUseTetrahedral, LPL16PARAMS p); LCMSBOOL lUseTetrahedral, LPL16PARAMS p);
WORD cdecl cmsLinearInterpLUT16(WORD Value, WORD LutTable[], LPL16PARAMS p); WORD cdecl cmsLinearInterpLUT16(WORD Value, WORD LutTable[], LPL16PARAMS p);
Fixed32 cdecl cmsLinearInterpFixed(WORD Value1, WORD LutTable[], LPL16PARAMS p); Fixed32 cdecl cmsLinearInterpFixed(WORD Value1, WORD LutTable[], LPL16PARAMS p);
@ -1692,7 +1706,7 @@ struct _lcms_LUT_struc {
// Gray axes fixup. Only on v2 8-bit Lab LUT // Gray axes fixup. Only on v2 8-bit Lab LUT
BOOL FixGrayAxes; LCMSBOOL FixGrayAxes;
// Parameters used for curve creation // Parameters used for curve creation
@ -1703,7 +1717,7 @@ struct _lcms_LUT_struc {
}; // LUT, FAR* LPLUT; }; // LUT, FAR* LPLUT;
BOOL cdecl _cmsSmoothEndpoints(LPWORD Table, int nEntries); LCMSBOOL cdecl _cmsSmoothEndpoints(LPWORD Table, int nEntries);
// CRC of gamma tables // CRC of gamma tables
@ -1721,7 +1735,7 @@ LPGAMMATABLE cdecl cmsConvertSampledCurveToGamma(LPSAMPLEDCURVE Sampled, doubl
void cdecl cmsEndpointsOfSampledCurve(LPSAMPLEDCURVE p, double* Min, double* Max); void cdecl cmsEndpointsOfSampledCurve(LPSAMPLEDCURVE p, double* Min, double* Max);
void cdecl cmsClampSampledCurve(LPSAMPLEDCURVE p, double Min, double Max); void cdecl cmsClampSampledCurve(LPSAMPLEDCURVE p, double Min, double Max);
BOOL cdecl cmsSmoothSampledCurve(LPSAMPLEDCURVE Tab, double SmoothingLambda); LCMSBOOL cdecl cmsSmoothSampledCurve(LPSAMPLEDCURVE Tab, double SmoothingLambda);
void cdecl cmsRescaleSampledCurve(LPSAMPLEDCURVE p, double Min, double Max, int nPoints); void cdecl cmsRescaleSampledCurve(LPSAMPLEDCURVE p, double Min, double Max, int nPoints);
LPSAMPLEDCURVE cdecl cmsJoinSampledCurves(LPSAMPLEDCURVE X, LPSAMPLEDCURVE Y, int nResultingPoints); LPSAMPLEDCURVE cdecl cmsJoinSampledCurves(LPSAMPLEDCURVE X, LPSAMPLEDCURVE Y, int nResultingPoints);
@ -1755,7 +1769,7 @@ LPMATSHAPER cdecl cmsAllocMatShaper2(LPMAT3 matrix, LPGAMMATABLE In[], LPGAMMATA
void cdecl cmsFreeMatShaper(LPMATSHAPER MatShaper); void cdecl cmsFreeMatShaper(LPMATSHAPER MatShaper);
void cdecl cmsEvalMatShaper(LPMATSHAPER MatShaper, WORD In[], WORD Out[]); void cdecl cmsEvalMatShaper(LPMATSHAPER MatShaper, WORD In[], WORD Out[]);
BOOL cdecl cmsReadICCMatrixRGB2XYZ(LPMAT3 r, cmsHPROFILE hProfile); LCMSBOOL cdecl cmsReadICCMatrixRGB2XYZ(LPMAT3 r, cmsHPROFILE hProfile);
LPMATSHAPER cdecl cmsBuildInputMatrixShaper(cmsHPROFILE InputProfile); LPMATSHAPER cdecl cmsBuildInputMatrixShaper(cmsHPROFILE InputProfile);
LPMATSHAPER cdecl cmsBuildOutputMatrixShaper(cmsHPROFILE OutputProfile); LPMATSHAPER cdecl cmsBuildOutputMatrixShaper(cmsHPROFILE OutputProfile);
@ -1763,11 +1777,11 @@ LPMATSHAPER cdecl cmsBuildOutputMatrixShaper(cmsHPROFILE OutputProfile);
// White Point & Primary chromas handling // White Point & Primary chromas handling
BOOL cdecl cmsAdaptationMatrix(LPMAT3 r, LPMAT3 ConeMatrix, LPcmsCIEXYZ FromIll, LPcmsCIEXYZ ToIll); LCMSBOOL cdecl cmsAdaptationMatrix(LPMAT3 r, LPMAT3 ConeMatrix, LPcmsCIEXYZ FromIll, LPcmsCIEXYZ ToIll);
BOOL cdecl cmsAdaptMatrixToD50(LPMAT3 r, LPcmsCIExyY SourceWhitePt); LCMSBOOL cdecl cmsAdaptMatrixToD50(LPMAT3 r, LPcmsCIExyY SourceWhitePt);
BOOL cdecl cmsAdaptMatrixFromD50(LPMAT3 r, LPcmsCIExyY DestWhitePt); LCMSBOOL cdecl cmsAdaptMatrixFromD50(LPMAT3 r, LPcmsCIExyY DestWhitePt);
BOOL cdecl cmsReadChromaticAdaptationMatrix(LPMAT3 r, cmsHPROFILE hProfile); LCMSBOOL cdecl cmsReadChromaticAdaptationMatrix(LPMAT3 r, cmsHPROFILE hProfile);
// Inter-PCS conversion routines. They assume D50 as white point. // Inter-PCS conversion routines. They assume D50 as white point.
void cdecl cmsXYZ2LabEncoded(WORD XYZ[3], WORD Lab[3]); void cdecl cmsXYZ2LabEncoded(WORD XYZ[3], WORD Lab[3]);
@ -1782,7 +1796,7 @@ WORD cdecl _cmsQuantizeVal(double i, int MaxSamples);
LPcmsNAMEDCOLORLIST cdecl cmsAllocNamedColorList(int n); LPcmsNAMEDCOLORLIST cdecl cmsAllocNamedColorList(int n);
int cdecl cmsReadICCnamedColorList(cmsHTRANSFORM xform, cmsHPROFILE hProfile, icTagSignature sig); int cdecl cmsReadICCnamedColorList(cmsHTRANSFORM xform, cmsHPROFILE hProfile, icTagSignature sig);
void cdecl cmsFreeNamedColorList(LPcmsNAMEDCOLORLIST List); void cdecl cmsFreeNamedColorList(LPcmsNAMEDCOLORLIST List);
BOOL cdecl cmsAppendNamedColor(cmsHTRANSFORM xform, const char* Name, WORD PCS[3], WORD Colorant[MAXCHANNELS]); LCMSBOOL cdecl cmsAppendNamedColor(cmsHTRANSFORM xform, const char* Name, WORD PCS[3], WORD Colorant[MAXCHANNELS]);
// I/O // I/O
@ -1826,8 +1840,8 @@ typedef struct _lcms_iccprofile_struct {
char PhysicalFile[MAX_PATH]; char PhysicalFile[MAX_PATH];
BOOL IsWrite; LCMSBOOL IsWrite;
BOOL SaveAs8Bits; LCMSBOOL SaveAs8Bits;
struct tm Created; struct tm Created;
@ -1835,14 +1849,14 @@ typedef struct _lcms_iccprofile_struct {
size_t (* Read)(void *buffer, size_t size, size_t count, struct _lcms_iccprofile_struct* Icc); size_t (* Read)(void *buffer, size_t size, size_t count, struct _lcms_iccprofile_struct* Icc);
BOOL (* Seek)(struct _lcms_iccprofile_struct* Icc, size_t offset); LCMSBOOL (* Seek)(struct _lcms_iccprofile_struct* Icc, size_t offset);
BOOL (* Close)(struct _lcms_iccprofile_struct* Icc); LCMSBOOL (* Close)(struct _lcms_iccprofile_struct* Icc);
size_t (* Tell)(struct _lcms_iccprofile_struct* Icc); size_t (* Tell)(struct _lcms_iccprofile_struct* Icc);
BOOL (* Grow)(struct _lcms_iccprofile_struct* Icc, size_t amount); LCMSBOOL (* Grow)(struct _lcms_iccprofile_struct* Icc, size_t amount);
// Writting // Writting
BOOL (* Write)(struct _lcms_iccprofile_struct* Icc, size_t size, LPVOID Ptr); LCMSBOOL (* Write)(struct _lcms_iccprofile_struct* Icc, size_t size, LPVOID Ptr);
size_t UsedSpace; size_t UsedSpace;
@ -1854,7 +1868,7 @@ typedef struct _lcms_iccprofile_struct {
cmsHPROFILE cdecl _cmsCreateProfilePlaceholder(void); cmsHPROFILE cdecl _cmsCreateProfilePlaceholder(void);
// Search into tag dictionary // Search into tag dictionary
icInt32Number cdecl _cmsSearchTag(LPLCMSICCPROFILE Profile, icTagSignature sig, BOOL lSignalError); icInt32Number cdecl _cmsSearchTag(LPLCMSICCPROFILE Profile, icTagSignature sig, LCMSBOOL lSignalError);
// Search for a particular tag, replace if found or add new one else // Search for a particular tag, replace if found or add new one else
LPVOID _cmsInitTag(LPLCMSICCPROFILE Icc, icTagSignature sig, size_t size, const void* Init); LPVOID _cmsInitTag(LPLCMSICCPROFILE Icc, icTagSignature sig, size_t size, const void* Init);
@ -1870,6 +1884,7 @@ void _cmsSetSaveToMemory(LPLCMSICCPROFILE Icc, LPVOID MemPtr, size_t dwSize);
// These macros unpack format specifiers into integers // These macros unpack format specifiers into integers
#define T_DITHER(s) (((s)>>22)&1)
#define T_COLORSPACE(s) (((s)>>16)&31) #define T_COLORSPACE(s) (((s)>>16)&31)
#define T_SWAPFIRST(s) (((s)>>14)&1) #define T_SWAPFIRST(s) (((s)>>14)&1)
#define T_FLAVOR(s) (((s)>>13)&1) #define T_FLAVOR(s) (((s)>>13)&1)
@ -1966,7 +1981,7 @@ typedef struct _cmstransform_struct {
// Flag for transform involving v4 profiles // Flag for transform involving v4 profiles
BOOL lInputV4Lab, lOutputV4Lab; LCMSBOOL lInputV4Lab, lOutputV4Lab;
// 1-pixel cache // 1-pixel cache
@ -2013,7 +2028,7 @@ int cdecl cmsChooseCnvrt(int Absolute,
// Clamping & Gamut handling // Clamping & Gamut handling
BOOL cdecl _cmsEndPointsBySpace(icColorSpaceSignature Space, LCMSBOOL cdecl _cmsEndPointsBySpace(icColorSpaceSignature Space,
WORD **White, WORD **Black, int *nOutputs); WORD **White, WORD **Black, int *nOutputs);
WORD * cdecl _cmsWhiteBySpace(icColorSpaceSignature Space); WORD * cdecl _cmsWhiteBySpace(icColorSpaceSignature Space);
@ -2042,7 +2057,7 @@ LPLUT _cmsPrecalculateBlackPreservingDeviceLink(cmsHTRANSFORM hCMYK2CMYK, DWORD
LPLUT cdecl _cmsPrecalculateGamutCheck(cmsHTRANSFORM h); LPLUT cdecl _cmsPrecalculateGamutCheck(cmsHTRANSFORM h);
// Hot fixes bad profiles // Hot fixes bad profiles
BOOL cdecl _cmsFixWhiteMisalignment(_LPcmsTRANSFORM p); LCMSBOOL cdecl _cmsFixWhiteMisalignment(_LPcmsTRANSFORM p);
// Marks LUT as 8 bit on input // Marks LUT as 8 bit on input
LPLUT cdecl _cmsBlessLUT8(LPLUT Lut); LPLUT cdecl _cmsBlessLUT8(LPLUT Lut);
@ -2060,6 +2075,10 @@ void cdecl _cmsComputePrelinearizationTablesFromXFORM(cmsHTRANSFORM h[], int nTr
// Build a tone curve for K->K' if possible (only works on CMYK) // Build a tone curve for K->K' if possible (only works on CMYK)
LPGAMMATABLE _cmsBuildKToneCurve(cmsHTRANSFORM hCMYK2CMYK, int nPoints); LPGAMMATABLE _cmsBuildKToneCurve(cmsHTRANSFORM hCMYK2CMYK, int nPoints);
// Validates a LUT
LCMSBOOL cdecl _cmsValidateLUT(LPLUT NewLUT);
// These are two VITAL macros, from converting between 8 and 16 bit // These are two VITAL macros, from converting between 8 and 16 bit
// representation. // representation.
@ -2077,3 +2096,4 @@ LPGAMMATABLE _cmsBuildKToneCurve(cmsHTRANSFORM hCMYK2CMYK, int nPoints);
#endif #endif
#endif #endif