提交 2c9872eb 编写于 作者: P prr

6821031: Upgrade OpenJDK's LittleCMS version to 1.18

Reviewed-by: bae, igor
上级 bde204b6
......@@ -374,6 +374,10 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagData
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
* 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");
}
BOOL _cmsModifyTagData(cmsHPROFILE hProfile, icTagSignature sig,
LCMSBOOL _cmsModifyTagData(cmsHPROFILE hProfile, icTagSignature sig,
void *data, size_t size)
{
BOOL isNew;
LCMSBOOL isNew;
int i, idx, delta, count;
LPBYTE padChars[3] = {0, 0, 0};
LPBYTE beforeBuf, afterBuf, ptr;
......
......@@ -29,7 +29,7 @@
//
//
// 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
// 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"
......@@ -196,6 +196,10 @@ CAM02COLOR NonlinearCompression(CAM02COLOR clr, LPcmsCIECAM02 pMod)
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;
}
......@@ -249,9 +253,6 @@ CAM02COLOR ComputeCorrelates(CAM02COLOR clr, LPcmsCIECAM02 pMod)
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),
(pMod->c * pMod->z));
......@@ -395,7 +396,7 @@ LCMSHANDLE LCMSEXPORT cmsCIECAM02Init(LPcmsViewingConditions pVC)
LPcmsCIECAM02 lpMod;
if((lpMod = (LPcmsCIECAM02) malloc(sizeof(cmsCIECAM02))) == NULL) {
if((lpMod = (LPcmsCIECAM02) _cmsMalloc(sizeof(cmsCIECAM02))) == NULL) {
return (LCMSHANDLE) NULL;
}
......@@ -449,14 +450,19 @@ LCMSHANDLE LCMSEXPORT cmsCIECAM02Init(LPcmsViewingConditions pVC)
lpMod -> z = compute_z(lpMod);
lpMod -> Nbb = computeNbb(lpMod);
lpMod -> FL = computeFL(lpMod);
if (lpMod -> D == D_CALCULATE ||
lpMod -> D == D_CALCULATE_DISCOUNT) {
lpMod -> D = computeD(lpMod);
}
lpMod -> Ncb = lpMod -> Nbb;
lpMod -> adoptedWhite = XYZtoCAT02(lpMod -> adoptedWhite);
lpMod -> adoptedWhite = ChromaticAdaptation(lpMod -> adoptedWhite, lpMod);
lpMod -> adoptedWhite = CAT02toHPE(lpMod -> adoptedWhite);
lpMod -> adoptedWhite = NonlinearCompression(lpMod -> adoptedWhite, lpMod);
lpMod -> adoptedWhite = ComputeCorrelates(lpMod -> adoptedWhite, lpMod);
return (LCMSHANDLE) lpMod;
......@@ -465,7 +471,7 @@ LCMSHANDLE LCMSEXPORT cmsCIECAM02Init(LPcmsViewingConditions pVC)
void LCMSEXPORT cmsCIECAM02Done(LCMSHANDLE 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];
}
......@@ -29,7 +29,7 @@
//
//
// 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
// a copy of this software and associated documentation files (the "Software"),
......@@ -174,7 +174,7 @@ typedef struct {
LCMSAPI void LCMSEXPORT cmsCIECAM97sDone(LCMSHANDLE hModel)
{
LPcmsCIECAM97s lpMod = (LPcmsCIECAM97s) (LPSTR) hModel;
if (lpMod) free(lpMod);
if (lpMod) _cmsFree(lpMod);
}
// Partial discounting for adaptation degree computation
......@@ -331,7 +331,7 @@ LCMSAPI LCMSHANDLE LCMSEXPORT cmsCIECAM97sInit(LPcmsViewingConditions pVC)
LPcmsCIECAM97s lpMod;
VEC3 tmp;
if((lpMod = (LPcmsCIECAM97s) malloc(sizeof(cmsCIECAM97s))) == NULL) {
if((lpMod = (LPcmsCIECAM97s) _cmsMalloc(sizeof(cmsCIECAM97s))) == NULL) {
return (LCMSHANDLE) NULL;
}
......@@ -449,7 +449,7 @@ LCMSAPI LCMSHANDLE LCMSEXPORT cmsCIECAM97sInit(LPcmsViewingConditions pVC)
// RGB_subw = [MlamRigg][WP/YWp]
#ifdef USE_CIECAM97s2
MAT3eval(&lpMod -> RGB_subw, &lpMod -> MlamRigg, (LPVEC3) &lpMod -> WP);
MAT3eval(&lpMod -> RGB_subw, &lpMod -> MlamRigg, &lpMod -> WP);
#else
VEC3divK(&tmp, (LPVEC3) &lpMod -> WP, lpMod->WP.Y);
MAT3eval(&lpMod -> RGB_subw, &lpMod -> MlamRigg, &tmp);
......
......@@ -29,7 +29,7 @@
//
//
// 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
// 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
static
BOOL IdentityParameters(LPWMAT3 m, LPWVEC3 of)
LCMSBOOL IdentityParameters(LPWMAT3 m, LPWVEC3 of)
{
WVEC3 wv0;
......@@ -661,3 +661,6 @@ int cmsChooseCnvrt(int Absolute,
return rc;
}
......@@ -29,7 +29,7 @@
//
//
// 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
// a copy of this software and associated documentation files (the "Software"),
......@@ -57,6 +57,7 @@
// errors.
void cdecl cmsSignalError(int ErrorCode, const char *ErrorText, ...);
int LCMSEXPORT cmsErrorAction(int lAbort);
void LCMSEXPORT cmsSetErrorHandler(cmsErrorHandlerFunction Fn);
......@@ -96,7 +97,7 @@ void cmsSignalError(int ErrorCode, const char *ErrorText, ...)
char Buffer[1024];
vsprintf(Buffer, ErrorText, args);
vsnprintf(Buffer, 1023, ErrorText, args);
va_end(args);
if (UserErrorHandler(ErrorCode, Buffer)) {
......@@ -118,8 +119,8 @@ void cmsSignalError(int ErrorCode, const char *ErrorText, ...)
char Buffer1[1024];
char Buffer2[256];
sprintf(Buffer1, "Error #%x; ", ErrorCode);
vsprintf(Buffer2, ErrorText, args);
snprintf(Buffer1, 767, "Error #%x; ", ErrorCode);
vsnprintf(Buffer2, 255, ErrorText, args);
strcat(Buffer1, Buffer2);
MessageBox(NULL, Buffer1, "Little cms",
MB_OK|MB_ICONSTOP|MB_TASKMODAL);
......
......@@ -29,7 +29,7 @@
//
//
// 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
// 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 cmsJoinGamma(LPGAMMATABLE InGamma, LPGAMMATABLE OutGamma);
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
......@@ -74,7 +74,7 @@ LPSAMPLEDCURVE cdecl cmsAllocSampledCurve(int nItems);
void cdecl cmsFreeSampledCurve(LPSAMPLEDCURVE p);
void cdecl cmsEndpointsOfSampledCurve(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);
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
typedef float vec[MAX_KNOTS+1];
......@@ -144,14 +143,14 @@ LPGAMMATABLE LCMSEXPORT cmsAllocGamma(int nEntries)
LPGAMMATABLE p;
size_t size;
if (nEntries > 65530) {
cmsSignalError(LCMS_ERRC_WARNING, "Couldn't create gammatable of more than 65530 entries; 65530 assumed");
nEntries = 65530;
if (nEntries > 65530 || nEntries <= 0) {
cmsSignalError(LCMS_ERRC_ABORTED, "Couldn't create gammatable of more than 65530 entries");
return NULL;
}
size = sizeof(GAMMATABLE) + (sizeof(WORD) * (nEntries-1));
p = (LPGAMMATABLE) malloc(size);
p = (LPGAMMATABLE) _cmsMalloc(size);
if (!p) return NULL;
ZeroMemory(p, size);
......@@ -164,7 +163,7 @@ LPGAMMATABLE LCMSEXPORT cmsAllocGamma(int nEntries)
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;
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);
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
BOOL LCMSEXPORT cmsSmoothGamma(LPGAMMATABLE Tab, double lambda)
LCMSBOOL LCMSEXPORT cmsSmoothGamma(LPGAMMATABLE Tab, double lambda)
{
vec w, y, z;
......@@ -640,13 +648,13 @@ LPSAMPLEDCURVE cmsAllocSampledCurve(int nItems)
{
LPSAMPLEDCURVE pOut;
pOut = (LPSAMPLEDCURVE) malloc(sizeof(SAMPLEDCURVE));
pOut = (LPSAMPLEDCURVE) _cmsMalloc(sizeof(SAMPLEDCURVE));
if (pOut == 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;
}
......@@ -659,8 +667,8 @@ LPSAMPLEDCURVE cmsAllocSampledCurve(int nItems)
void cmsFreeSampledCurve(LPSAMPLEDCURVE p)
{
free((LPVOID) p -> Values);
free((LPVOID) p);
_cmsFree((LPVOID) p -> Values);
_cmsFree((LPVOID) p);
}
......@@ -731,7 +739,7 @@ void cmsClampSampledCurve(LPSAMPLEDCURVE p, double Min, double Max)
// Smooths a curve sampled at regular intervals
BOOL cmsSmoothSampledCurve(LPSAMPLEDCURVE Tab, double lambda)
LCMSBOOL cmsSmoothSampledCurve(LPSAMPLEDCURVE Tab, double lambda)
{
vec w, y, z;
int i, nItems;
......@@ -915,14 +923,11 @@ LPSAMPLEDCURVE cmsConvertGammaToSampledCurve(LPGAMMATABLE Gamma, int nPoints)
// Smooth endpoints (used in Black/White compensation)
BOOL _cmsSmoothEndpoints(LPWORD Table, int nEntries)
LCMSBOOL _cmsSmoothEndpoints(LPWORD Table, int nEntries)
{
vec w, y, z;
int i, Zeros, Poles;
#ifdef DEBUG
ASAVE(Table, nEntries, "nonsmt.txt");
#endif
if (cmsIsLinear(Table, nEntries)) return FALSE; // Nothing to do
......
......@@ -29,7 +29,7 @@
//
//
// 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
// 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)
{
// Only most common spaces
......@@ -376,7 +376,6 @@ double LCMSEXPORT cmsCIE2000DeltaE(LPcmsCIELab Lab1, LPcmsCIELab Lab2,
double bs = Lab2 ->b;
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 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 h_ps = atan2deg(a_ps, b_ps);
double meanC_p =(C_p + C_ps) / 2;
double hps_plus_hp = h_ps + h_p;
double hps_minus_hp = h_ps - h_p;
double meanC_p =(C_p + C_ps) / 2;
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 meanh_p = fabs(h_ps-h_p) <= 180 ? (h_ps + h_p)/2 : (h_ps+h_p-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);
......@@ -1065,7 +1070,7 @@ void SlopeLimiting(WORD Table[], int nEntries)
// Check for monotonicity.
static
BOOL IsMonotonic(LPGAMMATABLE t)
LCMSBOOL IsMonotonic(LPGAMMATABLE t)
{
int n = t -> nEntries;
int i, last;
......@@ -1088,7 +1093,7 @@ BOOL IsMonotonic(LPGAMMATABLE t)
// Check for endpoints
static
BOOL HasProperEndpoints(LPGAMMATABLE t)
LCMSBOOL HasProperEndpoints(LPGAMMATABLE t)
{
if (t ->GammaTable[0] != 0) 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;
int j;
WORD In[MAXCHANNELS], Out[MAXCHANNELS];
BOOL lIsSuitable;
LCMSBOOL lIsSuitable;
_LPcmsTRANSFORM InputXForm = (_LPcmsTRANSFORM) h[0];
_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) ||
(OutputXForm->ExitColorSpace != icSigRgbData)) return;
if (((InputXForm ->EntryColorSpace != icSigRgbData) && (InputXForm ->EntryColorSpace != icSigGrayData)) ||
((OutputXForm->ExitColorSpace != icSigRgbData) && (OutputXForm->ExitColorSpace != icSigGrayData))) return;
for (t = 0; t < Grid -> InputChan; t++)
......@@ -1169,10 +1174,13 @@ void _cmsComputePrelinearizationTablesFromXFORM(cmsHTRANSFORM h[], int nTransfor
if (!HasProperEndpoints(Trans[t]))
lIsSuitable = FALSE;
/*
// Exclude if transfer function is not smooth enough
// to be modelled as a gamma function, or the gamma is reversed
if (cmsEstimateGamma(Trans[t]) < 1.0)
lIsSuitable = FALSE;
*/
}
......
......@@ -29,7 +29,7 @@
//
//
// 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
// 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
void cmsCalcCLUT16ParamsEx(int nSamples, int InputChan, int OutputChan,
BOOL lUseTetrahedral, LPL16PARAMS p)
LCMSBOOL lUseTetrahedral, LPL16PARAMS p)
{
int clutPoints;
......@@ -579,7 +579,7 @@ WORD cmsReverseLinearInterpLUT16(WORD Value, WORD LutTable[], LPL16PARAMS p)
// Identify if value fall downto 0 or FFFF zone
if (Value == 0) return 0;
if (Value == 0xFFFF) return 0xFFFF;
// if (Value == 0xFFFF) return 0xFFFF;
// else restrict to valid zone
......@@ -631,7 +631,7 @@ WORD cmsReverseLinearInterpLUT16(WORD Value, WORD LutTable[], LPL16PARAMS p)
a = (y1 - y0) / (x1 - x0);
b = y0 - a * x0;
if (a == 0) return (WORD) x;
if (fabs(a) < 0.01) return (WORD) x;
f = ((Value - b) / a);
......@@ -1131,3 +1131,4 @@ void cmsTetrahedralInterp8(WORD Input[],
}
#undef DENS
......@@ -29,7 +29,7 @@
//
//
// 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
// a copy of this software and associated documentation files (the "Software"),
......@@ -62,7 +62,7 @@
typedef struct {
LPBYTE Block; // Points to 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
} FILEMEM;
......@@ -70,18 +70,19 @@ typedef struct {
static
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));
if (Mode == 'r') {
fm ->Block = (LPBYTE) malloc(Size);
fm ->Block = (LPBYTE) _cmsMalloc(Size);
if (fm ->Block == NULL) {
free(fm);
_cmsFree(fm);
return NULL;
}
CopyMemory(fm->Block, Block, Size);
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;
LPBYTE Ptr;
size_t len = size * count;
size_t extent = ResData -> Pointer + len;
if (len == 0) {
return 0;
}
if (len / size != count) {
cmsSignalError(LCMS_ERRC_ABORTED, "Read from memory error. Integer overflow with count / size.");
return 0;
}
if (ResData -> Pointer + len > ResData -> Size){
if (extent < len || extent < ResData -> Pointer) {
cmsSignalError(LCMS_ERRC_ABORTED, "Read from memory error. Integer overflow with len.");
return 0;
}
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);
if (ResData -> Pointer + len > ResData -> Size) {
len = (ResData -> Size - ResData -> Pointer);
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;
......@@ -123,7 +138,7 @@ size_t MemoryRead(LPVOID buffer, size_t size, size_t count, struct _lcms_iccprof
// SEEK_CUR is assumed
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;
......@@ -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
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;
......@@ -167,11 +182,17 @@ BOOL MemoryWrite(struct _lcms_iccprofile_struct* Icc, size_t size, void *Ptr)
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;
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) {
return FALSE;
......@@ -183,15 +204,15 @@ BOOL MemoryGrow(struct _lcms_iccprofile_struct* Icc, size_t size)
static
BOOL MemoryClose(struct _lcms_iccprofile_struct* Icc)
LCMSBOOL MemoryClose(struct _lcms_iccprofile_struct* Icc)
{
FILEMEM* ResData = (FILEMEM*) Icc ->stream;
if (ResData ->FreeBlockOnClose) {
if (ResData ->Block) free(ResData ->Block);
if (ResData ->Block) _cmsFree(ResData ->Block);
}
free(ResData);
_cmsFree(ResData);
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);
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;
}
......@@ -218,7 +239,7 @@ size_t FileRead(void *buffer, size_t size, size_t count, struct _lcms_iccprofile
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) {
......@@ -240,7 +261,7 @@ size_t FileTell(struct _lcms_iccprofile_struct* Icc)
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;
......@@ -256,14 +277,14 @@ BOOL FileWrite(struct _lcms_iccprofile_struct* Icc, size_t size, LPVOID Ptr)
static
BOOL FileGrow(struct _lcms_iccprofile_struct* Icc, size_t size)
LCMSBOOL FileGrow(struct _lcms_iccprofile_struct* Icc, size_t size)
{
return TRUE;
}
static
BOOL FileClose(struct _lcms_iccprofile_struct* Icc)
LCMSBOOL FileClose(struct _lcms_iccprofile_struct* Icc)
{
return fclose((FILE*) Icc ->stream);
}
......@@ -276,7 +297,7 @@ BOOL FileClose(struct _lcms_iccprofile_struct* Icc)
cmsHPROFILE _cmsCreateProfilePlaceholder(void)
{
LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) malloc(sizeof(LCMSICCPROFILE));
LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) _cmsMalloc(sizeof(LCMSICCPROFILE));
if (Icc == NULL) return NULL;
// Empty values
......@@ -314,7 +335,7 @@ icTagSignature LCMSEXPORT cmsGetTagSignature(cmsHPROFILE hProfile, icInt32Number
// Search for a specific tag in tag dictionary
// 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;
......@@ -335,7 +356,7 @@ icInt32Number _cmsSearchTag(LPLCMSICCPROFILE Profile, icTagSignature sig, BOOL l
// Check existance
BOOL LCMSEXPORT cmsIsTag(cmsHPROFILE hProfile, icTagSignature sig)
LCMSBOOL LCMSEXPORT cmsIsTag(cmsHPROFILE hProfile, icTagSignature sig)
{
LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
return _cmsSearchTag(Icc, sig, FALSE) >= 0;
......@@ -354,7 +375,7 @@ LPVOID _cmsInitTag(LPLCMSICCPROFILE Icc, icTagSignature sig, size_t size, const
if (i >=0) {
if (Icc -> TagPtrs[i]) free(Icc -> TagPtrs[i]);
if (Icc -> TagPtrs[i]) _cmsFree(Icc -> TagPtrs[i]);
}
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);
Icc ->TagCount = MAX_TABLE_TAG-1;
return NULL;
}
}
Ptr = malloc(size);
Ptr = _cmsMalloc(size);
if (Ptr == NULL) return NULL;
CopyMemory(Ptr, Init, size);
Icc ->TagNames[i] = sig;
......@@ -400,6 +424,8 @@ LPLCMSICCPROFILE _cmsCreateProfileFromFilePlaceholder(const char* FileName)
if (NewIcc == NULL) return NULL;
strncpy(NewIcc -> PhysicalFile, FileName, MAX_PATH-1);
NewIcc -> PhysicalFile[MAX_PATH-1] = 0;
NewIcc ->stream = ICCfile;
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;
*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;
*Dest = Icc -> MediaBlackPoint;
return TRUE;
}
BOOL LCMSEXPORT cmsTakeIluminant(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile)
LCMSBOOL LCMSEXPORT cmsTakeIluminant(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile)
{
LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) hProfile;
*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;
CopyMemory(Dest, &Icc ->Created, sizeof(struct tm));
......@@ -596,23 +622,18 @@ void LCMSEXPORT cmsSetPCS(cmsHPROFILE hProfile, icColorSpaceSignature pcs)
Icc -> PCS = pcs;
}
icColorSpaceSignature LCMSEXPORT cmsGetColorSpace(cmsHPROFILE hProfile)
{
LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) hProfile;
return Icc -> ColorSpace;
}
void LCMSEXPORT cmsSetColorSpace(cmsHPROFILE hProfile, icColorSpaceSignature sig)
{
LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) hProfile;
Icc -> ColorSpace = sig;
}
icProfileClassSignature LCMSEXPORT cmsGetDeviceClass(cmsHPROFILE hProfile)
{
LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) hProfile;
......@@ -625,7 +646,6 @@ DWORD LCMSEXPORT cmsGetProfileICCversion(cmsHPROFILE hProfile)
return (DWORD) Icc -> Version;
}
void LCMSEXPORT cmsSetProfileICCversion(cmsHPROFILE hProfile, DWORD Version)
{
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
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;
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;
......@@ -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;
......@@ -709,7 +729,7 @@ BOOL LCMSEXPORT _cmsAddTextTag(cmsHPROFILE hProfile, icTagSignature sig, const c
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;
......@@ -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;
......@@ -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;
......@@ -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;
_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;
_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;
_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;
}
......@@ -29,7 +29,7 @@
//
//
// 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
// a copy of this software and associated documentation files (the "Software"),
......@@ -118,7 +118,7 @@ LPLUT LCMSEXPORT cmsAllocLUT(void)
{
LPLUT NewLUT;
NewLUT = (LPLUT) malloc(sizeof(LUT));
NewLUT = (LPLUT) _cmsMalloc(sizeof(LUT));
if (NewLUT)
ZeroMemory(NewLUT, sizeof(LUT));
......@@ -171,9 +171,10 @@ void LCMSEXPORT cmsFreeLUT(LPLUT Lut)
static
LPVOID DupBlockTab(LPVOID Org, size_t size)
{
LPVOID mem = malloc(size);
LPVOID mem = _cmsMalloc(size);
if (mem != NULL)
CopyMemory(mem, Org, size);
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)
{
DWORD nTabSize;
......@@ -220,12 +252,17 @@ LPLUT LCMSEXPORT cmsAlloc3DGrid(LPLUT NewLUT, int clutPoints, int inputChan, int
NewLUT -> InputChan = inputChan;
NewLUT -> OutputChan = outputChan;
if (!_cmsValidateLUT(NewLUT)) {
return NULL;
}
nTabSize = NewLUT -> OutputChan * UIpow(NewLUT->cLutPoints,
NewLUT->InputChan);
nTabSize = (NewLUT -> OutputChan * UIpow(NewLUT->cLutPoints,
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);
NewLUT ->Tsize = nTabSize;
......@@ -254,7 +291,9 @@ LPLUT LCMSEXPORT cmsAllocLinearTable(LPLUT NewLUT, LPGAMMATABLE Tables[], int nT
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;
CopyMemory(PtrW, Tables[i]->GammaTable, sizeof(WORD) * NewLUT -> InputEntries);
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;
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;
CopyMemory(PtrW, Tables[i]->GammaTable, sizeof(WORD) * NewLUT -> OutputEntries);
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++) {
PtrW = (LPWORD) malloc(sizeof(WORD) * NewLUT -> L3Entries);
PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * NewLUT -> L3Entries);
if (PtrW == NULL) return NULL;
NewLUT -> L3[i] = PtrW;
CopyMemory(PtrW, Tables[i]->GammaTable, sizeof(WORD) * NewLUT -> L3Entries);
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;
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;
CopyMemory(PtrW, Tables[i]->GammaTable, sizeof(WORD) * NewLUT -> L4Entries);
CopyMemory(&NewLUT -> LCurvesSeed[3][i], &Tables[i] -> Seed, sizeof(LCMSGAMMAPARAMS));
......@@ -580,7 +625,7 @@ LPLUT _cmsBlessLUT8(LPLUT Lut)
LPL16PARAMS p = &Lut ->CLut16params;
p8 = (LPL8PARAMS) malloc(sizeof(L8PARAMS));
p8 = (LPL8PARAMS) _cmsMalloc(sizeof(L8PARAMS));
if (p8 == NULL) return NULL;
// 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) {
for (j=0; j < 3; j++)
StageABC[i] = cmsLinearInterpLUT16(StageABC[i],
Lut -> L1[i],
StageABC[j] = cmsLinearInterpLUT16(StageABC[j],
Lut -> L1[j],
&Lut -> In16params);
Lut ->wFlags &= ~LUT_HASTL1;
}
......@@ -822,3 +867,6 @@ LCMSAPI double LCMSEXPORT cmsEvalLUTreverse(LPLUT Lut, WORD Target[], WORD Resul
return LastError;
}
......@@ -29,7 +29,7 @@
//
//
// 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
// 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.
// Then, we obtain data on 15.16, so we need to shift >> by 1 to
// obtain 1.15 PCS format.
// 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
// 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
// then the matrix, an additional FromFixedDomain() must be used to
// accomodate output values.
// For a sake of simplicity, I will handle this three behaviours
// with different routines, so the flags MATSHAPER_INPUT and MATSHAPER_OUTPUT
// can be conbined to signal smelted matrix-shapers
......@@ -89,7 +91,7 @@ int ComputeTables(LPGAMMATABLE Table[3], LPWORD Out[3], LPL16PARAMS p16)
{
LPWORD PtrW;
PtrW = (LPWORD) malloc(sizeof(WORD) * p16 -> nSamples);
PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * p16 -> nSamples);
if (PtrW == NULL) return -1; // Signal error
......@@ -119,7 +121,7 @@ LPMATSHAPER cmsAllocMatShaper2(LPMAT3 Matrix, LPGAMMATABLE In[], LPGAMMATABLE Ou
LPMATSHAPER NewMatShaper;
int rc;
NewMatShaper = (LPMATSHAPER) malloc(sizeof(MATSHAPER));
NewMatShaper = (LPMATSHAPER) _cmsMalloc(sizeof(MATSHAPER));
if (NewMatShaper)
ZeroMemory(NewMatShaper, sizeof(MATSHAPER));
......@@ -171,7 +173,13 @@ LPMATSHAPER cmsAllocMatShaper(LPMAT3 Matrix, LPGAMMATABLE Tables[], DWORD Behavi
LPMATSHAPER NewMatShaper;
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)
ZeroMemory(NewMatShaper, sizeof(MATSHAPER));
......@@ -187,17 +195,16 @@ LPMATSHAPER cmsAllocMatShaper(LPMAT3 Matrix, LPGAMMATABLE Tables[], DWORD Behavi
NewMatShaper -> dwFlags |= MATSHAPER_HASMATRIX;
// Now, on the table characteristics
cmsCalcL16Params(Tables[0] -> nEntries, &NewMatShaper -> p16);
// Copy tables
AllLinear = 0;
for (i=0; i < 3; i++)
{
for (i=0; i < 3; i++) {
LPWORD PtrW;
PtrW = (LPWORD) malloc(sizeof(WORD) * NewMatShaper -> p16.nSamples);
PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * NewMatShaper -> p16.nSamples);
if (PtrW == NULL) {
cmsFreeMatShaper(NewMatShaper);
......@@ -235,11 +242,11 @@ void cmsFreeMatShaper(LPMATSHAPER MatShaper)
for (i=0; i < 3; i++)
{
if (MatShaper -> L[i]) free(MatShaper ->L[i]);
if (MatShaper -> L2[i]) free(MatShaper ->L2[i]);
if (MatShaper -> L[i]) _cmsFree(MatShaper ->L[i]);
if (MatShaper -> L2[i]) _cmsFree(MatShaper ->L2[i]);
}
free(MatShaper);
_cmsFree(MatShaper);
}
......
......@@ -29,7 +29,7 @@
//
//
// 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
// 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 MAT3per(LPMAT3 r, 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);
void cdecl MAT3eval(LPVEC3 r, LPMAT3 a, LPVEC3 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
static
BOOL RangeCheck(double l, double h, double v)
LCMSBOOL RangeCheck(double l, double h, double v)
{
return (v >= l && v <= h);
}
BOOL VEC3equal(LPWVEC3 a, LPWVEC3 b, double Tolerance)
LCMSBOOL VEC3equal(LPWVEC3 a, LPWVEC3 b, double Tolerance)
{
int i;
double c;
......@@ -367,7 +367,7 @@ BOOL VEC3equal(LPWVEC3 a, LPWVEC3 b, double Tolerance)
return TRUE;
}
BOOL VEC3equalF(LPVEC3 a, LPVEC3 b, double Tolerance)
LCMSBOOL VEC3equalF(LPVEC3 a, LPVEC3 b, double Tolerance)
{
int i;
double c;
......@@ -462,7 +462,7 @@ void MAT3identity(LPMAT3 a)
// Check if matrix is Identity. Allow a tolerance as %
BOOL MAT3isIdentity(LPWMAT3 a, double Tolerance)
LCMSBOOL MAT3isIdentity(LPWMAT3 a, double Tolerance)
{
int i;
MAT3 Idd;
......@@ -545,7 +545,7 @@ int MAT3inverse(LPMAT3 a, LPMAT3 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;
......@@ -839,3 +839,7 @@ void MAT3scaleAndCut(LPWMAT3 r, LPMAT3 v, double d)
VEC3scaleAndCut(&r -> v[1], &v -> v[1], d);
VEC3scaleAndCut(&r -> v[2], &v -> v[2], d);
}
......@@ -29,7 +29,7 @@
//
//
// 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
// a copy of this software and associated documentation files (the "Software"),
......@@ -74,7 +74,7 @@ LPcmsNAMEDCOLORLIST GrowNamedColorList(LPcmsNAMEDCOLORLIST v, int ByElements)
NewElements *= 2;
size = sizeof(cmsNAMEDCOLORLIST) + (sizeof(cmsNAMEDCOLOR) * NewElements);
TheNewList = (LPcmsNAMEDCOLORLIST) malloc(size);
TheNewList = (LPcmsNAMEDCOLORLIST) _cmsMalloc(size);
if (TheNewList == NULL) {
......@@ -86,7 +86,7 @@ LPcmsNAMEDCOLORLIST GrowNamedColorList(LPcmsNAMEDCOLORLIST v, int ByElements)
CopyMemory(TheNewList, v, sizeof(cmsNAMEDCOLORLIST) + (v ->nColors - 1) * sizeof(cmsNAMEDCOLOR));
TheNewList -> Allocated = NewElements;
free(v);
_cmsFree(v);
return TheNewList;
}
}
......@@ -99,7 +99,7 @@ LPcmsNAMEDCOLORLIST cmsAllocNamedColorList(int n)
{
size_t size = sizeof(cmsNAMEDCOLORLIST) + (n - 1) * sizeof(cmsNAMEDCOLOR);
LPcmsNAMEDCOLORLIST v = (LPcmsNAMEDCOLORLIST) malloc(size);
LPcmsNAMEDCOLORLIST v = (LPcmsNAMEDCOLORLIST) _cmsMalloc(size);
if (v == NULL) {
......@@ -124,10 +124,10 @@ void cmsFreeNamedColorList(LPcmsNAMEDCOLORLIST v)
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;
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];
strncpy(List ->List[List ->nColors].Name, Name, MAX_PATH-1);
List ->List[List ->nColors].Name[MAX_PATH-1] = 0;
List ->nColors++;
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;
if (v ->NamedColorList == NULL) return FALSE;
if (nColor < 0 || nColor >= cmsNamedColorCount(xform)) return FALSE;
if (Name) strncpy(Name, v ->NamedColorList->List[nColor].Name, 31);
if (Prefix) strncpy(Prefix, v ->NamedColorList->Prefix, 31);
if (Suffix) strncpy(Suffix, v ->NamedColorList->Suffix, 31);
if (Name) { strncpy(Name, v ->NamedColorList->List[nColor].Name, 31); Name[31] = 0; }
if (Prefix) { strncpy(Prefix, v ->NamedColorList->Prefix, 31); Prefix[31] = 0; }
if (Suffix) { strncpy(Suffix, v ->NamedColorList->Suffix, 31); Suffix[31] = 0; }
return TRUE;
}
......@@ -196,3 +196,5 @@ int LCMSEXPORT cmsNamedColorIndex(cmsHTRANSFORM xform, const char* Name)
return -1;
}
......@@ -28,7 +28,7 @@
// file:
//
// 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
// 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
// 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
static
......@@ -1486,6 +1558,9 @@ _cmsFIXFN _cmsIdentifyInputFormat(_LPcmsTRANSFORM xform, DWORD dwInput)
case PT_HSV:
case PT_HLS:
case PT_Yxy:
if (T_CHANNELS(dwInput) == 1)
FromInput = UnrollDouble1Chan;
else
FromInput = UnrollDouble;
break;
......@@ -1749,6 +1824,9 @@ _cmsFIXFN _cmsIdentifyOutputFormat(_LPcmsTRANSFORM xform, DWORD dwOutput)
switch (T_CHANNELS(dwOutput))
{
case 1:
if (T_DITHER(dwOutput))
ToOutput = PackNBytesDither;
else
ToOutput = Pack1Byte;
if (T_EXTRA(dwOutput) == 1) {
if (T_SWAPFIRST(dwOutput))
......@@ -1766,8 +1844,12 @@ _cmsFIXFN _cmsIdentifyOutputFormat(_LPcmsTRANSFORM xform, DWORD dwOutput)
else
if (T_COLORSPACE(dwOutput) == PT_Lab)
ToOutput = Pack3BytesLab;
else {
if (T_DITHER(dwOutput))
ToOutput = PackNBytesDither;
else
ToOutput = Pack3Bytes;
}
break;
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) {
if (T_DOSWAP(dwOutput)) {
if (T_SWAPFIRST(dwOutput))
if (T_SWAPFIRST(dwOutput)) {
ToOutput = Pack4BytesSwapSwapFirst;
else
}
else {
if (T_DITHER(dwOutput)) {
ToOutput = PackNBytesSwapDither;
}
else {
ToOutput = Pack4BytesSwap;
}
}
}
else {
if (T_SWAPFIRST(dwOutput))
......@@ -1807,11 +1899,15 @@ _cmsFIXFN _cmsIdentifyOutputFormat(_LPcmsTRANSFORM xform, DWORD dwOutput)
if (T_FLAVOR(dwOutput))
ToOutput = Pack4BytesReverse;
else {
if (T_DITHER(dwOutput))
ToOutput = PackNBytesDither;
else
ToOutput = Pack4Bytes;
}
}
}
}
else {
if (!T_DOSWAP(dwOutput) && !T_SWAPFIRST(dwOutput))
ToOutput = PackNBytes;
......@@ -1849,9 +1945,14 @@ _cmsFIXFN _cmsIdentifyOutputFormat(_LPcmsTRANSFORM xform, DWORD dwOutput)
{
if (T_DOSWAP(dwOutput))
ToOutput = PackNBytesSwap;
else {
if (T_DITHER(dwOutput))
ToOutput = PackNBytesDither;
else
ToOutput = PackNBytes;
}
}
break;
default:;
......
......@@ -29,7 +29,7 @@
//
//
// 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
// 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]);
}
......@@ -29,7 +29,7 @@
//
//
// 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
// 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 [<...>]]
/RangeABC [ 0 1 0 1 0 1]
/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]
/WhitePoint [D50]
/BlackPoint [BP]
......@@ -347,7 +349,8 @@ typedef struct {
static
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));
......@@ -387,7 +390,6 @@ BYTE L2Byte(WORD w)
static
void WriteRawByte(LPMEMSTREAM m, BYTE b)
{
if (m -> dwUsed + 1 > m -> dwMax) {
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
void Writef(LPMEMSTREAM m, const char *frm, ...)
{
......@@ -432,7 +434,7 @@ void Writef(LPMEMSTREAM m, const char *frm, ...)
va_start(args, frm);
vsprintf((char*) Buffer, frm, args);
vsnprintf((char*) Buffer, 2048, frm, args);
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, "]\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, "{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");
......@@ -584,7 +586,11 @@ void Emit1Gamma(LPMEMSTREAM m, LPWORD Table, int nEntries)
if (nEntries <= 0) return; // Empty table
// 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"
gamma = cmsEstimateGammaEx(Table, nEntries, 0.001);
......@@ -646,7 +652,7 @@ void Emit1Gamma(LPMEMSTREAM m, LPWORD Table, int nEntries)
// Compare gamma table
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;
}
......@@ -676,7 +682,7 @@ void EmitNGamma(LPMEMSTREAM m, int n, LPWORD g[], int nEntries)
// Check whatever a profile has CLUT tables (only on input)
static
BOOL IsLUTbased(cmsHPROFILE hProfile, int Intent)
LCMSBOOL IsLUTbased(cmsHPROFILE hProfile, int Intent)
{
icTagSignature Tag;
......@@ -718,10 +724,10 @@ int OutputValueSampler(register WORD In[], register WORD Out[], register LPVOID
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) ||
(In[2] >= 0x8000 && In[2] <= 0x87FF)) {
if ((In[1] >= 0x7800 && In[1] <= 0x8800) &&
(In[2] >= 0x7800 && In[2] <= 0x8800)) {
WORD* Black;
WORD* White;
......@@ -830,7 +836,7 @@ void WriteCLUT(LPMEMSTREAM m, LPLUT Lut, int bps, const char* PreMaj,
sc.PostMaj= PostMaj;
sc.PreMin = PreMin;
sc.PostMin= PostMin;
sc.PostMin = PostMin;
sc.lIsInput = lIsInput;
sc.FixWhite = FixWhite;
sc.ColorSpace = ColorSpace;
......@@ -1231,7 +1237,7 @@ DWORD LCMSEXPORT cmsGetPostScriptCSA(cmsHPROFILE hProfile,
if (!WriteNamedColorCSA(mem, hProfile, Intent)) {
free((void*) mem);
_cmsFree((void*) mem);
return 0;
}
}
......@@ -1246,7 +1252,7 @@ DWORD LCMSEXPORT cmsGetPostScriptCSA(cmsHPROFILE hProfile,
ColorSpace != icSigLabData) {
cmsSignalError(LCMS_ERRC_ABORTED, "Invalid output color space");
free((void*) mem);
_cmsFree((void*) mem);
return 0;
}
......@@ -1256,7 +1262,7 @@ DWORD LCMSEXPORT cmsGetPostScriptCSA(cmsHPROFILE hProfile,
// Yes, so handle as LUT-based
if (!WriteInputLUT(mem, hProfile, Intent)) {
free((void*) mem);
_cmsFree((void*) mem);
return 0;
}
}
......@@ -1266,7 +1272,7 @@ DWORD LCMSEXPORT cmsGetPostScriptCSA(cmsHPROFILE hProfile,
if (!WriteInputMatrixShaper(mem, hProfile)) {
free((void*) mem); // Something went wrong
_cmsFree((void*) mem); // Something went wrong
return 0;
}
}
......@@ -1277,7 +1283,7 @@ DWORD LCMSEXPORT cmsGetPostScriptCSA(cmsHPROFILE hProfile,
dwBytesUsed = mem ->dwUsed;
// Get rid of memory stream
free((void*) mem);
_cmsFree((void*) mem);
// Finally, return used byte count
return dwBytesUsed;
......@@ -1350,27 +1356,40 @@ DWORD LCMSEXPORT cmsGetPostScriptCSA(cmsHPROFILE hProfile,
static
void EmitPQRStage(LPMEMSTREAM m, int DoBPC, int lIsAbsolute)
void EmitPQRStage(LPMEMSTREAM m, cmsHPROFILE hProfile, int DoBPC, int lIsAbsolute)
{
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");
if (lIsAbsolute) {
Writef(m, "/RangePQR [ -0.5 2 -0.5 2 -0.5 2 ]\n");
// For absolute colorimetric intent, encode back to relative
// and generate a relative LUT
// Relative encoding is obtained across XYZpcs*(D50/WhitePoint)
if (lIsAbsolute) {
cmsCIEXYZ White;
cmsTakeMediaWhitePoint(&White, hProfile);
// For absolute colorimetric intent, do nothing
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 -- no transformation\n"
Writef(m, "%% Absolute colorimetric -- encode to relative to maximize LUT usage\n"
"/TransformPQR [\n"
"{exch pop exch pop exch pop exch pop} bind dup dup]\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"
"/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");
// No BPC
if (!DoBPC) {
......@@ -1414,6 +1433,7 @@ void EmitPQRStage(LPMEMSTREAM m, int DoBPC, int lIsAbsolute)
static
void EmitXYZ2Lab(LPMEMSTREAM m)
{
Writef(m, "/RangeLMN [ -0.635 2.0 0 2 -0.635 2.0 ]\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, "{ 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, "{ 116 mul 16 sub 100 div } bind\n");
Writef(m, "{ 500 mul 128 add 255 div } bind\n");
Writef(m, "{ 200 mul 128 add 255 div } bind\n");
Writef(m, "{ 500 mul 128 add 256 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");
......@@ -1458,20 +1471,27 @@ int WriteOutputLUT(LPMEMSTREAM m, cmsHPROFILE hProfile, int Intent, DWORD dwFlag
LPLUT DeviceLink;
cmsHPROFILE Profiles[3];
cmsCIEXYZ BlackPointAdaptedToD50;
BOOL lFreeDeviceLink = FALSE;
BOOL lDoBPC = (dwFlags & cmsFLAGS_BLACKPOINTCOMPENSATION);
LCMSBOOL lFreeDeviceLink = FALSE;
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);
cmsSetProfileICCversion(hLab, 0);
hLab = cmsCreateLabProfile(NULL);
ColorSpace = cmsGetColorSpace(hProfile);
nChannels = _cmsChannelsOf(ColorSpace);
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?
if (cmsGetDeviceClass(hProfile) == icSigLinkClass) {
......@@ -1479,13 +1499,14 @@ int WriteOutputLUT(LPMEMSTREAM m, cmsHPROFILE hProfile, int Intent, DWORD dwFlag
if (ColorSpace == icSigLabData) {
// adjust input to Lab to out v4
// adjust input to Lab to our v4
Profiles[0] = hLab;
Profiles[1] = hProfile;
xform = cmsCreateMultiprofileTransform(Profiles, 2, TYPE_Lab_DBL,
OutputFormat, Intent, cmsFLAGS_NOPRELINEARIZATION);
OutputFormat, RelativeEncodingIntent,
dwFlags|cmsFLAGS_NOWHITEONWHITEFIXUP|cmsFLAGS_NOPRELINEARIZATION);
}
else {
......@@ -1499,7 +1520,7 @@ int WriteOutputLUT(LPMEMSTREAM m, cmsHPROFILE hProfile, int Intent, DWORD dwFlag
// This is a normal profile
xform = cmsCreateTransform(hLab, TYPE_Lab_DBL, hProfile,
OutputFormat, Intent, cmsFLAGS_NOPRELINEARIZATION);
OutputFormat, RelativeEncodingIntent, dwFlags|cmsFLAGS_NOWHITEONWHITEFIXUP|cmsFLAGS_NOPRELINEARIZATION);
}
if (xform == NULL) {
......@@ -1515,7 +1536,7 @@ int WriteOutputLUT(LPMEMSTREAM m, cmsHPROFILE hProfile, int Intent, DWORD dwFlag
if (!DeviceLink) {
DeviceLink = _cmsPrecalculateDeviceLink(xform, 0);
DeviceLink = _cmsPrecalculateDeviceLink(xform, cmsFLAGS_NOPRELINEARIZATION);
lFreeDeviceLink = TRUE;
}
......@@ -1527,7 +1548,7 @@ int WriteOutputLUT(LPMEMSTREAM m, cmsHPROFILE hProfile, int Intent, DWORD dwFlag
// Emit headers, etc.
EmitWhiteBlackD50(m, &BlackPointAdaptedToD50);
EmitPQRStage(m, lDoBPC, Intent == INTENT_ABSOLUTE_COLORIMETRIC);
EmitPQRStage(m, hProfile, lDoBPC, Intent == INTENT_ABSOLUTE_COLORIMETRIC);
EmitXYZ2Lab(m);
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
// scum dot. Ouch.
if (Intent == INTENT_ABSOLUTE_COLORIMETRIC)
lFixWhite = FALSE;
Writef(m, "/RenderTable ");
WriteCLUT(m, DeviceLink, 8, "<", ">\n", "", "", FALSE,
(Intent != INTENT_ABSOLUTE_COLORIMETRIC), ColorSpace);
lFixWhite, ColorSpace);
Writef(m, " %d {} bind ", nChannels);
......@@ -1582,6 +1606,9 @@ void BuildColorantList(char *Colorant, int nColorant, WORD Out[])
int j;
Colorant[0] = 0;
if (nColorant > MAXCHANNELS)
nColorant = MAXCHANNELS;
for (j=0; j < nColorant; j++) {
sprintf(Buff, "%.3f", Out[j] / 65535.0);
......@@ -1677,7 +1704,7 @@ DWORD LCMSEXPORT cmsGetPostScriptCRDEx(cmsHPROFILE hProfile,
if (!WriteNamedColorCRD(mem, hProfile, Intent, dwFlags)) {
free((void*) mem);
_cmsFree((void*) mem);
return 0;
}
}
......@@ -1687,7 +1714,7 @@ DWORD LCMSEXPORT cmsGetPostScriptCRDEx(cmsHPROFILE hProfile,
if (!WriteOutputLUT(mem, hProfile, Intent, dwFlags)) {
free((void*) mem);
_cmsFree((void*) mem);
return 0;
}
}
......@@ -1702,7 +1729,7 @@ DWORD LCMSEXPORT cmsGetPostScriptCRDEx(cmsHPROFILE hProfile,
dwBytesUsed = mem ->dwUsed;
// Get rid of memory stream
free((void*) mem);
_cmsFree((void*) mem);
// Finally, return used byte count
return dwBytesUsed;
......
......@@ -206,6 +206,11 @@ typedef __int32_t icInt64Number[2];
#if defined(__sun) || defined(__hpux) || defined (__MINGW) || defined(__MINGW32__)
#if defined (__MINGW) || defined(__MINGW32__)
#include <stdint.h>
#endif
typedef uint8_t icUInt8Number;
typedef uint16_t icUInt16Number;
typedef uint32_t icUInt32Number;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册