00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
#include <math.h>
00020
00021 #define MAX_LINELEN 240
00022 #define REVCURVE_RATIO 1
00023 #define CIEXYZRange 0x1FFEC // 1.9997 in 16.16 notation
00024 #define ALIGN_DWORD(nBytes) (((nBytes) + 3) & ~3)
00025
00026 #define FIX_16_16_SHIFT 16
00027 #define FIX_16_16_SCALE (1 << (FIX_16_16_SHIFT))
00028
00029 #define TO_FIX(x) ((x) << FIX_16_16_SHIFT)
00030 #define TO_INT(x) ((x) >> FIX_16_16_SHIFT)
00031 #define FIX_MUL(x, y) MulDiv((x), (y), FIX_16_16_SCALE)
00032 #define FIX_DIV(x, y) MulDiv((x), FIX_16_16_SCALE, (y))
00033
00034 #define FLOOR(x) ((x) >> FIX_16_16_SHIFT << FIX_16_16_SHIFT)
00035
00036 #define TYPE_CIEBASEDDEF 1
00037 #define TYPE_CIEBASEDDEFG 2
00038
00039 #define TAG_PS2CSA 'ps2s'
00040 #define TAG_REDCOLORANT 'rXYZ'
00041 #define TAG_GREENCOLORANT 'gXYZ'
00042 #define TAG_BLUECOLORANT 'bXYZ'
00043 #define TAG_REDTRC 'rTRC'
00044 #define TAG_GREENTRC 'gTRC'
00045 #define TAG_BLUETRC 'bTRC'
00046 #define TAG_GRAYTRC 'kTRC'
00047 #define TAG_MEDIAWHITEPOINT 'wtpt'
00048 #define TAG_AToB0 'A2B0'
00049 #define TAG_AToB1 'A2B1'
00050 #define TAG_AToB2 'A2B2'
00051 #define TAG_PS2INTENT0 'psi0'
00052 #define TAG_PS2INTENT1 'psi1'
00053 #define TAG_PS2INTENT2 'psi2'
00054 #define TAG_PS2INTENT3 'psi3'
00055 #define TAG_CRDINTENT0 'psd0'
00056 #define TAG_CRDINTENT1 'psd1'
00057 #define TAG_CRDINTENT2 'psd2'
00058 #define TAG_CRDINTENT3 'psd3'
00059 #define TAG_BToA0 'B2A0'
00060 #define TAG_BToA1 'B2A1'
00061 #define TAG_BToA2 'B2A2'
00062 #define TAG_BToA3 'B2A3'
00063
00064 #define LUT8_TYPE 'mft1'
00065 #define LUT16_TYPE 'mft2'
00066
00067 #define SIG_CURVE_TYPE 'curv'
00068
00069 #define GetCPConnSpace(pProfile) (FIX_ENDIAN(((PPROFILEHEADER)pProfile)->phConnectionSpace))
00070 #define GetCPDevSpace(pProfile) (FIX_ENDIAN(((PPROFILEHEADER)pProfile)->phDataColorSpace))
00071 #define GetCPRenderIntent(pProfile) (FIX_ENDIAN(((PPROFILEHEADER)pProfile)->phRenderingIntent))
00072 #define WriteObject(pBuf, pStr) (STRCPY(pBuf, pStr), STRLEN(pStr))
00073
00074
#ifdef KERNEL_MODE
00075
#define WriteInt(pBuf, i) OPSprintf(pBuf, "%l ", (i))
00076
#define WriteHex(pBuf, x) OPSprintf(pBuf, "%x", ((x) & 0x00FF))
00077
#define STRLEN strlen
00078
#define STRCPY strcpy
00079
#else
00080 #define WriteInt(pBuf, i) wsprintfA(pBuf, "%lu ", (i))
00081 #define WriteHex(pBuf, x) wsprintfA(pBuf, "%2.2x", ((x) & 0x00FF))
00082 #define STRLEN lstrlenA
00083 #define STRCPY lstrcpyA
00084
#endif
00085
00086 #define MAXCHANNELS 4
00087 #define PREVIEWCRDGRID 16
00088 #define MAXCOLOR8 255
00089
00090 #define DATATYPE_LUT 0
00091 #define DATATYPE_MATRIX 1
00092
00093 #define sRGB_CRC 0xa3d777b4L
00094 #define sRGB_TAGSIZE 6168
00095
00096
00097
00098
00099
00100 typedef DWORD FIX_16_16, *
PFIX_16_16;
00101
00102 typedef struct tagCURVETYPE {
00103 DWORD dwSignature;
00104 DWORD dwReserved;
00105 DWORD nCount;
00106 WORD
data[0];
00107 }
CURVETYPE, *
PCURVETYPE;
00108
00109 typedef struct tagXYZTYPE {
00110 DWORD dwSignature;
00111 DWORD dwReserved;
00112 FIX_16_16 afxData[0];
00113 }
XYZTYPE, *
PXYZTYPE;
00114
00115 typedef struct tagLUT8TYPE {
00116 DWORD dwSignature;
00117 DWORD dwReserved;
00118 BYTE nInputChannels;
00119 BYTE nOutputChannels;
00120 BYTE nClutPoints;
00121 BYTE padding;
00122 FIX_16_16 e00;
00123 FIX_16_16 e01;
00124 FIX_16_16 e02;
00125 FIX_16_16 e10;
00126 FIX_16_16 e11;
00127 FIX_16_16 e12;
00128 FIX_16_16 e20;
00129 FIX_16_16 e21;
00130 FIX_16_16 e22;
00131 BYTE data[0];
00132 }
LUT8TYPE, *
PLUT8TYPE;
00133
00134 typedef struct tagLUT16TYPE {
00135 DWORD dwSignature;
00136 DWORD dwReserved;
00137 BYTE nInputChannels;
00138 BYTE nOutputChannels;
00139 BYTE nClutPoints;
00140 BYTE padding;
00141 FIX_16_16 e00;
00142 FIX_16_16 e01;
00143 FIX_16_16 e02;
00144 FIX_16_16 e10;
00145 FIX_16_16 e11;
00146 FIX_16_16 e12;
00147 FIX_16_16 e20;
00148 FIX_16_16 e21;
00149 FIX_16_16 e22;
00150 WORD
wInputEntries;
00151 WORD
wOutputEntries;
00152 WORD
data[0];
00153 }
LUT16TYPE, *
PLUT16TYPE;
00154
00155
typedef struct tagHOSTCLUT {
00156 WORD
wSize;
00157 WORD
wDataType;
00158 DWORD dwDev;
00159 DWORD dwPCS;
00160 DWORD dwIntent;
00161 FIX_16_16 afxIlluminantWP[3];
00162 FIX_16_16 afxMediaWP[3];
00163 BYTE nInputCh;
00164 BYTE nOutputCh;
00165 BYTE nClutPoints;
00166 BYTE nLutBits;
00167 FIX_16_16 e[9];
00168 WORD
nInputEntries;
00169 WORD
nOutputEntries;
00170 PBYTE inputArray[
MAXCHANNELS];
00171 PBYTE outputArray[
MAXCHANNELS];
00172 PBYTE clut;
00173 }
HOSTCLUT, *
PHOSTCLUT;
00174
00175
00176
00177
00178
00179
BOOL IsSRGBColorProfile(PBYTE);
00180
00181
BOOL GetCSAFromProfile (PBYTE, DWORD, DWORD, PBYTE, PDWORD, PBOOL);
00182
BOOL GetPS2CSA_MONO_A(PBYTE, PBYTE, PDWORD, DWORD, PBOOL);
00183
BOOL GetPS2CSA_ABC(PBYTE, PBYTE, PDWORD, DWORD, PBOOL, BOOL);
00184
BOOL GetPS2CSA_ABC_Lab(PBYTE, PBYTE, PDWORD, DWORD, PBOOL);
00185
BOOL GetPS2CSA_DEFG(PBYTE, PBYTE, PDWORD, DWORD, DWORD, PBOOL);
00186
00187
BOOL CreateMonoCRD(PBYTE, DWORD, PBYTE, PDWORD, DWORD);
00188
BOOL CreateLutCRD(PBYTE, DWORD, PBYTE, PDWORD, DWORD, BOOL);
00189
00190
BOOL DoesCPTagExist(PBYTE, DWORD, PDWORD);
00191
BOOL DoesTRCAndColorantTagExist(PBYTE);
00192
BOOL GetCPWhitePoint(PBYTE, PFIX_16_16);
00193
BOOL GetCPMediaWhitePoint(PBYTE, PFIX_16_16);
00194
BOOL GetCPElementDataSize(PBYTE, DWORD, PDWORD);
00195
BOOL GetCPElementSize(PBYTE, DWORD, PDWORD);
00196
BOOL GetCPElementDataType(PBYTE, DWORD, PDWORD);
00197
BOOL GetCPElementData(PBYTE, DWORD, PBYTE, PDWORD);
00198
BOOL GetTRCElementSize(PBYTE, DWORD, PDWORD, PDWORD);
00199
00200
DWORD Ascii85Encode(PBYTE, DWORD, DWORD);
00201
00202
BOOL GetCRDInputOutputArraySize(PBYTE, DWORD, PDWORD, PDWORD, PDWORD, PDWORD);
00203
BOOL GetHostCSA(PBYTE, PBYTE, PDWORD, DWORD, DWORD);
00204
BOOL GetHostColorRenderingDictionary(PBYTE, DWORD, PBYTE, PDWORD);
00205
BOOL GetHostColorSpaceArray(PBYTE, DWORD, PBYTE, PDWORD);
00206
00207
DWORD SendCRDBWPoint(PBYTE, PFIX_16_16);
00208
DWORD SendCRDPQR(PBYTE, DWORD, PFIX_16_16);
00209
DWORD SendCRDLMN(PBYTE, DWORD, PFIX_16_16, PFIX_16_16, DWORD);
00210
DWORD SendCRDABC(PBYTE, PBYTE, DWORD, DWORD, PBYTE, PFIX_16_16, DWORD, BOOL);
00211
DWORD SendCRDOutputTable(PBYTE, PBYTE, DWORD, DWORD, BOOL, BOOL);
00212
00213
DWORD SendCSABWPoint(PBYTE, DWORD, PFIX_16_16, PFIX_16_16);
00214
VOID GetMediaWP(PBYTE, DWORD, PFIX_16_16, PFIX_16_16);
00215
00216
DWORD CreateCRDRevArray(PBYTE, PBYTE, PCURVETYPE, PWORD, DWORD, BOOL);
00217
DWORD SendCRDRevArray(PBYTE, PBYTE, PCURVETYPE, DWORD, BOOL);
00218
00219
DWORD CreateColSpArray(PBYTE, PBYTE, DWORD, BOOL);
00220
DWORD CreateColSpProc(PBYTE, PBYTE, DWORD, BOOL);
00221
DWORD CreateFloatString(PBYTE, PBYTE, DWORD);
00222
DWORD CreateInputArray(PBYTE, DWORD, DWORD, PBYTE, DWORD, PBYTE, BOOL, PBYTE);
00223
DWORD CreateOutputArray(PBYTE, DWORD, DWORD, DWORD, PBYTE, DWORD, PBYTE, BOOL, PBYTE);
00224
00225
DWORD GetPublicArrayName(DWORD, PBYTE);
00226
BOOL GetRevCurve(PCURVETYPE, PWORD, PWORD);
00227
VOID GetCLUTInfo(DWORD, PBYTE, PDWORD, PDWORD, PDWORD, PDWORD, PDWORD, PDWORD);
00228
DWORD EnableGlobalDict(PBYTE);
00229
DWORD BeginGlobalDict(PBYTE);
00230
DWORD EndGlobalDict(PBYTE);
00231
00232
DWORD WriteNewLineObject(PBYTE,
const char *);
00233
DWORD WriteHNAToken(PBYTE, BYTE, DWORD);
00234
DWORD WriteIntStringU2S(PBYTE, PBYTE, DWORD);
00235
DWORD WriteIntStringU2S_L(PBYTE, PBYTE, DWORD);
00236
DWORD WriteHexBuffer(PBYTE, PBYTE, PBYTE, DWORD);
00237
DWORD WriteStringToken(PBYTE, BYTE, DWORD);
00238
DWORD WriteByteString(PBYTE, PBYTE, DWORD);
00239
DWORD WriteInt2ByteString(PBYTE, PBYTE, DWORD);
00240
DWORD WriteFixed(PBYTE, FIX_16_16);
00241
DWORD WriteFixed2dot30(PBYTE, DWORD);
00242
#if !defined(KERNEL_MODE) || defined(USERMODE_DRIVER)
00243
DWORD WriteDouble(PBYTE,
double);
00244
00245
BOOL CreateMatrixCRD(PBYTE, PBYTE, PDWORD, DWORD, BOOL);
00246
DWORD CreateHostLutCRD(PBYTE, DWORD, PBYTE, DWORD);
00247
DWORD CreateHostMatrixCSAorCRD(PBYTE, PBYTE, PDWORD, DWORD, BOOL);
00248
DWORD CreateHostInputOutputArray(PBYTE, PBYTE*, DWORD, DWORD, DWORD, DWORD, PBYTE);
00249
DWORD CreateHostTRCInputTable(PBYTE, PHOSTCLUT, PCURVETYPE, PCURVETYPE, PCURVETYPE);
00250
DWORD CreateHostRevTRCInputTable(PBYTE, PHOSTCLUT, PCURVETYPE, PCURVETYPE, PCURVETYPE);
00251
00252
BOOL CheckInputOutputTable(PHOSTCLUT,
float*, BOOL, BOOL);
00253
BOOL CheckColorLookupTable(PHOSTCLUT,
float*);
00254
00255
BOOL DoHostConversionCSA(PHOSTCLUT,
float*,
float*);
00256
BOOL DoHostConversionCRD(PHOSTCLUT, PHOSTCLUT,
float*,
float*, BOOL);
00257
00258
float g(
float);
00259
float inverse_g(
float);
00260
BOOL TableInterp3(PHOSTCLUT,
float*);
00261
BOOL TableInterp4(PHOSTCLUT,
float*);
00262
void LabToXYZ(
float*,
float*, PFIX_16_16);
00263
void XYZToLab(
float*,
float*, PFIX_16_16);
00264
VOID ApplyMatrix(FIX_16_16 *e,
float *Input,
float *Output);
00265
00266
BOOL CreateColorantArray(PBYTE,
double *, DWORD);
00267
BOOL InvertColorantArray(
double *,
double *);
00268
#endif
00269
00270
DWORD crc32(PBYTE buff, DWORD length);
00271
00272
00273
00274
00275
00276 const char ASCII85DecodeBegin[] =
"<~";
00277 const char ASCII85DecodeEnd[] =
"~> cvx exec ";
00278 const char TestingDEFG[] =
"/SupportDEFG? {/CIEBasedDEFG \
00279
/ColorSpaceFamily resourcestatus { pop pop languagelevel 3 ge}{false} ifelse} def";
00280 const char SupportDEFG_S[] =
"SupportDEFG? { ";
00281 const char NotSupportDEFG_S[] =
"SupportDEFG? not { ";
00282 const char SupportDEFG_E[] =
"}if ";
00283 const char IndexArray16b[] =
" dup length 1 sub 3 -1 roll mul dup dup floor cvi\
00284
exch ceiling cvi 3 index exch get 32768 add 4 -1 roll 3 -1 roll get 32768 add\
00285
dup 3 1 roll sub 3 -1 roll dup floor cvi sub mul add ";
00286
00287 const char IndexArray[] =
" dup length 1 sub 3 -1 roll mul dup dup floor cvi\
00288
exch ceiling cvi 3 index exch get 4 -1 roll 3 -1 roll get\
00289
dup 3 1 roll sub 3 -1 roll dup floor cvi sub mul add ";
00290 const char StartClip[] =
"dup 1.0 le{dup 0.0 ge{" ;
00291 const char EndClip[] =
"}if}if " ;
00292 const char BeginString[] =
"<";
00293 const char EndString[] =
">";
00294 const char BeginArray[] =
"[";
00295 const char EndArray[] =
"]";
00296 const char BeginFunction[] =
"{";
00297 const char EndFunction[] =
"}bind ";
00298 const char BeginDict[] =
"<<" ;
00299 const char EndDict[] =
">>" ;
00300 const char BlackPoint[] =
"[0 0 0]" ;
00301 const char DictType[] =
"/ColorRenderingType 1 ";
00302 const char IntentType[] =
"/RenderingIntent ";
00303 const char IntentPer[] =
"/Perceptual";
00304 const char IntentSat[] =
"/Saturation";
00305 const char IntentACol[] =
"/AbsoluteColorimetric";
00306 const char IntentRCol[] =
"/RelativeColorimetric";
00307
00308 const char WhitePointTag[] =
"/WhitePoint " ;
00309 const char BlackPointTag[] =
"/BlackPoint " ;
00310 const char RangePQRTag[] =
"/RangePQR " ;
00311 const char TransformPQRTag[] =
"/TransformPQR " ;
00312 const char MatrixPQRTag[] =
"/MatrixPQR " ;
00313 const char RangePQR[] =
"[ -0.07 2.2 -0.02 1.4 -0.2 4.8 ]";
00314 const char MatrixPQR[] =
"[0.8951 -0.7502 0.0389 0.2664 1.7135 -0.0685 -0.1614 0.0367 1.0296]";
00315
#ifdef BARDFORD_TRANSFORM
00316
const char *
TransformPQR[3] = {
"exch pop exch 3 get mul exch pop exch 3 get div ",
00317
"exch pop exch 4 get mul exch pop exch 4 get div ",
00318
"exch pop exch 5 get mul exch pop exch 5 get div " };
00319
#else
00320 const char *
TransformPQR[3] = {
"4 index 0 get div 2 index 0 get mul 4 {exch pop} repeat ",
00321
"4 index 1 get div 2 index 1 get mul 4 {exch pop} repeat ",
00322
"4 index 2 get div 2 index 2 get mul 4 {exch pop} repeat " };
00323
#endif
00324 const char RangeABCTag[] =
"/RangeABC " ;
00325 const char MatrixATag[] =
"/MatrixA ";
00326 const char MatrixABCTag[] =
"/MatrixABC ";
00327 const char EncodeABCTag[] =
"/EncodeABC " ;
00328 const char RangeLMNTag[] =
"/RangeLMN " ;
00329 const char MatrixLMNTag[] =
"/MatrixLMN " ;
00330 const char EncodeLMNTag[] =
"/EncodeLMN " ;
00331 const char RenderTableTag[] =
"/RenderTable " ;
00332 const char CIEBasedATag[] =
"/CIEBasedA " ;
00333 const char CIEBasedABCTag[] =
"/CIEBasedABC " ;
00334 const char CIEBasedDEFGTag[] =
"/CIEBasedDEFG " ;
00335 const char CIEBasedDEFTag[] =
"/CIEBasedDEF " ;
00336 const char DecodeATag[] =
"/DecodeA " ;
00337 const char DecodeABCTag[] =
"/DecodeABC " ;
00338 const char DecodeLMNTag[] =
"/DecodeLMN " ;
00339 const char DeviceRGBTag[] =
"/DeviceRGB " ;
00340 const char DeviceCMYKTag[] =
"/DeviceCMYK " ;
00341 const char DeviceGrayTag[] =
"/DeviceGray " ;
00342 const char TableTag[] =
"/Table " ;
00343 const char DecodeDEFGTag[] =
"/DecodeDEFG " ;
00344 const char DecodeDEFTag[] =
"/DecodeDEF " ;
00345
00346 const char NullOp[] =
"";
00347 const char DupOp[] =
"dup ";
00348 const char UserDictOp[] =
"userdict ";
00349 const char GlobalDictOp[] =
"globaldict ";
00350 const char CurrentGlobalOp[] =
"currentglobal ";
00351 const char SetGlobalOp[] =
"setglobal ";
00352 const char DefOp[] =
"def ";
00353 const char BeginOp[] =
"begin ";
00354 const char EndOp[] =
"end ";
00355 const char TrueOp[] =
"true ";
00356 const char FalseOp[] =
"false ";
00357 const char MulOp[] =
"mul ";
00358 const char DivOp[] =
"div ";
00359
00360 const char NewLine[] =
"\r\n" ;
00361 const char Slash[] =
"/" ;
00362 const char Space[] =
" " ;
00363 const char CRDBegin[] =
"%** CRD Begin ";
00364 const char CRDEnd[] =
"%** CRD End ";
00365 const char CieBasedDEFGBegin[] =
"%** CieBasedDEFG CSA Begin ";
00366 const char CieBasedDEFBegin[] =
"%** CieBasedDEF CSA Begin ";
00367 const char CieBasedABCBegin[] =
"%** CieBasedABC CSA Begin ";
00368 const char CieBasedABegin[] =
"%** CieBasedA CSA Begin ";
00369 const char CieBasedDEFGEnd[] =
"%** CieBasedDEFG CSA End ";
00370 const char CieBasedDEFEnd[] =
"%** CieBasedDEF CSA End ";
00371 const char CieBasedABCEnd[] =
"%** CieBasedABC CSA End ";
00372 const char CieBasedAEnd[] =
"%** CieBasedA CSA End ";
00373 const char RangeABC[] =
"[ 0 1 0 1 0 1 ] ";
00374 const char RangeLMN[] =
"[ 0 2 0 2 0 2 ] ";
00375 const char Identity[] =
"[1 0 0 0 1 0 0 0 1]";
00376 const char RangeABC_Lab[] =
"[0 100 -128 127 -128 127]";
00377 const char Clip01[] =
"dup 1.0 ge{pop 1.0}{dup 0.0 lt{pop 0.0}if}ifelse " ;
00378 const char DecodeA3[] =
"256 div exp ";
00379 const char DecodeA3Rev[] =
"256 div 1.0 exch div exp ";
00380 const char DecodeABCArray[] =
"DecodeABC_";
00381 const char InputArray[] =
"Inp_";
00382 const char OutputArray[] =
"Out_";
00383 const char Scale8[] =
"255 div " ;
00384 const char Scale16[] =
"65535 div " ;
00385 const char Scale16XYZ[] =
"32768 div " ;
00386 const char TFunction8[] =
"exch 255 mul round cvi get 255 div " ;
00387 const char TFunction8XYZ[] =
"exch 255 mul round cvi get 128 div " ;
00388 const char MatrixABCLab[] =
"[1 1 1 1 0 0 0 0 -1]" ;
00389 const char DecodeABCLab1[] =
"[{16 add 116 div} bind {500 div} bind {200 div} bind]";
00390 const char DecodeALab[] =
" 50 mul 16 add 116 div ";
00391 const char DecodeLMNLab[] =
"dup 0.206897 ge{dup dup mul mul}{0.137931 sub 0.128419 mul} ifelse ";
00392
00393 const char RangeLMNLab[] =
"[0 1 0 1 0 1]" ;
00394 const char EncodeLMNLab[] =
"dup 0.008856 le{7.787 mul 0.13793 add}{0.3333 exp}ifelse " ;
00395
00396 const char MatrixABCLabCRD[] =
"[0 500 0 116 -500 200 0 0 -200]" ;
00397 const char MatrixABCXYZCRD[] =
"[0 1 0 1 0 0 0 0 1]" ;
00398 const char EncodeABCLab1[] =
"16 sub 100 div " ;
00399 const char EncodeABCLab2[] =
"128 add 255 div " ;
00400 const char *
DecodeABCLab[] = {
"50 mul 16 add 116 div ",
00401
"128 mul 128 sub 500 div",
00402
"128 mul 128 sub 200 div"};
00403
00404 const char ColorSpace1[] =
"/CIEBasedABC << /DecodeLMN ";
00405 const char ColorSpace3[] =
" exp} bind ";
00406 const char ColorSpace5[] =
"/WhitePoint [0.9642 1 0.8249] ";
00407
00408 const char PreViewInArray[] =
"IPV_";
00409 const char PreViewOutArray[] =
"OPV_";
00410
00411 const char sRGBColorSpaceArray[] =
"[/CIEBasedABC << \r\n\
00412
/DecodeLMN [{dup 0.03928 le {12.92321 div}{0.055 add 1.055 div 2.4 exp}ifelse} bind dup dup ] \r\n\
00413
/MatrixLMN [0.412457 0.212673 0.019334 0.357576 0.715152 0.119192 0.180437 0.072175 0.950301] \r\n\
00414
/WhitePoint [ 0.9505 1 1.0890 ] >> ]";
00415
00416
#ifdef BRADFORD_TRANSFORM
00417
const char sRGBColorRenderingDictionary[] =
"\
00418
/RangePQR [ -0.5 2 -0.5 2 -0.5 2 ] \r\n\
00419
/MatrixPQR [0.8951 -0.7502 0.0389 0.2664 1.7135 -0.0685 -0.1614 0.0367 1.0296] \r\n\
00420
/TransformPQR [\
00421
{exch pop exch 3 get mul exch pop exch 3 get div} bind \
00422
{exch pop exch 4 get mul exch pop exch 4 get div} bind \
00423
{exch pop exch 5 get mul exch pop exch 5 get div} bind] \r\n\
00424
/MatrixLMN [3.240449 -0.969265 0.055643 -1.537136 1.876011 -0.204026 -0.498531 0.041556 1.057229] \r\n\
00425
/EncodeABC [{dup 0.00304 le {12.92321 mul}{1 2.4 div exp 1.055 mul 0.055 sub}ifelse} bind dup dup] \r\n\
00426
/WhitePoint[0.9505 1 1.0890] >>";
00427
#else
00428 const char sRGBColorRenderingDictionary[] =
"\
00429
/RangePQR [ -0.5 2 -0.5 2 -0.5 2 ] \r\n\
00430
/MatrixPQR [0.8951 -0.7502 0.0389 0.2664 1.7135 -0.0685 -0.1614 0.0367 1.0296] \r\n\
00431
/TransformPQR [\
00432
{4 index 0 get div 2 index 0 get mul 4 {exch pop} repeat} \
00433
{4 index 1 get div 2 index 1 get mul 4 {exch pop} repeat} \
00434
{4 index 2 get div 2 index 2 get mul 4 {exch pop} repeat}] \r\n\
00435
/MatrixLMN [3.240449 -0.969265 0.055643 -1.537136 1.876011 -0.204026 -0.498531 0.041556 1.057229] \r\n\
00436
/EncodeABC [{dup 0.00304 le {12.92321 mul}{1 2.4 div exp 1.055 mul 0.055 sub}ifelse} bind dup dup] \r\n\
00437
/WhitePoint[0.9505 1 1.0890] >>";
00438
#endif
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
BOOL
00464 InternalGetPS2ColorSpaceArray (
00465 PBYTE pProfile,
00466 DWORD dwIntent,
00467 DWORD dwCSAType,
00468 PBYTE pBuffer,
00469 PDWORD pcbSize,
00470 LPBOOL pbBinary
00471 )
00472 {
00473
DWORD dwInpBufSize;
00474
BOOL bRc;
00475
00476
00477
00478
00479
00480 bRc =
GetCSAFromProfile(pProfile, dwIntent, dwCSAType, pBuffer,
00481 pcbSize, pbBinary);
00482
00483
if (! bRc && (GetLastError() != ERROR_INSUFFICIENT_BUFFER))
00484 {
00485
00486
00487
00488
00489
switch (dwCSAType)
00490 {
00491
case CSA_ABC:
00492 bRc =
GetPS2CSA_ABC(pProfile, pBuffer, pcbSize,
00493 dwIntent, pbBinary,
FALSE);
00494
break;
00495
00496
case CSA_DEF:
00497 bRc =
GetPS2CSA_DEFG(pProfile, pBuffer, pcbSize, dwIntent,
00498
TYPE_CIEBASEDDEF, pbBinary);
00499
break;
00500
00501
case CSA_RGB:
00502
case CSA_Lab:
00503
00504 dwInpBufSize = *pcbSize;
00505
00506
00507
00508
00509
00510
00511
00512 bRc =
GetPS2CSA_DEFG(pProfile, pBuffer, pcbSize, dwIntent,
00513
TYPE_CIEBASEDDEF, pbBinary);
00514
00515
if (bRc)
00516 {
00517
00518
00519
00520
00521
DWORD cbNewSize = 0;
00522
PBYTE pNewBuffer;
00523
PBYTE pOldBuffer;
00524
00525
if (pBuffer)
00526 {
00527 pNewBuffer = pBuffer + *pcbSize;
00528 pOldBuffer = pNewBuffer;
00529 pNewBuffer +=
WriteObject(pNewBuffer,
NewLine);
00530
if (dwCSAType == CSA_Lab)
00531 {
00532 pNewBuffer +=
WriteNewLineObject(pNewBuffer,
NotSupportDEFG_S);
00533 }
00534 cbNewSize = dwInpBufSize - (
DWORD)(pNewBuffer - pBuffer);
00535 }
00536
else
00537 {
00538 pNewBuffer =
NULL;
00539 }
00540
00541 bRc =
GetPS2CSA_ABC(pProfile, pNewBuffer, &cbNewSize,
00542 dwIntent, pbBinary,
TRUE);
00543
00544
if (pBuffer)
00545 {
00546 pNewBuffer += cbNewSize;
00547
if (dwCSAType == CSA_Lab)
00548 {
00549 pNewBuffer +=
WriteNewLineObject(pNewBuffer,
SupportDEFG_E);
00550 }
00551 *pcbSize += (
DWORD) (pNewBuffer - pOldBuffer);
00552 }
00553
else
00554 {
00555 *pcbSize += cbNewSize;
00556 }
00557
00558 }
00559
else
00560 {
00561 *pcbSize = dwInpBufSize;
00562
00563 bRc =
GetPS2CSA_ABC(pProfile, pBuffer, pcbSize, dwIntent, pbBinary,
FALSE);
00564 }
00565
00566
break;
00567
00568
case CSA_CMYK:
00569
case CSA_DEFG:
00570 bRc =
GetPS2CSA_DEFG(pProfile, pBuffer, pcbSize, dwIntent,
00571
TYPE_CIEBASEDDEFG, pbBinary);
00572
break;
00573
00574
case CSA_GRAY:
00575
case CSA_A:
00576 bRc =
GetPS2CSA_MONO_A(pProfile, pBuffer, pcbSize, dwIntent, pbBinary);
00577
break;
00578
00579
default:
00580
WARNING((__TEXT(
"Invalid CSA type passed to GetPS2ColorSpaceArray: %d\n"), dwCSAType));
00581 SetLastError(ERROR_INVALID_PARAMETER);
00582
return FALSE;
00583 }
00584 }
00585
00586
return bRc;
00587 }
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
BOOL
00612 InternalGetPS2ColorRenderingIntent(
00613 PBYTE pProfile,
00614 DWORD dwIntent,
00615 PBYTE pBuffer,
00616 PDWORD pcbSize
00617 )
00618 {
00619
DWORD dwIndex, dwTag, dwSize;
00620
BOOL bRc =
FALSE;
00621
00622
switch (dwIntent)
00623 {
00624
case INTENT_PERCEPTUAL:
00625 dwTag =
TAG_PS2INTENT0;
00626
break;
00627
00628
case INTENT_RELATIVE_COLORIMETRIC:
00629 dwTag =
TAG_PS2INTENT1;
00630
break;
00631
00632
case INTENT_SATURATION:
00633 dwTag =
TAG_PS2INTENT2;
00634
break;
00635
00636
case INTENT_ABSOLUTE_COLORIMETRIC:
00637 dwTag =
TAG_PS2INTENT3;
00638
break;
00639
00640
default:
00641
WARNING((__TEXT(
"Invalid intent passed to GetPS2ColorRenderingIntent: %d\n"), dwIntent));
00642 SetLastError(ERROR_INVALID_PARAMETER);
00643
return FALSE;
00644 }
00645
00646
if (
DoesCPTagExist(pProfile, dwTag, &dwIndex))
00647 {
00648 (
void)
GetCPElementDataSize(pProfile, dwIndex, &dwSize);
00649
00650
if (pBuffer)
00651 {
00652
if (*pcbSize >= dwSize + 1)
00653 {
00654 bRc =
GetCPElementData(pProfile, dwIndex, pBuffer, &dwSize);
00655 }
00656
else
00657 {
00658
WARNING((__TEXT(
"Buffer too small to get CRI\n")));
00659 SetLastError(ERROR_INSUFFICIENT_BUFFER);
00660 }
00661 }
00662
else
00663 bRc =
TRUE;
00664
00665 *pcbSize = dwSize;
00666 }
00667
else
00668 {
00669
WARNING((__TEXT(
"psi tag not present for intent %d in profile\n"), dwIntent));
00670 SetLastError(ERROR_TAG_NOT_PRESENT);
00671 }
00672
00673
00674
00675
00676
00677
if (bRc)
00678 {
00679
if (pBuffer)
00680 {
00681 pBuffer[*pcbSize] =
'\0';
00682 }
00683 (*pcbSize)++;
00684 }
00685
00686
return bRc;
00687 }
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
BOOL
00713 InternalGetPS2ColorRenderingDictionary(
00714 PBYTE pProfile,
00715 DWORD dwIntent,
00716 PBYTE pBuffer,
00717 PDWORD pcbSize,
00718 PBOOL pbBinary
00719 )
00720 {
00721
DWORD dwIndex, dwSize, dwDataType;
00722
DWORD dwCRDTag, dwBToATag;
00723
BOOL bRc =
FALSE;
00724
00725
switch (dwIntent)
00726 {
00727
case INTENT_PERCEPTUAL:
00728 dwCRDTag =
TAG_CRDINTENT0;
00729 dwBToATag =
TAG_BToA0;
00730
break;
00731
00732
case INTENT_RELATIVE_COLORIMETRIC:
00733 dwCRDTag =
TAG_CRDINTENT1;
00734 dwBToATag =
TAG_BToA1;
00735
break;
00736
00737
case INTENT_SATURATION:
00738 dwCRDTag =
TAG_CRDINTENT2;
00739 dwBToATag =
TAG_BToA2;
00740
break;
00741
00742
case INTENT_ABSOLUTE_COLORIMETRIC:
00743 dwCRDTag =
TAG_CRDINTENT3;
00744 dwBToATag =
TAG_BToA1;
00745
break;
00746
00747
default:
00748
WARNING((__TEXT(
"Invalid intent passed to GetPS2ColorRenderingDictionary: %d\n"), dwIntent));
00749 SetLastError(ERROR_INVALID_PARAMETER);
00750
return bRc;
00751 }
00752
00753
if (
DoesCPTagExist(pProfile, dwCRDTag, &dwIndex))
00754 {
00755 (
void)
GetCPElementDataSize(pProfile, dwIndex, &dwSize);
00756
00757 (
void)
GetCPElementDataType(pProfile, dwIndex, &dwDataType);
00758
00759
if (! *pbBinary && dwDataType == 1)
00760 {
00761
00762
00763
00764
00765
00766 dwSize = dwSize * 5 / 4 +
sizeof(
ASCII85DecodeBegin) +
sizeof(
ASCII85DecodeEnd) + 2048;
00767 }
00768
00769
if (pBuffer)
00770 {
00771
if (*pcbSize >= dwSize)
00772 {
00773 (
void)
GetCPElementData(pProfile, dwIndex, pBuffer, &dwSize);
00774
00775
if (! *pbBinary && dwDataType == 1)
00776 {
00777 dwSize =
Ascii85Encode(pBuffer, dwSize, *pcbSize);
00778 }
00779 bRc =
TRUE;
00780 }
00781
else
00782 {
00783
WARNING((__TEXT(
"Buffer too small to get CRD\n")));
00784 SetLastError(ERROR_INSUFFICIENT_BUFFER);
00785 }
00786 }
00787
else
00788 bRc =
TRUE;
00789
00790 *pcbSize = dwSize;
00791 }
00792
else if (
DoesCPTagExist(pProfile, dwBToATag, &dwIndex))
00793 {
00794 bRc =
CreateLutCRD(pProfile, dwIndex, pBuffer, pcbSize, dwIntent, *pbBinary);
00795 }
00796
else if (
DoesCPTagExist(pProfile,
TAG_GRAYTRC, &dwIndex))
00797 {
00798 bRc =
CreateMonoCRD(pProfile, dwIndex, pBuffer, pcbSize, dwIntent);
00799 }
00800
#if !defined(KERNEL_MODE) || defined(USERMODE_DRIVER)
00801
else if (
DoesTRCAndColorantTagExist(pProfile))
00802 {
00803 bRc =
CreateMatrixCRD(pProfile, pBuffer, pcbSize, dwIntent, *pbBinary);
00804 }
00805
#endif // !defined(KERNEL_MODE) || defined(USERMODE_DRIVER)
00806
else
00807 {
00808
WARNING((__TEXT(
"Profile doesn't have tags to create CRD\n")));
00809 SetLastError(ERROR_INVALID_PROFILE);
00810 }
00811
00812
return bRc;
00813 }
00814
00815
#if !defined(KERNEL_MODE) || defined(USERMODE_DRIVER)
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
BOOL
00847 InternalGetPS2PreviewCRD(
00848 PBYTE pDestProf,
00849 PBYTE pTargetProf,
00850 DWORD dwIntent,
00851 PBYTE pBuffer,
00852 PDWORD pcbSize,
00853 PBOOL pbBinary
00854 )
00855 {
00856
DWORD i, j, k, l, dwDev, dwTag, dwPCS;
00857
DWORD dwInArraySize, dwOutArraySize;
00858
DWORD nDevGrids, nTargetGrids, nPreviewCRDGrids;
00859
DWORD cbDevCRD, cbTargetCSA, cbTargetCRD;
00860
float fInput[
MAXCHANNELS];
00861
float fOutput[
MAXCHANNELS];
00862
float fTemp[
MAXCHANNELS];
00863
PBYTE pLineStart, pStart = pBuffer;
00864
PBYTE lpDevCRD =
NULL, lpTargetCSA =
NULL, lpTargetCRD =
NULL;
00865
char pPublicArrayName[5];
00866
BOOL bRc =
FALSE;
00867
00868 dwDev =
GetCPDevSpace(pTargetProf);
00869 i = (dwDev == SPACE_CMYK) ? 4 : 3;
00870
00871
00872
00873
00874
00875
if (!
GetCRDInputOutputArraySize(
00876 pTargetProf,
00877 dwIntent,
00878 &dwInArraySize,
00879
NULL,
00880 &dwTag,
00881 &nTargetGrids))
00882
return FALSE;
00883
00884
00885
00886
00887
00888
if (!
GetCRDInputOutputArraySize(
00889 pDestProf,
00890 dwIntent,
00891
NULL,
00892 &dwOutArraySize,
00893 &dwTag,
00894 &nDevGrids))
00895
return FALSE;
00896
00897 nPreviewCRDGrids = (nTargetGrids > nDevGrids) ? nTargetGrids : nDevGrids;
00898
00899
00900
00901
00902
00903
if (nPreviewCRDGrids <
PREVIEWCRDGRID)
00904 nPreviewCRDGrids =
PREVIEWCRDGRID;
00905
00906
if (pBuffer ==
NULL)
00907 {
00908
00909
00910
00911
00912 *pcbSize = nPreviewCRDGrids * nPreviewCRDGrids * nPreviewCRDGrids *
00913 i * 2 +
00914 dwOutArraySize +
00915 dwInArraySize +
00916 4096;
00917
00918
00919
00920
00921
00922 *pcbSize += (((*pcbSize) /
MAX_LINELEN) + 1) *
STRLEN(
NewLine);
00923
00924
return TRUE;
00925 }
00926
00927
00928
00929
00930
00931
if (!
GetHostColorRenderingDictionary(pTargetProf, dwIntent,
NULL, &cbTargetCRD) ||
00932 !
GetHostColorSpaceArray(pTargetProf, dwIntent,
NULL, &cbTargetCSA) ||
00933 !
GetHostColorRenderingDictionary(pDestProf, dwIntent,
NULL, &cbDevCRD))
00934 {
00935
return FALSE;
00936 }
00937
00938
00939
00940
00941
00942
if (((lpTargetCRD =
MemAlloc(cbTargetCRD)) ==
NULL) ||
00943 ((lpTargetCSA =
MemAlloc(cbTargetCSA)) ==
NULL) ||
00944 ((lpDevCRD =
MemAlloc(cbDevCRD)) ==
NULL))
00945 {
00946
goto Done;
00947 }
00948
00949
00950
00951
00952
00953
if (!
GetHostColorRenderingDictionary(pTargetProf, dwIntent, lpTargetCRD, &cbTargetCRD) ||
00954 !
GetHostColorSpaceArray(pTargetProf, dwIntent, lpTargetCSA, &cbTargetCSA) ||
00955 !
GetHostColorRenderingDictionary(pDestProf, dwIntent, lpDevCRD, &cbDevCRD))
00956 {
00957
goto Done;
00958 }
00959
00960
00961
00962
00963
00964
GetPublicArrayName(dwTag, pPublicArrayName);
00965
00966
00967
00968
00969
00970
00971
00972
00973 pBuffer +=
WriteNewLineObject(pBuffer,
CRDBegin);
00974
00975 pBuffer +=
EnableGlobalDict(pBuffer);
00976 pBuffer +=
BeginGlobalDict(pBuffer);
00977
00978 pBuffer +=
CreateInputArray(pBuffer, 0, 0, pPublicArrayName,
00979 0,
NULL, *pbBinary, lpTargetCRD);
00980
00981 pBuffer +=
CreateOutputArray(pBuffer, 0, 0, 0,
00982 pPublicArrayName, 0,
NULL, *pbBinary, lpDevCRD);
00983
00984 pBuffer +=
EndGlobalDict(pBuffer);
00985
00986
00987
00988
00989
00990 pBuffer +=
WriteNewLineObject(pBuffer,
BeginDict);
00991 pBuffer +=
WriteObject(pBuffer,
DictType);
00992
00993
00994
00995
00996
00997
switch (dwIntent)
00998 {
00999
case INTENT_PERCEPTUAL:
01000 pBuffer +=
WriteNewLineObject(pBuffer,
IntentType);
01001 pBuffer +=
WriteObject(pBuffer,
IntentPer);
01002
break;
01003
01004
case INTENT_SATURATION:
01005 pBuffer +=
WriteNewLineObject(pBuffer,
IntentType);
01006 pBuffer +=
WriteObject(pBuffer,
IntentSat);
01007
break;
01008
01009
case INTENT_RELATIVE_COLORIMETRIC:
01010 pBuffer +=
WriteNewLineObject(pBuffer,
IntentType);
01011 pBuffer +=
WriteObject(pBuffer,
IntentRCol);
01012
break;
01013
01014
case INTENT_ABSOLUTE_COLORIMETRIC:
01015 pBuffer +=
WriteNewLineObject(pBuffer,
IntentType);
01016 pBuffer +=
WriteObject(pBuffer,
IntentACol);
01017
break;
01018 }
01019
01020
01021
01022
01023
01024 pBuffer +=
SendCRDBWPoint(pBuffer, ((
PHOSTCLUT)lpTargetCRD)->afxIlluminantWP);
01025
01026
01027
01028
01029
01030 pBuffer +=
SendCRDPQR(pBuffer, dwIntent, ((
PHOSTCLUT)lpTargetCRD)->afxIlluminantWP);
01031
01032
01033
01034
01035
01036 pBuffer +=
SendCRDLMN(pBuffer, dwIntent,
01037 ((
PHOSTCLUT)lpTargetCRD)->afxIlluminantWP,
01038 ((
PHOSTCLUT)lpTargetCRD)->afxMediaWP,
01039 ((
PHOSTCLUT)lpTargetCRD)->dwPCS);
01040
01041
01042
01043
01044
01045 pBuffer +=
SendCRDABC(pBuffer, pPublicArrayName,
01046 ((
PHOSTCLUT)lpTargetCRD)->dwPCS,
01047 ((
PHOSTCLUT)lpTargetCRD)->nInputCh,
01048
NULL,
01049 ((
PHOSTCLUT)lpTargetCRD)->e,
01050 (((
PHOSTCLUT)lpTargetCRD)->nLutBits == 8)?
LUT8_TYPE :
LUT16_TYPE,
01051 *pbBinary);
01052
01053
01054
01055
01056
01057 pBuffer +=
WriteNewLineObject(pBuffer,
RenderTableTag);
01058 pBuffer +=
WriteObject(pBuffer,
BeginArray);
01059
01060 pBuffer +=
WriteInt(pBuffer, nPreviewCRDGrids);
01061 pBuffer +=
WriteInt(pBuffer, nPreviewCRDGrids);
01062 pBuffer +=
WriteInt(pBuffer, nPreviewCRDGrids);
01063
01064 pLineStart = pBuffer;
01065 pBuffer +=
WriteNewLineObject(pBuffer,
BeginArray);
01066 dwPCS = ((
PHOSTCLUT)lpDevCRD)->dwPCS;
01067
01068
for (i=0; i<nPreviewCRDGrids; i++)
01069 {
01070 pBuffer +=
WriteObject(pBuffer,
NewLine);
01071 pLineStart = pBuffer;
01072
if (*pbBinary)
01073 {
01074 pBuffer +=
WriteStringToken(pBuffer, 143,
01075 nPreviewCRDGrids * nPreviewCRDGrids * ((
PHOSTCLUT)lpDevCRD)->nOutputCh);
01076 }
01077
else
01078 {
01079 pBuffer +=
WriteObject(pBuffer,
BeginString);
01080 }
01081 fInput[0] = ((
float)i) / (nPreviewCRDGrids - 1);
01082
for (j=0; j<nPreviewCRDGrids; j++)
01083 {
01084 fInput[1] = ((
float)j) / (nPreviewCRDGrids - 1);
01085
for (k=0; k<nPreviewCRDGrids; k++)
01086 {
01087 fInput[2] = ((
float)k) / (nPreviewCRDGrids - 1);
01088
01089
DoHostConversionCRD((
PHOSTCLUT)lpTargetCRD,
NULL, fInput, fOutput, 1);
01090
DoHostConversionCSA((
PHOSTCLUT)lpTargetCSA, fOutput, fTemp);
01091
DoHostConversionCRD((
PHOSTCLUT)lpDevCRD, (
PHOSTCLUT)lpTargetCSA,
01092 fTemp, fOutput, 0);
01093
for (l=0; l<((
PHOSTCLUT)lpDevCRD)->nOutputCh; l++)
01094 {
01095
if (*pbBinary)
01096 {
01097 *pBuffer++ = (
BYTE)(fOutput[l] * 255);
01098 }
01099
else
01100 {
01101 pBuffer +=
WriteHex(pBuffer, (
USHORT)(fOutput[l] * 255));
01102
if ((pBuffer - pLineStart) >
MAX_LINELEN)
01103 {
01104 pLineStart = pBuffer;
01105 pBuffer +=
WriteObject(pBuffer,
NewLine);
01106 }
01107 }
01108 }
01109 }
01110 }
01111
if (!*pbBinary)
01112 pBuffer +=
WriteObject(pBuffer,
EndString);
01113 }
01114 pBuffer +=
WriteNewLineObject(pBuffer,
EndArray);
01115 pBuffer +=
WriteInt(pBuffer, ((
PHOSTCLUT)lpDevCRD)->nOutputCh);
01116
01117
01118
01119
01120
01121 pBuffer +=
SendCRDOutputTable(pBuffer, pPublicArrayName,
01122 ((
PHOSTCLUT)lpDevCRD)->nOutputCh,
01123 (((
PHOSTCLUT)lpDevCRD)->nLutBits == 8)?
LUT8_TYPE :
LUT16_TYPE,
01124
TRUE,
01125 *pbBinary);
01126
01127 pBuffer +=
WriteNewLineObject(pBuffer,
EndArray);
01128 pBuffer +=
WriteObject(pBuffer,
EndDict);
01129 pBuffer +=
WriteNewLineObject(pBuffer,
CRDEnd);
01130 bRc =
TRUE;
01131
01132 Done:
01133 *pcbSize = (
DWORD)(pBuffer - pStart);
01134
01135
if (lpTargetCRD)
01136
MemFree(lpTargetCRD);
01137
if (lpTargetCSA)
01138
MemFree(lpTargetCSA);
01139
if (lpDevCRD)
01140
MemFree(lpDevCRD);
01141
01142
return bRc;
01143 }
01144
01145
#endif // !defined(KERNEL_MODE) || defined(USERMODE_DRIVER)
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
BOOL
01172 GetCSAFromProfile (
01173 PBYTE pProfile,
01174 DWORD dwIntent,
01175 DWORD dwCSAType,
01176 PBYTE pBuffer,
01177 PDWORD pcbSize,
01178 PBOOL pbBinary
01179 )
01180 {
01181
DWORD dwDev, dwProfileIntent;
01182
DWORD dwIndex, dwSize, dwDataType;
01183
BOOL bRc =
FALSE;
01184
01185
01186
01187
01188
01189
01190 SetLastError(0);
01191
01192
01193
01194
01195
01196 dwDev =
GetCPDevSpace(pProfile);
01197 dwProfileIntent =
GetCPRenderIntent(pProfile);
01198
01199
01200
01201
01202
01203
01204
if ((dwIntent != dwProfileIntent) ||
01205 ((dwDev == SPACE_GRAY) &&
01206 ((dwCSAType != CSA_GRAY) && (dwCSAType != CSA_A))))
01207 {
01208
WARNING((__TEXT(
"Can't use profile's CSA tag due to different rendering intents\n")));
01209
return FALSE;
01210 }
01211
01212
if (
DoesCPTagExist(pProfile,
TAG_PS2CSA, &dwIndex))
01213 {
01214 (
void)
GetCPElementDataSize(pProfile, dwIndex, &dwSize);
01215
01216 (
void)
GetCPElementDataType(pProfile, dwIndex, &dwDataType);
01217
01218
if (! *pbBinary && dwDataType == 1)
01219 {
01220
01221
01222
01223
01224
01225 dwSize = dwSize * 5 / 4 +
sizeof(
ASCII85DecodeBegin) +
sizeof(
ASCII85DecodeEnd) + 2048;
01226 }
01227
01228
if (pBuffer)
01229 {
01230
if (*pcbSize >= dwSize)
01231 {
01232 (
void)
GetCPElementData(pProfile, dwIndex, pBuffer, &dwSize);
01233
01234
if (! *pbBinary && dwDataType == 1)
01235 {
01236 dwSize =
Ascii85Encode(pBuffer, dwSize, *pcbSize);
01237 }
01238 bRc =
TRUE;
01239 }
01240
else
01241 {
01242
WARNING((__TEXT(
"Buffer too small to get CSA\n")));
01243 SetLastError(ERROR_INSUFFICIENT_BUFFER);
01244 }
01245 }
01246
else
01247 bRc =
TRUE;
01248
01249 *pcbSize = dwSize;
01250 }
01251
01252
return bRc;
01253 }
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
BOOL
01279 GetPS2CSA_MONO_A(
01280 PBYTE pProfile,
01281 PBYTE pBuffer,
01282 PDWORD pcbSize,
01283 DWORD dwIntent,
01284 PBOOL pbBinary
01285 )
01286 {
01287
PCURVETYPE pData;
01288 PTAGDATA pTagData;
01289
PBYTE pLineStart, pStart = pBuffer;
01290
PBYTE pTable;
01291
DWORD i, dwPCS, nCount;
01292
DWORD dwIndex, dwSize;
01293
DWORD afxIlluminantWP[3];
01294
DWORD afxMediaWP[3];
01295
01296
01297
01298
01299
01300
01301
if (!
DoesCPTagExist(pProfile,
TAG_GRAYTRC, &dwIndex))
01302 {
01303
WARNING((__TEXT(
"Gray TRC tag not present to create MONO_A CSA\n")));
01304 SetLastError(ERROR_TAG_NOT_PRESENT);
01305
return FALSE;
01306 }
01307
01308 dwPCS =
GetCPConnSpace(pProfile);
01309
01310 (
void)
GetCPElementSize(pProfile, dwIndex, &dwSize);
01311
01312 pTagData = (PTAGDATA)(pProfile +
sizeof(PROFILEHEADER) +
sizeof(
DWORD) +
01313 dwIndex *
sizeof(TAGDATA));
01314
01315 pData = (
PCURVETYPE)(pProfile + FIX_ENDIAN(pTagData->dwOffset));
01316
01317 nCount = FIX_ENDIAN(pData->
nCount);
01318
01319
01320
01321
01322
01323 dwSize = nCount * 6 +
01324 3 * (
STRLEN(
IndexArray) +
01325
STRLEN(
StartClip) +
01326
STRLEN(
EndClip)) +
01327 2048;
01328
01329
01330
01331
01332
01333 dwSize += (((dwSize) /
MAX_LINELEN) + 1) *
STRLEN(
NewLine);
01334
01335
if (! pBuffer)
01336 {
01337 *pcbSize = dwSize;
01338
return TRUE;
01339 }
01340
else if (*pcbSize < dwSize)
01341 {
01342
WARNING((__TEXT(
"Buffer too small to get MONO_A CSA\n")));
01343 SetLastError(ERROR_INSUFFICIENT_BUFFER);
01344
return FALSE;
01345 }
01346
01347
01348
01349
01350
01351 (
void)
GetCPWhitePoint(pProfile, afxIlluminantWP);
01352
01353
01354
01355
01356
01357 (
void)
GetMediaWP(pProfile, dwIntent, afxIlluminantWP, afxMediaWP);
01358
01359
01360
01361
01362
01363 pBuffer +=
WriteNewLineObject(pBuffer,
CieBasedABegin);
01364
01365 pBuffer +=
WriteNewLineObject(pBuffer,
BeginArray);
01366
01367
01368
01369
01370
01371 pBuffer +=
WriteObject(pBuffer,
CIEBasedATag);
01372 pBuffer +=
WriteObject(pBuffer,
BeginDict);
01373
01374
01375
01376
01377
01378 pBuffer +=
SendCSABWPoint(pBuffer, dwIntent, afxIlluminantWP, afxMediaWP);
01379
01380
01381
01382
01383
01384 pBuffer +=
WriteObject(pBuffer,
NewLine);
01385 pLineStart = pBuffer;
01386
01387
if (nCount != 0)
01388 {
01389 pBuffer +=
WriteObject(pBuffer,
DecodeATag);
01390 pBuffer +=
WriteObject(pBuffer,
BeginArray);
01391
01392 pBuffer +=
WriteObject(pBuffer,
BeginFunction);
01393
01394 pTable = (
PBYTE)(pData->
data);
01395
01396
if (nCount == 1)
01397 {
01398 pBuffer +=
WriteInt(pBuffer, FIX_ENDIAN16(*((PWORD)pTable)));
01399 pBuffer +=
WriteObject(pBuffer,
DecodeA3);
01400
01401
01402
01403
01404
01405
01406
01407
if (dwPCS == SPACE_Lab)
01408 {
01409 pBuffer +=
WriteObject(pBuffer,
DecodeALab);
01410 pBuffer +=
WriteObject(pBuffer,
DecodeLMNLab);
01411 }
01412 }
01413
else
01414 {
01415 pBuffer +=
WriteObject(pBuffer,
StartClip);
01416 pBuffer +=
WriteObject(pBuffer,
BeginArray);
01417
for (i=0; i<nCount; i++)
01418 {
01419 pBuffer +=
WriteInt(pBuffer, FIX_ENDIAN16(*((PWORD)pTable)));
01420 pTable +=
sizeof(WORD);
01421
if (((
DWORD) (pBuffer - pLineStart)) >
MAX_LINELEN)
01422 {
01423 pLineStart = pBuffer;
01424 pBuffer +=
WriteObject (pBuffer,
NewLine);
01425 }
01426 }
01427 pBuffer +=
WriteObject(pBuffer,
EndArray);
01428 pLineStart = pBuffer;
01429 pBuffer +=
WriteObject(pBuffer,
NewLine);
01430
01431 pBuffer +=
WriteObject(pBuffer,
IndexArray);
01432 pBuffer +=
WriteObject(pBuffer,
Scale16);
01433
01434
01435
01436
01437
01438
01439
01440
if (dwPCS == SPACE_Lab)
01441 {
01442 pBuffer +=
WriteObject(pBuffer,
DecodeALab);
01443 pBuffer +=
WriteObject(pBuffer,
DecodeLMNLab);
01444 }
01445 pBuffer +=
WriteObject(pBuffer,
EndClip);
01446 }
01447
01448 pBuffer +=
WriteObject(pBuffer,
EndFunction);
01449 pBuffer +=
WriteObject(pBuffer,
EndArray);
01450 }
01451
01452
01453
01454
01455
01456 pBuffer +=
WriteNewLineObject(pBuffer,
MatrixATag);
01457 pBuffer +=
WriteObject(pBuffer,
BeginArray);
01458
for (i=0; i<3; i++)
01459 {
01460
if (dwIntent == INTENT_ABSOLUTE_COLORIMETRIC)
01461 {
01462 pBuffer +=
WriteFixed(pBuffer, afxMediaWP[i]);
01463 }
01464
else
01465 {
01466 pBuffer +=
WriteFixed(pBuffer, afxIlluminantWP[i]);
01467 }
01468 }
01469 pBuffer +=
WriteObject(pBuffer,
EndArray);
01470
01471
01472
01473
01474
01475 pBuffer +=
WriteNewLineObject(pBuffer,
RangeLMNTag);
01476 pBuffer +=
WriteObject(pBuffer,
RangeLMN);
01477
01478
01479
01480
01481
01482 pBuffer +=
WriteObject(pBuffer,
EndDict);
01483 pBuffer +=
WriteObject(pBuffer,
EndArray);
01484
01485 pBuffer +=
WriteNewLineObject(pBuffer,
CieBasedAEnd);
01486
01487 *pcbSize = (
DWORD) (pBuffer - pStart);
01488
01489
return TRUE;
01490 }
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
BOOL
01519 GetPS2CSA_ABC(
01520 PBYTE pProfile,
01521 PBYTE pBuffer,
01522 PDWORD pcbSize,
01523 DWORD dwIntent,
01524 PBOOL pbBinary,
01525 BOOL bBackup
01526 )
01527 {
01528
PBYTE pStart = pBuffer;
01529
DWORD i, dwPCS, dwDev, dwSize;
01530
FIX_16_16 afxIlluminantWP[3];
01531
FIX_16_16 afxMediaWP[3];
01532
01533
01534
01535
01536
01537
01538 dwPCS =
GetCPConnSpace(pProfile);
01539 dwDev =
GetCPDevSpace(pProfile);
01540
01541
01542
01543
01544
01545
if (dwDev == SPACE_Lab)
01546 {
01547
return GetPS2CSA_ABC_Lab(pProfile, pBuffer, pcbSize, dwIntent, pbBinary);
01548 }
01549
01550
01551
01552
01553
01554
if ((dwDev != SPACE_RGB) ||
01555 !
DoesTRCAndColorantTagExist(pProfile))
01556 {
01557
WARNING((__TEXT(
"Colorant or TRC tag not present to create ABC CSA\n")));
01558 SetLastError(ERROR_TAG_NOT_PRESENT);
01559
return FALSE;
01560 }
01561
01562
01563
01564
01565
01566 dwSize = 65530;
01567
01568
if (! pBuffer)
01569 {
01570 *pcbSize = dwSize;
01571
return TRUE;
01572 }
01573
else if (*pcbSize < dwSize)
01574 {
01575
WARNING((__TEXT(
"Buffer too small to get ABC CSA\n")));
01576 SetLastError(ERROR_INSUFFICIENT_BUFFER);
01577
return FALSE;
01578 }
01579
01580
01581
01582
01583
01584 (
void)
GetCPWhitePoint(pProfile, afxIlluminantWP);
01585
01586
01587
01588
01589
01590 (
void)
GetMediaWP(pProfile, dwIntent, afxIlluminantWP, afxMediaWP);
01591
01592
01593
01594
01595
01596 pBuffer +=
WriteNewLineObject(pBuffer,
CieBasedABCBegin);
01597
01598
if (
IsSRGBColorProfile(pProfile))
01599 {
01600 pBuffer +=
WriteNewLineObject(pBuffer,
sRGBColorSpaceArray);
01601 }
01602
else
01603 {
01604 pBuffer +=
EnableGlobalDict(pBuffer);
01605
01606
if (bBackup)
01607 {
01608 pBuffer +=
WriteNewLineObject(pBuffer,
NotSupportDEFG_S);
01609 }
01610
01611 pBuffer +=
BeginGlobalDict(pBuffer);
01612
01613 pBuffer +=
CreateColSpArray(pProfile, pBuffer,
TAG_REDTRC, *pbBinary);
01614 pBuffer +=
CreateColSpArray(pProfile, pBuffer,
TAG_GREENTRC, *pbBinary);
01615 pBuffer +=
CreateColSpArray(pProfile, pBuffer,
TAG_BLUETRC, *pbBinary);
01616
01617 pBuffer +=
WriteNewLineObject(pBuffer,
EndOp);
01618
01619
if (bBackup)
01620 {
01621 pBuffer +=
WriteNewLineObject(pBuffer,
SupportDEFG_E);
01622 }
01623
01624 pBuffer +=
WriteNewLineObject(pBuffer,
SetGlobalOp);
01625
01626
if (bBackup)
01627 {
01628 pBuffer +=
WriteNewLineObject(pBuffer,
NotSupportDEFG_S);
01629 }
01630
01631
01632
01633
01634
01635 pBuffer +=
WriteNewLineObject(pBuffer,
BeginArray);
01636
01637
01638
01639
01640
01641 pBuffer +=
WriteObject(pBuffer,
CIEBasedABCTag);
01642 pBuffer +=
WriteObject(pBuffer,
BeginDict);
01643
01644
01645
01646
01647
01648 pBuffer +=
SendCSABWPoint(pBuffer, dwIntent, afxIlluminantWP, afxMediaWP);
01649
01650
01651
01652
01653
01654 pBuffer +=
WriteNewLineObject(pBuffer,
DecodeABCTag);
01655 pBuffer +=
WriteObject(pBuffer,
BeginArray);
01656
01657 pBuffer +=
WriteObject(pBuffer,
NewLine);
01658 pBuffer +=
CreateColSpProc(pProfile, pBuffer,
TAG_REDTRC, *pbBinary);
01659 pBuffer +=
WriteObject(pBuffer,
NewLine);
01660 pBuffer +=
CreateColSpProc(pProfile, pBuffer,
TAG_GREENTRC, *pbBinary);
01661 pBuffer +=
WriteObject(pBuffer,
NewLine);
01662 pBuffer +=
CreateColSpProc(pProfile, pBuffer,
TAG_BLUETRC, *pbBinary);
01663 pBuffer +=
WriteObject(pBuffer,
EndArray);
01664
01665
01666
01667
01668
01669 pBuffer +=
WriteNewLineObject(pBuffer,
MatrixABCTag);
01670 pBuffer +=
WriteObject(pBuffer,
BeginArray);
01671
01672 pBuffer +=
CreateFloatString(pProfile, pBuffer,
TAG_REDCOLORANT);
01673 pBuffer +=
CreateFloatString(pProfile, pBuffer,
TAG_GREENCOLORANT);
01674 pBuffer +=
CreateFloatString(pProfile, pBuffer,
TAG_BLUECOLORANT);
01675
01676 pBuffer +=
WriteObject(pBuffer,
EndArray);
01677
01678
01679
01680
01681
01682 pBuffer +=
WriteObject(pBuffer,
NewLine);
01683 pBuffer +=
WriteObject(pBuffer,
RangeLMNTag);
01684 pBuffer +=
WriteObject(pBuffer,
RangeLMN);
01685
01686
01687
01688
01689
01690
if (dwIntent == INTENT_ABSOLUTE_COLORIMETRIC)
01691 {
01692
01693
01694
01695
01696 pBuffer +=
WriteNewLineObject(pBuffer,
DecodeLMNTag);
01697 pBuffer +=
WriteObject(pBuffer,
BeginArray);
01698
for (i=0; i<3; i++)
01699 {
01700 pBuffer +=
WriteObject(pBuffer,
BeginFunction);
01701 pBuffer +=
WriteFixed(pBuffer,
FIX_DIV(afxMediaWP[i], afxIlluminantWP[i]));
01702 pBuffer +=
WriteObject(pBuffer,
MulOp);
01703 pBuffer +=
WriteObject(pBuffer,
EndFunction);
01704 }
01705 pBuffer +=
WriteObject (pBuffer,
EndArray);
01706 }
01707
01708
01709
01710
01711
01712 pBuffer +=
WriteNewLineObject(pBuffer,
EndDict);
01713 pBuffer +=
WriteObject(pBuffer,
EndArray);
01714
01715 pBuffer +=
WriteNewLineObject(pBuffer,
CieBasedABCEnd);
01716 }
01717
01718 *pcbSize = (
DWORD) (pBuffer - pStart);
01719
01720
return TRUE;
01721 }
01722
01723
01724
01725
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
BOOL
01747 GetPS2CSA_ABC_Lab(
01748 PBYTE pProfile,
01749 PBYTE pBuffer,
01750 PDWORD pcbSize,
01751 DWORD dwIntent,
01752 PBOOL pbBinary
01753 )
01754 {
01755
PBYTE pStart = pBuffer;
01756
DWORD i, dwSize;
01757
FIX_16_16 afxIlluminantWP[3];
01758
FIX_16_16 afxMediaWP[3];
01759
01760
01761
01762
01763
01764 dwSize = 65530;
01765
01766
if (! pBuffer)
01767 {
01768 *pcbSize = dwSize;
01769
return TRUE;
01770 }
01771
else if (*pcbSize < dwSize)
01772 {
01773
WARNING((__TEXT(
"Buffer too small to get ABC_Lab CSA\n")));
01774 SetLastError(ERROR_INSUFFICIENT_BUFFER);
01775
return FALSE;
01776 }
01777
01778
01779
01780
01781
01782 (
void)
GetCPWhitePoint(pProfile, afxIlluminantWP);
01783
01784
01785
01786
01787
01788
GetMediaWP(pProfile, dwIntent, afxIlluminantWP, afxMediaWP);
01789
01790
01791
01792
01793
01794 pBuffer +=
WriteNewLineObject(pBuffer,
BeginArray);
01795
01796
01797
01798
01799
01800 pBuffer +=
WriteObject(pBuffer,
CIEBasedABCTag);
01801 pBuffer +=
WriteObject(pBuffer,
BeginDict);
01802
01803
01804
01805
01806
01807 pBuffer +=
SendCSABWPoint(pBuffer, dwIntent, afxIlluminantWP, afxMediaWP);
01808
01809
01810
01811
01812
01813 pBuffer +=
WriteNewLineObject(pBuffer,
RangeABCTag);
01814 pBuffer +=
WriteObject(pBuffer,
RangeABC_Lab);
01815
01816
01817
01818
01819
01820 pBuffer +=
WriteNewLineObject(pBuffer,
DecodeABCTag);
01821 pBuffer +=
WriteObject(pBuffer,
DecodeABCLab1);
01822
01823
01824
01825
01826
01827 pBuffer +=
WriteNewLineObject(pBuffer,
MatrixABCTag);
01828 pBuffer +=
WriteObject(pBuffer,
MatrixABCLab);
01829
01830
01831
01832
01833
01834 pBuffer +=
WriteNewLineObject(pBuffer,
DecodeLMNTag);
01835 pBuffer +=
WriteObject(pBuffer,
BeginArray);
01836
for (i=0; i<3; i++)
01837 {
01838 pBuffer +=
WriteObject(pBuffer,
BeginFunction);
01839 pBuffer +=
WriteObject(pBuffer,
DecodeLMNLab);
01840
01841
if (dwIntent == INTENT_ABSOLUTE_COLORIMETRIC)
01842 {
01843 pBuffer +=
WriteFixed(pBuffer, afxMediaWP[i]);
01844 }
01845
else
01846 {
01847 pBuffer +=
WriteFixed(pBuffer, afxIlluminantWP[i]);
01848 }
01849 pBuffer +=
WriteObject(pBuffer,
MulOp);
01850 pBuffer +=
WriteObject(pBuffer,
EndFunction);
01851 pBuffer +=
WriteObject(pBuffer,
NewLine);
01852 }
01853 pBuffer +=
WriteObject(pBuffer,
EndArray);
01854
01855
01856
01857
01858
01859
01860 pBuffer +=
WriteNewLineObject(pBuffer,
EndDict);
01861 pBuffer +=
WriteObject(pBuffer,
EndArray);
01862
01863 pBuffer +=
WriteNewLineObject(pBuffer,
CieBasedABCEnd);
01864
01865 *pcbSize = (
DWORD) (pBuffer - pStart);
01866
01867
return TRUE;
01868 }
01869
01870
01871
01872
01873
01874
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887
01888
01889
01890
01891
01892
01893
01894
BOOL
01895 GetPS2CSA_DEFG(
01896 PBYTE pProfile,
01897 PBYTE pBuffer,
01898 PDWORD pcbSize,
01899 DWORD dwIntent,
01900 DWORD dwType,
01901 PBOOL pbBinary
01902 )
01903 {
01904
PLUT16TYPE pLut;
01905 PTAGDATA pTagData;
01906
PBYTE pLineStart, pStart = pBuffer;
01907
PBYTE pTable;
01908
DWORD i, j, k, dwPCS, dwDev, dwIndex, dwTag, dwLutSig, SecondGrids, dwSize;
01909
DWORD nInputCh, nOutputCh, nGrids, nInputTable, nOutputTable, nNumbers;
01910
FIX_16_16 afxIlluminantWP[3];
01911
FIX_16_16 afxMediaWP[3];
01912
char pPublicArrayName[5];
01913
01914
01915
01916
01917
01918
switch (dwIntent)
01919 {
01920
case INTENT_PERCEPTUAL:
01921 dwTag =
TAG_AToB0;
01922
break;
01923
01924
case INTENT_RELATIVE_COLORIMETRIC:
01925 dwTag =
TAG_AToB1;
01926
break;
01927
01928
case INTENT_SATURATION:
01929 dwTag =
TAG_AToB2;
01930
break;
01931
01932
case INTENT_ABSOLUTE_COLORIMETRIC:
01933 dwTag =
TAG_AToB1;
01934
break;
01935
01936
default:
01937
WARNING((__TEXT(
"Invalid intent passed to GetPS2CSA_DEFG: %d\n"), dwIntent));
01938 SetLastError(ERROR_INVALID_PARAMETER);
01939
return FALSE;
01940 }
01941
01942
if (!
DoesCPTagExist(pProfile, dwTag, &dwIndex))
01943 {
01944
WARNING((__TEXT(
"AToB%d tag not present to create DEF(G) CSA\n"), dwIntent));
01945 SetLastError(ERROR_TAG_NOT_PRESENT);
01946
return FALSE;
01947 }
01948
01949
01950
01951
01952
01953
01954 dwPCS =
GetCPConnSpace(pProfile);
01955 dwDev =
GetCPDevSpace(pProfile);
01956
01957
if ((dwType ==
TYPE_CIEBASEDDEF && dwDev != SPACE_RGB) ||
01958 (dwType ==
TYPE_CIEBASEDDEFG && dwDev != SPACE_CMYK))
01959 {
01960
WARNING((__TEXT(
"RGB profile & requesting CMYK CSA or vice versa\n")));
01961 SetLastError(ERROR_TAG_NOT_PRESENT);
01962
return FALSE;
01963 }
01964
01965 pTagData = (PTAGDATA)(pProfile +
sizeof(PROFILEHEADER) +
sizeof(
DWORD) +
01966 dwIndex *
sizeof(TAGDATA));
01967
01968 pLut = (
PLUT16TYPE)(pProfile + FIX_ENDIAN(pTagData->dwOffset));
01969
01970 dwLutSig = FIX_ENDIAN(pLut->
dwSignature);
01971
01972
if (((dwPCS != SPACE_Lab) && (dwPCS != SPACE_XYZ)) ||
01973 ((dwLutSig !=
LUT8_TYPE) && (dwLutSig !=
LUT16_TYPE)))
01974 {
01975
WARNING((__TEXT(
"Invalid color space - unable to create DEF(G) CSA\n")));
01976 SetLastError(ERROR_INVALID_PROFILE);
01977
return FALSE;
01978 }
01979
01980
01981
01982
01983
01984 (
void)
GetCLUTInfo(dwLutSig, (
PBYTE)pLut, &nInputCh, &nOutputCh, &nGrids,
01985 &nInputTable, &nOutputTable,
NULL);
01986
01987
01988
01989
01990
01991
if (dwType ==
TYPE_CIEBASEDDEFG)
01992 {
01993 dwSize = nOutputCh * nGrids * nGrids * nGrids * nGrids * 2;
01994 }
01995
else
01996 {
01997 dwSize = nOutputCh * nGrids * nGrids * nGrids * 2;
01998 }
01999
02000 dwSize = dwSize +
02001 nInputCh * nInputTable * 6 +
02002 nOutputCh * nOutputTable * 6 +
02003 nInputCh * (
STRLEN(
IndexArray) +
02004
STRLEN(
StartClip) +
02005
STRLEN(
EndClip)) +
02006 nOutputCh * (
STRLEN(
IndexArray) +
02007
STRLEN(
StartClip) +
02008
STRLEN(
EndClip)) +
02009 4096;
02010
02011
02012
02013
02014
02015 dwSize += (((dwSize) /
MAX_LINELEN) + 1) *
STRLEN(
NewLine);
02016
02017
if (! pBuffer)
02018 {
02019 *pcbSize = dwSize;
02020
return TRUE;
02021 }
02022
else if (*pcbSize < dwSize)
02023 {
02024
WARNING((__TEXT(
"Buffer too small to get DEFG CSA\n")));
02025 SetLastError(ERROR_INSUFFICIENT_BUFFER);
02026
return FALSE;
02027 }
02028
02029
02030
02031
02032
02033 (
void)
GetCPWhitePoint(pProfile, afxIlluminantWP);
02034
02035
02036
02037
02038
02039 (
void)
GetMediaWP(pProfile, dwIntent, afxIlluminantWP, afxMediaWP);
02040
02041
02042
02043
02044
02045 pBuffer +=
WriteNewLineObject(pBuffer,
TestingDEFG);
02046
02047
02048
02049
02050
02051
GetPublicArrayName(dwTag, pPublicArrayName);
02052
02053
if (dwType ==
TYPE_CIEBASEDDEFG)
02054 {
02055 pBuffer +=
WriteNewLineObject(pBuffer,
CieBasedDEFGBegin);
02056 }
02057
else
02058 {
02059 pBuffer +=
WriteNewLineObject(pBuffer,
CieBasedDEFBegin);
02060 }
02061
02062 pBuffer +=
EnableGlobalDict(pBuffer);
02063 pBuffer +=
WriteNewLineObject(pBuffer,
SupportDEFG_S);
02064 pBuffer +=
BeginGlobalDict(pBuffer);
02065
02066 pBuffer +=
CreateInputArray(pBuffer, nInputCh, nInputTable,
02067 pPublicArrayName, dwLutSig, (
PBYTE)pLut, *pbBinary,
NULL);
02068
02069
if (dwType ==
TYPE_CIEBASEDDEFG)
02070 {
02071 i = nInputTable * nInputCh +
02072 nGrids * nGrids * nGrids * nGrids * nOutputCh;
02073 }
02074
else
02075 {
02076 i = nInputTable * nInputCh +
02077 nGrids * nGrids * nGrids * nOutputCh;
02078 }
02079 pBuffer +=
CreateOutputArray(pBuffer, nOutputCh, nOutputTable, i,
02080 pPublicArrayName, dwLutSig, (
PBYTE)pLut, *pbBinary,
NULL);
02081
02082 pBuffer +=
WriteNewLineObject(pBuffer,
EndOp);
02083 pBuffer +=
WriteNewLineObject(pBuffer,
SupportDEFG_E);
02084 pBuffer +=
WriteNewLineObject(pBuffer,
SetGlobalOp);
02085 pBuffer +=
WriteNewLineObject(pBuffer,
SupportDEFG_S);
02086
02087
02088
02089
02090
02091 pBuffer +=
WriteNewLineObject(pBuffer,
BeginArray);
02092
02093
02094
02095
02096
02097
if (dwType ==
TYPE_CIEBASEDDEFG)
02098 {
02099 pBuffer +=
WriteObject(pBuffer,
CIEBasedDEFGTag);
02100 }
02101
else
02102 {
02103 pBuffer +=
WriteObject(pBuffer,
CIEBasedDEFTag);
02104 }
02105
02106 pBuffer +=
WriteObject(pBuffer,
BeginDict);
02107
02108
02109
02110
02111
02112 pBuffer +=
SendCSABWPoint(pBuffer, dwIntent, afxIlluminantWP, afxMediaWP);
02113
02114
02115
02116
02117
02118 pLineStart = pBuffer;
02119
02120
if (dwType ==
TYPE_CIEBASEDDEFG)
02121 {
02122 pBuffer +=
WriteNewLineObject(pBuffer,
DecodeDEFGTag);
02123 }
02124
else
02125 {
02126 pBuffer +=
WriteNewLineObject(pBuffer,
DecodeDEFTag);
02127 }
02128
02129 pBuffer +=
WriteObject(pBuffer,
BeginArray);
02130
for (i=0; i<nInputCh; i++)
02131 {
02132 pLineStart = pBuffer;
02133
02134 pBuffer +=
WriteNewLineObject(pBuffer,
BeginFunction);
02135 pBuffer +=
WriteObject(pBuffer,
StartClip);
02136 pBuffer +=
WriteObject(pBuffer,
InputArray);
02137 pBuffer +=
WriteObject(pBuffer, pPublicArrayName);
02138 pBuffer +=
WriteInt(pBuffer, i);
02139
02140
if (! *pbBinary)
02141 {
02142 pBuffer +=
WriteObject(pBuffer,
IndexArray);
02143 }
02144
else
02145 {
02146
if (dwLutSig ==
LUT8_TYPE)
02147 {
02148 pBuffer +=
WriteObject(pBuffer,
IndexArray);
02149 }
02150
else
02151 {
02152 pBuffer +=
WriteObject(pBuffer,
IndexArray16b);
02153 }
02154 }
02155 pBuffer +=
WriteObject(pBuffer, (dwLutSig ==
LUT8_TYPE) ?
Scale8 :
Scale16);
02156 pBuffer +=
WriteObject(pBuffer,
EndClip);
02157 pBuffer +=
WriteObject(pBuffer,
EndFunction);
02158 }
02159 pBuffer +=
WriteObject(pBuffer,
EndArray);
02160
02161
02162
02163
02164
02165 pBuffer +=
WriteNewLineObject(pBuffer,
TableTag);
02166 pBuffer +=
WriteObject(pBuffer,
BeginArray);
02167
02168 pBuffer +=
WriteInt(pBuffer, nGrids);
02169 pBuffer +=
WriteInt(pBuffer, nGrids);
02170 pBuffer +=
WriteInt(pBuffer, nGrids);
02171 nNumbers = nGrids * nGrids * nOutputCh;
02172 SecondGrids = 1;
02173
02174
if (dwType ==
TYPE_CIEBASEDDEFG)
02175 {
02176 pBuffer +=
WriteInt (pBuffer, nGrids);
02177 SecondGrids = nGrids;
02178 }
02179 pBuffer +=
WriteNewLineObject(pBuffer,
BeginArray);
02180
02181
for (i=0; i<nGrids; i++)
02182 {
02183
if (dwType ==
TYPE_CIEBASEDDEFG)
02184 {
02185 pBuffer +=
WriteNewLineObject(pBuffer,
BeginArray);
02186 }
02187
for (k=0; k<SecondGrids; k++)
02188 {
02189 pLineStart = pBuffer;
02190 pBuffer +=
WriteObject(pBuffer,
NewLine);
02191
if (dwLutSig ==
LUT8_TYPE)
02192 {
02193 pTable = (
PBYTE)(((
PLUT8TYPE)pLut)->data) +
02194 nInputTable * nInputCh +
02195 nNumbers * (i * SecondGrids + k);
02196 }
02197
else
02198 {
02199 pTable = (
PBYTE)(((
PLUT16TYPE)pLut)->data) +
02200 2 * nInputTable * nInputCh +
02201 2 * nNumbers * (i * SecondGrids + k);
02202 }
02203
02204
if (! *pbBinary)
02205 {
02206 pBuffer +=
WriteObject(pBuffer,
BeginString);
02207
if (dwLutSig ==
LUT8_TYPE)
02208 {
02209 pBuffer +=
WriteHexBuffer(pBuffer, pTable, pLineStart, nNumbers);
02210 }
02211
else
02212 {
02213
for (j=0; j<nNumbers; j++)
02214 {
02215 pBuffer +=
WriteHex(pBuffer, FIX_ENDIAN16(*((PWORD)pTable)) / 256);
02216 pTable +=
sizeof(WORD);
02217
02218
if (((
DWORD) (pBuffer - pLineStart)) >
MAX_LINELEN)
02219 {
02220 pLineStart = pBuffer;
02221 pBuffer +=
WriteObject(pBuffer,
NewLine);
02222 }
02223 }
02224 }
02225 pBuffer +=
WriteObject(pBuffer,
EndString);
02226 }
02227
else
02228 {
02229 pBuffer +=
WriteStringToken(pBuffer, 143, nNumbers);
02230
if (dwLutSig ==
LUT8_TYPE)
02231 pBuffer +=
WriteByteString(pBuffer, pTable, nNumbers);
02232
else
02233 pBuffer +=
WriteInt2ByteString(pBuffer, pTable, nNumbers);
02234 }
02235 pBuffer +=
WriteObject (pBuffer,
NewLine);
02236 }
02237
if (dwType ==
TYPE_CIEBASEDDEFG)
02238 {
02239 pBuffer +=
WriteObject(pBuffer,
EndArray);
02240 }
02241 }
02242 pBuffer +=
WriteObject(pBuffer,
EndArray);
02243 pBuffer +=
WriteObject(pBuffer,
EndArray);
02244
02245
02246
02247
02248
02249 pLineStart = pBuffer;
02250 pBuffer +=
WriteNewLineObject(pBuffer,
DecodeABCTag);
02251 pBuffer +=
WriteObject(pBuffer,
BeginArray);
02252
for (i=0; i<nOutputCh; i++)
02253 {
02254 pLineStart = pBuffer;
02255
02256 pBuffer +=
WriteNewLineObject(pBuffer,
BeginFunction);
02257 pBuffer +=
WriteObject(pBuffer,
Clip01);
02258 pBuffer +=
WriteObject(pBuffer,
OutputArray);
02259 pBuffer +=
WriteObject(pBuffer, pPublicArrayName);
02260 pBuffer +=
WriteInt(pBuffer, i);
02261
02262
if (! *pbBinary)
02263 {
02264 pBuffer +=
WriteObject(pBuffer,
NewLine);
02265
02266
if (dwLutSig ==
LUT8_TYPE)
02267 {
02268 pBuffer +=
WriteObject(pBuffer,
TFunction8XYZ);
02269 }
02270
else
02271 {
02272 pBuffer +=
WriteObject(pBuffer,
IndexArray);
02273 pBuffer +=
WriteObject(pBuffer,
Scale16XYZ);
02274 }
02275 }
02276
else
02277 {
02278
if (dwLutSig ==
LUT8_TYPE)
02279 {
02280 pBuffer +=
WriteObject(pBuffer,
TFunction8XYZ);
02281 }
02282
else
02283 {
02284 pBuffer +=
WriteObject(pBuffer,
IndexArray16b);
02285 pBuffer +=
WriteObject(pBuffer,
Scale16XYZ);
02286 }
02287 }
02288
02289
02290
02291
02292
02293
02294
02295
if ((dwPCS == SPACE_XYZ) && (dwIntent == INTENT_ABSOLUTE_COLORIMETRIC))
02296 {
02297 pBuffer +=
WriteFixed(pBuffer,
FIX_DIV(afxMediaWP[i], afxIlluminantWP[i]));
02298 pBuffer +=
WriteObject(pBuffer,
MulOp);
02299 }
02300
else if (dwPCS == SPACE_Lab)
02301 {
02302
02303
02304
02305
02306 pBuffer +=
WriteObject(pBuffer,
DecodeABCLab[i]);
02307 }
02308 pBuffer +=
WriteObject(pBuffer,
EndFunction);
02309 }
02310 pBuffer +=
WriteObject(pBuffer,
EndArray);
02311
02312
if (dwPCS == SPACE_Lab)
02313 {
02314
02315
02316
02317
02318 pBuffer +=
WriteNewLineObject(pBuffer,
MatrixABCTag);
02319 pBuffer +=
WriteObject(pBuffer,
MatrixABCLab);
02320
02321
02322
02323
02324
02325 pLineStart = pBuffer;
02326 pBuffer +=
WriteNewLineObject(pBuffer,
DecodeLMNTag);
02327 pBuffer +=
WriteObject(pBuffer,
BeginArray);
02328
for (i=0; i<3; i++)
02329 {
02330 pLineStart = pBuffer;
02331
02332 pBuffer +=
WriteNewLineObject(pBuffer,
BeginFunction);
02333 pBuffer +=
WriteObject(pBuffer,
DecodeLMNLab);
02334
if (dwIntent == INTENT_ABSOLUTE_COLORIMETRIC)
02335 {
02336 pBuffer +=
WriteFixed(pBuffer, afxMediaWP[i]);
02337 }
02338
else
02339 {
02340 pBuffer +=
WriteFixed(pBuffer, afxIlluminantWP[i]);
02341 }
02342 pBuffer +=
WriteObject(pBuffer,
MulOp);
02343 pBuffer +=
WriteObject(pBuffer,
EndFunction);
02344 }
02345 pBuffer +=
WriteObject(pBuffer,
EndArray);
02346 }
02347
else
02348 {
02349
02350
02351
02352
02353 pBuffer +=
WriteNewLineObject(pBuffer,
RangeLMNTag);
02354 pBuffer +=
WriteObject(pBuffer,
RangeLMN);
02355 }
02356
02357
02358
02359
02360
02361 pBuffer +=
WriteNewLineObject(pBuffer,
EndDict);
02362 pBuffer +=
WriteObject(pBuffer,
EndArray);
02363
02364
if (dwType ==
TYPE_CIEBASEDDEFG)
02365 {
02366 pBuffer +=
WriteNewLineObject(pBuffer,
CieBasedDEFGEnd);
02367 }
02368
else
02369 {
02370 pBuffer +=
WriteNewLineObject(pBuffer,
CieBasedDEFEnd);
02371 }
02372
02373 pBuffer +=
WriteNewLineObject(pBuffer,
SupportDEFG_E);
02374
02375 *pcbSize = (
DWORD) (pBuffer - pStart);
02376
02377
return TRUE;
02378 }
02379
02380
02381
BOOL
02382 InternalGetPS2CSAFromLCS(
02383 LPLOGCOLORSPACE pLogColorSpace,
02384 PBYTE pBuffer,
02385 PDWORD pcbSize,
02386 PBOOL pbBinary
02387 )
02388 {
02389
PBYTE pStart = pBuffer;
02390
DWORD dwSize = 1024*2;
02391
02392
if (! pBuffer)
02393 {
02394 *pcbSize = dwSize;
02395
02396
return TRUE;
02397 }
02398
02399
if (*pcbSize < dwSize)
02400 {
02401
WARNING((__TEXT(
"Buffer too small to get CSA from LCS\n")));
02402 SetLastError(ERROR_INSUFFICIENT_BUFFER);
02403
return FALSE;
02404 }
02405
02406 pBuffer +=
WriteObject(pBuffer,
NewLine);
02407 pBuffer +=
WriteObject(pBuffer,
BeginArray);
02408
02409 pBuffer +=
WriteObject(pBuffer,
ColorSpace1);
02410 pBuffer +=
WriteObject(pBuffer,
BeginArray);
02411
02412
02413
02414
02415
02416 pBuffer +=
WriteObject(pBuffer,
BeginFunction);
02417 pBuffer +=
WriteFixed(pBuffer, pLogColorSpace->lcsGammaRed);
02418 pBuffer +=
WriteObject(pBuffer,
ColorSpace3);
02419
02420
02421
02422
02423
02424 pBuffer +=
WriteObject(pBuffer,
BeginFunction);
02425 pBuffer +=
WriteFixed(pBuffer, pLogColorSpace->lcsGammaGreen);
02426 pBuffer +=
WriteObject(pBuffer,
ColorSpace3);
02427
02428
02429
02430
02431
02432 pBuffer +=
WriteObject(pBuffer,
BeginFunction);
02433 pBuffer +=
WriteFixed(pBuffer, pLogColorSpace->lcsGammaBlue);
02434 pBuffer +=
WriteObject(pBuffer,
ColorSpace3);
02435
02436 pBuffer +=
WriteObject(pBuffer,
EndArray);
02437
02438 pBuffer +=
WriteObject(pBuffer,
ColorSpace5);
02439
02440
02441
02442
02443
02444 pBuffer +=
WriteObject(pBuffer,
MatrixLMNTag);
02445 pBuffer +=
WriteObject(pBuffer,
BeginArray);
02446
02447
02448
02449
02450
02451 pBuffer +=
WriteFixed2dot30(pBuffer, pLogColorSpace->lcsEndpoints.ciexyzRed.ciexyzX);
02452 pBuffer +=
WriteFixed2dot30(pBuffer, pLogColorSpace->lcsEndpoints.ciexyzRed.ciexyzY);
02453 pBuffer +=
WriteFixed2dot30(pBuffer, pLogColorSpace->lcsEndpoints.ciexyzRed.ciexyzZ);
02454
02455
02456
02457
02458
02459 pBuffer +=
WriteFixed2dot30(pBuffer, pLogColorSpace->lcsEndpoints.ciexyzGreen.ciexyzX);
02460 pBuffer +=
WriteFixed2dot30(pBuffer, pLogColorSpace->lcsEndpoints.ciexyzGreen.ciexyzY);
02461 pBuffer +=
WriteFixed2dot30(pBuffer, pLogColorSpace->lcsEndpoints.ciexyzGreen.ciexyzZ);
02462
02463
02464
02465
02466
02467 pBuffer +=
WriteFixed2dot30(pBuffer, pLogColorSpace->lcsEndpoints.ciexyzBlue.ciexyzX);
02468 pBuffer +=
WriteFixed2dot30(pBuffer, pLogColorSpace->lcsEndpoints.ciexyzBlue.ciexyzY);
02469 pBuffer +=
WriteFixed2dot30(pBuffer, pLogColorSpace->lcsEndpoints.ciexyzBlue.ciexyzZ);
02470
02471 pBuffer +=
WriteObject(pBuffer,
EndArray);
02472 pBuffer +=
WriteObject(pBuffer,
EndDict);
02473
02474 pBuffer +=
WriteObject(pBuffer,
EndArray);
02475
02476 *pcbSize = (
DWORD) (pBuffer - pStart);
02477
02478
return TRUE;
02479 }
02480
02481
02482
02483
02484
02485
02486
02487
02488
02489
02490
02491
02492
02493
02494
02495
02496
02497
02498
02499
02500
DWORD
02501 CreateColSpArray(
02502 PBYTE pProfile,
02503 PBYTE pBuffer,
02504 DWORD dwCPTag,
02505 BOOL bBinary
02506 )
02507 {
02508
PCURVETYPE pData;
02509 PTAGDATA pTagData;
02510
PBYTE pLineStart, pStart = pBuffer;
02511
PBYTE pTable;
02512
DWORD i, nCount, dwIndex;
02513
02514 pLineStart = pBuffer;
02515
02516
if (
DoesCPTagExist(pProfile, dwCPTag, &dwIndex))
02517 {
02518 pTagData = (PTAGDATA)(pProfile +
sizeof(PROFILEHEADER) +
sizeof(
DWORD) +
02519 dwIndex *
sizeof(TAGDATA));
02520
02521 pData = (
PCURVETYPE)(pProfile + FIX_ENDIAN(pTagData->dwOffset));
02522
02523 nCount = FIX_ENDIAN(pData->
nCount);
02524
02525
if (nCount > 1)
02526 {
02527 pBuffer +=
WriteNewLineObject(pBuffer,
Slash);
02528 pBuffer +=
WriteObject(pBuffer,
DecodeABCArray);
02529 pBuffer +=
WriteInt(pBuffer, dwCPTag);
02530
02531 pTable = (
PBYTE)(pData->
data);
02532
02533
if (! bBinary)
02534 {
02535 pBuffer +=
WriteObject(pBuffer,
BeginArray);
02536
for (i=0; i<nCount; i++)
02537 {
02538 pBuffer +=
WriteInt(pBuffer, FIX_ENDIAN16(*((PWORD)pTable)));
02539 pTable +=
sizeof(WORD);
02540
02541
if (((
DWORD) (pBuffer - pLineStart)) >
MAX_LINELEN)
02542 {
02543 pLineStart = pBuffer;
02544 pBuffer +=
WriteObject(pBuffer,
NewLine);
02545 }
02546 }
02547 pBuffer +=
WriteObject(pBuffer,
EndArray);
02548 }
02549
else
02550 {
02551 pBuffer +=
WriteHNAToken(pBuffer, 149, nCount);
02552 pBuffer +=
WriteIntStringU2S(pBuffer, pTable, nCount);
02553 }
02554
02555 pBuffer +=
WriteObject(pBuffer,
DefOp);
02556 }
02557 }
02558
return (
DWORD) (pBuffer - pStart);
02559 }
02560
02561
02562
02563
02564
02565
02566
02567
02568
02569
02570
02571
02572
02573
02574
02575
02576
02577
02578
02579
02580
DWORD
02581 CreateColSpProc(
02582 PBYTE pProfile,
02583 PBYTE pBuffer,
02584 DWORD dwCPTag,
02585 BOOL bBinary
02586 )
02587 {
02588
PCURVETYPE pData;
02589 PTAGDATA pTagData;
02590
PBYTE pStart = pBuffer;
02591
PBYTE pTable;
02592
DWORD nCount, dwIndex;
02593
02594 pBuffer +=
WriteObject(pBuffer,
BeginFunction);
02595
02596
if (
DoesCPTagExist(pProfile, dwCPTag, &dwIndex))
02597 {
02598 pTagData = (PTAGDATA)(pProfile +
sizeof(PROFILEHEADER) +
sizeof(
DWORD) +
02599 dwIndex *
sizeof(TAGDATA));
02600
02601 pData = (
PCURVETYPE)(pProfile + FIX_ENDIAN(pTagData->dwOffset));
02602
02603 nCount = FIX_ENDIAN(pData->
nCount);
02604
02605
if (nCount != 0)
02606 {
02607
if (nCount == 1)
02608 {
02609 pTable = (
PBYTE)(pData->
data);
02610 pBuffer +=
WriteInt(pBuffer, FIX_ENDIAN16(*((PWORD)pTable)));
02611 pBuffer +=
WriteObject(pBuffer,
DecodeA3);
02612 }
02613
else
02614 {
02615 pBuffer +=
WriteObject(pBuffer,
StartClip);
02616 pBuffer +=
WriteObject(pBuffer,
DecodeABCArray);
02617 pBuffer +=
WriteInt(pBuffer, dwCPTag);
02618
02619
if (! bBinary)
02620 {
02621 pBuffer +=
WriteObject(pBuffer,
IndexArray);
02622 }
02623
else
02624 {
02625 pBuffer +=
WriteObject(pBuffer,
IndexArray16b);
02626 }
02627 pBuffer +=
WriteObject(pBuffer,
Scale16);
02628 pBuffer +=
WriteObject(pBuffer,
EndClip);
02629 }
02630 }
02631 }
02632 pBuffer +=
WriteObject(pBuffer,
EndFunction);
02633
02634
return (
DWORD) (pBuffer - pStart);
02635 }
02636
02637
02638
02639
02640
02641
02642
02643
02644
02645
02646
02647
02648
02649
02650
02651
02652
02653
02654
02655
02656
DWORD
02657 CreateFloatString(
02658 PBYTE pProfile,
02659 PBYTE pBuffer,
02660 DWORD dwCPTag
02661 )
02662 {
02663 PTAGDATA pTagData;
02664
PBYTE pStart = pBuffer;
02665 PDWORD pTable;
02666
DWORD i, dwIndex;
02667
02668
if (
DoesCPTagExist(pProfile, dwCPTag, &dwIndex))
02669 {
02670 pTagData = (PTAGDATA)(pProfile +
sizeof(PROFILEHEADER) +
sizeof(
DWORD) +
02671 dwIndex *
sizeof(TAGDATA));
02672
02673 pTable = (PDWORD)(pProfile + FIX_ENDIAN(pTagData->dwOffset)) + 2;
02674
02675
for (i=0; i<3; i++)
02676 {
02677 pBuffer +=
WriteFixed(pBuffer, FIX_ENDIAN(*pTable));
02678 pTable ++;
02679 }
02680 }
02681
02682
return (
DWORD) (pBuffer - pStart);
02683 }
02684
02685
02686
02687
02688
02689
02690
02691
02692
02693
02694
02695
02696
02697
02698
02699
02700
02701
02702
02703
02704
02705
02706
02707
02708
DWORD
02709 CreateInputArray(
02710 PBYTE pBuffer,
02711 DWORD nInputChannels,
02712 DWORD nInputTable,
02713 PBYTE pIntent,
02714 DWORD dwTag,
02715 PBYTE pLut,
02716 BOOL bBinary,
02717 PBYTE pHostClut
02718 )
02719 {
02720
DWORD i, j;
02721
PBYTE pLineStart, pStart = pBuffer;
02722
PBYTE pTable;
02723
02724
if (pHostClut)
02725 {
02726 nInputChannels = ((
PHOSTCLUT)pHostClut)->nInputCh;
02727 nInputTable = ((
PHOSTCLUT)pHostClut)->nInputEntries;
02728 dwTag = ((
PHOSTCLUT)pHostClut)->nLutBits == 8 ?
LUT8_TYPE :
LUT16_TYPE;
02729 }
02730
02731
for (i=0; i<nInputChannels; i++)
02732 {
02733 pLineStart = pBuffer;
02734 pBuffer +=
WriteNewLineObject(pBuffer,
Slash);
02735
if (pHostClut)
02736 pBuffer +=
WriteObject(pBuffer,
PreViewInArray);
02737
else
02738 pBuffer +=
WriteObject(pBuffer,
InputArray);
02739
02740 pBuffer +=
WriteObject(pBuffer, pIntent);
02741 pBuffer +=
WriteInt(pBuffer, i);
02742
02743
if (pHostClut)
02744 {
02745 pTable = ((
PHOSTCLUT)pHostClut)->inputArray[i];
02746 }
02747
else
02748 {
02749
if (dwTag ==
LUT8_TYPE)
02750 {
02751 pTable = (
PBYTE)(((
PLUT8TYPE)pLut)->data) + nInputTable * i;
02752 }
02753
else
02754 {
02755 pTable = (
PBYTE)(((
PLUT16TYPE)pLut)->data) + 2 * nInputTable * i;
02756 }
02757 }
02758
02759
if (! bBinary)
02760 {
02761
if (dwTag ==
LUT8_TYPE)
02762 {
02763 pBuffer +=
WriteObject(pBuffer,
BeginString);
02764 pBuffer +=
WriteHexBuffer(pBuffer, pTable, pLineStart, nInputTable);
02765 pBuffer +=
WriteObject(pBuffer,
EndString);
02766 }
02767
else
02768 {
02769 pBuffer +=
WriteObject(pBuffer,
BeginArray);
02770
for (j=0; j<nInputTable; j++)
02771 {
02772
if (pHostClut)
02773 pBuffer +=
WriteInt(pBuffer, *((PWORD)pTable));
02774
else
02775 pBuffer +=
WriteInt(pBuffer, FIX_ENDIAN16(*((PWORD)pTable)));
02776 pTable +=
sizeof(WORD);
02777
if (((
DWORD) (pBuffer - pLineStart)) >
MAX_LINELEN)
02778 {
02779 pLineStart = pBuffer;
02780 pBuffer +=
WriteObject(pBuffer,
NewLine);
02781 }
02782 }
02783 pBuffer +=
WriteObject(pBuffer,
EndArray);
02784 }
02785 }
02786
else
02787 {
02788
if (dwTag ==
LUT8_TYPE)
02789 {
02790 pBuffer +=
WriteStringToken(pBuffer, 143, nInputTable);
02791 pBuffer +=
WriteByteString(pBuffer, pTable, nInputTable);
02792 }
02793
else
02794 {
02795 pBuffer +=
WriteHNAToken(pBuffer, 149, nInputTable);
02796
if (pHostClut)
02797 pBuffer +=
WriteIntStringU2S_L(pBuffer, pTable, nInputTable);
02798
else
02799 pBuffer +=
WriteIntStringU2S(pBuffer, pTable, nInputTable);
02800 }
02801 }
02802 pBuffer +=
WriteObject(pBuffer,
DefOp);
02803 }
02804
02805
return (
DWORD) (pBuffer - pStart);
02806 }
02807
02808
02809
02810
02811
02812
02813
02814
02815
02816
02817
02818
02819
02820
02821
02822
02823
02824
02825
02826
02827
02828
02829
02830
02831
02832
02833
DWORD
02834 CreateOutputArray(
02835 PBYTE pBuffer,
02836 DWORD nOutputChannels,
02837 DWORD nOutputTable,
02838 DWORD dwOffset,
02839 PBYTE pIntent,
02840 DWORD dwTag,
02841 PBYTE pLut,
02842 BOOL bBinary,
02843 PBYTE pHostClut
02844 )
02845 {
02846
DWORD i, j;
02847
PBYTE pLineStart, pStart = pBuffer;
02848
PBYTE pTable;
02849
02850
if (pHostClut)
02851 {
02852 nOutputChannels = ((
PHOSTCLUT)pHostClut)->nOutputCh;
02853 nOutputTable = ((
PHOSTCLUT)pHostClut)->nOutputEntries;
02854 dwTag = ((
PHOSTCLUT)pHostClut)->nLutBits == 8 ?
LUT8_TYPE :
LUT16_TYPE;
02855 }
02856
02857
for (i=0; i<nOutputChannels; i++)
02858 {
02859 pLineStart = pBuffer;
02860 pBuffer +=
WriteNewLineObject(pBuffer,
Slash);
02861
if (pHostClut)
02862 pBuffer +=
WriteObject(pBuffer,
PreViewOutArray);
02863
else
02864 pBuffer +=
WriteObject(pBuffer,
OutputArray);
02865 pBuffer +=
WriteObject(pBuffer, pIntent);
02866 pBuffer +=
WriteInt(pBuffer, i);
02867
02868
if (pHostClut)
02869 {
02870 pTable = ((
PHOSTCLUT)pHostClut)->outputArray[i];
02871 }
02872
else
02873 {
02874
if (dwTag ==
LUT8_TYPE)
02875 {
02876 pTable = (
PBYTE)(((
PLUT8TYPE)pLut)->data) +
02877 dwOffset + nOutputTable * i;
02878 }
02879
else
02880 {
02881 pTable = (
PBYTE)(((
PLUT16TYPE)pLut)->data) +
02882 2 * dwOffset + 2 * nOutputTable * i;
02883 }
02884 }
02885
02886
if (! bBinary)
02887 {
02888
if (dwTag ==
LUT8_TYPE)
02889 {
02890 pBuffer +=
WriteObject(pBuffer,
BeginString);
02891 pBuffer +=
WriteHexBuffer(pBuffer, pTable, pLineStart, nOutputTable);
02892 pBuffer +=
WriteObject(pBuffer,
EndString);
02893 }
02894
else
02895 {
02896 pBuffer +=
WriteObject(pBuffer,
BeginArray);
02897
for (j=0; j<nOutputTable; j++)
02898 {
02899
if (pHostClut)
02900 pBuffer +=
WriteInt(pBuffer, *((PWORD)pTable));
02901
else
02902 pBuffer +=
WriteInt(pBuffer, FIX_ENDIAN16(*((PWORD)pTable)));
02903 pTable +=
sizeof(WORD);
02904
if (((
DWORD) (pBuffer - pLineStart)) >
MAX_LINELEN)
02905 {
02906 pLineStart = pBuffer;
02907 pBuffer +=
WriteObject(pBuffer,
NewLine);
02908 }
02909 }
02910 pBuffer +=
WriteObject(pBuffer,
EndArray);
02911 }
02912 }
02913
else
02914 {
02915
if (dwTag ==
LUT8_TYPE)
02916 {
02917 pBuffer +=
WriteStringToken(pBuffer, 143, 256);
02918 pBuffer +=
WriteByteString(pBuffer, pTable, 256
L);
02919 }
02920
else
02921 {
02922 pBuffer +=
WriteHNAToken(pBuffer, 149, nOutputTable);
02923
if (pHostClut)
02924 pBuffer +=
WriteIntStringU2S_L(pBuffer, pTable, nOutputTable);
02925
else
02926 pBuffer +=
WriteIntStringU2S(pBuffer, pTable, nOutputTable);
02927 }
02928 }
02929 pBuffer +=
WriteObject(pBuffer,
DefOp);
02930 }
02931
02932
return (
DWORD)(pBuffer - pStart);
02933 }
02934
02935
02936
02937
02938
02939
02940
02941
02942
02943
02944
02945
02946
02947
02948
02949
02950
02951
02952
DWORD
02953 GetPublicArrayName(
02954 DWORD dwIntentSig,
02955 PBYTE pPublicArrayName
02956 )
02957 {
02958 *((
DWORD *)pPublicArrayName) = dwIntentSig;
02959 pPublicArrayName[
sizeof(
DWORD)] =
'\0';
02960
02961
return sizeof(
DWORD) + 1;
02962 }
02963
02964
02965
02966
02967
02968
02969
02970
02971
02972
02973
02974
02975
02976
02977
BOOL
02978 CreateMonoCRD(
02979 PBYTE pProfile,
02980 DWORD dwIndex,
02981 PBYTE pBuffer,
02982 PDWORD pcbSize,
02983 DWORD dwIntent
02984 )
02985 {
02986 PTAGDATA pTagData;
02987
PCURVETYPE pData;
02988
PBYTE pLineStart, pStart = pBuffer;
02989 PWORD pCurve, pRevCurve, pRevCurveStart;
02990
DWORD dwPCS, dwSize, nCount, i;
02991
FIX_16_16 afxIlluminantWP[3];
02992
FIX_16_16 afxMediaWP[3];
02993
02994 dwPCS =
GetCPConnSpace(pProfile);
02995
02996 pTagData = (PTAGDATA)(pProfile +
sizeof(PROFILEHEADER) +
sizeof(
DWORD) +
02997 dwIndex *
sizeof(TAGDATA));
02998
02999 pData = (
PCURVETYPE)(pProfile + FIX_ENDIAN(pTagData->dwOffset));
03000
03001 nCount = FIX_ENDIAN(pData->
nCount);
03002
03003
03004
03005
03006
03007 dwSize = nCount * 6 *
REVCURVE_RATIO +
03008 2048;
03009
03010
03011
03012
03013
03014 dwSize += (((dwSize) /
MAX_LINELEN) + 1) *
STRLEN(
NewLine);
03015
03016
if (! pBuffer)
03017 {
03018 *pcbSize = dwSize;
03019
return TRUE;
03020 }
03021
else if (*pcbSize < dwSize)
03022 {
03023
WARNING((__TEXT(
"Buffer too small to get Mono CRD\n")));
03024 SetLastError(ERROR_INSUFFICIENT_BUFFER);
03025
return FALSE;
03026 }
03027
03028
03029
03030
03031
03032
03033
03034
03035
if ((pRevCurveStart =
MemAlloc(nCount *
sizeof(WORD) * (
REVCURVE_RATIO + 1))) ==
NULL)
03036 {
03037
WARNING((__TEXT(
"Unable to allocate memory for reverse curve\n")));
03038 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
03039
return FALSE;
03040 }
03041
03042
03043
03044
03045
03046 pCurve = pRevCurveStart + nCount *
REVCURVE_RATIO;
03047 pRevCurve = pRevCurveStart;
03048
03049 (
void)
GetRevCurve(pData, pCurve, pRevCurve);
03050
03051
03052
03053
03054
03055 (
void)
GetCPWhitePoint(pProfile, afxIlluminantWP);
03056
03057
03058
03059
03060
03061
if (dwIntent == INTENT_ABSOLUTE_COLORIMETRIC)
03062 {
03063
if (!
GetCPMediaWhitePoint(pProfile, afxMediaWP))
03064 {
03065 afxMediaWP[0] = afxIlluminantWP[0];
03066 afxMediaWP[1] = afxIlluminantWP[1];
03067 afxMediaWP[2] = afxIlluminantWP[2];
03068 }
03069 }
03070
03071
03072
03073
03074
03075 pBuffer +=
WriteNewLineObject(pBuffer,
BeginDict);
03076 pBuffer +=
WriteObject(pBuffer,
DictType);
03077
03078
03079
03080
03081
03082
switch (dwIntent)
03083 {
03084
case INTENT_PERCEPTUAL:
03085 pBuffer +=
WriteNewLineObject(pBuffer,
IntentType);
03086 pBuffer +=
WriteObject(pBuffer,
IntentPer);
03087
break;
03088
03089
case INTENT_SATURATION:
03090 pBuffer +=
WriteNewLineObject(pBuffer,
IntentType);
03091 pBuffer +=
WriteObject(pBuffer,
IntentSat);
03092
break;
03093
03094
case INTENT_RELATIVE_COLORIMETRIC:
03095 pBuffer +=
WriteNewLineObject(pBuffer,
IntentType);
03096 pBuffer +=
WriteObject(pBuffer,
IntentRCol);
03097
break;
03098
03099
case INTENT_ABSOLUTE_COLORIMETRIC:
03100 pBuffer +=
WriteNewLineObject(pBuffer,
IntentType);
03101 pBuffer +=
WriteObject(pBuffer,
IntentACol);
03102
break;
03103 }
03104
03105
03106
03107
03108
03109 pBuffer +=
SendCRDBWPoint(pBuffer, afxIlluminantWP);
03110
03111
03112
03113
03114
03115 pBuffer +=
SendCRDPQR(pBuffer, dwIntent, afxIlluminantWP);
03116
03117
03118
03119
03120
03121 pBuffer +=
SendCRDLMN(pBuffer, dwIntent, afxIlluminantWP, afxMediaWP, dwPCS);
03122
03123
03124
03125
03126
03127
if (dwPCS == SPACE_XYZ)
03128 {
03129
03130
03131
03132
03133
03134 pBuffer +=
WriteNewLineObject(pBuffer,
MatrixABCTag);
03135 pBuffer +=
WriteObject(pBuffer,
MatrixABCXYZCRD);
03136 }
03137
else if (dwPCS == SPACE_Lab)
03138 {
03139 pBuffer +=
WriteNewLineObject(pBuffer,
MatrixABCTag);
03140 pBuffer +=
WriteObject(pBuffer,
MatrixABCLabCRD);
03141 }
03142
03143
03144
03145
03146
03147
if (nCount != 0)
03148 {
03149 pBuffer +=
WriteObject(pBuffer,
NewLine);
03150 pLineStart = pBuffer;
03151 pBuffer +=
WriteObject(pBuffer,
EncodeABCTag);
03152 pBuffer +=
WriteObject(pBuffer,
BeginArray);
03153 pBuffer +=
WriteObject(pBuffer,
BeginFunction);
03154
if (nCount == 1)
03155 {
03156
PBYTE pTable;
03157
03158 pTable = (
PBYTE) (pData->
data);
03159 pBuffer +=
WriteInt(pBuffer, FIX_ENDIAN16(*((PWORD)pTable)));
03160 pBuffer +=
WriteObject(pBuffer,
DecodeA3Rev);
03161 }
03162
else
03163 {
03164
if (dwPCS == SPACE_Lab)
03165 {
03166 pBuffer +=
WriteObject(pBuffer,
EncodeABCLab1);
03167 }
03168 pBuffer +=
WriteObject(pBuffer,
StartClip);
03169 pBuffer +=
WriteObject(pBuffer,
BeginArray);
03170
for (i=0; i<nCount *
REVCURVE_RATIO; i++)
03171 {
03172 pBuffer +=
WriteInt(pBuffer, *((WORD *)pRevCurve));
03173 pRevCurve++;
03174
if (((
DWORD) (pBuffer - pLineStart)) >
MAX_LINELEN)
03175 {
03176 pLineStart = pBuffer;
03177 pBuffer +=
WriteObject(pBuffer,
NewLine);
03178 }
03179 }
03180 pBuffer +=
WriteObject(pBuffer,
EndArray);
03181 pLineStart = pBuffer;
03182
03183 pBuffer +=
WriteNewLineObject(pBuffer,
IndexArray);
03184 pBuffer +=
WriteObject(pBuffer,
Scale16);
03185 pBuffer +=
WriteObject(pBuffer,
EndClip);
03186 }
03187 pBuffer +=
WriteObject (pBuffer,
EndFunction);
03188 pBuffer +=
WriteObject (pBuffer,
DupOp);
03189 pBuffer +=
WriteObject (pBuffer,
DupOp);
03190 pBuffer +=
WriteObject (pBuffer,
EndArray);
03191 }
03192 pBuffer +=
WriteObject(pBuffer,
EndDict);
03193
03194
MemFree(pRevCurveStart);
03195
03196 *pcbSize = (
DWORD) (pBuffer - pStart);
03197
03198
return TRUE;
03199 }
03200
03201
03202
03203
03204
03205
03206
03207
03208
03209
03210
03211
03212
03213
03214
BOOL
03215 CreateLutCRD(
03216 PBYTE pProfile,
03217 DWORD dwIndex,
03218 PBYTE pBuffer,
03219 PDWORD pcbSize,
03220 DWORD dwIntent,
03221 BOOL bBinary
03222 )
03223 {
03224 PTAGDATA pTagData;
03225
PLUT16TYPE pLut;
03226
PBYTE pTable;
03227
PBYTE pLineStart, pStart = pBuffer;
03228
DWORD dwPCS, dwSize, dwLutSig, dwTag, i, j;
03229
DWORD nInputCh, nOutputCh, nGrids, nInputTable, nOutputTable, nNumbers;
03230
FIX_16_16 afxIlluminantWP[3];
03231
FIX_16_16 afxMediaWP[3];
03232
char pPublicArrayName[5];
03233
03234
03235
03236
03237
03238
03239 dwPCS =
GetCPConnSpace(pProfile);
03240
03241 pTagData = (PTAGDATA)(pProfile +
sizeof(PROFILEHEADER) +
sizeof(
DWORD) +
03242 dwIndex *
sizeof(TAGDATA));
03243
03244 dwTag = FIX_ENDIAN(pTagData->tagType);
03245
03246 pLut = (
PLUT16TYPE)(pProfile + FIX_ENDIAN(pTagData->dwOffset));
03247
03248 dwLutSig = FIX_ENDIAN(pLut->
dwSignature);
03249
03250
if ((dwLutSig !=
LUT8_TYPE) && (dwLutSig !=
LUT16_TYPE))
03251 {
03252
WARNING((__TEXT(
"Invalid profile - unable to create Lut CRD\n")));
03253 SetLastError(ERROR_INVALID_PROFILE);
03254
return FALSE;
03255 }
03256
03257
03258
03259
03260
03261 (
void)
GetCLUTInfo(dwLutSig, (
PBYTE)pLut, &nInputCh, &nOutputCh, &nGrids,
03262 &nInputTable, &nOutputTable,
NULL);
03263
03264
03265
03266
03267
03268 dwSize = nInputCh * nInputTable * 6 +
03269 nOutputCh * nOutputTable * 6 +
03270 nOutputCh * nGrids * nGrids * nGrids * 2 +
03271 nInputCh * (
STRLEN(
IndexArray) +
03272
STRLEN(
StartClip) +
03273
STRLEN(
EndClip)) +
03274 nOutputCh * (
STRLEN(
IndexArray) +
03275
STRLEN(
StartClip) +
03276
STRLEN(
EndClip)) +
03277 2048;
03278
03279
03280
03281
03282
03283 dwSize += (((dwSize) /
MAX_LINELEN) + 1) *
STRLEN(
NewLine);
03284
03285
if (! pBuffer)
03286 {
03287 *pcbSize = dwSize;
03288
return TRUE;
03289 }
03290
else if (*pcbSize < dwSize)
03291 {
03292
WARNING((__TEXT(
"Buffer too small to get DEFG CSA\n")));
03293 SetLastError(ERROR_INSUFFICIENT_BUFFER);
03294
return FALSE;
03295 }
03296
03297
03298
03299
03300
03301 (
void)
GetCPWhitePoint(pProfile, afxIlluminantWP);
03302
03303
03304
03305
03306
03307
if (dwIntent == INTENT_ABSOLUTE_COLORIMETRIC)
03308 {
03309
if (!
GetCPMediaWhitePoint(pProfile, afxMediaWP))
03310 {
03311 afxMediaWP[0] = afxIlluminantWP[0];
03312 afxMediaWP[1] = afxIlluminantWP[1];
03313 afxMediaWP[2] = afxIlluminantWP[2];
03314 }
03315 }
03316
03317
03318
03319
03320
03321
GetPublicArrayName(dwTag, pPublicArrayName);
03322 pBuffer +=
WriteNewLineObject(pBuffer,
CRDBegin);
03323
03324 pBuffer +=
EnableGlobalDict(pBuffer);
03325 pBuffer +=
BeginGlobalDict(pBuffer);
03326
03327 pBuffer +=
CreateInputArray(pBuffer, nInputCh, nInputTable,
03328 pPublicArrayName, dwLutSig, (
PBYTE)pLut, bBinary,
NULL);
03329
03330 i = nInputTable * nInputCh +
03331 nGrids * nGrids * nGrids * nOutputCh;
03332 pBuffer +=
CreateOutputArray(pBuffer, nOutputCh, nOutputTable, i,
03333 pPublicArrayName, dwLutSig, (
PBYTE)pLut, bBinary,
NULL);
03334
03335 pBuffer +=
EndGlobalDict(pBuffer);
03336
03337
03338
03339
03340
03341 pBuffer +=
WriteNewLineObject(pBuffer,
BeginDict);
03342 pBuffer +=
WriteObject(pBuffer,
DictType);
03343
03344
03345
03346
03347
03348
switch (dwIntent)
03349 {
03350
case INTENT_PERCEPTUAL:
03351 pBuffer +=
WriteNewLineObject(pBuffer,
IntentType);
03352 pBuffer +=
WriteObject(pBuffer,
IntentPer);
03353
break;
03354
03355
case INTENT_SATURATION:
03356 pBuffer +=
WriteNewLineObject(pBuffer,
IntentType);
03357 pBuffer +=
WriteObject(pBuffer,
IntentSat);
03358
break;
03359
03360
case INTENT_RELATIVE_COLORIMETRIC:
03361 pBuffer +=
WriteNewLineObject(pBuffer,
IntentType);
03362 pBuffer +=
WriteObject(pBuffer,
IntentRCol);
03363
break;
03364
03365
case INTENT_ABSOLUTE_COLORIMETRIC:
03366 pBuffer +=
WriteNewLineObject(pBuffer,
IntentType);
03367 pBuffer +=
WriteObject(pBuffer,
IntentACol);
03368
break;
03369 }
03370
03371
03372
03373
03374
03375 pBuffer +=
SendCRDBWPoint(pBuffer, afxIlluminantWP);
03376
03377
03378
03379
03380
03381 pBuffer +=
SendCRDPQR(pBuffer, dwIntent, afxIlluminantWP);
03382
03383
03384
03385
03386
03387 pBuffer +=
SendCRDLMN(pBuffer, dwIntent, afxIlluminantWP, afxMediaWP, dwPCS);
03388
03389
03390
03391
03392
03393 pBuffer +=
SendCRDABC(pBuffer, pPublicArrayName, dwPCS, nInputCh,
03394 (
PBYTE)pLut,
NULL, dwLutSig, bBinary);
03395
03396
03397
03398
03399
03400 pBuffer +=
WriteNewLineObject(pBuffer,
RenderTableTag);
03401 pBuffer +=
WriteObject(pBuffer,
BeginArray);
03402
03403 pBuffer +=
WriteInt(pBuffer, nGrids);
03404 pBuffer +=
WriteInt(pBuffer, nGrids);
03405 pBuffer +=
WriteInt(pBuffer, nGrids);
03406
03407 pLineStart = pBuffer;
03408 pBuffer +=
WriteNewLineObject(pBuffer,
BeginArray);
03409 nNumbers = nGrids * nGrids * nOutputCh;
03410
03411
for (i=0; i<nGrids; i++)
03412 {
03413 pBuffer +=
WriteObject(pBuffer,
NewLine);
03414 pLineStart = pBuffer;
03415
if (dwLutSig ==
LUT8_TYPE)
03416 {
03417 pTable = (
PBYTE)(((
PLUT8TYPE)pLut)->data) + nInputTable * nInputCh + nNumbers * i;
03418 }
03419
else
03420 {
03421 pTable = (
PBYTE)(((
PLUT16TYPE)pLut)->data) + 2 * nInputTable * nInputCh + 2 * nNumbers * i;
03422 }
03423
03424
if (! bBinary)
03425 {
03426 pBuffer +=
WriteObject(pBuffer,
BeginString);
03427
if (dwLutSig ==
LUT8_TYPE)
03428 {
03429 pBuffer +=
WriteHexBuffer(pBuffer, pTable, pLineStart, nNumbers);
03430 }
03431
else
03432 {
03433
for (j=0; j<nNumbers; j++)
03434 {
03435 pBuffer +=
WriteHex(pBuffer, FIX_ENDIAN16(*((PWORD)pTable)) / 256);
03436 pTable +=
sizeof(WORD);
03437
if (((
DWORD) (pBuffer - pLineStart)) >
MAX_LINELEN)
03438 {
03439 pLineStart = pBuffer;
03440 pBuffer +=
WriteObject(pBuffer,
NewLine);
03441 }
03442 }
03443 }
03444 pBuffer +=
WriteObject(pBuffer,
EndString);
03445 }
03446
else
03447 {
03448 pBuffer +=
WriteStringToken(pBuffer, 143, nNumbers);
03449
if (dwLutSig ==
LUT8_TYPE)
03450 {
03451 pBuffer +=
WriteByteString(pBuffer, pTable, nNumbers);
03452 }
03453
else
03454 {
03455 pBuffer +=
WriteInt2ByteString(pBuffer, pTable, nNumbers);
03456 }
03457 }
03458 }
03459
03460 pBuffer +=
WriteObject(pBuffer,
EndArray);
03461 pBuffer +=
WriteInt(pBuffer, nOutputCh);
03462
03463 pBuffer +=
SendCRDOutputTable(pBuffer, pPublicArrayName,
03464 nOutputCh, dwLutSig,
FALSE, bBinary);
03465
03466 pBuffer +=
WriteObject(pBuffer,
EndArray);
03467 pBuffer +=
WriteObject(pBuffer,
EndDict);
03468
03469 pBuffer +=
WriteNewLineObject(pBuffer,
CRDEnd);
03470
03471 *pcbSize = (
DWORD) (pBuffer - pStart);
03472
03473
return TRUE;
03474 }
03475
03476
#if !defined(KERNEL_MODE) || defined(USERMODE_DRIVER)
03477
03478
03479
03480
03481
03482
03483
03484
03485
03486
03487
03488
03489
03490
03491
03492
03493
03494
BOOL
03495 CreateMatrixCRD(
03496 PBYTE pProfile,
03497 PBYTE pBuffer,
03498 PDWORD pcbSize,
03499 DWORD dwIntent,
03500 BOOL bBinary
03501 )
03502 {
03503 PTAGDATA pTagData;
03504
DWORD dwRedTRCIndex, dwGreenTRCIndex, dwBlueTRCIndex;
03505
DWORD dwRedCount, dwGreenCount, dwBlueCount;
03506
PBYTE pMem =
NULL;
03507
PCURVETYPE pRed, pGreen, pBlue;
03508
DWORD i, dwSize;
03509
PBYTE pStart = pBuffer;
03510 PWORD pRevCurve;
03511
FIX_16_16 afxIlluminantWP[3];
03512
double adColorant[9];
03513
double adRevColorant[9];
03514
03515
03516
03517
03518
03519
if (
IsSRGBColorProfile(pProfile))
03520 {
03521 dwSize = 4096;
03522
03523
03524
03525
03526
03527
if (! pBuffer)
03528 {
03529 *pcbSize = dwSize;
03530
return TRUE;
03531 }
03532
03533
03534
03535
03536
03537
if (*pcbSize < dwSize)
03538 {
03539
WARNING((__TEXT(
"Buffer too small to get sRGB CRD\n")));
03540 SetLastError(ERROR_INSUFFICIENT_BUFFER);
03541
return FALSE;
03542 }
03543
03544
03545
03546
03547
03548 pBuffer +=
WriteNewLineObject(pBuffer,
CRDBegin);
03549 pBuffer +=
WriteNewLineObject(pBuffer,
BeginDict);
03550 pBuffer +=
WriteObject(pBuffer,
DictType);
03551
03552
03553
03554
03555
03556
switch (dwIntent)
03557 {
03558
case INTENT_PERCEPTUAL:
03559 pBuffer +=
WriteNewLineObject(pBuffer,
IntentType);
03560 pBuffer +=
WriteObject(pBuffer,
IntentPer);
03561
break;
03562
03563
case INTENT_SATURATION:
03564 pBuffer +=
WriteNewLineObject(pBuffer,
IntentType);
03565 pBuffer +=
WriteObject(pBuffer,
IntentSat);
03566
break;
03567
03568
case INTENT_RELATIVE_COLORIMETRIC:
03569 pBuffer +=
WriteNewLineObject(pBuffer,
IntentType);
03570 pBuffer +=
WriteObject(pBuffer,
IntentRCol);
03571
break;
03572
03573
case INTENT_ABSOLUTE_COLORIMETRIC:
03574 pBuffer +=
WriteNewLineObject(pBuffer,
IntentType);
03575 pBuffer +=
WriteObject(pBuffer,
IntentACol);
03576
break;
03577 }
03578
03579
03580
03581
03582
03583 pBuffer +=
WriteNewLineObject(pBuffer,
sRGBColorRenderingDictionary);
03584
03585
03586
03587
03588
03589 pBuffer +=
WriteNewLineObject(pBuffer,
CRDEnd);
03590 }
03591
else
03592 {
03593
03594
03595
03596
03597
if (!
DoesCPTagExist(pProfile,
TAG_REDTRC, &dwRedTRCIndex) ||
03598 !
DoesCPTagExist(pProfile,
TAG_GREENTRC, &dwGreenTRCIndex) ||
03599 !
DoesCPTagExist(pProfile,
TAG_BLUETRC, &dwBlueTRCIndex))
03600 {
03601
return FALSE;
03602 }
03603
03604
03605
03606
03607
03608 pTagData = (PTAGDATA)(pProfile +
sizeof(PROFILEHEADER) +
sizeof(
DWORD) +
03609 dwRedTRCIndex *
sizeof(TAGDATA));
03610
03611 pRed = (
PCURVETYPE)(pProfile + FIX_ENDIAN(pTagData->dwOffset));
03612
03613 pTagData = (PTAGDATA)(pProfile +
sizeof(PROFILEHEADER) +
sizeof(
DWORD) +
03614 dwGreenTRCIndex *
sizeof(TAGDATA));
03615
03616 pGreen = (
PCURVETYPE)(pProfile + FIX_ENDIAN(pTagData->dwOffset));
03617
03618 pTagData = (PTAGDATA)(pProfile +
sizeof(PROFILEHEADER) +
sizeof(
DWORD) +
03619 dwBlueTRCIndex *
sizeof(TAGDATA));
03620
03621 pBlue = (
PCURVETYPE)(pProfile + FIX_ENDIAN(pTagData->dwOffset));
03622
03623
03624
03625
03626
03627 dwRedCount = FIX_ENDIAN(pRed->
nCount);
03628 dwGreenCount = FIX_ENDIAN(pGreen->
nCount);
03629 dwBlueCount = FIX_ENDIAN(pBlue->
nCount);
03630
03631
03632
03633
03634
03635 dwSize = (dwRedCount + dwGreenCount + dwBlueCount) * 6 *
REVCURVE_RATIO +
03636 4096;
03637
03638
03639
03640
03641
03642 dwSize += (((dwSize) /
MAX_LINELEN) + 1) *
STRLEN(
NewLine);
03643
03644
if (pBuffer ==
NULL)
03645 {
03646 *pcbSize = dwSize;
03647
return TRUE;
03648 }
03649
03650
03651
03652
03653
03654
if (*pcbSize < dwSize)
03655 {
03656
WARNING((__TEXT(
"Buffer too small to get sRGB CRD\n")));
03657 SetLastError(ERROR_INSUFFICIENT_BUFFER);
03658
return FALSE;
03659 }
03660
03661
03662
03663
03664
03665
if ((pRevCurve =
MemAlloc(dwRedCount *
sizeof(WORD) * (
REVCURVE_RATIO + 1))) ==
NULL)
03666 {
03667
WARNING((__TEXT(
"Unable to allocate memory for reserved curve\n")));
03668 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
03669
MemFree(pMem);
03670
return FALSE;
03671 }
03672
03673
03674
03675
03676
03677 (
void)
GetCPWhitePoint(pProfile, afxIlluminantWP);
03678
03679
03680
03681
03682
03683 pBuffer +=
EnableGlobalDict(pBuffer);
03684 pBuffer +=
BeginGlobalDict(pBuffer);
03685
03686 pBuffer +=
CreateCRDRevArray(pProfile, pBuffer, pRed, pRevCurve,
TAG_REDTRC, bBinary);
03687 pBuffer +=
CreateCRDRevArray(pProfile, pBuffer, pGreen, pRevCurve,
TAG_GREENTRC, bBinary);
03688 pBuffer +=
CreateCRDRevArray(pProfile, pBuffer, pBlue, pRevCurve,
TAG_BLUETRC, bBinary);
03689
03690 pBuffer +=
EndGlobalDict(pBuffer);
03691
03692
03693
03694
03695
03696 pBuffer +=
WriteNewLineObject(pBuffer,
CRDBegin);
03697 pBuffer +=
WriteNewLineObject(pBuffer,
BeginDict);
03698 pBuffer +=
WriteObject(pBuffer,
DictType);
03699
03700
03701
03702
03703
03704
switch (dwIntent)
03705 {
03706
case INTENT_PERCEPTUAL:
03707 pBuffer +=
WriteNewLineObject(pBuffer,
IntentType);
03708 pBuffer +=
WriteObject(pBuffer,
IntentPer);
03709
break;
03710
03711
case INTENT_SATURATION:
03712 pBuffer +=
WriteNewLineObject(pBuffer,
IntentType);
03713 pBuffer +=
WriteObject(pBuffer,
IntentSat);
03714
break;
03715
03716
case INTENT_RELATIVE_COLORIMETRIC:
03717 pBuffer +=
WriteNewLineObject(pBuffer,
IntentType);
03718 pBuffer +=
WriteObject(pBuffer,
IntentRCol);
03719
break;
03720
03721
case INTENT_ABSOLUTE_COLORIMETRIC:
03722 pBuffer +=
WriteNewLineObject(pBuffer,
IntentType);
03723 pBuffer +=
WriteObject(pBuffer,
IntentACol);
03724
break;
03725 }
03726
03727
03728
03729
03730
03731 pBuffer +=
SendCRDBWPoint(pBuffer, afxIlluminantWP);
03732
03733
03734
03735
03736
03737 pBuffer +=
SendCRDPQR(pBuffer, dwIntent, afxIlluminantWP);
03738
03739
03740
03741
03742
03743
CreateColorantArray(pProfile, &adColorant[0],
TAG_REDCOLORANT);
03744
CreateColorantArray(pProfile, &adColorant[3],
TAG_GREENCOLORANT);
03745
CreateColorantArray(pProfile, &adColorant[6],
TAG_BLUECOLORANT);
03746
InvertColorantArray(adColorant, adRevColorant);
03747
03748 pBuffer +=
WriteNewLineObject(pBuffer,
MatrixLMNTag);
03749
03750 pBuffer +=
WriteObject(pBuffer,
BeginArray);
03751
for (i = 0; i < 9; i++)
03752 {
03753 pBuffer +=
WriteDouble(pBuffer, adRevColorant[i]);
03754 }
03755 pBuffer +=
WriteObject(pBuffer,
EndArray);
03756
03757
03758
03759
03760
03761 pBuffer +=
WriteNewLineObject(pBuffer,
EncodeABCTag);
03762 pBuffer +=
WriteObject(pBuffer,
BeginArray);
03763
03764 pBuffer +=
WriteObject(pBuffer,
NewLine);
03765 pBuffer +=
SendCRDRevArray(pProfile, pBuffer, pRed,
TAG_REDTRC, bBinary);
03766
03767 pBuffer +=
WriteObject(pBuffer,
NewLine);
03768 pBuffer +=
SendCRDRevArray(pProfile, pBuffer, pGreen,
TAG_GREENTRC, bBinary);
03769
03770 pBuffer +=
WriteObject(pBuffer,
NewLine);
03771 pBuffer +=
SendCRDRevArray(pProfile, pBuffer, pBlue,
TAG_BLUETRC, bBinary);
03772
03773 pBuffer +=
WriteNewLineObject(pBuffer,
EndArray);
03774 pBuffer +=
WriteObject(pBuffer,
EndDict);
03775
03776 pBuffer +=
WriteNewLineObject(pBuffer,
CRDEnd);
03777
03778
MemFree (pRevCurve);
03779 }
03780
03781 *pcbSize = (
DWORD)(pBuffer - pStart);
03782
03783
return TRUE;
03784 }
03785
03786
03787
DWORD
03788 CreateCRDRevArray(
03789 PBYTE pProfile,
03790 PBYTE pBuffer,
03791 PCURVETYPE pData,
03792 PWORD pRevCurve,
03793 DWORD dwTag,
03794 BOOL bBinary
03795 )
03796 {
03797
DWORD i, nCount;
03798
PBYTE pStart, pLineStart;
03799 PWORD pCurve;
03800
03801 pStart = pBuffer;
03802 pLineStart = pBuffer;
03803
03804 nCount = FIX_ENDIAN(pData->
nCount);
03805
if (nCount > 1)
03806 {
03807 pBuffer +=
WriteNewLineObject(pBuffer,
Slash);
03808 pBuffer +=
WriteObject(pBuffer,
InputArray);
03809 pBuffer +=
WriteInt(pBuffer, (
INT) dwTag);
03810
03811 pCurve = pRevCurve + (
REVCURVE_RATIO * nCount);
03812
03813
GetRevCurve (pData, pCurve, pRevCurve);
03814
03815
if (!bBinary)
03816 {
03817 pBuffer +=
WriteObject(pBuffer,
BeginArray);
03818
for (i = 0; i < nCount *
REVCURVE_RATIO; i++)
03819 {
03820 pBuffer +=
WriteInt(pBuffer, *pRevCurve);
03821 pRevCurve++;
03822
if (((
DWORD) (pBuffer - pLineStart)) >
MAX_LINELEN)
03823 {
03824 pLineStart = pBuffer;
03825 pBuffer +=
WriteObject(pBuffer,
NewLine);
03826 }
03827 }
03828 pBuffer +=
WriteObject(pBuffer,
EndArray);
03829 }
03830
else
03831 {
03832 pBuffer +=
WriteHNAToken(pBuffer, 149, nCount);
03833 pBuffer +=
WriteIntStringU2S_L(pBuffer, (
PBYTE) pRevCurve, nCount);
03834 }
03835 pBuffer +=
WriteObject(pBuffer,
DefOp);
03836 }
03837
03838
return (
DWORD)(pBuffer - pStart);
03839 }
03840
03841
03842
DWORD
03843 SendCRDRevArray(
03844 PBYTE pProfile,
03845 PBYTE pBuffer,
03846 PCURVETYPE pData,
03847 DWORD dwTag,
03848 BOOL bBinary
03849 )
03850 {
03851
DWORD nCount;
03852
PBYTE pStart;
03853 PWORD pTable;
03854
03855 pStart = pBuffer;
03856
03857 pBuffer +=
WriteObject(pBuffer,
BeginFunction);
03858 nCount = FIX_ENDIAN(pData->
nCount);
03859
if (nCount != 0)
03860 {
03861
if (nCount == 1)
03862 {
03863 pTable = pData->
data;
03864 pBuffer +=
WriteInt(pBuffer, FIX_ENDIAN16(*pTable));
03865 pBuffer +=
WriteObject(pBuffer,
DecodeA3Rev);
03866 }
03867
else
03868 {
03869 pBuffer +=
WriteObject(pBuffer,
StartClip);
03870 pBuffer +=
WriteObject(pBuffer,
InputArray);
03871 pBuffer +=
WriteInt(pBuffer, dwTag);
03872
03873
if (!bBinary)
03874 {
03875 pBuffer +=
WriteObject(pBuffer,
IndexArray);
03876 }
03877
else
03878 {
03879 pBuffer +=
WriteObject(pBuffer,
IndexArray16b);
03880 }
03881
03882 pBuffer +=
WriteObject(pBuffer,
Scale16);
03883 pBuffer +=
WriteObject(pBuffer,
EndClip);
03884 }
03885 }
03886 pBuffer +=
WriteObject(pBuffer,
EndFunction);
03887
03888
return (
DWORD)(pBuffer - pStart);
03889 }
03890
03891
03892
BOOL
03893 CreateColorantArray(
03894 PBYTE pProfile,
03895
double *lpArray,
03896 DWORD dwTag
03897 )
03898 {
03899 PTAGDATA pTagData;
03900
PXYZTYPE pData;
03901
PFIX_16_16 pTable;
03902
DWORD i, dwIndex;
03903
BYTE buffer[1000];
03904
03905
if (
DoesCPTagExist(pProfile, dwTag, &dwIndex))
03906 {
03907 pTagData = (PTAGDATA)(pProfile +
sizeof(PROFILEHEADER) +
sizeof(
DWORD) +
03908 dwIndex *
sizeof(TAGDATA));
03909
03910 pData = (
PXYZTYPE)(pProfile + FIX_ENDIAN(pTagData->dwOffset));
03911
03912 pTable = pData->
afxData;
03913
03914
for (i = 0; i < 3; i++)
03915 {
03916
FIX_16_16 afxData = FIX_ENDIAN(*pTable);
03917
03918
03919
03920
03921
03922 *lpArray = ((
double) afxData) / ((
double)
FIX_16_16_SCALE);
03923
03924 pTable++; lpArray++;
03925 }
03926
03927
return (
TRUE);
03928 }
03929
03930
return (
FALSE);
03931 }
03932
03933
#endif // !defined(KERNEL_MODE) || defined(USERMODE_DRIVER)
03934
03935
03936
03937
03938
03939
03940
03941
03942
03943
BOOL
03944 GetRevCurve(
03945 PCURVETYPE pData,
03946 PWORD pInput,
03947 PWORD pOutput
03948 )
03949 {
03950
PBYTE pTable;
03951
DWORD nCount, dwStore, i, j;
03952
DWORD dwBegin, dwEnd, dwTemp;
03953
03954 nCount = FIX_ENDIAN(pData->
nCount);
03955 pTable = (
PBYTE)pData->
data;
03956
03957
for (i=0; i<nCount; i++)
03958 {
03959 pInput[i] = FIX_ENDIAN16(*((PWORD)pTable));
03960 pTable +=
sizeof(WORD);
03961 }
03962
03963 j = nCount *
REVCURVE_RATIO;
03964
for (i=0; i<j; i++)
03965 {
03966 dwStore = i * 65535 / (j - 1);
03967 pOutput[i] = (dwStore < 65535) ? (WORD) dwStore : 65535;
03968 }
03969
03970
for (i=0; i<j; i++)
03971 {
03972 dwBegin = 0;
03973 dwEnd = nCount - 1;
03974
for (;;)
03975 {
03976
if ((dwEnd - dwBegin) <= 1)
03977
break;
03978 dwTemp = (dwEnd + dwBegin) / 2;
03979
if (pOutput[i] < pInput[dwTemp])
03980 dwEnd = dwTemp;
03981
else
03982 dwBegin = dwTemp;
03983 }
03984
if (pOutput[i] <= pInput[dwBegin])
03985 {
03986 dwStore = dwBegin;
03987 }
03988
else if (pOutput[i] >= pInput[dwEnd])
03989 {
03990 dwStore = dwEnd;
03991 }
03992
else
03993 {
03994 dwStore = (pInput[dwEnd] - pOutput[i]) / (pOutput[i] - pInput[dwBegin]);
03995 dwStore = (dwBegin * dwStore + dwEnd) / (dwStore + 1);
03996 }
03997
03998 dwStore = dwStore * 65535 / (nCount - 1);
03999 pOutput[i] = (dwStore < 65535) ? (WORD) dwStore : 65535;
04000 }
04001
04002
return TRUE;
04003 }
04004
04005
04006
BOOL
04007 DoesCPTagExist(
04008 PBYTE pProfile,
04009 DWORD dwTag,
04010 PDWORD pdwIndex
04011 )
04012 {
04013
DWORD i, dwCount;
04014 PTAGDATA pTagData;
04015
BOOL bRc;
04016
04017
04018
04019
04020
04021 dwCount = FIX_ENDIAN(*((
DWORD *)(pProfile +
sizeof(PROFILEHEADER))));
04022
04023
04024
04025
04026
04027 pTagData = (PTAGDATA)(pProfile +
sizeof(PROFILEHEADER) +
sizeof(
DWORD));
04028
04029
04030
04031
04032
04033 bRc =
FALSE;
04034 dwTag = FIX_ENDIAN(dwTag);
04035
for (i=0; i<dwCount; i++)
04036 {
04037
if (pTagData->tagType == dwTag)
04038 {
04039
if (pdwIndex)
04040 {
04041 *pdwIndex = i;
04042 }
04043
04044 bRc =
TRUE;
04045
break;
04046 }
04047 pTagData++;
04048 }
04049
04050
return bRc;
04051 }
04052
04053
04054
BOOL
04055 DoesTRCAndColorantTagExist(
04056 PBYTE pProfile
04057 )
04058 {
04059
if (
DoesCPTagExist(pProfile,
TAG_REDCOLORANT,
NULL) &&
04060
DoesCPTagExist(pProfile,
TAG_REDTRC,
NULL) &&
04061
DoesCPTagExist(pProfile,
TAG_GREENCOLORANT,
NULL) &&
04062
DoesCPTagExist(pProfile,
TAG_GREENTRC,
NULL) &&
04063
DoesCPTagExist(pProfile,
TAG_BLUECOLORANT,
NULL) &&
04064
DoesCPTagExist(pProfile,
TAG_BLUETRC,
NULL))
04065 {
04066
return TRUE;
04067 }
04068
04069
return FALSE;
04070 }
04071
04072
04073
BOOL
04074 GetCPWhitePoint(
04075 PBYTE pProfile,
04076 PFIX_16_16 pafxWP
04077 )
04078 {
04079 pafxWP[0] = FIX_ENDIAN(((PPROFILEHEADER)pProfile)->phIlluminant.ciexyzX);
04080 pafxWP[1] = FIX_ENDIAN(((PPROFILEHEADER)pProfile)->phIlluminant.ciexyzY);
04081 pafxWP[2] = FIX_ENDIAN(((PPROFILEHEADER)pProfile)->phIlluminant.ciexyzZ);
04082
04083
return TRUE;
04084 }
04085
04086
BOOL
04087 GetCPMediaWhitePoint(
04088 PBYTE pProfile,
04089 PFIX_16_16 pafxMediaWP
04090 )
04091 {
04092 PTAGDATA pTagData;
04093 PDWORD pTable;
04094
DWORD dwIndex, i;
04095
04096
if (
DoesCPTagExist (pProfile,
TAG_MEDIAWHITEPOINT, &dwIndex))
04097 {
04098 pTagData = (PTAGDATA)(pProfile +
sizeof(PROFILEHEADER) +
sizeof(
DWORD) +
04099 dwIndex *
sizeof(TAGDATA));
04100
04101
04102
04103
04104
04105 pTable = (PDWORD)(pProfile + FIX_ENDIAN(pTagData->dwOffset)) + 2;
04106
04107
for (i=0; i<3; i++)
04108 {
04109 pafxMediaWP[i] = FIX_ENDIAN(*pTable);
04110 pTable++;
04111 }
04112
04113
return TRUE;
04114 }
04115
04116
return FALSE;
04117 }
04118
04119
04120
BOOL
04121 GetCPElementDataSize(
04122 PBYTE pProfile,
04123 DWORD dwIndex,
04124 PDWORD pcbSize)
04125 {
04126 PTAGDATA pTagData;
04127
04128 pTagData = (PTAGDATA)(pProfile +
sizeof(PROFILEHEADER) +
sizeof(
DWORD) +
04129 dwIndex *
sizeof(TAGDATA));
04130
04131
04132
04133
04134
04135
04136 *pcbSize = FIX_ENDIAN(pTagData->cbSize) - 3 *
sizeof(
DWORD);
04137
04138
return TRUE;
04139 }
04140
04141
04142
BOOL
04143 GetCPElementSize(
04144 PBYTE pProfile,
04145 DWORD dwIndex,
04146 PDWORD pcbSize)
04147 {
04148 PTAGDATA pTagData;
04149
04150 pTagData = (PTAGDATA)(pProfile +
sizeof(PROFILEHEADER) +
sizeof(
DWORD) +
04151 dwIndex *
sizeof(TAGDATA));
04152
04153 *pcbSize = FIX_ENDIAN(pTagData->cbSize);
04154
04155
return TRUE;
04156 }
04157
04158
04159
BOOL
04160 GetCPElementDataType(
04161 PBYTE pProfile,
04162 DWORD dwIndex,
04163 PDWORD pdwDataType)
04164 {
04165 PTAGDATA pTagData;
04166
PBYTE pData;
04167
04168 pTagData = (PTAGDATA)(pProfile +
sizeof(PROFILEHEADER) +
sizeof(
DWORD) +
04169 dwIndex *
sizeof(TAGDATA));
04170
04171 pData = pProfile + FIX_ENDIAN(pTagData->dwOffset);
04172
04173 *pdwDataType = FIX_ENDIAN(*((
DWORD *)(pData + 2 *
sizeof(
DWORD))));
04174
04175
return TRUE;
04176 }
04177
04178
04179
BOOL
04180 GetCPElementData(
04181 PBYTE pProfile,
04182 DWORD dwIndex,
04183 PBYTE pBuffer,
04184 PDWORD pdwSize
04185 )
04186 {
04187 PTAGDATA pTagData;
04188
PBYTE pData;
04189
04190 pTagData = (PTAGDATA)(pProfile +
sizeof(PROFILEHEADER) +
sizeof(
DWORD) +
04191 dwIndex *
sizeof(TAGDATA));
04192
04193 pData = pProfile + FIX_ENDIAN(pTagData->dwOffset);
04194
04195
04196
04197
04198
04199
04200 *pdwSize = FIX_ENDIAN(pTagData->cbSize) - 3 *
sizeof(
DWORD);
04201
04202
if (pBuffer)
04203 {
04204 CopyMemory(pBuffer, (pData + 3*
sizeof(
DWORD)), *pdwSize);
04205 }
04206
04207
return TRUE;
04208 }
04209
04210
04211
BOOL
04212 GetTRCElementSize(
04213 PBYTE pProfile,
04214 DWORD dwTag,
04215 PDWORD pdwIndex,
04216 PDWORD pdwSize
04217 )
04218 {
04219
DWORD dwDataType;
04220
04221
if (!
DoesCPTagExist(pProfile, dwTag, pdwIndex) ||
04222 !
GetCPElementDataType(pProfile, *pdwIndex, &dwDataType) ||
04223 !(dwDataType !=
SIG_CURVE_TYPE) ||
04224 !
GetCPElementSize(pProfile, *pdwIndex, pdwSize))
04225 {
04226
return FALSE;
04227 }
04228
04229
return TRUE;
04230 }
04231
04232
04233
DWORD
04234 Ascii85Encode(
04235 PBYTE pBuffer,
04236 DWORD dwDataSize,
04237 DWORD dwBufSize
04238 )
04239 {
04240
04241
04242
#if 0
04243
PBYTE pTempBuf, pPtr;
04244
DWORD dwASCII85Size = 0;
04245
DWORD dwBufSize = DataSize * 5 / 4 +
sizeof(
ASCII85DecodeBegin)+
sizeof(
ASCII85DecodeEnd) + 2048;
04246
04247
if ((pTempBuf = (
PBYTE)
MemAlloc(dwBufSize)))
04248 {
04249 pPtr = pTempBuf;
04250 pPtr +=
WriteObject(pPtr,
NewLine);
04251 pPtr +=
WriteObject(pPtr,
ASCII85DecodeBegin);
04252 pPtr +=
WriteObject(pPtr,
NewLine);
04253 pPtr +=
WriteASCII85Cont(pPtr, dwBufSize, pBuffer, dwDataSize);
04254 pPtr +=
WriteObject(pPtr,
ASCII85DecodeEnd);
04255 dwAscii85Size = (
DWORD)(pPtr - pTempBuf);
04256 lstrcpyn(pBuffer, pTempBuf, dwAscii85Size);
04257
04258
MemFree(pTempBuf);
04259 }
04260
04261
return dwAscii85Size;
04262
#else
04263
return 0;
04264
#endif
04265
}
04266
04267
04268
04269
04270
04271
04272
04273
DWORD
04274 WriteHNAToken(
04275 PBYTE pBuffer,
04276 BYTE token,
04277 DWORD dwNum
04278 )
04279 {
04280 *pBuffer++ = token;
04281 *pBuffer++ = 32;
04282 *pBuffer++ = (
BYTE)((dwNum & 0xFF00) >> 8);
04283 *pBuffer++ = (
BYTE)(dwNum & 0x00FF);
04284
04285
return 4;
04286 }
04287
04288
04289
04290
04291
04292
04293
04294
04295
DWORD
04296 WriteIntStringU2S(
04297 PBYTE pBuffer,
04298 PBYTE pData,
04299 DWORD dwNum
04300 )
04301 {
04302
DWORD i, dwTemp;
04303
04304
for (i=0; i<dwNum; i++)
04305 {
04306 dwTemp = FIX_ENDIAN16(*((PWORD)pData)) - 32768;
04307 *pBuffer++ = (
BYTE)((dwTemp & 0xFF00) >> 8);
04308 *pBuffer++ = (
BYTE)(dwTemp & 0x00FF);
04309 pData +=
sizeof(WORD);
04310 }
04311
04312
return dwNum * 2;
04313 }
04314
04315
04316
04317
04318
04319
04320
04321
04322
04323
DWORD
04324 WriteIntStringU2S_L(
04325 PBYTE pBuffer,
04326 PBYTE pData,
04327 DWORD dwNum
04328 )
04329 {
04330
DWORD i, dwTemp;
04331
04332
for (i=0; i<dwNum; i++)
04333 {
04334 dwTemp = *((PWORD)pData) - 32768;
04335 *pBuffer++ = (
BYTE)((dwTemp & 0xFF00) >> 8);
04336 *pBuffer++ = (
BYTE)(dwTemp & 0x00FF);
04337 pData +=
sizeof(WORD);
04338 }
04339
04340
return dwNum * 2;
04341 }
04342
04343
04344
04345
04346
04347
04348
04349
04350
DWORD
04351 WriteHexBuffer(
04352 PBYTE pBuffer,
04353 PBYTE pData,
04354 PBYTE pLineStart,
04355 DWORD dwBytes
04356 )
04357 {
04358
PBYTE pStart = pBuffer;
04359
04360
for ( ; dwBytes ; dwBytes-- )
04361 {
04362
WriteHex(pBuffer, *pData);
04363 pBuffer += 2;
04364 pData++;
04365
if (((
DWORD)(pBuffer - pLineStart)) >
MAX_LINELEN)
04366 {
04367 pLineStart = pBuffer;
04368 pBuffer +=
WriteObject(pBuffer,
NewLine);
04369 }
04370 }
04371
return( (
DWORD)(pBuffer - pStart));
04372 }
04373
04374
04375
04376
04377
04378
04379
04380
DWORD
04381 WriteStringToken(
04382 PBYTE pBuffer,
04383 BYTE token,
04384 DWORD dwNum
04385 )
04386 {
04387 *pBuffer++ = token;
04388 *pBuffer++ = (
BYTE)((dwNum & 0xFF00) >> 8);
04389 *pBuffer++ = (
BYTE)(dwNum & 0x00FF);
04390
04391
return 3;
04392 }
04393
04394
04395
04396
04397
04398
04399
04400
DWORD
04401 WriteByteString(
04402 PBYTE pBuffer,
04403 PBYTE pData,
04404 DWORD dwBytes
04405 )
04406 {
04407
DWORD i;
04408
04409
for (i=0; i<dwBytes; i++)
04410 *pBuffer++ = *pData++;
04411
04412
return dwBytes;
04413 }
04414
04415
04416
04417
04418
04419
04420
04421
DWORD
04422 WriteInt2ByteString(
04423 PBYTE pBuffer,
04424 PBYTE pData,
04425 DWORD dwBytes
04426 )
04427 {
04428
DWORD i;
04429
04430
for (i=0; i<dwBytes ; i++)
04431 {
04432 *pBuffer++ = (
BYTE)(FIX_ENDIAN16(*((PWORD)pData))/256);
04433 pData +=
sizeof(WORD);
04434 }
04435
04436
return dwBytes;
04437 }
04438
04439
#ifndef KERNEL_MODE
04440
DWORD
04441 WriteFixed(
04442 PBYTE pBuffer,
04443 FIX_16_16 fxNum
04444 )
04445 {
04446
double dFloat = (
double) ((
long) fxNum) / (
double)
FIX_16_16_SCALE;
04447
04448
return (
WriteDouble(pBuffer,dFloat));
04449 }
04450
#else
04451
DWORD
04452
WriteFixed(
04453 PBYTE pBuffer,
04454 FIX_16_16 fxNum
04455 )
04456 {
04457
PBYTE pStart = pBuffer;
04458
DWORD i;
04459
04460
04461
04462
04463
04464
#ifndef KERNEL_MODE
04465
pBuffer +=
wsprintfA(pBuffer,
"%lu", fxNum >> FIX_16_16_SHIFT);
04466
#else
04467
pBuffer += OPSprintf(pBuffer,
"%l", fxNum >> FIX_16_16_SHIFT);
04468
#endif
04469
04470
04471
04472
04473
04474 fxNum &= 0xffff;
04475
if (fxNum != 0)
04476 {
04477
04478
04479
04480
04481
04482 *pBuffer++ =
'.';
04483
04484 i = 0;
04485
while (fxNum && i++ < 6)
04486 {
04487 fxNum *= 10;
04488 *pBuffer++ = (
BYTE)(fxNum >>
FIX_16_16_SHIFT) +
'0';
04489 fxNum -=
FLOOR(fxNum);
04490 }
04491 }
04492
04493 *pBuffer++ =
' ';
04494
04495
return (
DWORD) (pBuffer - pStart);
04496 }
04497
#endif
04498
04499
DWORD
04500 WriteFixed2dot30(
04501 PBYTE pBuffer,
04502 DWORD fxNum
04503 )
04504 {
04505
PBYTE pStart = pBuffer;
04506
DWORD i;
04507
04508
04509
04510
04511
04512
#ifndef KERNEL_MODE
04513
pBuffer +=
wsprintfA(pBuffer,
"%lu", fxNum >> 30);
04514
#else
04515
pBuffer += OPSprintf(pBuffer,
"%l", fxNum >> 30);
04516
#endif
04517
04518
04519
04520
04521
04522 fxNum &= 0x3fffffff
L;
04523
if (fxNum != 0)
04524 {
04525
04526
04527
04528
04529
04530 *pBuffer++ =
'.';
04531
04532 i = 0;
04533
while (fxNum && i++ < 10)
04534 {
04535 fxNum *= 10;
04536 *pBuffer++ = (
BYTE)(fxNum >> 30) +
'0';
04537 fxNum -= ((fxNum >> 30) << 30);
04538 }
04539 }
04540
04541 *pBuffer++ =
' ';
04542
04543
return (
DWORD) (pBuffer - pStart);
04544 }
04545
04546
#if !defined(KERNEL_MODE) || defined(USERMODE_DRIVER)
04547
04548
04549
04550
04551
04552
04553
04554 DWORD WriteDouble(PBYTE pBuffer,
double dFloat)
04555 {
04556 LONG lFloat = (LONG) floor(dFloat * 10000.0 + 0.5);
04557
double dFloat1 = lFloat / 10000.0 ;
04558
double dInt = floor(fabs(dFloat1));
04559
double dFract = fabs(dFloat1) - dInt ;
04560
char cSign =
' ' ;
04561
04562
if (dFloat1 < 0)
04563 {
04564 cSign =
'-' ;
04565 }
04566
04567
return (
wsprintfA(pBuffer, (LPSTR)
"%c%d.%0.4lu ",
04568 cSign, (WORD) dInt , (
DWORD) (dFract * 10000.0)));
04569 }
04570
04571
#endif // !defined(KERNEL_MODE) || defined(USERMODE_DRIVER)
04572
04573 DWORD WriteNewLineObject(
04574 PBYTE pBuffer,
04575
const char *pData)
04576 {
04577
PBYTE pStart = pBuffer;
04578
04579 pBuffer +=
WriteObject(pBuffer,
NewLine);
04580 pBuffer +=
WriteObject(pBuffer, pData);
04581
04582
return (
DWORD)(pBuffer - pStart);
04583 }
04584
04585
04586
DWORD
04587 SendCRDBWPoint(
04588 PBYTE pBuffer,
04589 PFIX_16_16 pafxWP
04590 )
04591 {
04592
PBYTE pStart = pBuffer;
04593
int i;
04594
04595
04596
04597
04598
04599 pBuffer +=
WriteObject(pBuffer,
NewLine);
04600 pBuffer +=
WriteObject(pBuffer,
BlackPointTag);
04601 pBuffer +=
WriteObject(pBuffer,
BlackPoint);
04602
04603
04604
04605
04606
04607 pBuffer +=
WriteObject(pBuffer,
NewLine);
04608 pBuffer +=
WriteObject(pBuffer,
WhitePointTag);
04609 pBuffer +=
WriteObject(pBuffer,
BeginArray);
04610
for (i=0; i<3; i++)
04611 {
04612 pBuffer +=
WriteFixed(pBuffer, pafxWP[i]);
04613 }
04614 pBuffer +=
WriteObject(pBuffer,
EndArray);
04615
04616
return (
DWORD)(pBuffer - pStart);
04617 }
04618
04619
04620
DWORD
04621 SendCRDPQR(
04622 PBYTE pBuffer,
04623 DWORD dwIntent,
04624 PFIX_16_16 pafxWP
04625 )
04626 {
04627
PBYTE pStart = pBuffer;
04628
int i;
04629
04630
if (dwIntent != INTENT_ABSOLUTE_COLORIMETRIC)
04631 {
04632
04633
04634
04635
04636 pBuffer +=
WriteNewLineObject(pBuffer,
RangePQRTag);
04637 pBuffer +=
WriteObject(pBuffer,
RangePQR);
04638
04639
04640
04641
04642
04643 pBuffer +=
WriteNewLineObject(pBuffer,
MatrixPQRTag);
04644 pBuffer +=
WriteObject(pBuffer,
MatrixPQR);
04645 }
04646
else
04647 {
04648
04649
04650
04651
04652 pBuffer +=
WriteNewLineObject(pBuffer,
RangePQRTag);
04653 pBuffer +=
WriteObject(pBuffer,
BeginArray);
04654
for (i=0; i<3; i++)
04655 {
04656 pBuffer +=
WriteFixed(pBuffer, 0);
04657 pBuffer +=
WriteFixed(pBuffer, pafxWP[i]);
04658 }
04659 pBuffer +=
WriteObject(pBuffer,
EndArray);
04660
04661
04662
04663
04664
04665 pBuffer +=
WriteNewLineObject(pBuffer,
MatrixPQRTag);
04666 pBuffer +=
WriteObject(pBuffer,
Identity);
04667 }
04668
04669
04670
04671
04672
04673 pBuffer +=
WriteNewLineObject(pBuffer,
TransformPQRTag);
04674 pBuffer +=
WriteObject(pBuffer,
BeginArray);
04675
for (i=0; i<3; i++)
04676 {
04677 pBuffer +=
WriteObject(pBuffer,
BeginFunction);
04678 pBuffer +=
WriteObject(pBuffer,
04679 (dwIntent != INTENT_ABSOLUTE_COLORIMETRIC) ?
TransformPQR[i] :
NullOp);
04680 pBuffer +=
WriteObject(pBuffer,
EndFunction);
04681 }
04682 pBuffer +=
WriteObject(pBuffer,
EndArray);
04683
04684
return (
DWORD)(pBuffer - pStart);
04685 }
04686
04687
04688
DWORD
04689 SendCRDLMN(
04690 PBYTE pBuffer,
04691 DWORD dwIntent,
04692 PFIX_16_16 pafxIlluminantWP,
04693 PFIX_16_16 pafxMediaWP,
04694 DWORD dwPCS
04695 )
04696 {
04697
PBYTE pStart = pBuffer;
04698
DWORD i, j;
04699
04700
04701
04702
04703
04704
if (dwIntent == INTENT_ABSOLUTE_COLORIMETRIC)
04705 {
04706 pBuffer +=
WriteNewLineObject(pBuffer,
MatrixLMNTag);
04707
04708 pBuffer +=
WriteObject(pBuffer,
BeginArray);
04709
for (i=0; i<3; i++)
04710 {
04711
for (j=0; j<3; j++)
04712 pBuffer +=
WriteFixed(pBuffer,
04713 (i == j) ?
FIX_DIV(pafxIlluminantWP[i], pafxMediaWP[i]) : 0);
04714 }
04715 pBuffer +=
WriteObject(pBuffer,
EndArray);
04716 }
04717
04718
04719
04720
04721
04722 pBuffer +=
WriteNewLineObject(pBuffer,
RangeLMNTag);
04723
if (dwPCS == SPACE_XYZ)
04724 {
04725 pBuffer +=
WriteObject(pBuffer,
BeginArray);
04726
for (i=0; i<3; i++)
04727 {
04728 pBuffer +=
WriteFixed(pBuffer, 0);
04729 pBuffer +=
WriteFixed(pBuffer, pafxIlluminantWP[i]);
04730 }
04731 pBuffer +=
WriteObject(pBuffer,
EndArray);
04732 }
04733
else
04734 {
04735 pBuffer +=
WriteObject(pBuffer,
RangeLMNLab);
04736 }
04737
04738
04739
04740
04741
04742 pBuffer +=
WriteNewLineObject(pBuffer,
EncodeLMNTag);
04743 pBuffer +=
WriteObject(pBuffer,
BeginArray);
04744
for (i=0; i<3; i++)
04745 {
04746 pBuffer +=
WriteObject(pBuffer,
BeginFunction);
04747
if (dwPCS != SPACE_XYZ)
04748 {
04749 pBuffer +=
WriteFixed(pBuffer, pafxIlluminantWP[i]);
04750 pBuffer +=
WriteObject(pBuffer,
DivOp);
04751 pBuffer +=
WriteObject(pBuffer,
EncodeLMNLab);
04752 }
04753 pBuffer +=
WriteObject(pBuffer,
EndFunction);
04754 }
04755 pBuffer +=
WriteObject(pBuffer,
EndArray);
04756
04757
return (
DWORD)(pBuffer - pStart);
04758 }
04759
04760
04761
DWORD
04762 SendCRDABC(
04763 PBYTE pBuffer,
04764 PBYTE pPublicArrayName,
04765 DWORD dwPCS,
04766 DWORD nInputCh,
04767 PBYTE pLut,
04768 PFIX_16_16 e,
04769 DWORD dwLutSig,
04770 BOOL bBinary
04771 )
04772 {
04773
PBYTE pLineStart, pStart = pBuffer;
04774
PBYTE pTable;
04775
DWORD i, j;
04776
FIX_16_16 fxTempMatrixABC[9];
04777
04778
04779
04780
04781
04782 pBuffer +=
WriteNewLineObject(pBuffer,
RangeABCTag);
04783 pBuffer +=
WriteObject(pBuffer,
RangeABC);
04784
04785
04786
04787
04788
04789 pBuffer +=
WriteNewLineObject(pBuffer,
MatrixABCTag);
04790
if (dwPCS == SPACE_XYZ)
04791 {
04792 pBuffer +=
WriteObject(pBuffer,
BeginArray);
04793
if (e)
04794 {
04795
for (i=0; i<3; i++)
04796 {
04797
for (j=0; j<3; j++)
04798 {
04799 pBuffer +=
WriteFixed(pBuffer, e[i + j * 3]);
04800 }
04801 }
04802 }
04803
else
04804 {
04805
if (dwLutSig ==
LUT8_TYPE)
04806 {
04807 pTable = (
PBYTE) &((
PLUT8TYPE)pLut)->e00;
04808 }
04809
else
04810 {
04811 pTable = (
PBYTE) &((
PLUT16TYPE)pLut)->e00;
04812 }
04813
04814
for (i=0; i<9; i++)
04815 {
04816 fxTempMatrixABC[i] =
FIX_DIV(FIX_ENDIAN(*((PDWORD)pTable)),
CIEXYZRange);
04817 pTable +=
sizeof(
DWORD);
04818 }
04819
for (i=0; i<3; i++)
04820 {
04821
for (j=0; j<3; j++)
04822 {
04823 pBuffer +=
WriteFixed(pBuffer, fxTempMatrixABC[i + j * 3]);
04824 }
04825 }
04826 }
04827 pBuffer +=
WriteObject(pBuffer,
EndArray);
04828 }
04829
else
04830 {
04831 pBuffer +=
WriteObject(pBuffer,
MatrixABCLabCRD);
04832 }
04833
04834
04835
04836
04837
04838
if (nInputCh == 0)
04839 {
04840
return (
DWORD)(pBuffer - pStart);
04841 }
04842
04843 pLineStart = pBuffer;
04844 pBuffer +=
WriteNewLineObject(pBuffer,
EncodeABCTag);
04845 pBuffer +=
WriteObject(pBuffer,
BeginArray);
04846
for (i=0; i<nInputCh; i++)
04847 {
04848 pLineStart = pBuffer;
04849
04850 pBuffer +=
WriteNewLineObject(pBuffer,
BeginFunction);
04851
if (dwPCS == SPACE_Lab)
04852 {
04853 pBuffer +=
WriteObject(pBuffer, (i == 0) ?
EncodeABCLab1 :
EncodeABCLab2);
04854 }
04855
04856 pBuffer +=
WriteObject(pBuffer,
StartClip);
04857
if (e)
04858 pBuffer +=
WriteObject(pBuffer,
PreViewInArray);
04859
else
04860 pBuffer +=
WriteObject(pBuffer,
InputArray);
04861
04862 pBuffer +=
WriteObject(pBuffer, pPublicArrayName);
04863 pBuffer +=
WriteInt(pBuffer, i);
04864
04865
if (!bBinary)
04866 {
04867 pBuffer +=
WriteNewLineObject(pBuffer,
IndexArray);
04868 }
04869
else
04870 {
04871
if (dwLutSig ==
LUT8_TYPE)
04872 {
04873 pBuffer +=
WriteObject(pBuffer,
IndexArray);
04874 }
04875
else
04876 {
04877 pBuffer +=
WriteObject(pBuffer,
IndexArray16b);
04878 }
04879 }
04880
04881 pBuffer +=
WriteObject(pBuffer, (dwLutSig ==
LUT8_TYPE) ?
04882
Scale8 :
Scale16);
04883 pBuffer +=
WriteObject(pBuffer,
EndClip);
04884 pBuffer +=
WriteObject(pBuffer,
EndFunction);
04885 }
04886 pBuffer +=
WriteObject(pBuffer,
EndArray);
04887
04888
return (
DWORD)(pBuffer - pStart);
04889 }
04890
04891
04892
DWORD
04893 SendCRDOutputTable(
04894 PBYTE pBuffer,
04895 PBYTE pPublicArrayName,
04896 DWORD nOutputCh,
04897 DWORD dwLutSig,
04898 BOOL bHost,
04899 BOOL bBinary
04900 )
04901 {
04902
PBYTE pStart = pBuffer;
04903
DWORD i;
04904
04905
for (i=0; i<nOutputCh; i++)
04906 {
04907 pBuffer +=
WriteNewLineObject(pBuffer,
BeginFunction);
04908 pBuffer +=
WriteObject(pBuffer,
Clip01);
04909
if (bHost)
04910 pBuffer +=
WriteObject(pBuffer,
PreViewOutArray);
04911
else
04912 pBuffer +=
WriteObject(pBuffer,
OutputArray);
04913
04914 pBuffer +=
WriteObject(pBuffer, pPublicArrayName);
04915 pBuffer +=
WriteInt(pBuffer, i);
04916
04917
if (! bBinary)
04918 {
04919 pBuffer +=
WriteObject(pBuffer,
NewLine);
04920
if (dwLutSig ==
LUT8_TYPE)
04921 {
04922 pBuffer +=
WriteObject(pBuffer,
TFunction8);
04923 }
04924
else
04925 {
04926 pBuffer +=
WriteObject(pBuffer,
IndexArray);
04927 pBuffer +=
WriteObject(pBuffer,
Scale16);
04928 }
04929 }
04930
else
04931 {
04932
if (dwLutSig ==
LUT8_TYPE)
04933 {
04934 pBuffer +=
WriteObject(pBuffer,
TFunction8);
04935 }
04936
else
04937 {
04938 pBuffer +=
WriteObject(pBuffer,
IndexArray16b);
04939 pBuffer +=
WriteObject(pBuffer,
Scale16);
04940 }
04941 }
04942
04943 pBuffer +=
WriteObject(pBuffer,
EndFunction);
04944 }
04945
04946
return (
DWORD)(pBuffer - pStart);
04947 }
04948
04949
04950
VOID
04951 GetCLUTInfo(
04952 DWORD dwLutSig,
04953 PBYTE pLut,
04954 PDWORD pnInputCh,
04955 PDWORD pnOutputCh,
04956 PDWORD pnGrids,
04957 PDWORD pnInputTable,
04958 PDWORD pnOutputTable,
04959 PDWORD pdwSize
04960 )
04961 {
04962
if (dwLutSig ==
LUT8_TYPE)
04963 {
04964 *pnInputCh = ((
PLUT8TYPE)pLut)->nInputChannels;
04965 *pnOutputCh = ((
PLUT8TYPE)pLut)->nOutputChannels;
04966 *pnGrids = ((
PLUT8TYPE)pLut)->nClutPoints;
04967 *pnInputTable = 256
L;
04968 *pnOutputTable = 256
L;
04969
if (pdwSize)
04970 *pdwSize = 1;
04971 }
04972
else
04973 {
04974 *pnInputCh = ((
PLUT16TYPE)pLut)->nInputChannels;
04975 *pnOutputCh = ((
PLUT16TYPE)pLut)->nOutputChannels;
04976 *pnGrids = ((
PLUT16TYPE)pLut)->nClutPoints;
04977 *pnInputTable = FIX_ENDIAN16(((
PLUT16TYPE)pLut)->wInputEntries);
04978 *pnOutputTable = FIX_ENDIAN16(((
PLUT16TYPE)pLut)->wOutputEntries);
04979
if (pdwSize)
04980 *pdwSize = 2;
04981 }
04982
04983
return;
04984 }
04985
04986
DWORD
04987 EnableGlobalDict(
04988 PBYTE pBuffer
04989 )
04990 {
04991
PBYTE pStart = pBuffer;
04992
04993 pBuffer +=
WriteNewLineObject(pBuffer,
CurrentGlobalOp);
04994 pBuffer +=
WriteObject(pBuffer,
TrueOp);
04995 pBuffer +=
WriteObject(pBuffer,
SetGlobalOp);
04996
04997
return (
DWORD)(pBuffer - pStart);
04998 }
04999
05000
DWORD
05001 BeginGlobalDict(
05002 PBYTE pBuffer
05003 )
05004 {
05005
PBYTE pStart = pBuffer;
05006
05007 pBuffer +=
WriteNewLineObject(pBuffer,
GlobalDictOp);
05008 pBuffer +=
WriteObject(pBuffer,
BeginOp);
05009
05010
return (
DWORD)(pBuffer - pStart);
05011 }
05012
05013
DWORD
05014 EndGlobalDict(
05015 PBYTE pBuffer
05016 )
05017 {
05018
PBYTE pStart = pBuffer;
05019
05020 pBuffer +=
WriteNewLineObject(pBuffer,
EndOp);
05021 pBuffer +=
WriteObject(pBuffer,
SetGlobalOp);
05022
05023
return (
DWORD)(pBuffer - pStart);
05024 }
05025
05026
DWORD
05027 SendCSABWPoint(
05028 PBYTE pBuffer,
05029 DWORD dwIntent,
05030 PFIX_16_16 pafxIlluminantWP,
05031 PFIX_16_16 pafxMediaWP
05032 )
05033 {
05034
PBYTE pStart = pBuffer;
05035
int i;
05036
05037
05038
05039
05040
05041 pBuffer +=
WriteNewLineObject(pBuffer,
BlackPointTag);
05042 pBuffer +=
WriteObject(pBuffer,
BlackPoint);
05043
05044
05045
05046
05047
05048 pBuffer +=
WriteNewLineObject(pBuffer,
WhitePointTag);
05049 pBuffer +=
WriteObject(pBuffer,
BeginArray);
05050
for (i=0; i<3; i++)
05051 {
05052
if (dwIntent == INTENT_ABSOLUTE_COLORIMETRIC)
05053 {
05054 pBuffer +=
WriteFixed(pBuffer, pafxMediaWP[i]);
05055 }
05056
else
05057 {
05058 pBuffer +=
WriteFixed(pBuffer, pafxIlluminantWP[i]);
05059 }
05060 }
05061 pBuffer +=
WriteObject(pBuffer,
EndArray);
05062
05063
return (
DWORD)(pBuffer - pStart);
05064 }
05065
05066
05067
VOID
05068 GetMediaWP(
05069 PBYTE pProfile,
05070 DWORD dwIntent,
05071 PFIX_16_16 pafxIlluminantWP,
05072 PFIX_16_16 pafxMediaWP
05073 )
05074 {
05075
if (dwIntent == INTENT_ABSOLUTE_COLORIMETRIC)
05076 {
05077
if (!
GetCPMediaWhitePoint(pProfile, pafxMediaWP))
05078 {
05079 pafxMediaWP[0] = pafxIlluminantWP[0];
05080 pafxMediaWP[1] = pafxIlluminantWP[1];
05081 pafxMediaWP[2] = pafxIlluminantWP[2];
05082 }
05083 }
05084
05085
return;
05086 }
05087
05088
05089
BOOL
05090 GetCRDInputOutputArraySize(
05091 PBYTE pProfile,
05092 DWORD dwIntent,
05093 PDWORD pdwInTblSize,
05094 PDWORD pdwOutTblSize,
05095 PDWORD pdwTag,
05096 PDWORD pnGrids
05097 )
05098 {
05099 PTAGDATA pTagData;
05100
PLUT16TYPE pLut;
05101
DWORD dwIndex, dwLutSig;
05102
DWORD nInputEntries, nOutputEntries;
05103
DWORD nInputCh, nOutputCh, nGrids;
05104
BOOL bRet;
05105
05106
05107
05108
05109
05110
switch (dwIntent)
05111 {
05112
case INTENT_PERCEPTUAL:
05113 *pdwTag =
TAG_BToA0;
05114
break;
05115
05116
case INTENT_RELATIVE_COLORIMETRIC:
05117
case INTENT_ABSOLUTE_COLORIMETRIC:
05118 *pdwTag =
TAG_BToA1;
05119
break;
05120
05121
case INTENT_SATURATION:
05122 *pdwTag =
TAG_BToA2;
05123
break;
05124
05125
default:
05126
WARNING((__TEXT(
"Invalid intent passed to GetCRDInputOutputArraySize: %d\n"), dwIntent));
05127 SetLastError(ERROR_INVALID_PARAMETER);
05128
return FALSE;
05129 }
05130
05131
if (
DoesCPTagExist(pProfile, *pdwTag, &dwIndex))
05132 {
05133 pTagData = (PTAGDATA)(pProfile +
sizeof(PROFILEHEADER) +
sizeof(
DWORD) +
05134 dwIndex *
sizeof(TAGDATA));
05135
05136 pLut = (
PLUT16TYPE)(pProfile + FIX_ENDIAN(pTagData->dwOffset));
05137
05138 dwLutSig = FIX_ENDIAN(pLut->
dwSignature);
05139
05140
if ((dwLutSig !=
LUT8_TYPE) && (dwLutSig !=
LUT16_TYPE))
05141 {
05142
WARNING((__TEXT(
"Invalid Lut type - unable to create proofing CRD\n")));
05143 SetLastError(ERROR_INVALID_PROFILE);
05144
return FALSE;
05145 }
05146
05147 (
void)
GetCLUTInfo(dwLutSig, (
PBYTE)pLut, &nInputCh, &nOutputCh,
05148 &nGrids, &nInputEntries, &nOutputEntries,
NULL);
05149
05150
if (pdwInTblSize)
05151 {
05152
if (nInputCh != 3)
05153 {
05154
return FALSE;
05155 }
05156
05157 *pdwInTblSize = nInputCh * nInputEntries * 6;
05158 *pnGrids = nGrids;
05159 }
05160
05161
if (pdwOutTblSize)
05162 {
05163
if ((nOutputCh != 3) && (nOutputCh != 4))
05164 {
05165
return FALSE;
05166 }
05167
05168 *pdwOutTblSize = nOutputCh * nOutputEntries * 6;
05169 *pnGrids = nGrids;
05170 }
05171
05172
return TRUE;
05173 }
05174
else
05175 {
05176
05177
05178
05179
05180 *pnGrids = 2;
05181
05182
if (pdwInTblSize)
05183 {
05184 bRet =
GetHostCSA(pProfile,
NULL, pdwInTblSize,
05185 dwIntent,
TYPE_CIEBASEDDEF);
05186 *pdwInTblSize = *pdwInTblSize * 3;
05187 }
05188
05189
if (bRet && pdwOutTblSize)
05190 {
05191 bRet =
GetHostCSA(pProfile,
NULL, pdwInTblSize,
05192 dwIntent,
TYPE_CIEBASEDDEF);
05193 *pdwOutTblSize = *pdwOutTblSize * 3;
05194 }
05195
05196
return bRet;
05197 }
05198 }
05199
05200
#if !defined(KERNEL_MODE) || defined(USERMODE_DRIVER)
05201
05202
DWORD
05203 CreateHostLutCRD(
05204 PBYTE pProfile,
05205 DWORD dwIndex,
05206 PBYTE pBuffer,
05207 DWORD dwIntent
05208 )
05209 {
05210
PLUT16TYPE pLut;
05211
PHOSTCLUT pHostClut;
05212 PTAGDATA pTagData;
05213
PBYTE pTable;
05214
DWORD nInputCh, nOutputCh, nGrids;
05215
DWORD nInputEntries, nOutputEntries, nNumbers;
05216
DWORD dwPCS, dwLutSig;
05217
DWORD dwSize, i, j;
05218
PBYTE pStart = pBuffer;
05219
05220
05221
05222
05223
05224
05225 dwPCS =
GetCPConnSpace(pProfile);
05226
05227 pTagData = (PTAGDATA)(pProfile +
sizeof(PROFILEHEADER) +
sizeof(
DWORD) +
05228 dwIndex *
sizeof(TAGDATA));
05229
05230 pLut = (
PLUT16TYPE)(pProfile + FIX_ENDIAN(pTagData->dwOffset));
05231
05232 dwLutSig = FIX_ENDIAN(pLut->
dwSignature);
05233
05234
if ((dwLutSig !=
LUT8_TYPE) && (dwLutSig !=
LUT16_TYPE))
05235 {
05236
WARNING((__TEXT(
"Invalid profile - unable to create Lut CRD\n")));
05237 SetLastError(ERROR_INVALID_PROFILE);
05238
return 0;
05239 }
05240
05241 (
void)
GetCLUTInfo(dwLutSig, (
PBYTE)pLut, &nInputCh, &nOutputCh,
05242 &nGrids, &nInputEntries, &nOutputEntries, &i);
05243
05244
if (((nOutputCh != 3) && (nOutputCh != 4)) || (nInputCh != 3))
05245 {
05246
return 0;
05247 }
05248
05249
if (pBuffer ==
NULL)
05250 {
05251
05252
05253
05254
05255 dwSize = nInputCh * nInputEntries * i +
05256 nOutputCh * nOutputEntries * i +
05257 nOutputCh * nGrids * nGrids * nGrids +
05258
sizeof(
HOSTCLUT) +
05259 2048;
05260
05261
05262
05263
05264
05265 dwSize += (((dwSize) /
MAX_LINELEN) + 1) *
STRLEN(
NewLine);
05266
05267
return dwSize;
05268 }
05269
05270 pHostClut = (
PHOSTCLUT)pBuffer;
05271 pBuffer +=
sizeof(
HOSTCLUT);
05272 pHostClut->
wSize =
sizeof(
HOSTCLUT);
05273 pHostClut->
wDataType =
DATATYPE_LUT;
05274 pHostClut->
dwPCS = dwPCS;
05275 pHostClut->
dwIntent = dwIntent;
05276 pHostClut->
nLutBits = (dwLutSig ==
LUT8_TYPE) ? 8 : 16;
05277
05278 (
void)
GetCPWhitePoint(pProfile, pHostClut->
afxIlluminantWP);
05279
05280
05281
05282
05283
05284
if (!
GetCPMediaWhitePoint(pProfile, pHostClut->
afxMediaWP))
05285 {
05286 pHostClut->
afxMediaWP[0] = pHostClut->
afxIlluminantWP[0];
05287 pHostClut->
afxMediaWP[1] = pHostClut->
afxIlluminantWP[1];
05288 pHostClut->
afxMediaWP[2] = pHostClut->
afxIlluminantWP[2];
05289 }
05290
05291 pHostClut->
nInputCh = (
BYTE)nInputCh;
05292 pHostClut->
nOutputCh = (
BYTE)nOutputCh;
05293 pHostClut->
nClutPoints = (
BYTE)nGrids;
05294 pHostClut->
nInputEntries = (WORD)nInputEntries;
05295 pHostClut->
nOutputEntries = (WORD)nOutputEntries;
05296
05297
05298
05299
05300
05301 pBuffer +=
CreateHostInputOutputArray(
05302 pBuffer,
05303 pHostClut->
inputArray,
05304 nInputCh,
05305 nInputEntries,
05306 0,
05307 dwLutSig,
05308 (
PBYTE)pLut);
05309
05310
05311
05312
05313
05314 i = nInputEntries * nInputCh +
05315 nGrids * nGrids * nGrids * nOutputCh;
05316
05317
05318
05319
05320
05321 pBuffer +=
CreateHostInputOutputArray(
05322 pBuffer,
05323 pHostClut->
outputArray,
05324 nOutputCh,
05325 nOutputEntries,
05326 i,
05327 dwLutSig,
05328 (
PBYTE)pLut);
05329
05330
05331
05332
05333
05334
if (dwPCS == SPACE_XYZ)
05335 {
05336
if (dwLutSig ==
LUT8_TYPE)
05337 {
05338 pTable = (
PBYTE) &((
PLUT8TYPE)pLut)->e00;
05339 }
else
05340 {
05341 pTable = (
PBYTE) &((
PLUT16TYPE)pLut)->e00;
05342 }
05343
05344
for (i=0; i<9; i++)
05345 {
05346 pHostClut->
e[i] =
FIX_DIV(FIX_ENDIAN(*((PDWORD)pTable)),
CIEXYZRange);
05347 pTable +=
sizeof(
DWORD);
05348 }
05349 }
05350
05351
05352
05353
05354
05355 nNumbers = nGrids * nGrids * nOutputCh;
05356 pHostClut->
clut = pBuffer;
05357
05358
for (i=0; i<nGrids; i++)
05359 {
05360
if (dwLutSig ==
LUT8_TYPE)
05361 {
05362 pTable = (
PBYTE)(((
PLUT8TYPE)pLut)->data) +
05363 nInputEntries * nInputCh +
05364 nNumbers * i;
05365 }
05366
else
05367 {
05368 pTable = (
PBYTE)(((
PLUT16TYPE)pLut)->data) +
05369 2 * nInputEntries * nInputCh +
05370 2 * nNumbers * i;
05371 }
05372
05373
if (dwLutSig ==
LUT8_TYPE)
05374 {
05375 CopyMemory(pBuffer, pTable, nNumbers);
05376 pBuffer += nNumbers;
05377 }
05378
else
05379 {
05380
for (j=0; j<nNumbers; j++)
05381 {
05382 *pBuffer++ = (
BYTE)(FIX_ENDIAN16(*((PWORD)pTable)) / 256);
05383 pTable +=
sizeof(WORD);
05384 }
05385 }
05386 }
05387
05388
return (
DWORD)(pBuffer - pStart);
05389 }
05390
05391
05392
DWORD
05393 CreateHostMatrixCSAorCRD(
05394 PBYTE pProfile,
05395 PBYTE pBuffer,
05396 PDWORD pcbSize,
05397 DWORD dwIntent,
05398 BOOL bCSA
05399 )
05400 {
05401 PTAGDATA pTagData;
05402
DWORD dwRedTRCIndex, dwGreenTRCIndex, dwBlueTRCIndex;
05403
DWORD dwRedCount, dwGreenCount, dwBlueCount;
05404
PCURVETYPE pRed, pGreen, pBlue;
05405
PHOSTCLUT pHostClut;
05406
PBYTE pStart = pBuffer;
05407
DWORD i, dwSize;
05408
double adArray[9], adRevArray[9], adTemp[9];
05409
05410
05411
05412
05413
05414
if (!
DoesCPTagExist(pProfile,
TAG_REDTRC, &dwRedTRCIndex) ||
05415 !
DoesCPTagExist(pProfile,
TAG_GREENTRC, &dwGreenTRCIndex) ||
05416 !
DoesCPTagExist(pProfile,
TAG_BLUETRC, &dwBlueTRCIndex))
05417 {
05418
return FALSE;
05419 }
05420
05421
05422
05423
05424
05425 pTagData = (PTAGDATA)(pProfile +
sizeof(PROFILEHEADER) +
sizeof(
DWORD) +
05426 dwRedTRCIndex *
sizeof(TAGDATA));
05427
05428 pRed = (
PCURVETYPE)(pProfile + FIX_ENDIAN(pTagData->dwOffset));
05429
05430 pTagData = (PTAGDATA)(pProfile +
sizeof(PROFILEHEADER) +
sizeof(
DWORD) +
05431 dwGreenTRCIndex *
sizeof(TAGDATA));
05432
05433 pGreen = (
PCURVETYPE)(pProfile + FIX_ENDIAN(pTagData->dwOffset));
05434
05435 pTagData = (PTAGDATA)(pProfile +
sizeof(PROFILEHEADER) +
sizeof(
DWORD) +
05436 dwBlueTRCIndex *
sizeof(TAGDATA));
05437
05438 pBlue = (
PCURVETYPE)(pProfile + FIX_ENDIAN(pTagData->dwOffset));
05439
05440
05441
05442
05443
05444 dwRedCount = FIX_ENDIAN(pRed->
nCount);
05445 dwGreenCount = FIX_ENDIAN(pGreen->
nCount);
05446 dwBlueCount = FIX_ENDIAN(pBlue->
nCount);
05447
05448
05449
05450
05451
05452 dwSize = (dwRedCount + dwGreenCount + dwBlueCount) * 2 +
05453
sizeof(
HOSTCLUT) + 2048;
05454
05455
05456
05457
05458
05459 dwSize += (((dwSize) /
MAX_LINELEN) + 1) *
STRLEN(
NewLine);
05460
05461
if (pBuffer ==
NULL)
05462 {
05463 *pcbSize = dwSize;
05464
return TRUE;
05465 }
05466
05467
05468
05469
05470
05471
if (*pcbSize < dwSize)
05472 {
05473
WARNING((__TEXT(
"Buffer too small to get Host Matrix CSA/CRD\n")));
05474 SetLastError(ERROR_INSUFFICIENT_BUFFER);
05475
return FALSE;
05476 }
05477
05478 pHostClut = (
PHOSTCLUT)pBuffer;
05479 pBuffer +=
sizeof(
HOSTCLUT);
05480 pHostClut->
wSize =
sizeof(
HOSTCLUT);
05481 pHostClut->
wDataType =
DATATYPE_MATRIX;
05482 pHostClut->
dwPCS = SPACE_XYZ;
05483 pHostClut->
dwIntent = dwIntent;
05484 pHostClut->
nClutPoints = 2;
05485
05486 (
void)
GetCPWhitePoint(pProfile, pHostClut->
afxIlluminantWP);
05487
05488
if (bCSA)
05489 {
05490 pHostClut->
nInputEntries = (
USHORT) dwRedCount;
05491 pHostClut->
nInputCh = 3;
05492
05493 pBuffer +=
CreateHostTRCInputTable(pBuffer, pHostClut,
05494 pRed, pGreen, pBlue);
05495 }
05496
else
05497 {
05498 pHostClut->
nOutputEntries = (
USHORT) dwRedCount;
05499 pHostClut->
nOutputCh = 3;
05500
05501 pBuffer +=
CreateHostRevTRCInputTable(pBuffer, pHostClut,
05502 pRed, pGreen, pBlue);
05503 }
05504
05505
if (!
CreateColorantArray(pProfile, &adTemp[0],
TAG_REDCOLORANT) ||
05506 !
CreateColorantArray(pProfile, &adTemp[3],
TAG_GREENCOLORANT) ||
05507 !
CreateColorantArray(pProfile, &adTemp[6],
TAG_BLUECOLORANT))
05508 {
05509
WARNING((__TEXT(
"Fail to create colorant array for Host Matrix CSA/CRD\n")));
05510
return FALSE;
05511 }
05512
05513
for (i = 0; i < 9; i++)
05514 {
05515 adArray[i] = adTemp[i/8*8 + i*3%8];
05516 }
05517
05518
if (bCSA)
05519 {
05520
for (i = 0; i < 9; i++)
05521 {
05522
05523
05524
05525
05526 pHostClut->
e[i] = (
FIX_16_16)(adArray[i] * (
double)
FIX_16_16_SCALE);
05527 }
05528 }
05529
else
05530 {
05531
InvertColorantArray(adArray, adRevArray);
05532
for (i = 0; i < 9; i++)
05533 {
05534
05535
05536
05537
05538 pHostClut->
e[i] = (
FIX_16_16)(adRevArray[i] * (
double)
FIX_16_16_SCALE);
05539 }
05540 }
05541
05542 *pcbSize = (
DWORD)(pBuffer - pStart);
05543
05544
return TRUE;
05545 }
05546
05547
05548
DWORD
05549 CreateHostTRCInputTable(
05550 PBYTE pBuffer,
05551 PHOSTCLUT pHostClut,
05552 PCURVETYPE pRed,
05553 PCURVETYPE pGreen,
05554 PCURVETYPE pBlue
05555 )
05556 {
05557
DWORD i;
05558 PWORD pBuffer16 = (PWORD) pBuffer;
05559 PWORD pTable;
05560
05561
05562
05563
05564
05565 pHostClut->
inputArray[0] = (
PBYTE) pBuffer16;
05566 pTable = pRed->
data;
05567
for (i = 0; i < pHostClut->
nInputEntries; i++)
05568 {
05569 *pBuffer16++ = FIX_ENDIAN16(*pTable);
05570 pTable++;
05571 }
05572
05573
05574
05575
05576
05577 pHostClut->
inputArray[1] = (
PBYTE) pBuffer16;
05578 pTable = pGreen->
data;
05579
for (i = 0; i < pHostClut->
nInputEntries; i++)
05580 {
05581 *pBuffer16++ = FIX_ENDIAN16(*pTable);
05582 pTable++;
05583 }
05584
05585
05586
05587
05588
05589 pHostClut->
inputArray[2] = (
PBYTE) pBuffer16;
05590 pTable = pBlue->
data;
05591
for (i = 0; i < pHostClut->
nInputEntries; i++)
05592 {
05593 *pBuffer16++ = FIX_ENDIAN16(*pTable);
05594 pTable++;
05595 }
05596
05597
return (
DWORD)((
PBYTE)pBuffer16 - pBuffer);
05598 }
05599
05600
DWORD
05601 CreateHostRevTRCInputTable(
05602 PBYTE pBuffer,
05603 PHOSTCLUT pHostClut,
05604 PCURVETYPE pRed,
05605 PCURVETYPE pGreen,
05606 PCURVETYPE pBlue
05607 )
05608 {
05609 PWORD pTemp =
MemAlloc(pHostClut->
nOutputEntries * (
REVCURVE_RATIO + 1) * 2);
05610
05611
if (! pTemp)
05612 {
05613
return 0;
05614 }
05615
05616
05617
05618
05619
05620 pHostClut->
outputArray[0] = pBuffer;
05621
GetRevCurve(pRed, pTemp, (PWORD) pHostClut->
outputArray[0]);
05622
05623
05624
05625
05626
05627 pHostClut->
outputArray[1] = pHostClut->
outputArray[0] +
05628 2 *
REVCURVE_RATIO * pHostClut->
nOutputEntries;
05629
GetRevCurve(pGreen, pTemp, (PWORD) pHostClut->
outputArray[1]);
05630
05631
05632
05633
05634
05635 pHostClut->
outputArray[2] = pHostClut->
outputArray[1] +
05636 2 *
REVCURVE_RATIO * pHostClut->
nOutputEntries;
05637
GetRevCurve(pBlue, pTemp, (PWORD) pHostClut->
outputArray[2]);
05638
05639
MemFree(pTemp);
05640
05641
return (
DWORD)(2 *
REVCURVE_RATIO * pHostClut->
nOutputEntries * 3);
05642 }
05643
05644
05645
05646
05647
05648
05649
05650
05651
05652
05653
05654
05655
05656
05657
05658
05659
05660
05661
BOOL
05662 GetHostColorRenderingDictionary(
05663 PBYTE pProfile,
05664 DWORD dwIntent,
05665 PBYTE pBuffer,
05666 PDWORD pdwSize
05667 )
05668 {
05669
DWORD dwBToATag, dwIndex;
05670
05671
switch (dwIntent)
05672 {
05673
case INTENT_PERCEPTUAL:
05674 dwBToATag =
TAG_BToA0;
05675
break;
05676
05677
case INTENT_RELATIVE_COLORIMETRIC:
05678
case INTENT_ABSOLUTE_COLORIMETRIC:
05679 dwBToATag =
TAG_BToA1;
05680
break;
05681
05682
case INTENT_SATURATION:
05683 dwBToATag =
TAG_BToA2;
05684
break;
05685
05686
default:
05687 *pdwSize = 0;
05688
return FALSE;
05689 }
05690
05691
if (
DoesCPTagExist(pProfile, dwBToATag, &dwIndex))
05692 {
05693 *pdwSize =
CreateHostLutCRD(pProfile, dwIndex, pBuffer, dwIntent);
05694
05695
return *pdwSize > 0;
05696 }
05697
else if (
DoesTRCAndColorantTagExist(pProfile))
05698 {
05699
return CreateHostMatrixCSAorCRD(pProfile, pBuffer, pdwSize, dwIntent,
FALSE);
05700 }
05701
else
05702 {
05703
return FALSE;
05704 }
05705 }
05706
05707
05708
05709
05710
05711
05712
05713
05714
05715
05716
05717
05718
05719
05720
05721
05722
05723
05724
05725
05726
05727
DWORD
05728 CreateHostInputOutputArray(
05729 PBYTE pBuffer,
05730 PBYTE *ppArray,
05731 DWORD nNumChan,
05732 DWORD nTableSize,
05733 DWORD dwOffset,
05734 DWORD dwLutSig,
05735 PBYTE pLut
05736 )
05737 {
05738
PBYTE pStart = pBuffer;
05739
PBYTE pTable;
05740
DWORD i, j;
05741
05742
for (i=0; i<nNumChan; i++)
05743 {
05744 ppArray[i] = pBuffer;
05745
05746
if (dwLutSig ==
LUT8_TYPE)
05747 {
05748 pTable = (
PBYTE) (((
PLUT8TYPE)pLut)->data) +
05749 dwOffset + nTableSize * i;
05750
05751 CopyMemory(pBuffer, pTable, nTableSize);
05752
05753 pBuffer += nTableSize;
05754 }
05755
else
05756 {
05757 pTable = (
PBYTE) (((
PLUT16TYPE)pLut)->data) +
05758 2 * dwOffset +
05759 2 * nTableSize * i;
05760
05761
for (j=0; j<nTableSize; j++)
05762 {
05763 *((PWORD)pBuffer) = FIX_ENDIAN16(*((PWORD)pTable));
05764 pBuffer +=
sizeof(WORD);
05765 pTable +=
sizeof(WORD);
05766 }
05767 }
05768 }
05769
05770
return (
DWORD) (pBuffer - pStart);
05771 }
05772
05773
05774
05775
05776
05777
05778
05779
05780
05781
05782
05783
05784
05785
05786
05787
05788
05789
05790
05791
BOOL
05792 GetHostCSA(
05793 PBYTE pProfile,
05794 PBYTE pBuffer,
05795 PDWORD pdwSize,
05796 DWORD dwIntent,
05797 DWORD dwType
05798 )
05799 {
05800
PHOSTCLUT pHostClut;
05801 PTAGDATA pTagData;
05802
PLUT16TYPE pLut;
05803
DWORD dwAToBTag;
05804
DWORD dwPCS, dwLutSig;
05805
DWORD nInputCh, nOutputCh, nGrids, SecondGrids;
05806
DWORD nInputTable, nOutputTable, nNumbers;
05807
DWORD dwIndex, i, j, k;
05808
PBYTE pTable;
05809
PBYTE pStart = pBuffer;
05810
05811
switch (dwIntent)
05812 {
05813
case INTENT_PERCEPTUAL:
05814 dwAToBTag =
TAG_AToB0;
05815
break;
05816
05817
case INTENT_RELATIVE_COLORIMETRIC:
05818
case INTENT_ABSOLUTE_COLORIMETRIC:
05819 dwAToBTag =
TAG_AToB1;
05820
break;
05821
05822
case INTENT_SATURATION:
05823 dwAToBTag =
TAG_AToB2;
05824
break;
05825
05826
default:
05827
WARNING((__TEXT(
"Invalid intent passed to GetHostCSA: %d\n"), dwIntent));
05828 SetLastError(ERROR_INVALID_PARAMETER);
05829
return FALSE;
05830
break;
05831 }
05832
05833
if (!
DoesCPTagExist(pProfile, dwAToBTag, &dwIndex))
05834 {
05835
if (
DoesTRCAndColorantTagExist(pProfile) && (dwType ==
TYPE_CIEBASEDDEF))
05836 {
05837
05838
05839
05840
05841
return CreateHostMatrixCSAorCRD(pProfile,pBuffer,pdwSize,dwIntent,
TRUE);
05842 }
05843
else
05844 {
05845
WARNING((__TEXT(
"AToB tag not present for intent %d\n"), dwIntent));
05846 SetLastError(ERROR_TAG_NOT_PRESENT);
05847
return FALSE;
05848 }
05849 }
05850
05851
05852
05853
05854
05855 dwPCS =
GetCPConnSpace(pProfile);
05856
05857 pTagData = (PTAGDATA)(pProfile +
sizeof(PROFILEHEADER) +
sizeof(
DWORD) +
05858 dwIndex *
sizeof(TAGDATA));
05859
05860 pLut = (
PLUT16TYPE)(pProfile + FIX_ENDIAN(pTagData->dwOffset));
05861
05862 dwLutSig = FIX_ENDIAN(pLut->
dwSignature);
05863
05864
if (((dwPCS != SPACE_Lab) && (dwPCS != SPACE_XYZ)) ||
05865 ((dwLutSig !=
LUT8_TYPE) && (dwLutSig !=
LUT16_TYPE)))
05866 {
05867
WARNING((__TEXT(
"Invalid color space - unable to create DEF(G) host CSA\n")));
05868 SetLastError(ERROR_INVALID_PROFILE);
05869
return FALSE;
05870 }
05871
05872
05873
05874
05875
05876 (
void)
GetCLUTInfo(dwLutSig, (
PBYTE)pLut, &nInputCh, &nOutputCh, &nGrids,
05877 &nInputTable, &nOutputTable, &i);
05878
05879
if (!(nOutputCh == 3) ||
05880 !((nInputCh == 3) && (dwType ==
TYPE_CIEBASEDDEF)) &&
05881 !((nInputCh == 4) && (dwType ==
TYPE_CIEBASEDDEFG)))
05882 {
05883
return FALSE;
05884 }
05885
05886
if (pBuffer ==
NULL)
05887 {
05888
05889
05890
05891
05892
if (dwType ==
TYPE_CIEBASEDDEFG)
05893 *pdwSize = nOutputCh * nGrids * nGrids * nGrids * nGrids;
05894
else
05895 *pdwSize = nOutputCh * nGrids * nGrids * nGrids;
05896
05897 *pdwSize +=
05898 nInputCh * nInputTable * i +
05899 nOutputCh * nOutputTable * i +
05900
sizeof(
HOSTCLUT) + 2048;
05901
05902
05903
05904
05905
05906 *pdwSize += (((*pdwSize) /
MAX_LINELEN) + 1) *
STRLEN(
NewLine);
05907
05908
return TRUE;
05909 }
05910
05911 pHostClut = (
PHOSTCLUT)pBuffer;
05912 pBuffer +=
sizeof(
HOSTCLUT);
05913 pHostClut->
wSize =
sizeof(
HOSTCLUT);
05914 pHostClut->
wDataType =
DATATYPE_LUT;
05915 pHostClut->
dwPCS = dwPCS;
05916 pHostClut->
dwIntent = dwIntent;
05917 pHostClut->
nLutBits = (dwLutSig ==
LUT8_TYPE) ? 8 : 16;
05918
05919
05920
05921
05922
05923 (
void)
GetCPWhitePoint(pProfile, pHostClut->
afxIlluminantWP);
05924
05925 pHostClut->
nInputCh = (
BYTE)nInputCh;
05926 pHostClut->
nOutputCh = (
BYTE)nOutputCh;
05927 pHostClut->
nClutPoints = (
BYTE)nGrids;
05928 pHostClut->
nInputEntries = (WORD)nInputTable;
05929 pHostClut->
nOutputEntries = (WORD)nOutputTable;
05930
05931
05932
05933
05934
05935 pBuffer +=
CreateHostInputOutputArray(pBuffer, pHostClut->
inputArray,
05936 nInputCh, nInputTable, 0, dwLutSig, (
PBYTE)pLut);
05937
05938
if (dwType ==
TYPE_CIEBASEDDEFG)
05939 {
05940 i = nInputTable * nInputCh +
05941 nGrids * nGrids * nGrids * nGrids * nOutputCh;
05942 }
05943
else
05944 {
05945 i = nInputTable * nInputCh +
05946 nGrids * nGrids * nGrids * nOutputCh;
05947 }
05948
05949
05950
05951
05952
05953 pBuffer +=
CreateHostInputOutputArray(pBuffer, pHostClut->
outputArray,
05954 nOutputCh, nOutputTable, i, dwLutSig, (
PBYTE)pLut);
05955
05956
05957
05958
05959
05960 pHostClut->
clut = pBuffer;
05961 nNumbers = nGrids * nGrids * nOutputCh;
05962 SecondGrids = 1;
05963
if (dwType ==
TYPE_CIEBASEDDEFG)
05964 {
05965 SecondGrids = nGrids;
05966 }
05967
05968
for (i=0; i<nGrids; i++)
05969 {
05970
for (k=0; k<SecondGrids; k++)
05971 {
05972
if (dwLutSig ==
LUT8_TYPE)
05973 {
05974 pTable = (
PBYTE) (((
PLUT8TYPE)pLut)->data) +
05975 nInputTable * nInputCh +
05976 nNumbers * (i * SecondGrids + k);
05977 }
05978
else
05979 {
05980 pTable = (
PBYTE) (((
PLUT16TYPE)pLut)->data) +
05981 2 * nInputTable * nInputCh +
05982 2 * nNumbers * (i * SecondGrids + k);
05983 }
05984
05985
if (dwLutSig ==
LUT8_TYPE)
05986 {
05987 CopyMemory(pBuffer, pTable, nNumbers);
05988 pBuffer += nNumbers;
05989 }
05990
else
05991 {
05992
for (j=0; j<nNumbers; j++)
05993 {
05994 *pBuffer++ = (
BYTE)(FIX_ENDIAN16(*((PWORD)pTable)) / 256);
05995 pTable +=
sizeof(WORD);
05996 }
05997 }
05998 }
05999 }
06000
06001 *pdwSize = (
DWORD) (pBuffer - pStart);
06002
06003
return TRUE;
06004 }
06005
06006
06007
06008
06009
06010
06011
06012
06013
06014
06015
06016
06017
06018
06019
06020
06021
06022
06023
BOOL
06024 GetHostColorSpaceArray(
06025 PBYTE pProfile,
06026 DWORD dwIntent,
06027 PBYTE pBuffer,
06028 PDWORD pdwSize
06029 )
06030 {
06031
DWORD dwDev;
06032
BOOL bRc =
FALSE;
06033
06034 dwDev =
GetCPDevSpace(pProfile);
06035
06036
switch (dwDev)
06037 {
06038
case SPACE_RGB:
06039 bRc =
GetHostCSA(pProfile, pBuffer, pdwSize,
06040 dwIntent,
TYPE_CIEBASEDDEF);
06041
break;
06042
case SPACE_CMYK:
06043 bRc =
GetHostCSA(pProfile, pBuffer, pdwSize,
06044 dwIntent,
TYPE_CIEBASEDDEFG);
06045
break;
06046
default:
06047
break;
06048 }
06049
06050
return bRc;
06051 }
06052
06053
06054
06055
06056
06057
06058
06059
06060
06061
06062
06063
06064
06065
06066
06067
BOOL
06068 DoHostConversionCRD(
06069 PHOSTCLUT pHostCRD,
06070 PHOSTCLUT pHostCSA,
06071
float *pfInput,
06072
float *pfOutput,
06073 BOOL bCheckOutputTable
06074 )
06075 {
06076
float fTemp[
MAXCHANNELS];
06077
float fTemp1[
MAXCHANNELS];
06078
DWORD i, j;
06079
06080
06081
06082
06083
06084
06085
06086
06087
06088
if (pHostCSA)
06089 {
06090
06091
06092
06093
06094
if ((pHostCRD->
dwPCS == SPACE_XYZ) &&
06095 (pHostCSA->
dwPCS == SPACE_Lab))
06096 {
06097
LabToXYZ(pfInput, fTemp1, pHostCRD->
afxIlluminantWP);
06098 }
06099
else if ((pHostCRD->
dwPCS == SPACE_Lab) &&
06100 (pHostCSA->
dwPCS == SPACE_XYZ))
06101 {
06102
06103
06104
06105
06106
XYZToLab(pfInput, fTemp, pHostCSA->
afxIlluminantWP);
06107 }
06108
else if ((pHostCRD->
dwPCS == SPACE_Lab) &&
06109 (pHostCSA->
dwPCS == SPACE_Lab))
06110 {
06111
06112
06113
06114
06115
for (i=0; i<3; i++)
06116 fTemp[i] = pfInput[i] / 2;
06117 }
06118
else
06119 {
06120
06121
06122
06123
06124
06125
06126
06127
06128
06129
for (i=0; i<3; i++)
06130 fTemp1[i] = (pfInput[i] * pHostCRD->
afxIlluminantWP[i]) / pHostCSA->
afxIlluminantWP[i];
06131 }
06132
06133
06134
06135
06136
06137
if (pHostCRD->
dwPCS == SPACE_XYZ)
06138 {
06139
ApplyMatrix(pHostCRD->
e, fTemp1, fTemp);
06140 }
06141
06142
if (pHostCRD->
wDataType !=
DATATYPE_MATRIX)
06143 {
06144
06145
06146
06147
06148 (
void)
CheckInputOutputTable(pHostCRD, fTemp,
FALSE,
TRUE);
06149 }
06150 }
06151
06152
06153
06154
06155
06156
06157
else
06158 {
06159 WORD nGrids;
06160
06161 nGrids = pHostCRD->
nClutPoints;
06162
06163
06164
06165
06166
06167
06168
06169
if (pHostCRD->
wDataType ==
DATATYPE_MATRIX)
06170 {
06171
for (i = 0; i < 3; i++)
06172 {
06173 fTemp[i] = pfInput[i];
06174 }
06175 }
06176
else
06177 {
06178
for (i=0; i<3; i++)
06179 {
06180 fTemp[i] = pfInput[i] * (nGrids - 1);
06181
if (fTemp[i] > (nGrids - 1))
06182 fTemp[i] = (
float)(nGrids - 1);
06183 }
06184 }
06185 }
06186
06187
if (pHostCRD->
wDataType !=
DATATYPE_MATRIX)
06188 {
06189
06190
06191
06192
06193 (
void)
CheckColorLookupTable(pHostCRD, fTemp);
06194 }
06195
06196
06197
06198
06199
06200
if (bCheckOutputTable)
06201 {
06202 (
void)
CheckInputOutputTable(pHostCRD, fTemp,
FALSE,
FALSE);
06203 }
06204
06205
for (i=0; (i<=
MAXCHANNELS) && (i<pHostCRD->
nOutputCh); i++)
06206 {
06207 pfOutput[i] = fTemp[i];
06208 }
06209
06210
return TRUE;
06211 }
06212
06213
06214
06215
06216
06217
06218
06219
06220
06221
06222
06223
06224
06225
BOOL
06226 DoHostConversionCSA(
06227 PHOSTCLUT pHostClut,
06228
float *pfInput,
06229
float *pfOutput
06230 )
06231 {
06232
float fTemp[
MAXCHANNELS];
06233
DWORD i;
06234
06235
06236
06237
06238
06239
for (i=0; (i<=
MAXCHANNELS) && (i<pHostClut->
nInputCh); i++)
06240 {
06241 fTemp[i] = pfInput[i];
06242 }
06243
06244
06245
06246
06247
06248 (
void)
CheckInputOutputTable(pHostClut, fTemp,
TRUE,
TRUE);
06249
06250
if (pHostClut->
wDataType ==
DATATYPE_MATRIX)
06251 {
06252
ApplyMatrix(pHostClut->
e, fTemp, pfOutput);
06253 }
06254
else
06255 {
06256
06257
06258
06259
06260 (
void)
CheckColorLookupTable(pHostClut, fTemp);
06261
06262
06263
06264
06265
06266 (
void)
CheckInputOutputTable(pHostClut, fTemp,
TRUE,
FALSE);
06267
06268
06269
06270
06271
06272
for (i=0; (i<=
MAXCHANNELS) && (i<pHostClut->
nOutputCh); i++)
06273 {
06274 pfOutput[i] = fTemp[i];
06275 }
06276 }
06277
06278
return TRUE;
06279 }
06280
06281
06282
06283
06284
06285
06286
06287
06288
06289
06290
06291
06292
06293
06294
BOOL
06295 CheckInputOutputTable(
06296 PHOSTCLUT pHostClut,
06297
float *pfTemp,
06298 BOOL bCSA,
06299 BOOL bInputTable
06300 )
06301 {
06302
PBYTE *ppArray;
06303
float fIndex;
06304
DWORD nNumCh;
06305
DWORD nNumEntries, i;
06306 WORD nGrids;
06307 WORD floor1, ceiling1;
06308
06309
if (bInputTable)
06310 {
06311 nNumCh = pHostClut->
nInputCh;
06312 nNumEntries = pHostClut->
nInputEntries - 1;
06313 ppArray = pHostClut->
inputArray;
06314 }
06315
else
06316 {
06317 nNumCh = pHostClut->
nOutputCh;
06318 nNumEntries = pHostClut->
nOutputEntries - 1;
06319 ppArray = pHostClut->
outputArray;
06320 }
06321
06322 nGrids = pHostClut->
nClutPoints;
06323
for (i=0; (i<=
MAXCHANNELS) && (i<nNumCh); i++)
06324 {
06325 pfTemp[i] = (pfTemp[i] < 0) ? 0 : ((pfTemp[i] > 1) ? 1 : pfTemp[i]);
06326
06327 fIndex = pfTemp[i] * nNumEntries;
06328
06329
if (pHostClut->
nLutBits == 8)
06330 {
06331 floor1 = ppArray[i][(
DWORD)fIndex];
06332 ceiling1 = ppArray[i][((
DWORD)fIndex) + 1];
06333
06334 pfTemp[i] = (
float)(floor1 + (ceiling1 - floor1) * (fIndex - floor(fIndex)));
06335
06336
if (bCSA && !bInputTable)
06337 pfTemp[i] = pfTemp[i] / 127.0f;
06338
else
06339 pfTemp[i] = pfTemp[i] / 255.0f;
06340 }
06341
else
06342 {
06343 floor1 = ((PWORD)(ppArray[i]))[(
DWORD)fIndex];
06344 ceiling1 = ((PWORD)(ppArray[i]))[((
DWORD)fIndex) + 1];
06345
06346 pfTemp[i] = (
float)(floor1 + (ceiling1 - floor1) * (fIndex - floor(fIndex)));
06347
06348
if (bCSA && !bInputTable)
06349 pfTemp[i] = pfTemp[i] / 32767.0f;
06350
else
06351 pfTemp[i] = pfTemp[i] / 65535.0f;
06352
06353 }
06354
06355
if (bInputTable)
06356 {
06357 pfTemp[i] *= (nGrids - 1);
06358
if (pfTemp[i] > (nGrids - 1))
06359 pfTemp[i] = (
float)(nGrids - 1);
06360 }
06361 }
06362
06363
return TRUE;
06364 }
06365
06366
06367
06368
06369
06370
06371
06372
06373
06374
06375
06376
06377
06378
06379 float g(
06380
float f
06381 )
06382 {
06383
float fRc;
06384
06385
if (f >= (6.0f/29.0f))
06386 {
06387 fRc = f * f * f;
06388 }
06389
else
06390 {
06391 fRc = f - (4.0f / 29.0f) * (108.0f / 841.0f);
06392 }
06393
06394
return fRc;
06395 }
06396
06397
06398
06399
06400
06401
06402
06403
06404
06405
06406
06407
float
06408 inverse_g(
06409
float f
06410 )
06411 {
06412
double fRc;
06413
06414
if (f >= (6.0f*6.0f*6.0f)/(29.0f*29.0f*29.0f))
06415 {
06416 fRc = pow(f, 1.0 / 3.0);
06417 }
06418
else
06419 {
06420 fRc = f * (841.0f / 108.0f) + (4.0f / 29.0f);
06421 }
06422
06423
return (
float)fRc;
06424 }
06425
06426
06427
void
06428 LabToXYZ(
06429
float *pfInput,
06430
float *pfOutput,
06431 PFIX_16_16 pafxWP
06432 )
06433 {
06434
float fL, fa, fb;
06435
06436 fL = (pfInput[0] * 50 + 16) / 116;
06437 fa = (pfInput[1] * 128 - 128) / 500;
06438 fb = (pfInput[2] * 128 - 128) / 200;
06439
06440 pfOutput[0] = pafxWP[0] *
g(fL + fa) /
FIX_16_16_SCALE;
06441 pfOutput[1] = pafxWP[1] *
g(fL) /
FIX_16_16_SCALE;
06442 pfOutput[2] = pafxWP[2] *
g(fL - fb) /
FIX_16_16_SCALE;
06443
06444
return;
06445 }
06446
06447
06448
void
06449 XYZToLab(
06450
float *pfInput,
06451
float *pfOutput,
06452 PFIX_16_16 pafxWP
06453 )
06454 {
06455
float fL, fa, fb;
06456
06457 fL =
inverse_g(pfInput[0] *
FIX_16_16_SCALE / pafxWP[0]);
06458 fa =
inverse_g(pfInput[1] *
FIX_16_16_SCALE / pafxWP[1]);
06459 fb =
inverse_g(pfInput[2] *
FIX_16_16_SCALE / pafxWP[2]);
06460
06461 pfOutput[0] = (fa * 116 - 16) / 100;
06462 pfOutput[1] = (fL * 500 - fa * 500 + 128) / 255;
06463 pfOutput[2] = (fa * 200 - fb * 200 + 128) / 255;
06464
06465
return;
06466 }
06467
06468
06469
BOOL
06470 TableInterp3(
06471 PHOSTCLUT pHostClut,
06472
float *pfTemp
06473 )
06474 {
06475
06476
PBYTE v000, v001, v010, v011;
06477
PBYTE v100, v101, v110, v111;
06478
float fA, fB, fC;
06479
float fVx0x, fVx1x;
06480
float fV0xx, fV1xx;
06481
DWORD tmpA, tmpBC;
06482
DWORD cellA, cellB, cellC;
06483
DWORD idx;
06484 WORD nGrids;
06485 WORD nOutputCh;
06486
06487 cellA = (
DWORD)pfTemp[0];
06488 fA = pfTemp[0] - cellA;
06489
06490 cellB = (
DWORD)pfTemp[1];
06491 fB = pfTemp[1] - cellB;
06492
06493 cellC = (
DWORD)pfTemp[2];
06494 fC = pfTemp[2] - cellC;
06495
06496 nGrids = pHostClut->
nClutPoints;
06497 nOutputCh = pHostClut->
nOutputCh;
06498 tmpA = nOutputCh * nGrids * nGrids;
06499 tmpBC = nOutputCh * (nGrids * cellB + cellC);
06500
06501
06502
06503
06504
06505 v000 = pHostClut->
clut + tmpA * cellA + tmpBC;
06506 v001 = (cellC < (
DWORD)(nGrids - 1)) ? v000 + nOutputCh : v000;
06507 v010 = (cellB < (
DWORD)(nGrids - 1)) ? v000 + nOutputCh * nGrids : v000;
06508 v011 = (cellC < (
DWORD)(nGrids - 1)) ? v010 + nOutputCh : v010 ;
06509
06510 v100 = (cellA < (
DWORD)(nGrids - 1)) ? v000 + tmpA : v000;
06511 v101 = (cellC < (
DWORD)(nGrids - 1)) ? v100 + nOutputCh : v100;
06512 v110 = (cellB < (
DWORD)(nGrids - 1)) ? v100 + nOutputCh * nGrids : v100;
06513 v111 = (cellC < (
DWORD)(nGrids - 1)) ? v110 + nOutputCh : v110;
06514
06515
for (idx=0; idx<nOutputCh; idx++)
06516 {
06517
06518
06519
06520
06521 fVx0x = *v000 + fC * (
int)((
int)*v001 - (
int)*v000);
06522 fVx1x = *v010 + fC * (
int)((
int)*v011 - (
int)*v010);
06523 fV0xx = fVx0x + fB * (fVx1x - fVx0x);
06524
06525
06526
06527
06528
06529 fVx0x = *v100 + fC * (
int)((
int)*v101 - (
int)*v100);
06530 fVx1x = *v110 + fC * (
int)((
int)*v111 - (
int)*v110);
06531 fV1xx = fVx0x + fB * (fVx1x - fVx0x);
06532
06533
06534
06535
06536
06537 pfTemp[idx] = (fV0xx + fA * (fV1xx - fV0xx)) /
MAXCOLOR8;
06538
06539
if ( idx < (
DWORD)(nOutputCh - 1))
06540 {
06541 v000++;
06542 v001++;
06543 v010++;
06544 v011++;
06545 v100++;
06546 v101++;
06547 v110++;
06548 v111++;
06549 }
06550 }
06551
06552
return TRUE;
06553 }
06554
06555
06556
BOOL
06557 TableInterp4(
06558 PHOSTCLUT pHostClut,
06559
float *pfTemp
06560 )
06561 {
06562
PBYTE v0000, v0001, v0010, v0011;
06563
PBYTE v0100, v0101, v0110, v0111;
06564
PBYTE v1000, v1001, v1010, v1011;
06565
PBYTE v1100, v1101, v1110, v1111;
06566
float fH, fI, fJ, fK;
06567
float fVxx0x, fVxx1x;
06568
float fVx0xx, fVx1xx;
06569
float fV0xxx, fV1xxx;
06570
DWORD tmpH, tmpI, tmpJK;
06571
DWORD cellH, cellI, cellJ, cellK;
06572
DWORD idx;
06573 WORD nGrids;
06574 WORD nOutputCh;
06575
06576 cellH = (
DWORD)pfTemp[0];
06577 fH = pfTemp[0] - cellH;
06578
06579 cellI = (
DWORD)pfTemp[1];
06580 fI = pfTemp[1] - cellI;
06581
06582 cellJ = (
DWORD)pfTemp[2];
06583 fJ = pfTemp[2] - cellJ;
06584
06585 cellK = (
DWORD)pfTemp[3];
06586 fK = pfTemp[3] - cellK;
06587
06588 nGrids = pHostClut->
nClutPoints;
06589 nOutputCh = pHostClut->
nOutputCh;
06590 tmpI = nOutputCh * nGrids * nGrids;
06591 tmpH = tmpI * nGrids;
06592 tmpJK = nOutputCh * (nGrids * cellJ + cellK);
06593
06594
06595
06596
06597
06598 v0000 = pHostClut->
clut + tmpH * cellH + tmpI * cellI + tmpJK;
06599 v0001 = (cellK < (
DWORD)(nGrids - 1))? v0000 + nOutputCh : v0000;
06600 v0010 = (cellJ < (
DWORD)(nGrids - 1))? v0000 + nOutputCh * nGrids : v0000;
06601 v0011 = (cellK < (
DWORD)(nGrids - 1))? v0010 + nOutputCh : v0010;
06602
06603 v0100 = (cellI < (
DWORD)(nGrids - 1))? v0000 + tmpI : v0000;
06604 v0101 = (cellK < (
DWORD)(nGrids - 1))? v0100 + nOutputCh : v0100;
06605 v0110 = (cellJ < (
DWORD)(nGrids - 1))? v0100 + nOutputCh * nGrids : v0100;
06606 v0111 = (cellK < (
DWORD)(nGrids - 1))? v0110 + nOutputCh : v0110;
06607
06608 v1000 = (cellH < (
DWORD)(nGrids - 1))? v0000 + tmpH : v0000;
06609 v1001 = (cellK < (
DWORD)(nGrids - 1))? v1000 + nOutputCh : v1000;
06610 v1010 = (cellJ < (
DWORD)(nGrids - 1))? v1000 + nOutputCh * nGrids : v1000;
06611 v1011 = (cellK < (
DWORD)(nGrids - 1))? v1010 + nOutputCh : v1010;
06612
06613 v1100 = (cellI < (
DWORD)(nGrids - 1))? v1000 + tmpI : v1000;
06614 v1101 = (cellK < (
DWORD)(nGrids - 1))? v1100 + nOutputCh : v1100;
06615 v1110 = (cellJ < (
DWORD)(nGrids - 1))? v1100 + nOutputCh * nGrids : v1100;
06616 v1111 = (cellK < (
DWORD)(nGrids - 1))? v1110 + nOutputCh : v1110;
06617
06618
06619
for (idx=0; idx<nOutputCh; idx++)
06620 {
06621
06622
06623
06624
06625 fVxx0x = *v0000 + fK * (
int)((
int)*v0001 - (
int)*v0000);
06626 fVxx1x = *v0010 + fK * (
int)((
int)*v0011 - (
int)*v0010);
06627 fVx0xx = fVxx0x + fJ * (fVxx1x - fVxx0x);
06628 fVxx0x = *v0100 + fK * (
int)((
int)*v0101 - (
int)*v0100);
06629 fVxx1x = *v0110 + fK * (
int)((
int)*v0111 - (
int)*v0110);
06630 fVx1xx = fVxx0x + fJ * (fVxx1x - fVxx0x);
06631 fV0xxx = fVx0xx + fI * (fVx1xx - fVx0xx);
06632
06633
06634
06635
06636
06637 fVxx0x = *v1000 + fK * (
int)((
int)*v1001 - (
int)*v1000);
06638 fVxx1x = *v1010 + fK * (
int)((
int)*v1011 - (
int)*v1010);
06639 fVx0xx = fVxx0x + fJ * (fVxx1x - fVxx0x);
06640 fVxx0x = *v1100 + fK * (
int)((
int)*v1101 - (
int)*v1100);
06641 fVxx1x = *v1110 + fK * (
int)((
int)*v1111 - (
int)*v1110);
06642 fVx1xx = fVxx0x + fJ * (fVxx1x - fVxx0x);
06643 fV1xxx = fVx0xx + fI * (fVx1xx - fVx0xx);
06644
06645
06646
06647
06648
06649 pfTemp[idx] = (fV0xxx + fH * (fV1xxx - fV0xxx)) /
MAXCOLOR8;
06650
06651
if (idx < (
DWORD)(nOutputCh - 1))
06652 {
06653 v0000++;
06654 v0001++;
06655 v0010++;
06656 v0011++;
06657 v0100++;
06658 v0101++;
06659 v0110++;
06660 v0111++;
06661 v1000++;
06662 v1001++;
06663 v1010++;
06664 v1011++;
06665 v1100++;
06666 v1101++;
06667 v1110++;
06668 v1111++;
06669 }
06670 }
06671
06672
return TRUE;
06673 }
06674
06675
BOOL
06676 InvertColorantArray(
06677
double *lpInMatrix,
06678
double *lpOutMatrix)
06679 {
06680
double det;
06681
06682
double *a;
06683
double *b;
06684
double *
c;
06685
06686 a = &(lpInMatrix[0]);
06687 b = &(lpInMatrix[3]);
06688
c = &(lpInMatrix[6]);
06689
06690 det = a[0] * b[1] *
c[2] + a[1] * b[2] *
c[0] + a[2] * b[0] *
c[1] -
06691 (a[2] * b[1] *
c[0] + a[1] * b[0] *
c[2] + a[0] * b[2] *
c[1]);
06692
06693
if (det == 0.0)
06694 {
06695 lpOutMatrix[0] = 1.0;
06696 lpOutMatrix[1] = 0.0;
06697 lpOutMatrix[2] = 0.0;
06698
06699 lpOutMatrix[3] = 0.0;
06700 lpOutMatrix[4] = 1.0;
06701 lpOutMatrix[5] = 0.0;
06702
06703 lpOutMatrix[6] = 0.0;
06704 lpOutMatrix[7] = 0.0;
06705 lpOutMatrix[8] = 1.0;
06706 }
06707
else
06708 {
06709 lpOutMatrix[0] = (b[1] *
c[2] - b[2] *
c[1]) / det;
06710 lpOutMatrix[3] = -(b[0] *
c[2] - b[2] *
c[0]) / det;
06711 lpOutMatrix[6] = (b[0] *
c[1] - b[1] *
c[0]) / det;
06712
06713 lpOutMatrix[1] = -(a[1] *
c[2] - a[2] *
c[1]) / det;
06714 lpOutMatrix[4] = (a[0] *
c[2] - a[2] *
c[0]) / det;
06715 lpOutMatrix[7] = -(a[0] *
c[1] - a[1] *
c[0]) / det;
06716
06717 lpOutMatrix[2] = (a[1] * b[2] - a[2] * b[1]) / det;
06718 lpOutMatrix[5] = -(a[0] * b[2] - a[2] * b[0]) / det;
06719 lpOutMatrix[8] = (a[0] * b[1] - a[1] * b[0]) / det;
06720 }
06721
06722
return (
TRUE);
06723 }
06724
06725
VOID
06726 ApplyMatrix(
06727 FIX_16_16 *e,
06728
float *Input,
06729
float *Output)
06730 {
06731
DWORD i, j;
06732
06733
for (i=0; i<3; i++)
06734 {
06735 j = i * 3;
06736
06737 Output[i] = ((e[j] * Input[0]) /
FIX_16_16_SCALE) +
06738 ((e[j + 1] * Input[1]) /
FIX_16_16_SCALE) +
06739 ((e[j + 2] * Input[2]) /
FIX_16_16_SCALE);
06740 }
06741 }
06742
06743
06744
06745
06746
06747
06748
06749
06750
06751
06752
06753
06754
06755
06756
BOOL
06757 CheckColorLookupTable(
06758 PHOSTCLUT pHostClut,
06759
float *pfTemp
06760 )
06761 {
06762
if (pHostClut->
nInputCh == 3)
06763 {
06764
return TableInterp3(pHostClut, pfTemp);
06765 }
06766
else if (pHostClut->
nInputCh == 4)
06767 {
06768
return TableInterp4(pHostClut, pfTemp);
06769 }
06770
else
06771
return FALSE;
06772 }
06773
06774
06775
06776
06777
06778
BOOL WINAPI
06779 GetPS2PreviewCRD (
06780 HPROFILE hDestProfile,
06781 HPROFILE hTargetProfile,
06782 DWORD dwIntent,
06783 PBYTE pBuffer,
06784 PDWORD pcbSize,
06785 LPBOOL pbBinary
06786 )
06787 {
06788 PPROFOBJ pDestProfObj;
06789 PPROFOBJ pTargetProfObj;
06790
06791 pDestProfObj = (PPROFOBJ)HDLTOPTR(hDestProfile);
06792 pTargetProfObj = (PPROFOBJ)HDLTOPTR(hTargetProfile);
06793
06794
06795
return InternalGetPS2PreviewCRD(pDestProfObj->pView, pTargetProfObj->pView, dwIntent, pBuffer, pcbSize, pbBinary);
06796 }
06797
06798
#endif // !defined(KERNEL_MODE) || defined(USERMODE_DRIVER)
06799
06800
06801
06802
06803
06804
06805
06806
06807
06808 static DWORD crc_32_tab[] = {
06809 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
06810 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
06811 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
06812 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
06813 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
06814 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
06815 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
06816 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
06817 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
06818 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
06819 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
06820 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
06821 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
06822 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
06823 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
06824 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
06825 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
06826 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
06827 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
06828 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
06829 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
06830 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
06831 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
06832 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
06833 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
06834 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
06835 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
06836 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
06837 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
06838 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
06839 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
06840 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
06841 };
06842
06843 DWORD crc32(PBYTE buff, DWORD length)
06844 {
06845
DWORD crc, charcnt;
06846
BYTE c;
06847
06848 crc = 0xFFFFFFFF;
06849 charcnt = 0;
06850
06851
for (charcnt = 0 ; charcnt < length ; charcnt++)
06852 {
06853
c = buff[charcnt];
06854 crc =
crc_32_tab[(crc ^
c) & 0xff] ^ (crc >> 8);
06855 }
06856
06857
return crc;
06858 }
06859
06860
06861
06862
06863
06864
06865
06866
06867
06868
06869
06870
06871
06872
06873 BOOL IsSRGBColorProfile(
06874 PBYTE pProfile
06875 )
06876 {
06877
BOOL bMatch =
FALSE;
06878
DWORD dwRedTRCIndex, dwGreenTRCIndex, dwBlueTRCIndex;
06879
DWORD dwRedCIndex, dwGreenCIndex, dwBlueCIndex;
06880
DWORD dwSize;
06881
DWORD dwRedTRCSize=0, dwGreenTRCSize=0, dwBlueTRCSize=0;
06882
DWORD dwRedCSize=0, dwGreenCSize=0, dwBlueCSize=0;
06883
PBYTE pRed, pGreen, pBlue, pRedC, pGreenC, pBlueC;
06884
BYTE DataBuffer[
ALIGN_DWORD(
sRGB_TAGSIZE)];
06885
06886
if (
DoesCPTagExist(pProfile,
TAG_REDTRC, &dwRedTRCIndex) &&
06887
GetCPElementDataSize(pProfile, dwRedTRCIndex, &dwRedTRCSize) &&
06888
06889
DoesCPTagExist(pProfile,
TAG_GREENTRC, &dwGreenTRCIndex) &&
06890
GetCPElementDataSize(pProfile, dwGreenTRCIndex, &dwGreenTRCSize) &&
06891
06892
DoesCPTagExist(pProfile,
TAG_BLUETRC, &dwBlueTRCIndex) &&
06893
GetCPElementDataSize(pProfile, dwBlueTRCIndex, &dwBlueTRCSize) &&
06894
06895
DoesCPTagExist(pProfile,
TAG_REDCOLORANT, &dwRedCIndex) &&
06896
GetCPElementDataSize(pProfile, dwRedCIndex, &dwRedCSize) &&
06897
06898
DoesCPTagExist(pProfile,
TAG_GREENCOLORANT, &dwGreenCIndex) &&
06899
GetCPElementDataSize(pProfile, dwGreenCIndex, &dwGreenCSize) &&
06900
06901
DoesCPTagExist(pProfile,
TAG_BLUECOLORANT, &dwBlueCIndex) &&
06902
GetCPElementDataSize(pProfile, dwBlueCIndex, &dwBlueCSize))
06903 {
06904 dwSize = dwRedTRCSize + dwGreenTRCSize + dwBlueTRCSize +
06905 dwRedCSize + dwGreenCSize + dwBlueCSize;
06906
06907
if (dwSize ==
sRGB_TAGSIZE)
06908 {
06909 ZeroMemory(DataBuffer,
sizeof(DataBuffer));
06910
06911 pRed = DataBuffer;
06912 pGreen = pRed + dwRedTRCSize;
06913 pBlue = pGreen + dwGreenTRCSize;
06914 pRedC = pBlue + dwBlueTRCSize;
06915 pGreenC = pRedC + dwRedCSize;
06916 pBlueC = pGreenC + dwGreenCSize;
06917
06918
if (
GetCPElementData(pProfile, dwRedTRCIndex, pRed, &dwRedTRCSize) &&
06919
GetCPElementData(pProfile, dwGreenTRCIndex, pGreen, &dwGreenTRCSize) &&
06920
GetCPElementData(pProfile, dwBlueTRCIndex, pBlue, &dwBlueTRCSize) &&
06921
GetCPElementData(pProfile, dwRedCIndex, pRedC, &dwRedCSize) &&
06922
GetCPElementData(pProfile, dwGreenCIndex, pGreenC, &dwGreenCSize) &&
06923
GetCPElementData(pProfile, dwBlueCIndex, pBlueC, &dwBlueCSize))
06924 {
06925 bMatch = (
crc32(DataBuffer,
sRGB_TAGSIZE) ==
sRGB_CRC);
06926 }
06927 }
06928 }
06929
06930
return (bMatch);
06931 }
06932
06933
06934
06935