You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
4777 lines
143 KiB
4777 lines
143 KiB
/*++
|
|
|
|
Copyright (c) 1990-1991 Microsoft Corporation
|
|
|
|
|
|
Module Name:
|
|
|
|
htmapclr.c
|
|
|
|
|
|
Abstract:
|
|
|
|
This module contains low levels functions which map the input color to
|
|
the dyes' densities.
|
|
|
|
|
|
Author:
|
|
|
|
29-Jan-1991 Tue 10:28:20 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
[Environment:]
|
|
|
|
GDI Device Driver - Halftone.
|
|
|
|
|
|
[Notes:]
|
|
|
|
1. In the near future we will also allowed the XYZ/LAB to be specified in
|
|
the color table
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
#define DBGP_VARNAME dbgpHTMapClr
|
|
|
|
#include "htp.h"
|
|
#include "htmapclr.h"
|
|
#include "htrender.h"
|
|
#include "htmath.h"
|
|
#include "htapi.h"
|
|
#include "htpat.h"
|
|
#include "htalias.h"
|
|
|
|
|
|
#define DBGP_SHOWXFORM_RGB 0x00000001
|
|
#define DBGP_SHOWXFORM_ALL 0x00000002
|
|
#define DBGP_CIEMATRIX 0x00000004
|
|
#define DBGP_CSXFORM 0x00000008
|
|
#define DBGP_CCT 0x00000010
|
|
#define DBGP_DYE_CORRECT 0x00000020
|
|
#define DBGP_HCA 0x00000040
|
|
#define DBGP_PRIMARY_ORDER 0x00000080
|
|
#define DBGP_CACHED_GAMMA 0x00000100
|
|
#define DBGP_RGBLUTAA 0x00000200
|
|
#define DBGP_SCALE_RGB 0x00000400
|
|
#define DBGP_MONO_PRIM 0x00000800
|
|
#define DBGP_PRIMADJFLAGS 0x00001000
|
|
#define DBGP_CELLGAMMA 0x00002000
|
|
#define DBGP_CONST_ALPHA 0x00004000
|
|
#define DBGP_BGRMAPTABLE 0x00008000
|
|
|
|
|
|
DEF_DBGPVAR(BIT_IF(DBGP_SHOWXFORM_RGB, 0) |
|
|
BIT_IF(DBGP_SHOWXFORM_ALL, 0) |
|
|
BIT_IF(DBGP_CIEMATRIX, 0) |
|
|
BIT_IF(DBGP_CSXFORM, 0) |
|
|
BIT_IF(DBGP_CCT, 0) |
|
|
BIT_IF(DBGP_DYE_CORRECT, 0) |
|
|
BIT_IF(DBGP_HCA, 0) |
|
|
BIT_IF(DBGP_PRIMARY_ORDER, 0) |
|
|
BIT_IF(DBGP_CACHED_GAMMA, 0) |
|
|
BIT_IF(DBGP_RGBLUTAA, 0) |
|
|
BIT_IF(DBGP_SCALE_RGB, 0) |
|
|
BIT_IF(DBGP_MONO_PRIM, 0) |
|
|
BIT_IF(DBGP_PRIMADJFLAGS, 0) |
|
|
BIT_IF(DBGP_CELLGAMMA, 0) |
|
|
BIT_IF(DBGP_CONST_ALPHA, 0) |
|
|
BIT_IF(DBGP_BGRMAPTABLE, 0))
|
|
|
|
|
|
extern HTCOLORADJUSTMENT DefaultCA;
|
|
extern CONST LPBYTE p8BPPXlate[];
|
|
extern HTGLOBAL HTGlobal;
|
|
|
|
|
|
#define FD6_p25 (FD6_5 / 2)
|
|
#define FD6_p75 (FD6_p25 * 3)
|
|
#define JND_ADJ(j,x) RaisePower((j), (FD6)(x), RPF_INTEXP)
|
|
|
|
#define FD6_p1125 (FD6)112500
|
|
#define FD6_p225 (FD6)225000
|
|
#define FD6_p325 (FD6)325000
|
|
#define FD6_p55 (FD6)550000
|
|
#define FD6_p775 (FD6)775000
|
|
|
|
|
|
|
|
const FD6 SinNumber[] = {
|
|
|
|
0, 17452, 34899, 52336, 69756, // 0
|
|
87156, 104528, 121869, 139173, 156434, // 5.0
|
|
173648, 190809, 207912, 224951, 241922, // 10
|
|
258819, 275637, 292372, 309017, 325568, // 15.0
|
|
342020, 358368, 374607, 390731, 406737, // 20
|
|
422618, 438371, 453990, 469472, 484810, // 25.0
|
|
500000, 515038, 529919, 544639, 559193, // 30
|
|
573576, 587785, 601815, 615661, 629320, // 35.0
|
|
642788, 656059, 669131, 681998, 694658, // 40
|
|
707107, 719340, 731354, 743145, 754710, // 45.0
|
|
766044, 777146, 788011, 798636, 809017, // 50
|
|
819152, 829038, 838671, 848048, 857167, // 55.0
|
|
866025, 874620, 882948, 891007, 898794, // 60
|
|
906308, 913545, 920505, 927184, 933580, // 65.0
|
|
939693, 945519, 951057, 956305, 961262, // 70
|
|
965926, 970296, 974370, 978148, 981627, // 75.0
|
|
984808, 987688, 990268, 992546, 994522, // 80
|
|
996195, 997564, 998630, 999391, 999848, // 85.0
|
|
1000000
|
|
};
|
|
|
|
|
|
#define CLAMP_0(x) if ((x) < FD6_0) { (x) = FD6_0; }
|
|
#define CLAMP_1(x) if ((x) > FD6_1) { (x) = FD6_1; }
|
|
#define CLAMP_01(x) CLAMP_0(x) else CLAMP_1(x)
|
|
#define CLAMP_PRIMS_0(a,b,c) CLAMP_0(a); CLAMP_0(b); CLAMP_0(c)
|
|
#define CLAMP_PRIMS_1(a,b,c) CLAMP_1(a); CLAMP_1(b); CLAMP_1(c)
|
|
#define CLAMP_PRIMS_01(a,b,c) CLAMP_01(a); CLAMP_01(b); CLAMP_01(c)
|
|
|
|
|
|
FD6 LogFilterMax = 0;
|
|
|
|
#if 0
|
|
#define LOG_FILTER_RATIO 4
|
|
#else
|
|
#define LOG_FILTER_RATIO 7
|
|
#endif
|
|
|
|
#define LOG_FILTER_POWER (FD6)1200000
|
|
#define PRIM_LOG_RATIO(p) Log(FD6xL((p), LOG_FILTER_RATIO) + FD6_1)
|
|
|
|
#define PRIM_CONTRAST(p,adj) (p)=MulFD6((p), (adj).Contrast)
|
|
#define PRIM_BRIGHTNESS(p,adj) (p)+=((adj).Brightness)
|
|
#define PRIM_COLORFULNESS(a,b,adj) (a)=MulFD6((a),(adj).Color); \
|
|
(b)=MulFD6((b),(adj).Color)
|
|
#define PRIM_TINT(a,b,t,adj) (t)=(a); \
|
|
(a)=MulFD6((a),(adj).TintCosAngle) - \
|
|
MulFD6((b),(adj).TintSinAngle); \
|
|
(b)=MulFD6((t),(adj).TintSinAngle) + \
|
|
MulFD6((b),(adj).TintCosAngle)
|
|
#if 0
|
|
#define PRIM_LOG_FILTER(p) \
|
|
(p)=FD6_1-Power(FD6_1-DivFD6(PRIM_LOG_RATIO(p),LogFilterMax),LOG_FILTER_POWER)
|
|
#else
|
|
#define PRIM_LOG_FILTER(p) (p)=DivFD6(PRIM_LOG_RATIO(p),LogFilterMax)
|
|
#endif
|
|
|
|
#define PRIM_BW_ADJ(p,adj) \
|
|
{ \
|
|
if ((p) <= (adj).MinL) { \
|
|
\
|
|
(p) = MulFD6(p, (adj).MinLMul); \
|
|
\
|
|
} else if ((p) >= (adj).MaxL) { \
|
|
\
|
|
(p) = HT_W_REF_BASE + MulFD6((p)-(adj).MaxL, (adj).MaxLMul); \
|
|
\
|
|
} else { \
|
|
\
|
|
(p) = HT_K_REF_BASE + MulFD6((p)-(adj).MinL, (adj).RangeLMul); \
|
|
} \
|
|
}
|
|
|
|
|
|
#define COMP_CA(pca1,pca2) CompareMemory((LPBYTE)(pca1), \
|
|
(LPBYTE)(pca2), \
|
|
sizeof(HTCOLORADJUSTMENT))
|
|
#define ADJ_CA(a,min,max) if (a < min) { a = min; } else \
|
|
if (a > max) { a = max; }
|
|
|
|
#define GET_CHECKSUM(c, f) (c)=ComputeChecksum((LPBYTE)&(f),(c),sizeof(f))
|
|
#define PRIM_GAMMA_ADJ(p,g) (p)=Power((p),(g))
|
|
|
|
|
|
#define NO_NEGATIVE_RGB_SCALE 0
|
|
|
|
#if NO_NEGATIVE_RGB_SCALE
|
|
#define SCALE_PRIM_RGB(pPrim,py) ScaleRGB((pPrim))
|
|
#else
|
|
#define SCALE_PRIM_RGB(pPrim,py) ScaleRGB((pPrim), (py))
|
|
#endif
|
|
|
|
|
|
#define SET_CACHED_CMI_CA(ca) \
|
|
{ \
|
|
(ca).caFlags &= ~(CLRADJF_LOG_FILTER | \
|
|
CLRADJF_NEGATIVE); \
|
|
(ca).caRedGamma = \
|
|
(ca).caGreenGamma = \
|
|
(ca).caBlueGamma = 0; \
|
|
(ca).caReferenceBlack = 0x1234; \
|
|
(ca).caReferenceWhite = 0x5678; \
|
|
(ca).caContrast = (SHORT)0xABCD; \
|
|
(ca).caBrightness = (SHORT)0xFFFF; \
|
|
}
|
|
|
|
|
|
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
//
|
|
// The following macros used in Color space transform functions, these macros
|
|
// are used to compute CIELAB X/Xw, Y/Yw, Z/Zw when its values is less
|
|
// than 0.008856
|
|
//
|
|
// 1/3
|
|
// fX = (X/RefXw) - (16/116) (X/RefXw) > 0.008856
|
|
// fX = 7.787 x (X/RefXw) (X/RefXw) <= 0.008856
|
|
//
|
|
// 1/3
|
|
// fY = (Y/RefYw) - (16/116) (Y/RefYw) > 0.008856
|
|
// fY = 7.787 x (Y/RefYw) (Y/RefYw) <= 0.008856
|
|
//
|
|
// 1/3
|
|
// fZ = (Z/RefZw) - (16/116) (Z/RefZw) > 0.008856
|
|
// fZ = 7.787 x (Z/RefZw) (Z/RefZw) <= 0.008856
|
|
//
|
|
//
|
|
// 1/3
|
|
// Thresholds at 0.008856 - (16/116) = 0.068962
|
|
// 7.787 x 0.008856 = 0.068962
|
|
//
|
|
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
|
|
|
|
#define NORM_XYZ(xyz, w) (FD6)(((w)==FD6_1) ? (xyz) : DivFD6((xyz), (w)))
|
|
|
|
#define fXYZFromXYZ(f,n,w) (f) = ((((f)=NORM_XYZ((n),(w))) >= FD6_p008856) ? \
|
|
(CubeRoot((f))) : \
|
|
(MulFD6((f), FD6_7p787) + FD6_16Div116))
|
|
|
|
#define XYZFromfXYZ(n,f,w) (n)=((f)>(FD6)206893) ? \
|
|
(Cube((f))) : \
|
|
(DivFD6((f) - FD6_16Div116, FD6_7p787)); \
|
|
if ((w)!=FD6_1) { (n)=MulFD6((n),(w)); }
|
|
|
|
|
|
//
|
|
// Following #defines are used in ComputeColorSpaceXForm, XFormRGB_XYZ_UCS()
|
|
// and XFormUCS_XYZ_RGB() functions for easy referenced.
|
|
//
|
|
|
|
#define CSX_AUw(XForm) XForm.AUw
|
|
#define CSX_BVw(XForm) XForm.BVw
|
|
#define CSX_RefXw(XForm) XForm.WhiteXYZ.X
|
|
#define CSX_RefYw(XForm) FD6_1
|
|
#define CSX_RefZw(XForm) XForm.WhiteXYZ.Z
|
|
|
|
#define iAw CSX_AUw(pDevClrAdj->PrimAdj.rgbCSXForm)
|
|
#define iBw CSX_BVw(pDevClrAdj->PrimAdj.rgbCSXForm)
|
|
#define iUw CSX_AUw(pDevClrAdj->PrimAdj.rgbCSXForm)
|
|
#define iVw CSX_BVw(pDevClrAdj->PrimAdj.rgbCSXForm)
|
|
#define iRefXw CSX_RefXw(pDevClrAdj->PrimAdj.rgbCSXForm)
|
|
#define iRefYw CSX_RefYw(pDevClrAdj->PrimAdj.rgbCSXForm)
|
|
#define iRefZw CSX_RefZw(pDevClrAdj->PrimAdj.rgbCSXForm)
|
|
|
|
#define oAw CSX_AUw(pDevClrAdj->PrimAdj.DevCSXForm)
|
|
#define oBw CSX_BVw(pDevClrAdj->PrimAdj.DevCSXForm)
|
|
#define oUw CSX_AUw(pDevClrAdj->PrimAdj.DevCSXForm)
|
|
#define oVw CSX_BVw(pDevClrAdj->PrimAdj.DevCSXForm)
|
|
#define oRefXw CSX_RefXw(pDevClrAdj->PrimAdj.DevCSXForm)
|
|
#define oRefYw CSX_RefYw(pDevClrAdj->PrimAdj.DevCSXForm)
|
|
#define oRefZw CSX_RefZw(pDevClrAdj->PrimAdj.DevCSXForm)
|
|
|
|
|
|
|
|
CONST CIExy2 StdIlluminant[ILLUMINANT_MAX_INDEX] = {
|
|
|
|
{ (UDECI4)4476, (UDECI4)4074 }, // A Tungsten
|
|
{ (UDECI4)3489, (UDECI4)3520 }, // B Noon Sun
|
|
{ (UDECI4)3101, (UDECI4)3162 }, // C NTSC
|
|
{ (UDECI4)3457, (UDECI4)3585 }, // D50 Plain Paper
|
|
{ (UDECI4)3324, (UDECI4)3474 }, // D55 White Bond Paper
|
|
{ (UDECI4)3127, (UDECI4)3290 }, // D65 Standard Sun
|
|
{ (UDECI4)2990, (UDECI4)3149 }, // D75 Northern Sun
|
|
{ (UDECI4)3721, (UDECI4)3751 } // F2 Cool White
|
|
};
|
|
|
|
CONST REGDATA RegData[] = {
|
|
|
|
{ 9,251,35000,950000,100840336,68627450,31372549,100745314,40309045 },
|
|
{ 8,249,45000,930000, 69716775,66386554,33613445,101097041,42542759 },
|
|
{ 7,247,55000,910000, 49910873,65141612,34858387,101555706,44600305 },
|
|
{ 6,245,65000,890000, 36199095,64349376,35650623,102121877,46557500 },
|
|
{ 5,243,75000,870000, 26143790,63800904,36199095,102799050,48461978 },
|
|
{ 4,241,85000,850000, 18454440,63398692,36601307,103595587,50361904 },
|
|
{ 3,239,95000,830000, 12383900,63091118,36908881,104537807,52367907 }
|
|
};
|
|
|
|
//
|
|
//
|
|
// REG_L_MIN = 0.075
|
|
// REG_L_MAX = 0.8500
|
|
// REG_D255MIN = 7
|
|
// REG_D255MAX = 248 (255 - 7)
|
|
//
|
|
// iP 7
|
|
// REG_DMIN_MUL = ------- * -----
|
|
// 0.075 255
|
|
//
|
|
// = iP * 0.366013
|
|
// = (iP * 36.601307) / 100
|
|
//
|
|
//
|
|
// 248 iP - 0.8500 7
|
|
// REG_DMAX_MUL = ----- + ( ------------- * ----- )
|
|
// 255 0.1500 255
|
|
//
|
|
// = 0.972549 + (0.183007 * iP) - 0.155556
|
|
// = 0.816993 + (0.183007 * iP)
|
|
// ~~~~~~~~ ~~~~~~~~
|
|
// = (81.699346 + (18.300654 * iP)) / 100;
|
|
//
|
|
//
|
|
//
|
|
// 7 X - RegLogSub 241
|
|
// REG_DEN_MUL = ----- + ((--------------- ) * ----- )
|
|
// 255 RegLogRange 255
|
|
//
|
|
// 7 X - RegLogSub 241
|
|
// = ----- + ((--------------- ) * ----- )
|
|
// 255 RegLogRange 255
|
|
//
|
|
// 7 X - -2.080771 241
|
|
// = ----- + ((--------------- ) * ----- )
|
|
// 255 1.900361 255
|
|
//
|
|
// 7 X + 2.080771 241
|
|
// = ----- + ((-------------- ) * ----- )
|
|
// 255 1.900361 255
|
|
//
|
|
// 7 X + 2.080771 241
|
|
// = ----- + ((-------------- ) * ----- )
|
|
// 255 1.900361 255
|
|
//
|
|
// = 0.027451 + (( X + 2.080771) * 0.49736)
|
|
// = 0.027451 + ( 0.49736X + 1.034820)
|
|
// = 0.027451 + 0.49736X + 1.034820
|
|
// = 0.497326X + 1.062271
|
|
// = (49.732555 X + 106.227145) / 100
|
|
//
|
|
//
|
|
// X = Log(CIE_L2I(iP)),
|
|
// RegLogMin = Log(CIE_L2I(REG_L_MIN)) = Log(CIE_L2I(0.075)) = -2.080771
|
|
// RegLogMax = Log(CIE_L2I(REG_L_MAX)) = Log(CIE_L2I(0.85)) = -0.180410
|
|
// RegLogSub = -2.080771
|
|
// RegLogRange = -0.180410 - -2.080771 = 1.900361
|
|
//
|
|
|
|
//
|
|
// Standard Illuminant Coordinates and its tristimulus values
|
|
//
|
|
// Illuminant x y X Y Z
|
|
//------------ ---------- ---------- --------- --------- ---------
|
|
// EQU 0.333333 0.333333 100.000 100.000 100.000
|
|
// A 0.447573 0.407440 109.850 100.000 35.585
|
|
// B 0.348904 0.352001 99.120 100.000 84.970
|
|
// C 0.310061 0.316150 98.074 100.000 118.232
|
|
// D50 0.345669 0.358496 96.422 100.000 82.521
|
|
// D55 0.332424 0.347426 95.682 100.000 92.149
|
|
// D65 0.312727 0.329023 95.047 100.000 108.883
|
|
// D75 0.299021 0.314852 94.972 100.000 122.638
|
|
// F2 0.372069 0.375119 99.187 100.000 67.395
|
|
// F7 0.312852 0.329165 95.044 100.000 108.755
|
|
// F11 0.380521 0.376881 100.966 100.000 64.370
|
|
//-----------------------------------------------------------------
|
|
//
|
|
|
|
//
|
|
// This is the Source RGB order in Halftone's order, ORDER_ABC, where A is
|
|
// lowest memory location and C is the highest memory location
|
|
//
|
|
|
|
const RGBORDER SrcOrderTable[PRIMARY_ORDER_MAX + 1] = {
|
|
|
|
{ PRIMARY_ORDER_RGB, { 0, 1, 2 } },
|
|
{ PRIMARY_ORDER_RBG, { 0, 2, 1 } },
|
|
{ PRIMARY_ORDER_GRB, { 1, 0, 2 } },
|
|
{ PRIMARY_ORDER_GBR, { 2, 0, 1 } },
|
|
{ PRIMARY_ORDER_BGR, { 2, 1, 0 } },
|
|
{ PRIMARY_ORDER_BRG, { 1, 2, 0 } }
|
|
};
|
|
|
|
//
|
|
// This is the destination RGB order in Halftone's order, ORDER_ABC, where C is
|
|
// lowest memory location and A is the highest memory location
|
|
//
|
|
|
|
const RGBORDER DstOrderTable[PRIMARY_ORDER_MAX + 1] = {
|
|
|
|
{ PRIMARY_ORDER_RGB, { 2, 1, 0 } },
|
|
{ PRIMARY_ORDER_RBG, { 2, 0, 1 } },
|
|
{ PRIMARY_ORDER_GRB, { 1, 2, 0 } },
|
|
{ PRIMARY_ORDER_GBR, { 0, 2, 1 } },
|
|
{ PRIMARY_ORDER_BGR, { 0, 1, 2 } },
|
|
{ PRIMARY_ORDER_BRG, { 1, 0, 2 } }
|
|
};
|
|
|
|
|
|
#define SRC_BF_HT_RGB 0
|
|
#define SRC_TABLE_BYTE 1
|
|
#define SRC_TABLE_WORD 2
|
|
#define SRC_TABLE_DWORD 3
|
|
|
|
|
|
#if DBG
|
|
|
|
|
|
const LPBYTE pCBFLUTName[] = { "CBFLI_16_MONO",
|
|
"CBFLI_24_MONO",
|
|
"CBFLI_32_MONO",
|
|
"CBFLI_16_COLOR",
|
|
"CBFLI_24_COLOR",
|
|
"CBFLI_32_COLOR" };
|
|
|
|
const LPBYTE pSrcPrimTypeName[] = { "SRC_BF_HT_RGB",
|
|
"SRC_TABLE_BYTE",
|
|
"SRC_TABLE_WORD",
|
|
"SRC_TABLE_DWORD" };
|
|
|
|
const LPBYTE pDbgCSName[] = { "LUV", "LAB" };
|
|
const LPBYTE pDbgCMIName[] = { "TABLE:MONO", "TABLE:COLOR",
|
|
"HT555:MONO", "HT555:COLOR" };
|
|
#endif
|
|
|
|
DWORD dwABPreMul[256] = { 0xFFFFFFFF };
|
|
|
|
|
|
VOID
|
|
GenCMYMaskXlate(
|
|
LPBYTE pbXlate,
|
|
BOOL CMYInverted,
|
|
LONG cC,
|
|
LONG cM,
|
|
LONG cY
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function generate xlate table for 332 format which CMYMask Mode 3-255
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
|
|
|
|
Author:
|
|
|
|
08-Sep-2000 Fri 17:57:02 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
LONG iC;
|
|
LONG iM;
|
|
LONG iY;
|
|
LONG IdxDup;
|
|
LONG Clr;
|
|
LONG MaxC;
|
|
LONG MaxM;
|
|
LONG MaxIdx;
|
|
LONG IdxC;
|
|
LONG IdxM;
|
|
LONG IdxY;
|
|
|
|
|
|
MaxC = (cM + 1) * (cY + 1);
|
|
MaxM = (cY + 1);
|
|
MaxIdx = (cC + 1) * (cM + 1) * (cY + 1);
|
|
|
|
if ((MaxIdx >= 1) && (MaxIdx <= 256) && (CMYInverted)) {
|
|
|
|
if (MaxIdx & 0x01) {
|
|
|
|
IdxDup = MaxIdx / 2;
|
|
++MaxIdx;
|
|
|
|
} else {
|
|
|
|
IdxDup = 0x200;
|
|
}
|
|
|
|
MaxIdx += ((256 - MaxIdx) / 2) - 1;
|
|
|
|
for (iC = 0, IdxC = -MaxC; iC <= 7; iC++) {
|
|
|
|
if (iC <= cC) {
|
|
|
|
IdxC += MaxC;
|
|
}
|
|
|
|
for (iM = 0, IdxM = -MaxM; iM <= 7; iM++) {
|
|
|
|
if (iM <= cM) {
|
|
|
|
IdxM += MaxM;
|
|
}
|
|
|
|
for (iY = 0, IdxY = -1; iY <= 3; iY++) {
|
|
|
|
if (iY <= cY) {
|
|
|
|
++IdxY;
|
|
}
|
|
|
|
if ((Clr = IdxC + IdxM + IdxY) > IdxDup) {
|
|
|
|
++Clr;
|
|
}
|
|
|
|
*pbXlate++ = (BYTE)(MaxIdx - Clr);
|
|
}
|
|
}
|
|
}
|
|
|
|
} else {
|
|
|
|
for (iC = 0; iC < 256; iC++) {
|
|
|
|
*pbXlate++ = (BYTE)iC;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
HTENTRY
|
|
TintAngle(
|
|
LONG TintAdjust,
|
|
LONG AngleStep,
|
|
PFD6 pSin,
|
|
PFD6 pCos
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function return a sin/cos number for the tint adjust, these returned
|
|
numbers are used to rotate the color space.
|
|
|
|
Arguments:
|
|
|
|
TintAdjust - Range from -100 to 100
|
|
|
|
AngleStep - Range from 1 to 10
|
|
|
|
pSin - Pointer to a FD6 number to store the SIN result
|
|
|
|
pCos - Pointer to a FD6 number to store the COS result
|
|
|
|
Return Value:
|
|
|
|
no return value, but the result is stored in pSin/pCos
|
|
|
|
Author:
|
|
|
|
13-Mar-1992 Fri 15:58:30 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
LONG Major;
|
|
LONG Minor;
|
|
BOOL PosSin;
|
|
BOOL PosCos = TRUE;
|
|
FD6 Sin;
|
|
FD6 Cos;
|
|
|
|
|
|
if (PosSin = (BOOL)(TintAdjust <= 0)) {
|
|
|
|
if (!(TintAdjust = (LONG)-TintAdjust)) {
|
|
|
|
*pSin = *pCos = (FD6)0;
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (TintAdjust > 100) {
|
|
|
|
TintAdjust = 100;
|
|
}
|
|
|
|
if ((AngleStep < 1) || (AngleStep > 10)) {
|
|
|
|
AngleStep = 10;
|
|
}
|
|
|
|
if ((TintAdjust *= AngleStep) >= 900) {
|
|
|
|
TintAdjust = 1800L - TintAdjust;
|
|
PosCos = FALSE;
|
|
}
|
|
|
|
//
|
|
// Compute the Sin portion
|
|
//
|
|
|
|
Major = TintAdjust / 10L;
|
|
Minor = TintAdjust % 10L;
|
|
|
|
Sin = SinNumber[Major];
|
|
|
|
if (Minor) {
|
|
|
|
Sin += (FD6)((((LONG)(SinNumber[Major+1] - Sin) * Minor) + 5L) / 10L);
|
|
}
|
|
|
|
*pSin = (PosSin) ? Sin : -Sin;
|
|
|
|
//
|
|
// Compute the cosine portion
|
|
//
|
|
|
|
if (Minor) {
|
|
|
|
Minor = 10 - Minor;
|
|
++Major;
|
|
}
|
|
|
|
Major = 90 - Major;
|
|
|
|
Cos = SinNumber[Major];
|
|
|
|
if (Minor) {
|
|
|
|
Cos += (FD6)((((LONG)(SinNumber[Major+1] - Cos) * Minor) + 5L) / 10L);
|
|
}
|
|
|
|
*pCos = (PosCos) ? Cos : -Cos;
|
|
}
|
|
|
|
|
|
|
|
|
|
#define DO_DEST_GAMMA 1
|
|
#define DO_SS_GAMMA 0
|
|
|
|
|
|
|
|
BOOL
|
|
HTENTRY
|
|
AdjustSrcDevGamma(
|
|
PDEVICECOLORINFO pDCI,
|
|
PPRIMADJ pPrimAdj,
|
|
PHTCOLORADJUSTMENT pca,
|
|
BYTE DestSurfFormat,
|
|
WORD AdjForceFlags
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
|
|
|
|
Author:
|
|
|
|
29-Jan-1997 Wed 12:34:13 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
FD6 SrcGamma[3];
|
|
FD6 DevGamma[3];
|
|
FD6 PelGamma;
|
|
DWORD Flags;
|
|
BOOL Changed;
|
|
|
|
|
|
|
|
Changed = FALSE;
|
|
Flags = 0;
|
|
SrcGamma[0] = DivFD6((FD6)pca->caRedGamma, (FD6)HT_DEF_RGB_GAMMA);
|
|
SrcGamma[1] = DivFD6((FD6)pca->caGreenGamma, (FD6)HT_DEF_RGB_GAMMA);
|
|
SrcGamma[2] = DivFD6((FD6)pca->caBlueGamma, (FD6)HT_DEF_RGB_GAMMA);
|
|
PelGamma = FD6_1;
|
|
pPrimAdj->Flags &= ~DCA_DO_DEVCLR_XFORM;
|
|
|
|
|
|
if (AdjForceFlags & ADJ_FORCE_ICM) {
|
|
|
|
Flags |= DCA_HAS_ICM;
|
|
DevGamma[0] =
|
|
DevGamma[1] =
|
|
DevGamma[2] = FD6_1;
|
|
|
|
//
|
|
// ??? LATER - We may have to turn off ALL gamma correction here
|
|
//
|
|
|
|
DBGP_IF(DBGP_CELLGAMMA, DBGP("--- DCA_HAS_ICM ---"));
|
|
|
|
} else {
|
|
|
|
FD6 GammaMul = FD6_1;
|
|
|
|
|
|
if (pDCI->Flags & DCIF_ADDITIVE_PRIMS) {
|
|
|
|
//
|
|
// Screen Devices
|
|
//
|
|
|
|
switch (DestSurfFormat) {
|
|
|
|
case BMF_1BPP:
|
|
case BMF_4BPP:
|
|
case BMF_4BPP_VGA16:
|
|
|
|
//
|
|
// Since we only have two levels (on/off) we will simulate the
|
|
// 16bpp's darker output
|
|
//
|
|
|
|
DevGamma[0] =
|
|
DevGamma[1] =
|
|
DevGamma[2] = 1325000;
|
|
pca->caReferenceBlack += 550;
|
|
pca->caReferenceWhite -= 300;
|
|
|
|
break;
|
|
|
|
case BMF_8BPP_VGA256:
|
|
|
|
DevGamma[0] =
|
|
DevGamma[1] =
|
|
DevGamma[2] = (FD6)1025000;
|
|
break;
|
|
|
|
case BMF_16BPP_555:
|
|
case BMF_16BPP_565:
|
|
case BMF_24BPP:
|
|
case BMF_32BPP:
|
|
|
|
DevGamma[0] =
|
|
DevGamma[1] =
|
|
DevGamma[2] = (FD6)1000000;
|
|
break;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
} else {
|
|
|
|
FD6 CellSubGamma = GET_REG_GAMMA(pDCI->ClrXFormBlock.RegDataIdx);
|
|
|
|
#if DO_DEST_GAMMA
|
|
CopyMemory(DevGamma, pDCI->ClrXFormBlock.DevGamma, sizeof(DevGamma));
|
|
#else
|
|
SrcGamma[0] = MulFD6(SrcGamma[0], pDCI->ClrXFormBlock.DevGamma[0]);
|
|
SrcGamma[1] = MulFD6(SrcGamma[1], pDCI->ClrXFormBlock.DevGamma[1]);
|
|
SrcGamma[2] = MulFD6(SrcGamma[2], pDCI->ClrXFormBlock.DevGamma[2]);
|
|
DevGamma[0] =
|
|
DevGamma[1] =
|
|
DevGamma[2] = FD6_1;
|
|
#endif
|
|
//
|
|
// Printer Devices
|
|
//
|
|
|
|
pPrimAdj->Flags |= DCA_DO_DEVCLR_XFORM;
|
|
|
|
if (pDCI->HTCell.HTPatIdx <= HTPAT_SIZE_16x16_M) {
|
|
|
|
GammaMul = FD6_1 +
|
|
FD6xL(((pDCI->HTCell.HTPatIdx >> 1) + 1), 25000);
|
|
|
|
if (DestSurfFormat == BMF_1BPP) {
|
|
|
|
DBGP_IF(DBGP_CELLGAMMA,
|
|
DBGP("1BPP: HTPatIdx=%ld, GammaMul=%s --> %s"
|
|
ARGDW(pDCI->HTCell.HTPatIdx)
|
|
ARGFD6(GammaMul, 1, 6)
|
|
ARGFD6(MulFD6(GammaMul, 1125000), 1, 6)));
|
|
|
|
GammaMul = MulFD6(GammaMul, 1125000);
|
|
}
|
|
}
|
|
|
|
if (pDCI->DevPelRatio > FD6_1) {
|
|
|
|
PelGamma = DivFD6(-477121,
|
|
Log(DivFD6(333333, pDCI->DevPelRatio)));
|
|
|
|
} else if (pDCI->DevPelRatio < FD6_1) {
|
|
|
|
PelGamma = DivFD6(Log(pDCI->DevPelRatio / 3), -477121);
|
|
}
|
|
|
|
switch (DestSurfFormat) {
|
|
|
|
case BMF_1BPP:
|
|
case BMF_4BPP:
|
|
case BMF_4BPP_VGA16:
|
|
|
|
break;
|
|
|
|
case BMF_8BPP_VGA256:
|
|
|
|
if ((pDCI->Flags & (DCIF_USE_8BPP_BITMASK |
|
|
DCIF_MONO_8BPP_BITMASK)) ==
|
|
DCIF_USE_8BPP_BITMASK) {
|
|
|
|
DBGP_IF(DBGP_CELLGAMMA,
|
|
DBGP("Mask 8BPP, Reset PelGamma=FD6_1, CellSubGamma=%s --> %s"
|
|
ARGFD6(CellSubGamma, 1, 6)
|
|
ARGFD6(DivFD6(CellSubGamma, MASK8BPP_GAMMA_DIV), 1, 6)));
|
|
|
|
CellSubGamma = DivFD6(CellSubGamma, MASK8BPP_GAMMA_DIV);
|
|
PelGamma = FD6_1;
|
|
}
|
|
|
|
break;
|
|
|
|
case BMF_16BPP_555:
|
|
case BMF_16BPP_565:
|
|
case BMF_24BPP:
|
|
case BMF_32BPP:
|
|
|
|
if (!(pDCI->Flags & DCIF_DO_DEVCLR_XFORM)) {
|
|
|
|
pPrimAdj->Flags &= ~DCA_DO_DEVCLR_XFORM;
|
|
CellSubGamma = FD6_1;
|
|
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
DBGP_IF(DBGP_CELLGAMMA,
|
|
DBGP("Res=%ldx%ld, , PelRatio=%s, PelGamma=%s"
|
|
ARGDW(pDCI->DeviceResXDPI) ARGDW(pDCI->DeviceResYDPI)
|
|
ARGFD6(pDCI->DevPelRatio, 1, 6) ARGFD6(PelGamma, 1, 6)));
|
|
|
|
DBGP_IF(DBGP_CELLGAMMA,
|
|
DBGP("HTPatIdx=%ld, CellSubGamma=%s, SUB GammaMul=%s"
|
|
ARGDW(pDCI->HTCell.HTPatIdx)
|
|
ARGFD6(CellSubGamma, 1, 6)
|
|
ARGFD6(GammaMul, 1, 6)));
|
|
|
|
GammaMul = MulFD6(GammaMul, CellSubGamma);
|
|
|
|
#if DO_SS_GAMMA
|
|
if (pDCI->Flags & (DCIF_SUPERCELL | DCIF_SUPERCELL_M)) {
|
|
|
|
DBGP_IF(DBGP_CELLGAMMA,
|
|
DBGP("SM: Gamma: %s:%s:%s --> %s:%s:%s"
|
|
ARGFD6(SrcGamma[0], 1, 6)
|
|
ARGFD6(SrcGamma[1], 1, 6)
|
|
ARGFD6(SrcGamma[2], 1, 6)
|
|
ARGFD6(MulFD6(SrcGamma[0], SCM_R_GAMMA_MUL), 1, 6)
|
|
ARGFD6(MulFD6(SrcGamma[1], SCM_G_GAMMA_MUL), 1, 6)
|
|
ARGFD6(MulFD6(SrcGamma[2], SCM_B_GAMMA_MUL), 1, 6)));
|
|
|
|
SrcGamma[0] = MulFD6(SrcGamma[0], SCM_R_GAMMA_MUL);
|
|
SrcGamma[1] = MulFD6(SrcGamma[1], SCM_G_GAMMA_MUL);
|
|
SrcGamma[2] = MulFD6(SrcGamma[2], SCM_B_GAMMA_MUL);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
SrcGamma[0] = MulFD6(SrcGamma[0], GammaMul);
|
|
SrcGamma[1] = MulFD6(SrcGamma[1], GammaMul);
|
|
SrcGamma[2] = MulFD6(SrcGamma[2], GammaMul);
|
|
|
|
DBGP_IF(DBGP_CELLGAMMA,
|
|
DBGP("Gamma: Src=%s:%s:%s, Dev=%s:%s:%s, Pel=%s, Mul=%s"
|
|
ARGFD6(SrcGamma[0], 1, 6)
|
|
ARGFD6(SrcGamma[1], 1, 6)
|
|
ARGFD6(SrcGamma[2], 1, 6)
|
|
ARGFD6(DevGamma[0], 1, 6)
|
|
ARGFD6(DevGamma[1], 1, 6)
|
|
ARGFD6(DevGamma[2], 1, 6)
|
|
ARGFD6(PelGamma, 1, 6)
|
|
ARGFD6(GammaMul, 1, 6)));
|
|
|
|
DBGP_IF(DBGP_CELLGAMMA,
|
|
DBGP("Source Gamma=%s:%s:%s, PelGamma=%s"
|
|
ARGFD6(SrcGamma[0], 1, 6) ARGFD6(SrcGamma[1], 1, 6)
|
|
ARGFD6(SrcGamma[2], 1, 6) ARGFD6(PelGamma, 1, 6)));
|
|
|
|
if (PelGamma != FD6_1) {
|
|
|
|
DevGamma[0] = MulFD6(DevGamma[0], PelGamma);
|
|
DevGamma[1] = MulFD6(DevGamma[1], PelGamma);
|
|
DevGamma[2] = MulFD6(DevGamma[2], PelGamma);
|
|
|
|
DBGP_IF(DBGP_CELLGAMMA,
|
|
DBGP("DevGamma=%s:%s:%s, PelGamma=%s"
|
|
ARGFD6(DevGamma[0], 1, 6) ARGFD6(DevGamma[1], 1, 6)
|
|
ARGFD6(DevGamma[2], 1, 6) ARGFD6(PelGamma, 1, 6)));
|
|
}
|
|
}
|
|
|
|
if ((SrcGamma[0] != FD6_1) ||
|
|
(SrcGamma[1] != FD6_1) ||
|
|
(SrcGamma[2] != FD6_1)) {
|
|
|
|
Flags |= DCA_HAS_SRC_GAMMA;
|
|
|
|
DBGP_IF(DBGP_CELLGAMMA,
|
|
DBGP("--- DCA_HAS_SRC_GAMMA --- %s:%s:%s [%s]"
|
|
ARGFD6(SrcGamma[0], 1, 6)
|
|
ARGFD6(SrcGamma[1], 1, 6)
|
|
ARGFD6(SrcGamma[2], 1, 6)
|
|
ARGFD6(MulFD6(SrcGamma[0], (FD6)2200000), 1, 6)));
|
|
}
|
|
|
|
if ((SrcGamma[0] != pPrimAdj->SrcGamma[0]) ||
|
|
(SrcGamma[1] != pPrimAdj->SrcGamma[1]) ||
|
|
(SrcGamma[2] != pPrimAdj->SrcGamma[2])) {
|
|
|
|
CopyMemory(pPrimAdj->SrcGamma, SrcGamma, sizeof(SrcGamma));
|
|
Changed = TRUE;
|
|
}
|
|
|
|
if ((DevGamma[0] != FD6_1) ||
|
|
(DevGamma[1] != FD6_1) ||
|
|
(DevGamma[2] != FD6_1)) {
|
|
|
|
Flags |= DCA_HAS_DEST_GAMMA;
|
|
|
|
DBGP_IF(DBGP_CELLGAMMA,
|
|
DBGP("--- DCA_HAS_DEST_GAMMA --- %s:%s:%s"
|
|
ARGFD6(DevGamma[0], 1, 6)
|
|
ARGFD6(DevGamma[1], 1, 6)
|
|
ARGFD6(DevGamma[2], 1, 6)));
|
|
}
|
|
|
|
if ((DevGamma[0] != pPrimAdj->DevGamma[0]) ||
|
|
(DevGamma[1] != pPrimAdj->DevGamma[1]) ||
|
|
(DevGamma[2] != pPrimAdj->DevGamma[2])) {
|
|
|
|
CopyMemory(pPrimAdj->DevGamma, DevGamma, sizeof(DevGamma));
|
|
|
|
Changed = TRUE;
|
|
}
|
|
|
|
if ((pPrimAdj->Flags & (DCA_HAS_ICM |
|
|
DCA_HAS_SRC_GAMMA |
|
|
DCA_HAS_DEST_GAMMA)) != Flags) {
|
|
|
|
Changed = TRUE;
|
|
}
|
|
|
|
if (Changed) {
|
|
|
|
pPrimAdj->Flags = (pPrimAdj->Flags & ~(DCA_HAS_ICM |
|
|
DCA_HAS_SRC_GAMMA |
|
|
DCA_HAS_DEST_GAMMA)) | Flags;
|
|
}
|
|
|
|
return(Changed);
|
|
}
|
|
|
|
|
|
|
|
PDEVICECOLORINFO
|
|
HTENTRY
|
|
pDCIAdjClr(
|
|
PDEVICEHALFTONEINFO pDeviceHalftoneInfo,
|
|
PHTCOLORADJUSTMENT pHTColorAdjustment,
|
|
PDEVCLRADJ *ppDevClrAdj,
|
|
DWORD cbAlloc,
|
|
WORD ForceFlags,
|
|
CTSTDINFO CTSTDInfo,
|
|
PLONG pError
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function allowed the caller to changed the overall color adjustment
|
|
for all the pictures rendered
|
|
|
|
Arguments:
|
|
|
|
pDeviceHalftoneInfo - Pointer to the DEVICEHALFTONEINFO data structure
|
|
which returned from the HT_CreateDeviceHalftoneInfo.
|
|
|
|
pHTColorAdjustment - Pointer to the HTCOLORADJUSTMENT data structure, if
|
|
this pointer is NULL then a default is applied.
|
|
|
|
ppDevClrAdj - Pointer to pointer to the DEVCLRADJ data structure
|
|
where the computed results will be stored, if this
|
|
pointer isNULL then no color adjustment is done.
|
|
|
|
if pSrcSI and ppDevClrAdj are not NULL then
|
|
*ppDevClrAdj->Flags must contains the BBPFlags;
|
|
|
|
ForceFlags - Force flags to make color changed.
|
|
|
|
Return Value:
|
|
|
|
PDEVICECOLORINFO, if return is NULL then a invalid pDeviceHalftoneInfo
|
|
pointer is passed.
|
|
|
|
Author:
|
|
|
|
29-May-1991 Wed 09:11:31 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
PDEVICECOLORINFO pDCI;
|
|
|
|
|
|
if ((!pDeviceHalftoneInfo) ||
|
|
(PHT_DHI_DCI_OF(HalftoneDLLID) != HALFTONE_DLL_ID)) {
|
|
|
|
*pError = HTERR_INVALID_DHI_POINTER;
|
|
|
|
return(NULL);
|
|
}
|
|
|
|
pDCI = PDHI_TO_PDCI(pDeviceHalftoneInfo);
|
|
|
|
//
|
|
// Lock For this DCI
|
|
//
|
|
|
|
ACQUIRE_HTMUTEX(pDCI->HTMutex);
|
|
|
|
//
|
|
// Only if caller required color adjustments computations, then we will
|
|
// compute for it.
|
|
//
|
|
|
|
if (ppDevClrAdj) {
|
|
|
|
PDEVCLRADJ pDevClrAdj;
|
|
PCIEPRIMS pDevPrims;
|
|
PRGBLUTAA prgbLUT;
|
|
HTCOLORADJUSTMENT ca;
|
|
HTCOLORADJUSTMENT caCached;
|
|
DEVMAPINFO DMI;
|
|
DWORD LUTAAHdr[LUTAA_HDR_COUNT];
|
|
PRIMADJ PrimAdj;
|
|
DWORD DCIFlags;
|
|
|
|
|
|
if ((ForceFlags & ADJ_FORCE_AB_PREMUL_SRC) &&
|
|
(dwABPreMul[0])) {
|
|
|
|
DWORD i;
|
|
|
|
//
|
|
// Generate a ABPreMul[] so that we can multiply it and get the
|
|
// original pre-mul source value
|
|
//
|
|
|
|
dwABPreMul[0] = 0;
|
|
|
|
for (i = 1; i < 256; i++) {
|
|
|
|
dwABPreMul[i] = (DWORD)((0xFF000000 + (i - 1)) / i);
|
|
}
|
|
}
|
|
|
|
if (!(*ppDevClrAdj = pDevClrAdj =
|
|
(PDEVCLRADJ)HTAllocMem((LPVOID)pDCI,
|
|
HTMEM_DevClrAdj,
|
|
LPTR,
|
|
cbAlloc + sizeof(DEVCLRADJ)))) {
|
|
|
|
*pError = HTERR_INSUFFICIENT_MEMORY;
|
|
|
|
//================================================================
|
|
// Release SEMAPHORE NOW, since we are failing the memory request
|
|
//================================================================
|
|
|
|
RELEASE_HTMUTEX(pDCI->HTMutex);
|
|
|
|
return(NULL);
|
|
}
|
|
|
|
//
|
|
// Force the ICM on
|
|
//
|
|
|
|
if ((DCIFlags = pDCI->Flags) & DCIF_FORCE_ICM) {
|
|
|
|
ForceFlags |= ADJ_FORCE_ICM;
|
|
}
|
|
|
|
//
|
|
// Force gray scale
|
|
//
|
|
|
|
DMI.CTSTDInfo = CTSTDInfo;
|
|
|
|
if ((DMI.CTSTDInfo.BMFDest == BMF_1BPP) ||
|
|
((DMI.CTSTDInfo.BMFDest == BMF_8BPP_VGA256) &&
|
|
((DCIFlags & (DCIF_USE_8BPP_BITMASK | DCIF_MONO_8BPP_BITMASK)) ==
|
|
(DCIF_USE_8BPP_BITMASK | DCIF_MONO_8BPP_BITMASK)))) {
|
|
|
|
ForceFlags |= (ADJ_FORCE_MONO | ADJ_FORCE_IDXBGR_MONO);
|
|
}
|
|
|
|
prgbLUT = (ForceFlags & ADJ_FORCE_BRUSH) ? &pDCI->rgbLUTPat :
|
|
&pDCI->rgbLUT;
|
|
|
|
if (ForceFlags & ADJ_FORCE_ICM) {
|
|
|
|
//
|
|
// These two does not mix
|
|
//
|
|
|
|
ForceFlags &= ~ADJ_FORCE_BRUSH;
|
|
}
|
|
|
|
//=====================================================================
|
|
// We must make sure only one thread using this info.
|
|
//=====================================================================
|
|
|
|
ca = (pHTColorAdjustment) ? *pHTColorAdjustment :
|
|
pDeviceHalftoneInfo->HTColorAdjustment;
|
|
|
|
if ((ca.caSize != sizeof(HTCOLORADJUSTMENT)) ||
|
|
(ca.caFlags & ~(CLRADJF_FLAGS_MASK))) {
|
|
|
|
ca = DefaultCA;
|
|
}
|
|
|
|
caCached = pDCI->ca;
|
|
PrimAdj = pDCI->PrimAdj;
|
|
|
|
|
|
//
|
|
// Now validate all color adjustments
|
|
//
|
|
|
|
ca.caFlags &= CLRADJF_FLAGS_MASK;
|
|
|
|
if (ca.caIlluminantIndex > ILLUMINANT_MAX_INDEX) {
|
|
|
|
ca.caIlluminantIndex = DefaultCA.caIlluminantIndex;
|
|
}
|
|
|
|
ADJ_CA(ca.caRedGamma, RGB_GAMMA_MIN, RGB_GAMMA_MAX);
|
|
ADJ_CA(ca.caGreenGamma, RGB_GAMMA_MIN, RGB_GAMMA_MAX);
|
|
ADJ_CA(ca.caBlueGamma, RGB_GAMMA_MIN, RGB_GAMMA_MAX);
|
|
ADJ_CA(ca.caReferenceBlack, 0, REFERENCE_BLACK_MAX);
|
|
ADJ_CA(ca.caReferenceWhite, REFERENCE_WHITE_MIN, 10000);
|
|
ADJ_CA(ca.caContrast, MIN_COLOR_ADJ, MAX_COLOR_ADJ);
|
|
ADJ_CA(ca.caBrightness, MIN_COLOR_ADJ, MAX_COLOR_ADJ);
|
|
ADJ_CA(ca.caColorfulness, MIN_COLOR_ADJ, MAX_COLOR_ADJ);
|
|
ADJ_CA(ca.caRedGreenTint, MIN_COLOR_ADJ, MAX_COLOR_ADJ);
|
|
|
|
if ((ForceFlags & ADJ_FORCE_MONO) ||
|
|
(ca.caColorfulness == MIN_COLOR_ADJ)) {
|
|
|
|
ca.caColorfulness = MIN_COLOR_ADJ;
|
|
ca.caRedGreenTint = 0;
|
|
}
|
|
|
|
if (ForceFlags & ADJ_FORCE_NEGATIVE) {
|
|
|
|
ca.caFlags |= CLRADJF_NEGATIVE;
|
|
}
|
|
|
|
ca.caSize = (WORD)(ForceFlags & (ADJ_FORCE_DEVXFORM |
|
|
ADJ_FORCE_BRUSH |
|
|
ADJ_FORCE_MONO |
|
|
ADJ_FORCE_IDXBGR_MONO |
|
|
ADJ_FORCE_ICM));
|
|
|
|
if ((AdjustSrcDevGamma(pDCI,
|
|
&PrimAdj,
|
|
&ca,
|
|
DMI.CTSTDInfo.BMFDest,
|
|
ForceFlags)) ||
|
|
(!COMP_CA(&ca, &caCached))){
|
|
|
|
DBGP_IF(DBGP_HCA,
|
|
DBGP("---- New Color Adjustments --%08lx---" ARGDW(ca.caSize));
|
|
DBGP("Flags = %08x" ARGDW(ca.caFlags));
|
|
DBGP("Illum = %d" ARGW(ca.caIlluminantIndex));
|
|
DBGP("R_Power = %u" ARGI(ca.caRedGamma));
|
|
DBGP("G_Power = %u" ARGI(ca.caGreenGamma));
|
|
DBGP("B_Power = %u" ARGI(ca.caBlueGamma));
|
|
DBGP("BlackRef = %u" ARGW(ca.caReferenceBlack));
|
|
DBGP("WhiteRef = %u" ARGW(ca.caReferenceWhite));
|
|
DBGP("Contrast = %d" ARGI(ca.caContrast));
|
|
DBGP("Bright = %d" ARGI(ca.caBrightness));
|
|
DBGP("Colorful = %d" ARGI(ca.caColorfulness));
|
|
DBGP("RG_Tint = %d" ARGI(ca.caRedGreenTint));
|
|
DBGP("ForceAdj = %04lx" ARGDW(ForceFlags)));
|
|
|
|
PrimAdj.Flags &= (DCA_HAS_ICM |
|
|
DCA_DO_DEVCLR_XFORM |
|
|
DCA_HAS_SRC_GAMMA |
|
|
DCA_HAS_DEST_GAMMA);
|
|
|
|
if (ForceFlags & ADJ_FORCE_IDXBGR_MONO) {
|
|
|
|
PrimAdj.Flags |= DCA_MONO_ONLY;
|
|
|
|
DBGP_IF(DBGP_HCA, DBGP("---DCA_MONO_ONLY---"));
|
|
|
|
}
|
|
|
|
if (ca.caFlags & CLRADJF_LOG_FILTER) {
|
|
|
|
if (!LogFilterMax) {
|
|
|
|
LogFilterMax = PRIM_LOG_RATIO(FD6_1);
|
|
}
|
|
|
|
PrimAdj.Flags |= DCA_LOG_FILTER;
|
|
|
|
DBGP_IF(DBGP_HCA, DBGP("---DCA_LOG_FILTER---"));
|
|
}
|
|
|
|
if (ca.caFlags & CLRADJF_NEGATIVE) {
|
|
|
|
PrimAdj.Flags |= DCA_NEGATIVE;
|
|
|
|
DBGP_IF(DBGP_HCA, DBGP("---DCA_NEGATIVE---"));
|
|
}
|
|
|
|
pDevPrims = (PrimAdj.Flags & DCA_HAS_ICM) ?
|
|
&(pDCI->ClrXFormBlock.rgbCIEPrims) :
|
|
&(pDCI->ClrXFormBlock.DevCIEPrims);
|
|
|
|
if ((ca.caSize & (ADJ_FORCE_ICM | ADJ_FORCE_DEVXFORM)) !=
|
|
(caCached.caSize & (ADJ_FORCE_ICM | ADJ_FORCE_DEVXFORM))) {
|
|
|
|
//
|
|
// Re-Compute Device RGB xfrom matrix
|
|
//
|
|
|
|
DBGP_IF(DBGP_CCT,
|
|
DBGP("\n*** ComputeColorSpaceForm(%hs_XFORM) ***\n"
|
|
ARGPTR((PrimAdj.Flags & DCA_HAS_ICM) ?
|
|
"ICM" : "DEVICE")));
|
|
|
|
ComputeColorSpaceXForm(pDCI,
|
|
pDevPrims,
|
|
&(PrimAdj.DevCSXForm),
|
|
-1);
|
|
}
|
|
|
|
if (ca.caIlluminantIndex != caCached.caIlluminantIndex) {
|
|
|
|
DBGP_IF(DBGP_CCT,
|
|
DBGP("*** ComputeColorSpaceForm(RGB_XFORM Illuminant=%u) ***"
|
|
ARGU(ca.caIlluminantIndex)));
|
|
|
|
ComputeColorSpaceXForm(pDCI,
|
|
&(pDCI->ClrXFormBlock.rgbCIEPrims),
|
|
&(PrimAdj.rgbCSXForm),
|
|
(INT)ca.caIlluminantIndex);
|
|
}
|
|
|
|
if ((PrimAdj.Flags & DCA_MONO_ONLY) ||
|
|
(CompareMemory((LPBYTE)pDevPrims,
|
|
(LPBYTE)&(pDCI->ClrXFormBlock.rgbCIEPrims),
|
|
sizeof(CIEPRIMS)))) {
|
|
|
|
PrimAdj.Flags &= ~DCA_HAS_CLRSPACE_ADJ;
|
|
|
|
} else {
|
|
|
|
PrimAdj.Flags |= DCA_HAS_CLRSPACE_ADJ;
|
|
}
|
|
|
|
PrimAdj.MinL = UDECI4ToFD6(ca.caReferenceBlack) + HT_K_REF_ADD;
|
|
PrimAdj.MaxL = UDECI4ToFD6(ca.caReferenceWhite) - HT_W_REF_SUB;
|
|
|
|
if ((PrimAdj.MinL != HT_K_REF_BASE) ||
|
|
(PrimAdj.MaxL != HT_W_REF_BASE)) {
|
|
|
|
PrimAdj.Flags |= DCA_HAS_BW_REF_ADJ;
|
|
PrimAdj.MinLMul = DivFD6(HT_K_REF_CLIP, PrimAdj.MinL);
|
|
PrimAdj.MaxLMul = DivFD6(HT_W_REF_CLIP,
|
|
FD6_1 - PrimAdj.MaxL);
|
|
PrimAdj.RangeLMul = DivFD6(HT_KW_REF_RANGE,
|
|
PrimAdj.MaxL - PrimAdj.MinL);
|
|
|
|
DBGP_IF(DBGP_HCA,
|
|
DBGP("--- DCA_HAS_BW_REF_ADJ %s to %s, xK=%s, xW=%s, xRange=%s ---"
|
|
ARGFD6(PrimAdj.MinL, 1, 6)
|
|
ARGFD6(PrimAdj.MaxL, 1, 6)
|
|
ARGFD6(PrimAdj.MinLMul, 1, 6)
|
|
ARGFD6(PrimAdj.MaxLMul, 1, 6)
|
|
ARGFD6(PrimAdj.RangeLMul, 1, 6)));
|
|
|
|
} else {
|
|
|
|
PrimAdj.Flags &= ~DCA_HAS_BW_REF_ADJ;
|
|
PrimAdj.MinL = FD6_0;
|
|
PrimAdj.MaxL = FD6_1;
|
|
PrimAdj.MinLMul =
|
|
PrimAdj.MaxLMul =
|
|
PrimAdj.RangeLMul = FD6_0;
|
|
}
|
|
|
|
if (ca.caContrast) {
|
|
|
|
PrimAdj.Contrast = JND_ADJ((FD6)1015000, ca.caContrast);
|
|
PrimAdj.Flags |= DCA_HAS_CONTRAST_ADJ;
|
|
|
|
DBGP_IF(DBGP_HCA,
|
|
DBGP("--- DCA_HAS_CONTRAST_ADJ = %s ---"
|
|
ARGFD6(PrimAdj.Contrast, 1, 6)));
|
|
}
|
|
|
|
if (ca.caBrightness) {
|
|
|
|
PrimAdj.Brightness = FD6xL((FD6)3750, ca.caBrightness);
|
|
PrimAdj.Flags |= DCA_HAS_BRIGHTNESS_ADJ;
|
|
|
|
DBGP_IF(DBGP_HCA,
|
|
DBGP("--- DCA_HAS_BRIGHTNESS_ADJ = %s ---"
|
|
ARGFD6(PrimAdj.Brightness, 1, 6)));
|
|
}
|
|
|
|
//
|
|
// Colorfulness, RedGreenTint, and DYE_CORRECTIONS only valid and
|
|
// necessary if it a color device output
|
|
//
|
|
|
|
if (!(PrimAdj.Flags & DCA_MONO_ONLY)) {
|
|
|
|
PrimAdj.Color = (FD6)(ca.caColorfulness + MAX_COLOR_ADJ);
|
|
|
|
// if (ca.caSize & ADJ_FORCE_BRUSH) {
|
|
//
|
|
// PrimAdj.Color += HT_BRUSH_COLORFULNESS;
|
|
// }
|
|
|
|
if ((PrimAdj.Color *= 10000) != FD6_1) {
|
|
|
|
PrimAdj.Flags |= DCA_HAS_COLOR_ADJ;
|
|
|
|
DBGP_IF(DBGP_HCA,
|
|
DBGP("--- DCA_HAS_COLOR_ADJ = %s ---"
|
|
ARGFD6(PrimAdj.Color, 1, 6)));
|
|
}
|
|
|
|
if (ca.caRedGreenTint) {
|
|
|
|
TintAngle((LONG)ca.caRedGreenTint,
|
|
(LONG)6,
|
|
(PFD6)&(PrimAdj.TintSinAngle),
|
|
(PFD6)&(PrimAdj.TintCosAngle));
|
|
|
|
PrimAdj.Flags |= DCA_HAS_TINT_ADJ;
|
|
|
|
DBGP_IF(DBGP_HCA,
|
|
DBGP("--- DCA_HAS_TINT_ADJ Sin=%s, Cos=%s ---"
|
|
ARGFD6(PrimAdj.TintSinAngle, 1, 6)
|
|
ARGFD6(PrimAdj.TintCosAngle, 1, 6)));
|
|
}
|
|
|
|
if ((DCIFlags & DCIF_NEED_DYES_CORRECTION) &&
|
|
((PrimAdj.Flags & (DCA_HAS_ICM | DCA_DO_DEVCLR_XFORM)) ==
|
|
DCA_DO_DEVCLR_XFORM)) {
|
|
|
|
PrimAdj.Flags |= DCA_NEED_DYES_CORRECTION;
|
|
|
|
DBGP_IF(DBGP_HCA, DBGP("---DCA_NEED_DYES_CORRECTION---"));
|
|
|
|
if (DCIFlags & DCIF_HAS_BLACK_DYE) {
|
|
|
|
PrimAdj.Flags |= DCA_HAS_BLACK_DYE;
|
|
|
|
DBGP_IF(DBGP_HCA, DBGP("---DCA_HAS_BLACK_DYE---"));
|
|
}
|
|
}
|
|
}
|
|
|
|
DBGP_IF(DBGP_CCT,
|
|
DBGP("** Save PrimAdj back to pDCI, Flags=%08lx **"
|
|
ARGDW(PrimAdj.Flags)));
|
|
|
|
pDCI->ca = ca;
|
|
pDCI->PrimAdj = PrimAdj;
|
|
|
|
} else {
|
|
|
|
DBGP_IF(DBGP_CCT, DBGP("* Use cached HTCOLORADJUSTMENT *"));
|
|
}
|
|
|
|
//
|
|
// These flags are always computed per call, so turn it off first
|
|
//
|
|
|
|
PrimAdj.Flags &= ~(DCA_NO_ANY_ADJ |
|
|
DCA_NO_MAPPING_TABLE |
|
|
DCA_MASK8BPP |
|
|
DCA_BBPF_AA_OFF |
|
|
DCA_USE_ADDITIVE_PRIMS |
|
|
DCA_XLATE_555_666 |
|
|
DCA_XLATE_332 |
|
|
DCA_REPLACE_BLACK);
|
|
|
|
if (!(PrimAdj.Flags & (DCA_NEED_DYES_CORRECTION |
|
|
DCA_HAS_CLRSPACE_ADJ |
|
|
DCA_HAS_SRC_GAMMA |
|
|
DCA_HAS_BW_REF_ADJ |
|
|
DCA_HAS_CONTRAST_ADJ |
|
|
DCA_HAS_BRIGHTNESS_ADJ |
|
|
DCA_HAS_COLOR_ADJ |
|
|
DCA_HAS_TINT_ADJ |
|
|
DCA_LOG_FILTER |
|
|
DCA_NEGATIVE |
|
|
DCA_DO_DEVCLR_XFORM |
|
|
DCA_HAS_DEST_GAMMA))) {
|
|
|
|
PrimAdj.Flags |= DCA_NO_ANY_ADJ;
|
|
|
|
DBGP_IF(DBGP_HCA, DBGP("---DCA_NO_ANY_ADJ---"));
|
|
}
|
|
|
|
if ((PrimAdj.Flags & DCA_MONO_ONLY) ||
|
|
(!(PrimAdj.Flags & (DCA_NEED_DYES_CORRECTION |
|
|
DCA_HAS_CLRSPACE_ADJ |
|
|
DCA_HAS_COLOR_ADJ |
|
|
DCA_HAS_TINT_ADJ)))) {
|
|
|
|
PrimAdj.Flags |= DCA_NO_MAPPING_TABLE;
|
|
|
|
DBGP_IF(DBGP_HCA, DBGP("---DCA_NO_MAPPING_TABLE---"));
|
|
}
|
|
|
|
if ((DCIFlags & DCIF_PRINT_DRAFT_MODE) ||
|
|
(ForceFlags & ADJ_FORCE_NO_EXP_AA)) {
|
|
|
|
PrimAdj.Flags |= DCA_BBPF_AA_OFF;
|
|
|
|
DBGP_IF(DBGP_HCA, DBGP("---DCA_BBPF_AA_OFF---"));
|
|
}
|
|
|
|
if (ForceFlags & ADJ_FORCE_ALPHA_BLEND) {
|
|
|
|
PrimAdj.Flags |= DCA_ALPHA_BLEND;
|
|
|
|
DBGP_IF(DBGP_HCA, DBGP("---DCA_ALPHA_BLEND---"));
|
|
|
|
if (ForceFlags & ADJ_FORCE_CONST_ALPHA) {
|
|
|
|
PrimAdj.Flags |= DCA_CONST_ALPHA;
|
|
|
|
DBGP_IF(DBGP_HCA, DBGP("---DCA_CONST_ALPHA---"));
|
|
|
|
} else {
|
|
|
|
if (ForceFlags & ADJ_FORCE_AB_PREMUL_SRC) {
|
|
|
|
DBGP_IF(DBGP_HCA, DBGP("---DCA_AB_PREMUL_SRC---"));
|
|
|
|
PrimAdj.Flags |= DCA_AB_PREMUL_SRC;
|
|
}
|
|
|
|
if (ForceFlags & ADJ_FORCE_AB_DEST) {
|
|
|
|
DBGP_IF(DBGP_HCA, DBGP("---DCA_AB_DEST---"));
|
|
|
|
PrimAdj.Flags |= DCA_AB_DEST;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Since we do substractive prims at output time, we need to re-set
|
|
// this flag evertime the pDCIAdjClr called.
|
|
//
|
|
|
|
if (ForceFlags & ADJ_FORCE_ADDITIVE_PRIMS) {
|
|
|
|
PrimAdj.Flags |= DCA_USE_ADDITIVE_PRIMS;
|
|
|
|
DBGP_IF(DBGP_HCA, DBGP("---DCA_USE_ADDITIVE_PRIMS---"));
|
|
}
|
|
|
|
//
|
|
// All following is first set in RGB order wehre B is lowest memory
|
|
// location (0) and R is in highest memory location (2), see
|
|
// DstOrderTable[], so the index 0=B, 1=G. 2=R
|
|
//
|
|
// LUTAAHdr[]: DWORD Masking for the destination in BGR order
|
|
// Mul[]: Multiply factor when makeing RGBLUTAA table
|
|
// MulAdd: Addition amount after Mul
|
|
// LSft: Left shift amount after Mul/MulAdd
|
|
//
|
|
|
|
ZeroMemory(LUTAAHdr, sizeof(LUTAAHdr));
|
|
|
|
DMI.BlackChk = FD6_1;
|
|
DMI.Flags = 0;
|
|
DMI.LSft[0] =
|
|
DMI.LSft[1] =
|
|
DMI.LSft[2] = 4;
|
|
DMI.CTSTDInfo.cbPrim = sizeof(BGR8);
|
|
|
|
if (PrimAdj.Flags & DCA_MONO_ONLY) {
|
|
|
|
PrimAdj.Flags |= DCA_RGBLUTAA_MONO;
|
|
DMI.Flags |= DMIF_GRAY;
|
|
DMI.Mul[0] =
|
|
DMI.Mul[1] =
|
|
DMI.Mul[2] = GRAY_MAX_IDX;
|
|
DMI.MulAdd = 0;
|
|
|
|
} else {
|
|
|
|
DMI.MulAdd = 0x1000;
|
|
DMI.Mul[0] =
|
|
DMI.Mul[1] =
|
|
DMI.Mul[2] = DMI.MulAdd - 1;
|
|
}
|
|
|
|
switch (DMI.CTSTDInfo.BMFDest) {
|
|
|
|
case BMF_1BPP:
|
|
|
|
//
|
|
// PRIMARY_ORDER_RGB (Always)
|
|
//
|
|
// NOT APPLICABLE
|
|
//
|
|
|
|
ASSERT(DMI.Flags & DMIF_GRAY);
|
|
|
|
DMI.CTSTDInfo.DestOrder = PRIMARY_ORDER_RGB;
|
|
|
|
break;
|
|
|
|
case BMF_4BPP_VGA16:
|
|
|
|
//
|
|
// PRIMARY_ORDER_BGR
|
|
// |||
|
|
// ||+-- bit 0/4
|
|
// ||
|
|
// |+--- bit 1/5
|
|
// |
|
|
// +---- bit 2/7
|
|
//
|
|
//
|
|
|
|
PrimAdj.Flags |= DCA_USE_ADDITIVE_PRIMS;
|
|
DMI.CTSTDInfo.DestOrder = PRIMARY_ORDER_BGR;
|
|
|
|
//
|
|
// Fall through for same as BMF_4BPP
|
|
//
|
|
|
|
case BMF_4BPP:
|
|
|
|
//
|
|
// PRIMARY_ORDER_abc
|
|
// |||
|
|
// ||+-- bit 0/4
|
|
// ||
|
|
// |+--- bit 1/5
|
|
// |
|
|
// +---- bit 2/7
|
|
//
|
|
//
|
|
|
|
LUTAAHdr[0] = 0x100000;
|
|
LUTAAHdr[1] = 0x200000;
|
|
LUTAAHdr[2] = 0x400000;
|
|
LUTAAHdr[3] = 0x010000;
|
|
LUTAAHdr[4] = 0x020000;
|
|
LUTAAHdr[5] = 0x040000;
|
|
DMI.LSft[0] = 4;
|
|
DMI.LSft[1] = 5;
|
|
DMI.LSft[2] = 6;
|
|
DMI.MulAdd = 0x0;
|
|
|
|
break;
|
|
|
|
case BMF_8BPP_VGA256:
|
|
|
|
//
|
|
// 8BPP_MASK_CLR (COLOR)
|
|
//
|
|
// PRIMARY_ORDER_CMY (system standard 3:3:2 CMY format)
|
|
// |||
|
|
// ||+-- bit 0-1 (Max. 2 bits of yellow)
|
|
// ||
|
|
// |+--- bit 2-4 (Max. 3 bits of magenta)
|
|
// |
|
|
// +---- bit 5-7 (Max. 3 bits of cyan)
|
|
//
|
|
//
|
|
// 8BPP_MASK_MONO (MONO)
|
|
//
|
|
// NOT APPLICABLE
|
|
//
|
|
//
|
|
//
|
|
// VGA_256 System Halftone Standard (BGR Always)
|
|
//
|
|
// PRIMARY_ORDER_BGR
|
|
// | |
|
|
// | +-- Lowest Primary Index
|
|
// |
|
|
// |
|
|
// |
|
|
// +---- Highest Primary Index
|
|
//
|
|
//
|
|
|
|
if (DCIFlags & DCIF_USE_8BPP_BITMASK) {
|
|
|
|
BM8BPPINFO bm8i;
|
|
|
|
|
|
PrimAdj.Flags |= DCA_MASK8BPP;
|
|
bm8i.dw = 0;
|
|
|
|
if (pDCI->CMY8BPPMask.GenerateXlate) {
|
|
|
|
GenCMYMaskXlate(pDCI->CMY8BPPMask.bXlate,
|
|
(BOOL)(DCIFlags &
|
|
DCIF_INVERT_8BPP_BITMASK_IDX),
|
|
(LONG)pDCI->CMY8BPPMask.cC,
|
|
(LONG)pDCI->CMY8BPPMask.cM,
|
|
(LONG)pDCI->CMY8BPPMask.cY);
|
|
|
|
pDCI->CMY8BPPMask.GenerateXlate = 0;
|
|
}
|
|
|
|
if (DCIFlags & DCIF_INVERT_8BPP_BITMASK_IDX) {
|
|
|
|
bm8i.Data.pXlateIdx |= XLATE_RGB_IDX_OR;
|
|
bm8i.Data.bXor = 0xFF;
|
|
|
|
} else {
|
|
|
|
bm8i.Data.bXor = 0;
|
|
}
|
|
|
|
bm8i.Data.bBlack = pDCI->CMY8BPPMask.Mask ^ bm8i.Data.bXor;
|
|
bm8i.Data.bWhite = bm8i.Data.bXor;
|
|
|
|
if (DCIFlags & DCIF_MONO_8BPP_BITMASK) {
|
|
|
|
ASSERT(DMI.Flags & DMIF_GRAY);
|
|
|
|
LUTAAHdr[0] =
|
|
LUTAAHdr[1] =
|
|
LUTAAHdr[2] = 0xFF0000;
|
|
DMI.CTSTDInfo.DestOrder = PRIMARY_ORDER_RGB;
|
|
DMI.CTSTDInfo.BMFDest = BMF_8BPP_MONO;
|
|
|
|
DBGP_IF(DBGP_HCA, DBGP("---DCA_MASK8BPP_MONO---"));
|
|
|
|
} else {
|
|
|
|
LPBYTE pXlate;
|
|
DWORD KIdx;
|
|
|
|
|
|
DMI.Mul[0] = ((DWORD)pDCI->CMY8BPPMask.cY << 12) - 1;
|
|
DMI.Mul[1] = ((DWORD)pDCI->CMY8BPPMask.cM << 12) - 1;
|
|
DMI.Mul[2] = ((DWORD)pDCI->CMY8BPPMask.cC << 12) - 1;
|
|
LUTAAHdr[0] = (DWORD)pDCI->CMY8BPPMask.PatSubY;
|
|
LUTAAHdr[1] = (DWORD)pDCI->CMY8BPPMask.PatSubM;
|
|
LUTAAHdr[2] = (DWORD)pDCI->CMY8BPPMask.PatSubC;
|
|
DMI.LSft[0] = 4;
|
|
DMI.LSft[1] = 7;
|
|
DMI.LSft[2] = 10;
|
|
|
|
switch (pDCI->CMY8BPPMask.SameLevel) {
|
|
|
|
case 4:
|
|
case 5:
|
|
|
|
if (pDCI->CMY8BPPMask.SameLevel == 4) {
|
|
|
|
DMI.CTSTDInfo.BMFDest = BMF_8BPP_L555;
|
|
KIdx = SIZE_XLATE_555 - 1;
|
|
|
|
} else {
|
|
|
|
DMI.CTSTDInfo.BMFDest = BMF_8BPP_L666;
|
|
bm8i.Data.pXlateIdx |= XLATE_666_IDX_OR;
|
|
KIdx = SIZE_XLATE_666 - 1;
|
|
}
|
|
|
|
PrimAdj.Flags |= DCA_XLATE_555_666;
|
|
bm8i.Data.pXlateIdx &= XLATE_IDX_MASK;
|
|
pXlate = p8BPPXlate[bm8i.Data.pXlateIdx];
|
|
bm8i.Data.bBlack = pXlate[KIdx];
|
|
bm8i.Data.bWhite = pXlate[0];
|
|
break;
|
|
|
|
default:
|
|
|
|
DMI.LSft[1] = 6;
|
|
DMI.LSft[2] = 9;
|
|
DMI.CTSTDInfo.BMFDest = BMF_8BPP_B332;
|
|
|
|
if (DCIFlags & DCIF_INVERT_8BPP_BITMASK_IDX) {
|
|
|
|
PrimAdj.Flags |= DCA_XLATE_332;
|
|
bm8i.Data.bBlack = pDCI->CMY8BPPMask.bXlate[255];
|
|
bm8i.Data.bWhite = pDCI->CMY8BPPMask.bXlate[0];
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
|
|
if (pDCI->CMY8BPPMask.KCheck) {
|
|
|
|
PrimAdj.Flags |= DCA_REPLACE_BLACK;
|
|
DMI.BlackChk = pDCI->CMY8BPPMask.KCheck;
|
|
DMI.LSft[0] -= 4;
|
|
DMI.LSft[1] -= 4;
|
|
DMI.LSft[2] -= 4;
|
|
|
|
switch (DMI.CTSTDInfo.BMFDest) {
|
|
|
|
case BMF_8BPP_B332:
|
|
|
|
DMI.CTSTDInfo.BMFDest = BMF_8BPP_K_B332;
|
|
break;
|
|
|
|
case BMF_8BPP_L555:
|
|
|
|
DMI.CTSTDInfo.BMFDest = BMF_8BPP_K_L555;
|
|
break;
|
|
|
|
case BMF_8BPP_L666:
|
|
|
|
DMI.CTSTDInfo.BMFDest = BMF_8BPP_K_L666;
|
|
break;
|
|
}
|
|
}
|
|
|
|
DMI.CTSTDInfo.DestOrder = PRIMARY_ORDER_CMY;
|
|
|
|
DBGP_IF(DBGP_HCA,
|
|
DBGP("---%hsFlag=%04lx, KCheck=%s, KPower=%s ---"
|
|
ARGPTR((PrimAdj.Flags & DCA_REPLACE_BLACK) ?
|
|
"DCA_REPLACE_BLACK, " : " ")
|
|
ARGDW(DMI.Flags)
|
|
ARGFD6(DMI.BlackChk, 1, 6)
|
|
ARGFD6(K_REP_POWER, 1, 6)));
|
|
}
|
|
|
|
DBGP_IF(DBGP_HCA,
|
|
DBGP("---DCA_MASK8BPP (%hs), Idx=%02lx, Xor=%02lx, K=%02lx (%ld), W=(%02lx/%ld) ---"
|
|
ARGPTR((DCIFlags & DCIF_INVERT_8BPP_BITMASK_IDX) ?
|
|
"RGB" : "CMY")
|
|
ARGDW(bm8i.Data.pXlateIdx)
|
|
ARGDW(bm8i.Data.bXor)
|
|
ARGDW(bm8i.Data.bBlack) ARGDW(bm8i.Data.bBlack)
|
|
ARGDW(bm8i.Data.bWhite) ARGDW(bm8i.Data.bWhite)));
|
|
|
|
LUTAAHdr[3] =
|
|
LUTAAHdr[4] =
|
|
LUTAAHdr[5] = bm8i.dw;
|
|
|
|
|
|
} else {
|
|
|
|
//
|
|
// PRIMARY_ORDER_BGR (Always BGR system halftone palette)
|
|
// |||
|
|
// ||+-- bit 0-2 (3 bits)
|
|
// ||
|
|
// |+--- bit 3-5 (3 bits)
|
|
// |
|
|
// +---- bit 6-8 (3 bits)
|
|
//
|
|
//
|
|
|
|
DMI.Mul[0] =
|
|
DMI.Mul[1] =
|
|
DMI.Mul[2] = 0x4FFF;
|
|
LUTAAHdr[0] = 0x0070000;
|
|
LUTAAHdr[1] = 0x0380000;
|
|
LUTAAHdr[2] = 0x1c00000;
|
|
DMI.LSft[0] = 4;
|
|
DMI.LSft[1] = 7;
|
|
DMI.LSft[2] = 10;
|
|
DMI.CTSTDInfo.DestOrder = PRIMARY_ORDER_BGR;
|
|
PrimAdj.Flags &= ~DCA_MASK8BPP;
|
|
}
|
|
|
|
break;
|
|
|
|
case BMF_16BPP_555:
|
|
|
|
//
|
|
// PRIMARY_ORDER_abc
|
|
// |||
|
|
// ||+-- bit 0-4 (5 bits)
|
|
// ||
|
|
// |+--- bit 5-9 (5 bits)
|
|
// |
|
|
// +---- bit 10-14 (5 bits)
|
|
//
|
|
//
|
|
|
|
DMI.Mul[0] =
|
|
DMI.Mul[1] =
|
|
DMI.Mul[2] = 0x1EFFF;
|
|
LUTAAHdr[0] = 0x001F0000;
|
|
LUTAAHdr[1] = 0x03e00000;
|
|
LUTAAHdr[2] = 0x7c000000;
|
|
LUTAAHdr[3] =
|
|
LUTAAHdr[4] =
|
|
LUTAAHdr[5] = 0x7FFF7FFF;
|
|
DMI.LSft[0] = 4;
|
|
DMI.LSft[1] = 9;
|
|
DMI.LSft[2] = 14;
|
|
|
|
break;
|
|
|
|
case BMF_16BPP_565:
|
|
|
|
//
|
|
// PRIMARY_ORDER_RGB (or BGR)
|
|
// |||
|
|
// ||+-- bit 0-4 (5 bits)
|
|
// ||
|
|
// |+--- bit 5-10 (6 bits)
|
|
// |
|
|
// +---- bit 11-15 (5 bits)
|
|
//
|
|
//
|
|
|
|
switch (DMI.CTSTDInfo.DestOrder) {
|
|
|
|
case PRIMARY_ORDER_RGB:
|
|
case PRIMARY_ORDER_BGR:
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
DBGP("Invalid 16BPP 565 Order=%ld, Allowed=(%ld,%ld) --> %ld"
|
|
ARGDW(DMI.CTSTDInfo.DestOrder)
|
|
ARGDW(PRIMARY_ORDER_RGB) ARGDW(PRIMARY_ORDER_BGR)
|
|
ARGDW(PRIMARY_ORDER_RGB));
|
|
|
|
DMI.CTSTDInfo.DestOrder = PRIMARY_ORDER_RGB;
|
|
}
|
|
|
|
DMI.Mul[0] =
|
|
DMI.Mul[2] = 0x1EFFF;
|
|
DMI.Mul[1] = 0x3EFFF;
|
|
LUTAAHdr[0] = 0x001F0000;
|
|
LUTAAHdr[1] = 0x07e00000;
|
|
LUTAAHdr[2] = 0xF8000000;
|
|
LUTAAHdr[3] =
|
|
LUTAAHdr[4] =
|
|
LUTAAHdr[5] = 0xFFFFFFFF;
|
|
DMI.LSft[0] = 4;
|
|
DMI.LSft[1] = 9;
|
|
DMI.LSft[2] = 15;
|
|
|
|
break;
|
|
|
|
case BMF_24BPP:
|
|
|
|
//
|
|
// PRIMARY_ORDER_BGR (system standard always BGR)
|
|
// |||
|
|
// ||+-- bit 0-7 (8 bits)
|
|
// ||
|
|
// |+--- bit 8-15 (8 bits)
|
|
// |
|
|
// +---- bit 16-23 (8 bits)
|
|
//
|
|
//
|
|
|
|
DBGP_IF(DBGP_HCA,
|
|
DBGP("24BPP DstOrder=%ld" ARGDW(DMI.CTSTDInfo.DestOrder)));
|
|
|
|
//
|
|
// Fall through
|
|
//
|
|
|
|
case BMF_32BPP:
|
|
|
|
//
|
|
// PRIMARY_ORDER_abc
|
|
// |||
|
|
// ||+-- bit 0-7 (8 bits)
|
|
// ||
|
|
// |+--- bit 8-15 (8 bits)
|
|
// |
|
|
// +---- bit 16-23 (8 bits)
|
|
//
|
|
//
|
|
|
|
DMI.Mul[0] =
|
|
DMI.MulAdd = 0;
|
|
DMI.LSft[0] =
|
|
DMI.LSft[1] =
|
|
DMI.LSft[2] = 0;
|
|
DMI.Mul[0] =
|
|
DMI.Mul[1] =
|
|
DMI.Mul[2] = 0xFF;
|
|
LUTAAHdr[0] = 0;
|
|
LUTAAHdr[1] = 1;
|
|
LUTAAHdr[2] = 2;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Watch out!!!, the ExtBGR must in BGR order
|
|
//
|
|
|
|
DMI.DstOrder = DstOrderTable[DMI.CTSTDInfo.DestOrder];
|
|
pDevClrAdj->DMI = DMI;
|
|
pDevClrAdj->ca = ca;
|
|
prgbLUT->ExtBGR[2] = LUTAAHdr[DMI.DstOrder.Order[0]];
|
|
prgbLUT->ExtBGR[1] = LUTAAHdr[DMI.DstOrder.Order[1]];
|
|
prgbLUT->ExtBGR[0] = LUTAAHdr[DMI.DstOrder.Order[2]];
|
|
prgbLUT->ExtBGR[5] = LUTAAHdr[DMI.DstOrder.Order[0] + 3];
|
|
prgbLUT->ExtBGR[4] = LUTAAHdr[DMI.DstOrder.Order[1] + 3];
|
|
prgbLUT->ExtBGR[3] = LUTAAHdr[DMI.DstOrder.Order[2] + 3];
|
|
pDevClrAdj->PrimAdj = PrimAdj;
|
|
pDevClrAdj->pClrXFormBlock = &(pDCI->ClrXFormBlock);
|
|
pDevClrAdj->pCRTXLevel255 = &(pDCI->CRTX[CRTX_LEVEL_255]);
|
|
pDevClrAdj->pCRTXLevelRGB = &(pDCI->CRTX[CRTX_LEVEL_RGB]);
|
|
|
|
DBGP_IF(DBGP_HCA,
|
|
DBGP("DestFmt=%3ld, Order=%ld [%ld:%ld:%ld], DMI.Flags=%02lx"
|
|
ARGDW(DMI.CTSTDInfo.BMFDest) ARGDW(DMI.DstOrder.Index)
|
|
ARGDW(DMI.DstOrder.Order[0]) ARGDW(DMI.DstOrder.Order[1])
|
|
ARGDW(DMI.DstOrder.Order[2]) ARGDW(DMI.Flags)));
|
|
|
|
DBGP_IF(DBGP_HCA,
|
|
DBGP("ExtBGR=%08lx:%08lx:%08lx:%08lx:%08lx:%08lx, LSft=%ld:%ld:%ld"
|
|
ARGDW(prgbLUT->ExtBGR[0]) ARGDW(prgbLUT->ExtBGR[1])
|
|
ARGDW(prgbLUT->ExtBGR[2]) ARGDW(prgbLUT->ExtBGR[3])
|
|
ARGDW(prgbLUT->ExtBGR[4]) ARGDW(prgbLUT->ExtBGR[5])
|
|
ARGDW(pDevClrAdj->DMI.LSft[0])
|
|
ARGDW(pDevClrAdj->DMI.LSft[1])
|
|
ARGDW(pDevClrAdj->DMI.LSft[2])));
|
|
|
|
DBGP_IF(DBGP_HCA,
|
|
DBGP("Mul=%08lx:%08lx:%08lx, MulAdd=%08lx"
|
|
ARGDW(pDevClrAdj->DMI.Mul[0]) ARGDW(pDevClrAdj->DMI.Mul[1])
|
|
ARGDW(pDevClrAdj->DMI.Mul[2]) ARGDW(pDevClrAdj->DMI.MulAdd)));
|
|
|
|
DBGP_IF(DBGP_PRIMADJFLAGS,
|
|
DBGP("pDCIAdjClr: PrimAdj.Flags=%08lx" ARGDW(PrimAdj.Flags)));
|
|
}
|
|
|
|
return(pDCI);
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
HTENTRY
|
|
ComputeColorSpaceXForm(
|
|
PDEVICECOLORINFO pDCI,
|
|
PCIEPRIMS pCIEPrims,
|
|
PCOLORSPACEXFORM pCSXForm,
|
|
INT IlluminantIndex
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function take device's R/G/B/W CIE coordinate (x,y) and compute
|
|
3 x 3 transform matrix, it assume the primaries are additively.
|
|
|
|
Calcualte the 3x3 CIE matrix and its inversion (matrix) based on the
|
|
C.I.E. CHROMATICITY x, y coordinates or RGB and WHITE alignment.
|
|
|
|
this function produces the CIE XYZ matrix and/or its inversion for trnaform
|
|
between RGB primary colors and CIE color spaces, the transforms are
|
|
-1
|
|
[ X ] = [ Xr Xg Xb ] [ R ] [ R ] = [ Xr Xg Xb ] [ X ]
|
|
[ Y ] = [ Yr Yg Yb ] [ G ] and [ G ] [ Yr Yg Yb ] [ Y ]
|
|
[ Z ] = [ Zr Zg Zb ] [ B ] [ B ] [ Zr Zg Zb ] [ Z ]
|
|
|
|
Arguments:
|
|
|
|
pDCI - The current device color info
|
|
|
|
pCIEPrims - Pointer to CIEPRIMS data structure, the CIEPRIMS data
|
|
must already validated.
|
|
|
|
pCSXForm - Pointer to the location to stored the transfrom
|
|
|
|
ColorSpace - CIELUV or CIELAB
|
|
|
|
IlluminantIndex - Standard illuminant index if < 0 then pCIEPrims->w is
|
|
used
|
|
|
|
Return Value:
|
|
|
|
VOID
|
|
|
|
Author:
|
|
|
|
11-Oct-1991 Fri 14:19:59 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
20-Apr-1993 Tue 03:08:15 updated -by- Daniel Chou (danielc)
|
|
re-write so that xform will be correct when device default is used.
|
|
|
|
22-Jan-1998 Thu 03:01:02 updated -by- Daniel Chou (danielc)
|
|
use IlluminantIndex to indicate if device reverse transform is needed
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
MATRIX3x3 Matrix3x3;
|
|
FD6XYZ WhiteXYZ;
|
|
MULDIVPAIR MDPairs[5];
|
|
FD6 DiffRGB;
|
|
FD6 RedXYZScale;
|
|
FD6 GreenXYZScale;
|
|
FD6 BlueXYZScale;
|
|
FD6 AUw;
|
|
FD6 BVw;
|
|
FD6 xr;
|
|
FD6 yr;
|
|
FD6 xg;
|
|
FD6 yg;
|
|
FD6 xb;
|
|
FD6 yb;
|
|
FD6 xw;
|
|
FD6 yw;
|
|
FD6 Yw;
|
|
|
|
|
|
|
|
xr = pCIEPrims->r.x;
|
|
yr = pCIEPrims->r.y;
|
|
xg = pCIEPrims->g.x;
|
|
yg = pCIEPrims->g.y;
|
|
xb = pCIEPrims->b.x;
|
|
yb = pCIEPrims->b.y;
|
|
Yw = pCIEPrims->Yw;
|
|
|
|
if (IlluminantIndex < 0) {
|
|
|
|
xw = pCIEPrims->w.x;
|
|
yw = pCIEPrims->w.y;
|
|
|
|
} else {
|
|
|
|
if (--IlluminantIndex < 0) {
|
|
|
|
IlluminantIndex = ILLUMINANT_D65 - 1;
|
|
}
|
|
|
|
pCIEPrims->w.x =
|
|
xw = UDECI4ToFD6(StdIlluminant[IlluminantIndex].x);
|
|
pCIEPrims->w.y =
|
|
yw = UDECI4ToFD6(StdIlluminant[IlluminantIndex].y);
|
|
}
|
|
|
|
DBGP_IF(DBGP_CIEMATRIX,
|
|
DBGP("** CIEINFO: [xw, yw, Yw] = [%s, %s, %s], Illuminant=%d"
|
|
ARGFD6l(xw) ARGFD6l(yw) ARGFD6l(Yw) ARGI(IlluminantIndex)));
|
|
|
|
DBGP_IF(DBGP_CIEMATRIX,
|
|
DBGP("[xR yR] = [%s %s]" ARGFD6l(xr) ARGFD6l(yr));
|
|
DBGP("[xG yG] = [%s %s]" ARGFD6l(xg) ARGFD6l(yg));
|
|
DBGP("[xB yB] = [%s %s]" ARGFD6l(xb) ARGFD6l(yb));
|
|
DBGP("***********************************************"));
|
|
|
|
//
|
|
// Normalized to have C.I.E. Y equal to 1.0
|
|
//
|
|
|
|
MAKE_MULDIV_INFO(MDPairs, 3, MULDIV_HAS_DIVISOR);
|
|
MAKE_MULDIV_DVSR(MDPairs, Yw);
|
|
|
|
MAKE_MULDIV_PAIR(MDPairs, 1, xr, yg - yb);
|
|
MAKE_MULDIV_PAIR(MDPairs, 2, xg, yb - yr);
|
|
MAKE_MULDIV_PAIR(MDPairs, 3, xb, yr - yg);
|
|
|
|
DiffRGB = MulFD6(yw, MulDivFD6Pairs(MDPairs));
|
|
|
|
//
|
|
// Compute Scaling factors for each color
|
|
//
|
|
|
|
MAKE_MULDIV_INFO(MDPairs, 4, MULDIV_HAS_DIVISOR);
|
|
MAKE_MULDIV_DVSR(MDPairs, DiffRGB);
|
|
|
|
MAKE_MULDIV_PAIR(MDPairs, 1, xw, yg - yb);
|
|
MAKE_MULDIV_PAIR(MDPairs, 2, -yw, xg - xb);
|
|
MAKE_MULDIV_PAIR(MDPairs, 3, xg, yb );
|
|
MAKE_MULDIV_PAIR(MDPairs, 4, -xb, yg );
|
|
|
|
RedXYZScale = MulDivFD6Pairs(MDPairs);
|
|
|
|
MAKE_MULDIV_PAIR(MDPairs, 1, xw, yb - yr);
|
|
MAKE_MULDIV_PAIR(MDPairs, 2, -yw, xb - xr);
|
|
MAKE_MULDIV_PAIR(MDPairs, 3, -xr, yb );
|
|
MAKE_MULDIV_PAIR(MDPairs, 4, xb, yr );
|
|
|
|
GreenXYZScale = MulDivFD6Pairs(MDPairs);
|
|
|
|
MAKE_MULDIV_PAIR(MDPairs, 1, xw, yr - yg);
|
|
MAKE_MULDIV_PAIR(MDPairs, 2, -yw, xr - xg);
|
|
MAKE_MULDIV_PAIR(MDPairs, 3, xr, yg );
|
|
MAKE_MULDIV_PAIR(MDPairs, 4, -xg, yr );
|
|
|
|
BlueXYZScale = MulDivFD6Pairs(MDPairs);
|
|
|
|
//
|
|
// Now scale the RGB coordinate by it ratio, notice that C.I.E z value.
|
|
// equal to (1.0 - x - y)
|
|
//
|
|
// Make sure Yr + Yg + Yb = 1.0, this may happened when ruound off
|
|
// durning the computation, we will add the difference (at most it will
|
|
// be 0.000002) to the Yg since this is brightnest color
|
|
//
|
|
|
|
CIE_Xr(Matrix3x3) = MulFD6(xr, RedXYZScale);
|
|
CIE_Xg(Matrix3x3) = MulFD6(xg, GreenXYZScale);
|
|
CIE_Xb(Matrix3x3) = MulFD6(xb, BlueXYZScale);
|
|
|
|
pCSXForm->Yrgb.R =
|
|
CIE_Yr(Matrix3x3) = MulFD6(yr, RedXYZScale);
|
|
pCSXForm->Yrgb.G =
|
|
CIE_Yg(Matrix3x3) = MulFD6(yg, GreenXYZScale);
|
|
pCSXForm->Yrgb.B =
|
|
CIE_Yb(Matrix3x3) = MulFD6(yb, BlueXYZScale);
|
|
|
|
CIE_Zr(Matrix3x3) = MulFD6(FD6_1 - xr - yr, RedXYZScale);
|
|
CIE_Zg(Matrix3x3) = MulFD6(FD6_1 - xg - yg, GreenXYZScale);
|
|
CIE_Zb(Matrix3x3) = MulFD6(FD6_1 - xb - yb, BlueXYZScale);
|
|
|
|
WhiteXYZ.X = CIE_Xr(Matrix3x3) + CIE_Xg(Matrix3x3) + CIE_Xb(Matrix3x3);
|
|
WhiteXYZ.Y = CIE_Yr(Matrix3x3) + CIE_Yg(Matrix3x3) + CIE_Yb(Matrix3x3);
|
|
WhiteXYZ.Z = CIE_Zr(Matrix3x3) + CIE_Zg(Matrix3x3) + CIE_Zb(Matrix3x3);
|
|
|
|
//
|
|
// If request a 3 x 3 transform matrix then save the result back
|
|
//
|
|
|
|
DBGP_IF(DBGP_CIEMATRIX,
|
|
|
|
DBGP("== RGB -> XYZ 3x3 Matrix ==== White = (%s, %s) =="
|
|
ARGFD6s(xw) ARGFD6s(yw));
|
|
DBGP("[Xr Xg Xb] = [%s %s %s]" ARGFD6l(CIE_Xr(Matrix3x3))
|
|
ARGFD6l(CIE_Xg(Matrix3x3))
|
|
ARGFD6l(CIE_Xb(Matrix3x3)));
|
|
DBGP("[Yr Yg Yb] = [%s %s %s]" ARGFD6l(CIE_Yr(Matrix3x3))
|
|
ARGFD6l(CIE_Yg(Matrix3x3))
|
|
ARGFD6l(CIE_Yb(Matrix3x3)));
|
|
DBGP("[Zr Zg Zb] = [%s %s %s]" ARGFD6l(CIE_Zr(Matrix3x3))
|
|
ARGFD6l(CIE_Zg(Matrix3x3))
|
|
ARGFD6l(CIE_Zb(Matrix3x3)));
|
|
DBGP("===============================================");
|
|
);
|
|
|
|
DBGP_IF(DBGP_CIEMATRIX,
|
|
DBGP("RGB->XYZ: [Xw=%s, Yw=%s, Zw=%s]"
|
|
ARGFD6l(WhiteXYZ.X)
|
|
ARGFD6l(WhiteXYZ.Y)
|
|
ARGFD6l(WhiteXYZ.Z)));
|
|
|
|
if (IlluminantIndex < 0) {
|
|
|
|
pCSXForm->M3x3 = Matrix3x3;
|
|
|
|
ComputeInverseMatrix3x3(&(pCSXForm->M3x3), &Matrix3x3);
|
|
|
|
DBGP_IF(DBGP_CIEMATRIX,
|
|
|
|
DBGP("======== XYZ -> RGB INVERSE 3x3 Matrix ========");
|
|
DBGP(" -1");
|
|
DBGP("[Xr Xg Xb] = [%s %s %s]" ARGFD6l(CIE_Xr(Matrix3x3))
|
|
ARGFD6l(CIE_Xg(Matrix3x3))
|
|
ARGFD6l(CIE_Xb(Matrix3x3)));
|
|
DBGP("[Yr Yg Yb] = [%s %s %s]"
|
|
ARGFD6l(CIE_Yr(Matrix3x3))
|
|
ARGFD6l(CIE_Yg(Matrix3x3))
|
|
ARGFD6l(CIE_Yb(Matrix3x3)));
|
|
DBGP("[Zr Zg Zb] = [%s %s %s]"
|
|
ARGFD6l(CIE_Zr(Matrix3x3))
|
|
ARGFD6l(CIE_Zg(Matrix3x3))
|
|
ARGFD6l(CIE_Zb(Matrix3x3)));
|
|
DBGP("===============================================");
|
|
);
|
|
}
|
|
|
|
if ((pCSXForm->YW = WhiteXYZ.Y) != NORMALIZED_WHITE) {
|
|
|
|
if (WhiteXYZ.Y) {
|
|
|
|
WhiteXYZ.X = DivFD6(WhiteXYZ.X, WhiteXYZ.Y);
|
|
WhiteXYZ.Z = DivFD6(WhiteXYZ.Z, WhiteXYZ.Y);
|
|
|
|
} else {
|
|
|
|
WhiteXYZ.X =
|
|
WhiteXYZ.Z = FD6_0;
|
|
}
|
|
|
|
WhiteXYZ.Y = NORMALIZED_WHITE;
|
|
}
|
|
|
|
switch (pDCI->ClrXFormBlock.ColorSpace) {
|
|
|
|
case CIELUV_1976:
|
|
|
|
//
|
|
// U' = 4X / (X + 15Y + 3Z)
|
|
// V' = 9Y / (X + 15Y + 3Z)
|
|
//
|
|
// U* = 13 x L x (U' - Uw)
|
|
// V* = 13 x L x (V' - Vw)
|
|
//
|
|
//
|
|
|
|
DiffRGB = WhiteXYZ.X + FD6xL(WhiteXYZ.Y, 15) + FD6xL(WhiteXYZ.Z, 3);
|
|
AUw = DivFD6(FD6xL(WhiteXYZ.X, 4), DiffRGB);
|
|
BVw = DivFD6(FD6xL(WhiteXYZ.Y, 9), DiffRGB);
|
|
|
|
break;
|
|
|
|
case CIELAB_1976:
|
|
default:
|
|
|
|
//
|
|
// CIELAB 1976 L*A*B*
|
|
//
|
|
// A* = 500 x (fX - fY)
|
|
// B* = 200 x (fY - fZ)
|
|
//
|
|
// 1/3
|
|
// fX = (X/Xw) (X/Xw) > 0.008856
|
|
// fX = 7.787 x (X/Xw) + (16/116) (X/Xw) <= 0.008856
|
|
//
|
|
// 1/3
|
|
// fY = (Y/Yw) (Y/Yw) > 0.008856
|
|
// fY = 7.787 Y (Y/Yw) + (16/116) (Y/Yw) <= 0.008856
|
|
//
|
|
// 1/3
|
|
// fZ = (Z/Zw) (Z/Zw) > 0.008856
|
|
// fZ = 7.787 Z (Z/Zw) + (16/116) (Z/Zw) <= 0.008856
|
|
//
|
|
|
|
AUw =
|
|
BVw = FD6_0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
pCSXForm->M3x3 = Matrix3x3;
|
|
pCSXForm->WhiteXYZ = WhiteXYZ;
|
|
pCSXForm->AUw = AUw;
|
|
pCSXForm->BVw = BVw;
|
|
pCSXForm->xW = xw;
|
|
pCSXForm->yW = yw;
|
|
|
|
DBGP_IF(DBGP_CSXFORM,
|
|
DBGP("------- ComputeColorSpaceXForm: %s ---------"
|
|
ARG(pDbgCSName[pDCI->ClrXFormBlock.ColorSpace]));
|
|
DBGP(" White XYZ = (%s, %s, %s)" ARGFD6(WhiteXYZ.X, 1, 6)
|
|
ARGFD6(WhiteXYZ.Y, 1, 6)
|
|
ARGFD6(WhiteXYZ.Z, 1, 6));
|
|
DBGP(" AUw/BVw = %s / %s" ARGFD6(AUw, 1, 6) ARGFD6s(BVw));
|
|
DBGP(" White xyY = (%s, %s, %s)" ARGFD6(pCSXForm->xW, 1, 6)
|
|
ARGFD6(pCSXForm->yW, 1, 6)
|
|
ARGFD6(pCSXForm->YW, 1, 6));
|
|
DBGP("------------------------------------------------");
|
|
);
|
|
}
|
|
|
|
|
|
|
|
|
|
PCACHERGBTOXYZ
|
|
HTENTRY
|
|
CacheRGBToXYZ(
|
|
PCACHERGBTOXYZ pCRTX,
|
|
PFD6XYZ pFD6XYZ,
|
|
LPDWORD pNewChecksum,
|
|
PDEVCLRADJ pDevClrAdj
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function cached the RGB color input to XYZ
|
|
|
|
|
|
Arguments:
|
|
|
|
pCRTX - Pointer to the CACHERGBTOXYZ
|
|
|
|
pFD6XYZ - Pointer to the local cached RGB->XYZ table (will be updated)
|
|
|
|
pNewChecksum- Pointer to the new checksum computed
|
|
|
|
pDevClrAdj - Pointer to DEVCLRADJ,
|
|
|
|
Return Value:
|
|
|
|
if a cahced is copied to the pFD6XYZ then NULL will be returned, otherwise
|
|
the cache table is computed on the pFD6XYZ and pCRTX returned
|
|
|
|
|
|
TRUE if cached XYZ info is generate, false otherwise, only possible failure
|
|
is that memory allocation failed.
|
|
|
|
Author:
|
|
|
|
08-May-1992 Fri 13:21:03 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
09-Mar-1995 Thu 10:50:13 updated -by- Daniel Chou (danielc)
|
|
DO NOT TURN OFF DCA_NEGATIVE in this function
|
|
|
|
--*/
|
|
|
|
{
|
|
PMATRIX3x3 pRGBToXYZ;
|
|
PPRIMADJ pPrimAdj;
|
|
FD6 rgbX;
|
|
FD6 rgbY;
|
|
FD6 rgbZ;
|
|
FD6 PrimCur;
|
|
UINT PrimMax;
|
|
UINT PrimInc;
|
|
DWORD Checksum;
|
|
UINT RGBIndex;
|
|
|
|
//
|
|
// Turn off the one we did not need any checksum for
|
|
//
|
|
|
|
pPrimAdj = &(pDevClrAdj->PrimAdj);
|
|
pRGBToXYZ = &(pPrimAdj->rgbCSXForm.M3x3);
|
|
Checksum = ComputeChecksum((LPBYTE)pRGBToXYZ, 'CXYZ', sizeof(MATRIX3x3));
|
|
|
|
if ((pCRTX->pFD6XYZ) &&
|
|
(pCRTX->Checksum == Checksum)) {
|
|
|
|
CopyMemory(pFD6XYZ, pCRTX->pFD6XYZ, pCRTX->SizeCRTX);
|
|
|
|
DBGP_IF(DBGP_CACHED_GAMMA,
|
|
DBGP("*** Use %u bytes CACHED RGB->XYZ Table ***"
|
|
ARGU(pCRTX->SizeCRTX)));
|
|
|
|
return(NULL);
|
|
}
|
|
|
|
*pNewChecksum = Checksum;
|
|
|
|
DBGP_IF(DBGP_CCT, DBGP("** Re-Compute %ld bytes RGB->XYZ xform table **"
|
|
ARGDW(pCRTX->SizeCRTX)));
|
|
|
|
PrimMax = (UINT)pCRTX->PrimMax;
|
|
|
|
for (RGBIndex = 0; RGBIndex < 3; RGBIndex++) {
|
|
|
|
rgbX = pRGBToXYZ->m[X_INDEX][RGBIndex];
|
|
rgbY = pRGBToXYZ->m[Y_INDEX][RGBIndex];
|
|
rgbZ = pRGBToXYZ->m[Z_INDEX][RGBIndex];
|
|
|
|
DBGP_IF(DBGP_CACHED_GAMMA,
|
|
DBGP("CachedRGBToXYZ %u:%u, XYZ=%s:%s:%s"
|
|
ARGU(RGBIndex) ARGU(PrimMax)
|
|
ARGFD6(rgbX, 2, 6) ARGFD6(rgbY, 2, 6)
|
|
ARGFD6(rgbZ, 2, 6)));
|
|
|
|
for (PrimInc = 0; PrimInc <= PrimMax; PrimInc++, pFD6XYZ++) {
|
|
|
|
PrimCur = DivFD6((FD6)PrimInc, (FD6)PrimMax);
|
|
pFD6XYZ->X = MulFD6(rgbX, PrimCur);
|
|
pFD6XYZ->Y = MulFD6(rgbY, PrimCur);
|
|
pFD6XYZ->Z = MulFD6(rgbZ, PrimCur);
|
|
|
|
DBGP_IF(DBGP_CACHED_GAMMA,
|
|
DBGP("(%u:%3u): %s, XYZ=%s:%s:%s"
|
|
ARGU(RGBIndex) ARGU(PrimInc)
|
|
ARGFD6(PrimCur, 1, 6)
|
|
ARGFD6(pFD6XYZ->X, 1, 6)
|
|
ARGFD6(pFD6XYZ->Y, 1, 6)
|
|
ARGFD6(pFD6XYZ->Z, 1, 6)));
|
|
}
|
|
}
|
|
|
|
return(pCRTX);
|
|
}
|
|
|
|
|
|
#define RD_MIN_POWER (FD6)1500000
|
|
#define RD_MAX_POWER (FD6)2000000
|
|
|
|
#define GET_RD_MIN_PRIM(p, RD) \
|
|
{ \
|
|
(p) = FD6_1 - DivFD6(p, RD.LMin); \
|
|
(p) = MulFD6(FD6_1 - Power(p, RD_MIN_POWER), RD.LMin); \
|
|
}
|
|
|
|
#define GET_RD_MAX_PRIM(p, RD) \
|
|
{ \
|
|
(p) = DivFD6((p) - RD.LMax, FD6_1 - RD.LMax); \
|
|
(p) = RD.LMax + MulFD6(Power(p, RD_MAX_POWER), FD6_1 - RD.LMax); \
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID
|
|
HTENTRY
|
|
ComputeRGBLUTAA(
|
|
PDEVICECOLORINFO pDCI,
|
|
PDEVCLRADJ pDevClrAdj,
|
|
PRGBLUTAA prgbLUT
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function compute a RGB to Monochrome *L translation table.
|
|
|
|
|
|
Arguments:
|
|
|
|
pDCI - Pointer to the DEVICECOLORINFO
|
|
|
|
pDevClrAdj - Pointer to DEVCLRADJ, the DCA_NEGATIVE and DCA_HAS_SRC_GAMMA
|
|
flags in pDevClrAdj->PrimAdj.Flags will always be turn off
|
|
at return.
|
|
|
|
prgbLUT - Pointer to the RGBLUTAA buffer for computation
|
|
|
|
Return Value:
|
|
|
|
VOID
|
|
|
|
Author:
|
|
|
|
05-Mar-1993 Fri 17:37:12 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
LPDWORD pdw;
|
|
LPBYTE pbAB;
|
|
REGDATA RD;
|
|
PRIMADJ PrimAdj;
|
|
DEVMAPINFO DMI;
|
|
HTCOLORADJUSTMENT ca;
|
|
FD6 Prim;
|
|
FD6 PrimOrg;
|
|
FD6 PrimKDiv;
|
|
FD6 Mul;
|
|
FD6 SrcGamma;
|
|
FD6 DevGamma;
|
|
DWORD dwPrim;
|
|
DWORD PrimMask;
|
|
DWORD aMulAdd[3];
|
|
DWORD CurCA;
|
|
DWORD PrevCA;
|
|
FD6 aPrimMaxMul[3];
|
|
FD6 PrimMaxMul;
|
|
PFD6 pDenCMY[3];
|
|
PFD6 pDensity;
|
|
UINT Index;
|
|
UINT LeftShift;
|
|
UINT PrimIdx;
|
|
INT PrimCur;
|
|
|
|
|
|
PrimAdj = pDevClrAdj->PrimAdj;
|
|
ca = pDevClrAdj->ca;
|
|
DMI = pDevClrAdj->DMI;
|
|
pDevClrAdj->PrimAdj.Flags &= ~(DCA_HAS_SRC_GAMMA |
|
|
DCA_HAS_DEST_GAMMA |
|
|
DCA_HAS_BW_REF_ADJ |
|
|
DCA_HAS_CONTRAST_ADJ |
|
|
DCA_HAS_BRIGHTNESS_ADJ |
|
|
DCA_LOG_FILTER |
|
|
DCA_NEGATIVE |
|
|
DCA_DO_DEVCLR_XFORM);
|
|
|
|
ca.caColorfulness =
|
|
ca.caRedGreenTint = (PrimAdj.Flags & DCA_MONO_ONLY) ? 0xff : 0x00;
|
|
|
|
SET_CACHED_CMI_CA(pDevClrAdj->ca);
|
|
|
|
aPrimMaxMul[0] =
|
|
aPrimMaxMul[1] =
|
|
aPrimMaxMul[2] = FD6_1;
|
|
aMulAdd[0] =
|
|
aMulAdd[1] =
|
|
aMulAdd[2] = DMI.MulAdd;
|
|
pDenCMY[0] =
|
|
pDenCMY[1] =
|
|
pDenCMY[2] = NULL;
|
|
|
|
if (PrimAdj.Flags & DCA_RGBLUTAA_MONO) {
|
|
|
|
ASSERT(PrimAdj.Flags & DCA_NO_MAPPING_TABLE);
|
|
ASSERT(DMI.Mul[1] == GRAY_MAX_IDX);
|
|
ASSERT(PrimAdj.Flags & DCA_MONO_ONLY);
|
|
ASSERT(DMI.MulAdd == 0);
|
|
ASSERT(DMI.Flags & DMIF_GRAY);
|
|
|
|
DMI.Mul[0] = (DWORD)MulFD6(NTSC_R_INT, DMI.Mul[1]);
|
|
DMI.Mul[2] = (DWORD)MulFD6(NTSC_B_INT, DMI.Mul[1]);
|
|
DMI.Mul[1] -= (DMI.Mul[0] + DMI.Mul[2]);
|
|
DMI.DstOrder.Order[0] = 0;
|
|
DMI.DstOrder.Order[1] = 1;
|
|
DMI.DstOrder.Order[2] = 2;
|
|
DMI.LSft[0] =
|
|
DMI.LSft[1] =
|
|
DMI.LSft[2] = 0;
|
|
|
|
} else {
|
|
|
|
ASSERT(!(DMI.Flags & DMIF_GRAY));
|
|
|
|
if (PrimAdj.Flags & DCA_MASK8BPP) {
|
|
|
|
ASSERT((pDCI->Flags & (DCIF_USE_8BPP_BITMASK |
|
|
DCIF_MONO_8BPP_BITMASK)) ==
|
|
DCIF_USE_8BPP_BITMASK);
|
|
|
|
aPrimMaxMul[0] = pDCI->CMY8BPPMask.MaxMulY;
|
|
aPrimMaxMul[1] = pDCI->CMY8BPPMask.MaxMulM;
|
|
aPrimMaxMul[2] = pDCI->CMY8BPPMask.MaxMulC;
|
|
|
|
if (pDCI->Flags & DCIF_HAS_DENSITY) {
|
|
|
|
pDenCMY[0] = pDCI->CMY8BPPMask.DenY;
|
|
pDenCMY[1] = pDCI->CMY8BPPMask.DenM;
|
|
pDenCMY[2] = pDCI->CMY8BPPMask.DenC;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!(PrimAdj.Flags & DCA_REPLACE_BLACK)) {
|
|
|
|
DMI.BlackChk = FD6_1;
|
|
}
|
|
|
|
PrimMask = PrimAdj.Flags & (DCA_REPLACE_BLACK |
|
|
DCA_DO_DEVCLR_XFORM |
|
|
DCA_ALPHA_BLEND |
|
|
DCA_CONST_ALPHA |
|
|
DCA_NO_MAPPING_TABLE);
|
|
|
|
GET_CHECKSUM(PrimMask, PrimAdj.SrcGamma);
|
|
GET_CHECKSUM(PrimMask, PrimAdj.DevGamma);
|
|
GET_CHECKSUM(PrimMask, ca);
|
|
GET_CHECKSUM(PrimMask, DMI);
|
|
|
|
CurCA = (DWORD)pDCI->CurConstAlpha;
|
|
PrevCA = (DWORD)pDCI->PrevConstAlpha;
|
|
|
|
if (prgbLUT->Checksum != PrimMask) {
|
|
|
|
prgbLUT->Checksum = PrimMask;
|
|
PrevCA =
|
|
pDCI->PrevConstAlpha = AB_CONST_MAX + 1;
|
|
|
|
DBGP_IF(DBGP_RGBLUTAA,
|
|
DBGP("** Re-Compute %ld bytes of pLUT=%p, SG=%s:%s:%s, DG=%s:%s:%s **"
|
|
ARGDW(sizeof(RGBLUTAA))
|
|
ARGPTR(prgbLUT)
|
|
ARGFD6(PrimAdj.SrcGamma[0], 1, 4)
|
|
ARGFD6(PrimAdj.SrcGamma[1], 1, 4)
|
|
ARGFD6(PrimAdj.SrcGamma[2], 1, 4)
|
|
ARGFD6(PrimAdj.DevGamma[0], 1, 4)
|
|
ARGFD6(PrimAdj.DevGamma[1], 1, 4)
|
|
ARGFD6(PrimAdj.DevGamma[2], 1, 4)));
|
|
|
|
DBGP_IF(DBGP_RGBLUTAA,
|
|
DBGP("DMI.Mul=%08lx:%08lx:%08lx, %08lx, LSft=%ld:%ld:%ld"
|
|
ARGDW(DMI.Mul[0]) ARGDW(DMI.Mul[1]) ARGDW(DMI.Mul[2])
|
|
ARGDW(DMI.Mul[0] + DMI.Mul[1] + DMI.Mul[2])
|
|
ARGDW(DMI.LSft[0]) ARGDW(DMI.LSft[1]) ARGDW(DMI.LSft[2])));
|
|
|
|
if (PrimAdj.Flags & DCA_DO_DEVCLR_XFORM) {
|
|
|
|
RD = RegData[pDCI->ClrXFormBlock.RegDataIdx];
|
|
}
|
|
|
|
//
|
|
// Compute order BGR
|
|
//
|
|
|
|
Index = 3;
|
|
PrimKDiv = FD6_1 - DMI.BlackChk;
|
|
PrimMask = (DWORD)(DMI.MulAdd - 1);
|
|
pdw = (LPDWORD)prgbLUT->IdxBGR;
|
|
|
|
if ((PrimAdj.Flags & DCA_ALPHA_BLEND) &&
|
|
(!(DMI.Flags & DMIF_GRAY))) {
|
|
|
|
pbAB = (LPBYTE)pDCI->pAlphaBlendBGR;
|
|
|
|
} else {
|
|
|
|
pbAB = NULL;
|
|
}
|
|
|
|
while (Index--) {
|
|
|
|
SrcGamma = PrimAdj.SrcGamma[Index];
|
|
DevGamma = PrimAdj.DevGamma[Index];
|
|
PrimIdx = DMI.DstOrder.Order[Index];
|
|
PrimMaxMul = aPrimMaxMul[PrimIdx];
|
|
DMI.MulAdd = aMulAdd[PrimIdx];
|
|
LeftShift = DMI.LSft[PrimIdx];
|
|
Mul = DMI.Mul[PrimIdx];
|
|
pDensity = pDenCMY[PrimIdx];
|
|
PrimCur = -1;
|
|
|
|
DBGP_IF(DBGP_RGBLUTAA,
|
|
DBGP("Index=%ld: Mul=%08lx, LSft=%2ld [%08lx], PrimMaxMul=%s, MulAdd=%04lx"
|
|
ARGDW(Index) ARGDW(Mul) ARGDW(LeftShift)
|
|
ARGDW( ((Mul + DMI.MulAdd) & PrimMask) |
|
|
(((Mul + DMI.MulAdd) & ~PrimMask) << LeftShift))
|
|
ARGFD6(PrimMaxMul, 1, 6) ARGDW(DMI.MulAdd)));
|
|
|
|
while (++PrimCur < BF_GRAY_TABLE_COUNT) {
|
|
|
|
PrimOrg =
|
|
Prim = DivFD6((FD6)PrimCur, (FD6)(BF_GRAY_TABLE_COUNT - 1));
|
|
|
|
if (PrimAdj.Flags & DCA_HAS_SRC_GAMMA) {
|
|
|
|
Prim = Power(Prim, SrcGamma);
|
|
}
|
|
|
|
if (PrimAdj.Flags & DCA_HAS_BW_REF_ADJ) {
|
|
|
|
PRIM_BW_ADJ(Prim, PrimAdj);
|
|
}
|
|
|
|
if (PrimAdj.Flags & DCA_HAS_CONTRAST_ADJ) {
|
|
|
|
PRIM_CONTRAST(Prim, PrimAdj);
|
|
}
|
|
|
|
if (PrimAdj.Flags & DCA_HAS_BRIGHTNESS_ADJ) {
|
|
|
|
PRIM_BRIGHTNESS(Prim, PrimAdj);
|
|
}
|
|
|
|
if (PrimAdj.Flags & DCA_LOG_FILTER) {
|
|
|
|
PRIM_LOG_FILTER(Prim);
|
|
}
|
|
|
|
CLAMP_01(Prim);
|
|
|
|
if (PrimAdj.Flags & DCA_NEGATIVE) {
|
|
|
|
Prim = FD6_1 - Prim;
|
|
}
|
|
|
|
if (PrimAdj.Flags & DCA_DO_DEVCLR_XFORM) {
|
|
|
|
if (Prim <= RD.LMin) {
|
|
|
|
GET_RD_MIN_PRIM(Prim, RD);
|
|
Prim = REG_DMIN_ADD + 50 + MulFD6(Prim, RD.DMinMul);
|
|
|
|
} else if (Prim >= RD.LMax) {
|
|
|
|
GET_RD_MAX_PRIM(Prim, RD);
|
|
Prim = RD.DMaxAdd + 50 + MulFD6(Prim, RD.DMaxMul);
|
|
|
|
} else {
|
|
|
|
Prim = RD.DenAdd + 50 +
|
|
MulFD6(Log(CIE_L2I(Prim)), RD.DenMul);
|
|
}
|
|
|
|
Prim /= 100;
|
|
}
|
|
|
|
CLAMP_01(Prim);
|
|
|
|
if (PrimAdj.Flags & DCA_HAS_DEST_GAMMA) {
|
|
|
|
Prim = Power(Prim, DevGamma);
|
|
}
|
|
|
|
if (pbAB) {
|
|
|
|
*pbAB++ = (BYTE)MulFD6(Prim, 0xFF);
|
|
Prim = PrimOrg;
|
|
}
|
|
|
|
if (!(DMI.Flags & DMIF_GRAY)) {
|
|
|
|
Prim = FD6_1 - Prim;
|
|
}
|
|
|
|
if (pDensity) {
|
|
|
|
FD6 p1;
|
|
FD6 p2;
|
|
DWORD Idx;
|
|
|
|
p2 = FD6_0;
|
|
Idx = ~0;
|
|
|
|
do {
|
|
|
|
p1 = p2;
|
|
p2 = pDensity[++Idx];
|
|
|
|
} while (Prim > p2);
|
|
|
|
dwPrim = MulFD6(DivFD6(Prim - p1, p2 - p1), MAX_BGR_IDX) +
|
|
(Idx << 12) + DMI.MulAdd;
|
|
|
|
} else {
|
|
|
|
dwPrim = (DWORD)MulFD6(Prim, Mul) + DMI.MulAdd;
|
|
}
|
|
|
|
dwPrim = (DWORD)MulFD6(dwPrim & PrimMask, PrimMaxMul) |
|
|
((DWORD)(dwPrim & ~PrimMask) << LeftShift);
|
|
|
|
if (Prim > DMI.BlackChk) {
|
|
|
|
dwPrim |= (DWORD)MulFD6(Power(DivFD6(Prim - DMI.BlackChk,
|
|
PrimKDiv),
|
|
K_REP_POWER),
|
|
MAX_K_IDX) << 21;
|
|
}
|
|
|
|
*pdw++ = dwPrim;
|
|
}
|
|
|
|
for (PrimCur = 0; PrimCur < BF_GRAY_TABLE_COUNT; PrimCur++) {
|
|
|
|
DBGP_IF(DBGP_RGBLUTAA,
|
|
DBGP("COLOR(%04lx:%4ld) %3u = %08lx"
|
|
ARGU(Index) ARGU(Mul) ARGU(PrimCur)
|
|
ARGDW(*(pdw - BF_GRAY_TABLE_COUNT + PrimCur))));
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
DBGP_IF(DBGP_RGBLUTAA, DBGP("** Used Cached %ld bytes pLUT **"
|
|
ARGDW(sizeof(RGBLUTAA))));
|
|
}
|
|
|
|
if ((PrimAdj.Flags & (DCA_ALPHA_BLEND | DCA_CONST_ALPHA)) ==
|
|
(DCA_ALPHA_BLEND | DCA_CONST_ALPHA)) {
|
|
|
|
if (PrevCA != CurCA) {
|
|
|
|
LPWORD pwBGR;
|
|
LPWORD pCA;
|
|
|
|
|
|
DBGP_IF(DBGP_CONST_ALPHA,
|
|
DBGP("** %hs ConstAlpha=%3ld: Re-compute"
|
|
ARGPTR((DMI.Flags & DMIF_GRAY) ? "GRAY" : "STD")
|
|
ARGDW(CurCA)));
|
|
|
|
pbAB = pDCI->pAlphaBlendBGR;
|
|
pwBGR = (LPWORD)(pbAB + AB_BGR_SIZE);
|
|
pCA = (LPWORD)((LPBYTE)pwBGR + AB_BGR_CA_SIZE);
|
|
pDCI->CurConstAlpha =
|
|
pDCI->PrevConstAlpha = (WORD)CurCA;
|
|
PrevCA = (DMI.Flags & DMIF_GRAY) ? 0xFFFF : 0xFF00;
|
|
CurCA = (((CurCA * PrevCA) + 0x7F) / 0xFF);
|
|
PrevCA -= CurCA;
|
|
|
|
for (Index = 0, dwPrim = 0x7F;
|
|
Index < 256;
|
|
Index++, dwPrim += CurCA) {
|
|
|
|
pCA[Index] = (WORD)(dwPrim / 255);
|
|
}
|
|
|
|
if (DMI.Flags & DMIF_GRAY) {
|
|
|
|
CopyMemory(pwBGR, pCA, sizeof(WORD) * 256);
|
|
|
|
} else {
|
|
|
|
Index = 256 * 3;
|
|
|
|
while (Index--) {
|
|
|
|
*pwBGR++ = pCA[*pbAB++];
|
|
}
|
|
}
|
|
|
|
for (Index = 0, dwPrim = 0x7F;
|
|
Index < 256;
|
|
Index++, dwPrim += PrevCA) {
|
|
|
|
pCA[Index] = (WORD)(dwPrim / 255);
|
|
}
|
|
|
|
} else {
|
|
|
|
DBGP_IF(DBGP_CONST_ALPHA,
|
|
DBGP("** %hs ConstAlpha=%3ld: Use Cache"
|
|
ARGPTR((DMI.Flags & DMIF_GRAY) ? "GRAY" : "STD")
|
|
ARGDW(CurCA)));
|
|
}
|
|
}
|
|
|
|
DBGP_IF(DBGP_RGBLUTAA,
|
|
DBGP("ComputeRGBLUTAA: PrimAdj.Flags=%08lx"
|
|
ARGDW(pDevClrAdj->PrimAdj.Flags)));
|
|
|
|
}
|
|
|
|
|
|
|
|
#if NO_NEGATIVE_RGB_SCALE
|
|
|
|
|
|
VOID
|
|
HTENTRY
|
|
ScaleRGB(
|
|
PFD6 pRGB
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function scale out of range RGB back into range and taking the
|
|
lumminance of the color into consideration.
|
|
|
|
if any of RGB is less then 0.0 then it will first clamp that to 0.0 and
|
|
it only scale if any of RGB is greater then 1.0
|
|
|
|
Arguments:
|
|
|
|
pRGB - Pointer to RGB (FD6) prims to be adjust
|
|
|
|
|
|
Return Value:
|
|
|
|
VOID
|
|
|
|
|
|
Author:
|
|
|
|
08-Mar-1995 Wed 19:19:33 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
PFD6 pRGBTmp;
|
|
FD6 MaxClr;
|
|
INT Idx;
|
|
|
|
|
|
DEFDBGVAR(FD6, RGBOld[3])
|
|
DEFDBGVAR(BOOL, Negative = FALSE)
|
|
|
|
|
|
|
|
Idx = 3;
|
|
pRGBTmp = pRGB;
|
|
MaxClr = FD6_1;
|
|
|
|
while (Idx--) {
|
|
|
|
FD6 CurClr;
|
|
|
|
//
|
|
// Firstable Clamp the negative component
|
|
//
|
|
|
|
if ((CurClr = *pRGBTmp) < FD6_0) {
|
|
|
|
*pRGBTmp = FD6_0;
|
|
|
|
SETDBGVAR(Negative, TRUE);
|
|
|
|
} else if (CurClr > MaxClr) {
|
|
|
|
MaxClr = CurClr;
|
|
}
|
|
|
|
++pRGBTmp;
|
|
|
|
SETDBGVAR(RGBOld[Idx], CurClr);
|
|
}
|
|
|
|
if (MaxClr > FD6_1) {
|
|
|
|
//
|
|
// Now Scale it
|
|
//
|
|
|
|
*pRGB++ = DivFD6(*pRGB, MaxClr);
|
|
*pRGB++ = DivFD6(*pRGB, MaxClr);
|
|
*pRGB = DivFD6(*pRGB, MaxClr);
|
|
|
|
DBGP_IF(DBGP_SCALE_RGB,
|
|
DBGP("ScaleRGB: %s:%s:%s -> %s:%s:%s, Max=%s%s"
|
|
ARGFD6(RGBOld[2], 1, 6)
|
|
ARGFD6(RGBOld[1], 1, 6)
|
|
ARGFD6(RGBOld[0], 1, 6)
|
|
ARGFD6(*(pRGB - 2), 1, 6)
|
|
ARGFD6(*(pRGB - 1), 1, 6)
|
|
ARGFD6(*(pRGB ), 1, 6)
|
|
ARGFD6(MaxClr, 1, 6)
|
|
ARG((Negative) ? "*NEG CLAMP*" : "")));
|
|
} else {
|
|
|
|
DBGP_IF(DBGP_SCALE_RGB,
|
|
{
|
|
|
|
if (Negative) {
|
|
|
|
DBGP("*NEG CLAMP ONLY* ScaleRGB: %s:%s:%s -> %s:%s:%s"
|
|
ARGFD6(RGBOld[2], 1, 6)
|
|
ARGFD6(RGBOld[1], 1, 6)
|
|
ARGFD6(RGBOld[0], 1, 6)
|
|
ARGFD6(*(pRGB ), 1, 6)
|
|
ARGFD6(*(pRGB + 1), 1, 6)
|
|
ARGFD6(*(pRGB + 2), 1, 6));
|
|
}
|
|
}
|
|
)
|
|
}
|
|
}
|
|
|
|
|
|
#else
|
|
|
|
|
|
VOID
|
|
HTENTRY
|
|
ScaleRGB(
|
|
PFD6 pRGB,
|
|
PFD6 pYrgb
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function scale out of range RGB back into range and taking the
|
|
lumminance of the color into consideration.
|
|
|
|
if any of RGB is less then 0.0 then it will first clamp that to 0.0 and
|
|
it only scale if any of RGB is greater then 1.0
|
|
|
|
Arguments:
|
|
|
|
pRGB - Pointer to RGB (FD6) prims to be adjust
|
|
|
|
pYrgb - Pinter to the Luminance (FD6) of the RGB, if NULL then it is not
|
|
used in the computation
|
|
|
|
|
|
Return Value:
|
|
|
|
VOID
|
|
|
|
|
|
Author:
|
|
|
|
08-Mar-1995 Wed 19:19:33 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
FD6 MaxClr = FD6_1;
|
|
FD6 MinClr = FD6_10;
|
|
FD6 RGBNew[3];
|
|
FD6 RGBOld[3];
|
|
|
|
|
|
|
|
if ((RGBOld[0] = pRGB[0]) > (RGBOld[1] = pRGB[1])) {
|
|
|
|
MaxClr = RGBOld[0];
|
|
MinClr = RGBOld[1];
|
|
|
|
} else {
|
|
|
|
MaxClr = RGBOld[1];
|
|
MinClr = RGBOld[0];
|
|
}
|
|
|
|
if ((RGBOld[2] = pRGB[2]) > MaxClr) {
|
|
|
|
MaxClr = RGBOld[2];
|
|
}
|
|
|
|
if (RGBOld[2] < MinClr) {
|
|
|
|
MinClr = RGBOld[2];
|
|
}
|
|
|
|
if ((MaxClr <= FD6_1) && (MinClr >= FD6_0)) {
|
|
|
|
return;
|
|
}
|
|
|
|
if (MinClr >= FD6_1) {
|
|
|
|
DBGP_IF((DBGP_SCALE_RGB | DBGP_SCALE_RGB),
|
|
DBGP("** RGB %s:%s:%s is too LIGHT make it WHITE"
|
|
ARGFD6(RGBOld[0], 1, 6)
|
|
ARGFD6(RGBOld[1], 1, 6)
|
|
ARGFD6(RGBOld[2], 1, 6)));
|
|
|
|
pRGB[0] =
|
|
pRGB[1] =
|
|
pRGB[2] = FD6_1;
|
|
|
|
return;
|
|
}
|
|
|
|
if (MaxClr <= FD6_0) {
|
|
|
|
DBGP_IF((DBGP_SCALE_RGB | DBGP_SCALE_RGB),
|
|
DBGP("** RGB %s:%s:%s is too DARK make it BLACK"
|
|
ARGFD6(RGBOld[0], 1, 6)
|
|
ARGFD6(RGBOld[1], 1, 6)
|
|
ARGFD6(RGBOld[2], 1, 6)));
|
|
|
|
pRGB[0] =
|
|
pRGB[1] =
|
|
pRGB[2] = FD6_0;
|
|
|
|
return;
|
|
}
|
|
|
|
if (MaxClr < FD6_1) {
|
|
|
|
MaxClr = FD6_1;
|
|
}
|
|
|
|
if (MinClr > FD6_0) {
|
|
|
|
MinClr = FD6_0;
|
|
}
|
|
|
|
MaxClr -= MinClr;
|
|
RGBNew[0] = DivFD6(RGBOld[0] - MinClr, MaxClr);
|
|
RGBNew[1] = DivFD6(RGBOld[1] - MinClr, MaxClr);
|
|
RGBNew[2] = DivFD6(RGBOld[2] - MinClr, MaxClr);
|
|
|
|
DBGP_IF(DBGP_SCALE_RGB,
|
|
DBGP("ScaleRGB: %s:%s:%s -> %s:%s:%s, (%s/%s, %s)"
|
|
ARGFD6(RGBOld[0], 1, 6)
|
|
ARGFD6(RGBOld[1], 1, 6)
|
|
ARGFD6(RGBOld[2], 1, 6)
|
|
ARGFD6(RGBNew[0], 1, 6)
|
|
ARGFD6(RGBNew[1], 1, 6)
|
|
ARGFD6(RGBNew[2], 1, 6)
|
|
ARGFD6(MinClr, 1, 6)
|
|
ARGFD6(MaxClr + MinClr, 1, 6)
|
|
ARGFD6(MaxClr, 1, 6)));
|
|
|
|
|
|
if (pYrgb) {
|
|
|
|
FD6 OldY;
|
|
|
|
if ((OldY = MulFD6(RGBOld[0], pYrgb[0]) +
|
|
MulFD6(RGBOld[1], pYrgb[1]) +
|
|
MulFD6(RGBOld[2], pYrgb[2])) <= FD6_0) {
|
|
|
|
DBGP_IF(DBGP_SHOWXFORM_RGB,
|
|
DBGP("OldY <= 0.0 (%s), Ignore and NO Y Scale"
|
|
ARGFD6(OldY, 2, 6)));
|
|
|
|
} else if (OldY >= FD6_1) {
|
|
|
|
DBGP_IF(DBGP_SHOWXFORM_RGB,
|
|
DBGP("OldY >= 1.0 (%s), Ignore and NO Y Scale"
|
|
ARGFD6(OldY, 2, 6)));
|
|
|
|
} else {
|
|
|
|
FD6 NewY;
|
|
FD6 CurRatio;
|
|
FD6 MaxRatio;
|
|
|
|
NewY = MulFD6(RGBNew[0], pYrgb[0]) +
|
|
MulFD6(RGBNew[1], pYrgb[1]) +
|
|
MulFD6(RGBNew[2], pYrgb[2]);
|
|
|
|
DBGP_IF(DBGP_SHOWXFORM_RGB,
|
|
DBGP("RGBOld=%s:%s:%s [Y=%s] --> New=%s:%s:%s [Y=%s]"
|
|
ARGFD6(pRGB[0], 1, 6)
|
|
ARGFD6(pRGB[1], 1, 6)
|
|
ARGFD6(pRGB[2], 1, 6)
|
|
ARGFD6(OldY, 1, 6)
|
|
ARGFD6(RGBNew[0], 1, 6)
|
|
ARGFD6(RGBNew[1], 1, 6)
|
|
ARGFD6(RGBNew[2], 1, 6)
|
|
ARGFD6(NewY, 1, 6)));
|
|
|
|
if (OldY != NewY) {
|
|
|
|
MaxClr = (RGBNew[0] > RGBNew[1]) ? RGBNew[0] : RGBNew[1];
|
|
|
|
if (RGBNew[2] > MaxClr) {
|
|
|
|
MaxClr = RGBNew[2];
|
|
}
|
|
|
|
MaxRatio = DivFD6(FD6_1, MaxClr);
|
|
CurRatio = DivFD6(OldY, NewY);
|
|
|
|
if (CurRatio > MaxRatio) {
|
|
|
|
CurRatio = MaxRatio;
|
|
}
|
|
|
|
RGBNew[0] = MulFD6(RGBNew[0], CurRatio);
|
|
RGBNew[1] = MulFD6(RGBNew[1], CurRatio);
|
|
RGBNew[2] = MulFD6(RGBNew[2], CurRatio);
|
|
|
|
DBGP_IF(DBGP_SHOWXFORM_RGB,
|
|
DBGP("CurRatio%s, MaxRatio=%s, MaxClr=%s"
|
|
ARGFD6(CurRatio, 1, 6)
|
|
ARGFD6(MaxRatio, 1, 6)
|
|
ARGFD6(MaxClr, 1, 6)));
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Save back and return
|
|
//
|
|
|
|
pRGB[0] = RGBNew[0];
|
|
pRGB[1] = RGBNew[1];
|
|
pRGB[2] = RGBNew[2];
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
LONG
|
|
HTENTRY
|
|
ComputeBGRMappingTable(
|
|
PDEVICECOLORINFO pDCI,
|
|
PDEVCLRADJ pDevClrAdj,
|
|
PCOLORTRIAD pSrcClrTriad,
|
|
PBGR8 pbgr
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This functions set up all the DECI4 value in PRIMRGB, PRIMCMY with
|
|
PowerGamma, Brightness, Contrast adjustment and optionally to transform
|
|
to C.I.E. color space and/or do the Colorfulness adjustment.
|
|
|
|
Arguments:
|
|
|
|
pDCI - Pointer to computed DEVICECOLORINFO
|
|
|
|
pDevClrAdj - Pointer to the pre-computed DEVCLRADJ data structure.
|
|
|
|
pSrcClrTriad - Pointer to the COLORTRIAD strcutrue for computation
|
|
|
|
pbgr - Pointer to the storage for computed BGR table
|
|
|
|
|
|
Return Value:
|
|
|
|
Return value LONG
|
|
|
|
Count of table generated, if < 0 then it is an error number
|
|
|
|
|
|
Author:
|
|
|
|
30-Jan-1991 Wed 13:31:58 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
06-Feb-1992 Thu 21:39:46 updated -by- Daniel Chou (danielc)
|
|
|
|
Rewrite!
|
|
|
|
02-Feb-1994 Wed 17:33:55 updated -by- Daniel Chou (danielc)
|
|
Remove unreferenced/unused variable L
|
|
|
|
10-May-1994 Tue 11:24:16 updated -by- Daniel Chou (danielc)
|
|
Bug# 13329, Memory Leak, Free Up pR_XYZ which I fogot to free it after
|
|
allocated it.
|
|
|
|
17-Dec-1998 Thu 16:33:16 updated -by- Daniel Chou (danielc)
|
|
Re-organized so it use pbgr now, and it will only generate for color
|
|
|
|
15-Feb-1999 Mon 15:40:03 updated -by- Daniel Chou (danielc)
|
|
Re-do it only BGR 3 bytes for each entry, and it will generate both
|
|
color or gray scale conversion, all color mapping for coloradjustment
|
|
is done here, this includes internal ICM (when external icm is off)
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
PFD6 pPrimA;
|
|
PFD6 pPrimB;
|
|
PFD6 pPrimC;
|
|
LPBYTE pSrcPrims;
|
|
PCACHERGBTOXYZ pCRTX;
|
|
PFD6XYZ pR_XYZ = NULL;
|
|
PFD6XYZ pG_XYZ;
|
|
PFD6XYZ pB_XYZ;
|
|
COLORTRIAD SrcClrTriad;
|
|
PMATRIX3x3 pCMYDyeMasks;
|
|
DWORD Loop;
|
|
DWORD CRTXChecksum;
|
|
DWORD PrimAdjFlags;
|
|
FD6 Prim[3];
|
|
FD6 X;
|
|
FD6 Y;
|
|
FD6 Z;
|
|
FD6 AU;
|
|
FD6 BV;
|
|
FD6 U1;
|
|
FD6 V1;
|
|
FD6 p0;
|
|
FD6 p1;
|
|
FD6 p2;
|
|
FD6 C;
|
|
FD6 W;
|
|
FD6 AutoPrims[3];
|
|
MULDIVPAIR MDPairs[4];
|
|
MULDIVPAIR AUMDPairs[3];
|
|
MULDIVPAIR BVMDPairs[3];
|
|
RGBORDER RGBOrder;
|
|
INT TempI;
|
|
INT TempJ;
|
|
BYTE DataSet[8];
|
|
|
|
DEFDBGVAR(WORD, ClrNo)
|
|
DEFDBGVAR(BYTE, dbgR)
|
|
DEFDBGVAR(BYTE, dbgG)
|
|
DEFDBGVAR(BYTE, dbgB)
|
|
|
|
#define _SrcPrimType DataSet[ 0]
|
|
#define _DevBytesPerPrimary DataSet[ 1]
|
|
#define _DevBytesPerEntry DataSet[ 2]
|
|
#define _ColorSpace DataSet[ 3]
|
|
#define _fX p0
|
|
#define _fY p1
|
|
#define _fZ p2
|
|
#define _X15Y3Z C
|
|
#define _L13 W
|
|
|
|
SETDBGVAR(ClrNo, 0);
|
|
|
|
if (pSrcClrTriad) {
|
|
|
|
SrcClrTriad = *pSrcClrTriad;
|
|
|
|
} else {
|
|
|
|
SrcClrTriad.Type = COLOR_TYPE_RGB;
|
|
SrcClrTriad.BytesPerPrimary = 0;
|
|
SrcClrTriad.BytesPerEntry = 0;
|
|
SrcClrTriad.PrimaryOrder = PRIMARY_ORDER_RGB;
|
|
SrcClrTriad.PrimaryValueMax = 0xFF;
|
|
SrcClrTriad.ColorTableEntries = HT_RGB_CUBE_COUNT;
|
|
SrcClrTriad.pColorTable = (LPBYTE)&Prim[0];
|
|
}
|
|
|
|
if (SrcClrTriad.Type != COLOR_TYPE_RGB) {
|
|
|
|
return(HTERR_INVALID_COLOR_TYPE);
|
|
}
|
|
|
|
//
|
|
// Two possible cases:
|
|
//
|
|
// A: The transform is used for color adjustment only, this is for
|
|
// HT_AdjustColorTable API call
|
|
//
|
|
// B: The halftone is taking places, the final output will be either
|
|
// Prim1/2 or Prim1/2/3 and each primary must 1 byte long.
|
|
//
|
|
|
|
PrimAdjFlags = pDevClrAdj->PrimAdj.Flags;
|
|
|
|
ASSERT((PrimAdjFlags & (DCA_HAS_SRC_GAMMA |
|
|
DCA_HAS_DEST_GAMMA |
|
|
DCA_HAS_BW_REF_ADJ |
|
|
DCA_HAS_CONTRAST_ADJ |
|
|
DCA_HAS_BRIGHTNESS_ADJ |
|
|
DCA_LOG_FILTER |
|
|
DCA_NEGATIVE |
|
|
DCA_DO_DEVCLR_XFORM)) == 0);
|
|
|
|
//
|
|
// We will not do regression (source to destination mapping) for
|
|
//
|
|
// 1. ICM is ON
|
|
// 2. Subtractive with 24bpp
|
|
// 3. Additive surface.
|
|
//
|
|
|
|
if (pbgr) {
|
|
|
|
_DevBytesPerEntry = (BYTE)pDevClrAdj->DMI.CTSTDInfo.cbPrim;
|
|
_DevBytesPerPrimary = 1;
|
|
|
|
ASSERT(_DevBytesPerEntry == sizeof(BGR8));
|
|
|
|
} else {
|
|
|
|
return(HTERR_INVALID_COLOR_TYPE);
|
|
}
|
|
|
|
if (!(pSrcPrims = (LPBYTE)SrcClrTriad.pColorTable)) {
|
|
|
|
return(HTERR_INVALID_COLOR_TABLE);
|
|
}
|
|
|
|
//
|
|
// If the total color table entries is less than MIN_CCT_COLORS then
|
|
// we just compute the color directly
|
|
//
|
|
|
|
pCRTX = NULL;
|
|
|
|
DBGP_IF(DBGP_CCT,
|
|
DBGP("PrimAdjFlags=%08lx" ARGDW(PrimAdjFlags)));
|
|
|
|
if (SrcClrTriad.BytesPerPrimary) {
|
|
|
|
//
|
|
// Something passed
|
|
//
|
|
|
|
RGBOrder = SrcOrderTable[SrcClrTriad.PrimaryOrder];
|
|
pPrimA = &Prim[RGBOrder.Order[0]];
|
|
pPrimB = &Prim[RGBOrder.Order[1]];
|
|
pPrimC = &Prim[RGBOrder.Order[2]];
|
|
|
|
DBGP_IF(DBGP_PRIMARY_ORDER,
|
|
DBGP("SOURCE PrimaryOrder: %u [%u] - %u:%u:%u"
|
|
ARGU(SrcClrTriad.PrimaryOrder)
|
|
ARGU(RGBOrder.Index) ARGU(RGBOrder.Order[0])
|
|
ARGU(RGBOrder.Order[1]) ARGU(RGBOrder.Order[2])));
|
|
}
|
|
|
|
//
|
|
// Now compute the cache info
|
|
//
|
|
|
|
switch (SrcClrTriad.BytesPerPrimary) {
|
|
|
|
case 0:
|
|
|
|
SrcClrTriad.BytesPerEntry = 0; // stay there!!
|
|
_SrcPrimType = SRC_BF_HT_RGB;
|
|
SrcClrTriad.PrimaryValueMax = HT_RGB_MAX_COUNT - 1;
|
|
pCRTX = pDevClrAdj->pCRTXLevelRGB;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
_SrcPrimType = SRC_TABLE_BYTE;
|
|
break;
|
|
|
|
case 2:
|
|
|
|
_SrcPrimType = SRC_TABLE_WORD;
|
|
break;
|
|
|
|
case 4:
|
|
|
|
_SrcPrimType = SRC_TABLE_DWORD;
|
|
break;
|
|
|
|
default:
|
|
|
|
return(INTERR_INVALID_SRCRGB_SIZE);
|
|
}
|
|
|
|
if (PrimAdjFlags & DCA_NEED_DYES_CORRECTION) {
|
|
|
|
pCMYDyeMasks = &(pDevClrAdj->pClrXFormBlock->CMYDyeMasks);
|
|
}
|
|
|
|
_ColorSpace = (BYTE)pDevClrAdj->pClrXFormBlock->ColorSpace;
|
|
|
|
if (((_ColorSpace == CIELUV_1976) &&
|
|
((pDevClrAdj->PrimAdj.rgbCSXForm.xW !=
|
|
pDevClrAdj->PrimAdj.DevCSXForm.xW) ||
|
|
(pDevClrAdj->PrimAdj.rgbCSXForm.yW !=
|
|
pDevClrAdj->PrimAdj.DevCSXForm.yW))) ||
|
|
(PrimAdjFlags & (DCA_HAS_CLRSPACE_ADJ |
|
|
DCA_HAS_COLOR_ADJ |
|
|
DCA_HAS_TINT_ADJ))) {
|
|
|
|
TempI = 1;
|
|
TempJ = (_ColorSpace == CIELUV_1976) ? MULDIV_HAS_DIVISOR :
|
|
MULDIV_NO_DIVISOR;
|
|
C = FD6_1;
|
|
AU =
|
|
BV = (PrimAdjFlags & DCA_HAS_COLOR_ADJ) ?
|
|
pDevClrAdj->PrimAdj.Color : FD6_1;
|
|
|
|
if (PrimAdjFlags & DCA_HAS_TINT_ADJ) {
|
|
|
|
if (_ColorSpace == CIELAB_1976) {
|
|
|
|
AU = FD6xL(AU, 500);
|
|
BV = FD6xL(BV, 200);
|
|
}
|
|
|
|
TempI = 2;
|
|
TempJ = MULDIV_HAS_DIVISOR;
|
|
C = pDevClrAdj->PrimAdj.TintSinAngle;
|
|
AUMDPairs[2].Pair1.Mul = MulFD6(BV, -C);
|
|
BVMDPairs[2].Pair1.Mul = MulFD6(AU, C);
|
|
C = pDevClrAdj->PrimAdj.TintCosAngle;
|
|
|
|
MAKE_MULDIV_DVSR(AUMDPairs, (FD6)500000000);
|
|
MAKE_MULDIV_DVSR(BVMDPairs, (FD6)200000000);
|
|
}
|
|
|
|
AUMDPairs[1].Pair1.Mul = MulFD6(AU, C);
|
|
BVMDPairs[1].Pair1.Mul = MulFD6(BV, C);
|
|
|
|
MAKE_MULDIV_INFO(AUMDPairs, TempI, TempJ);
|
|
MAKE_MULDIV_INFO(BVMDPairs, TempI, TempJ);
|
|
}
|
|
|
|
DBGP_IF(DBGP_SHOWXFORM_ALL,
|
|
DBGP("iUVw = %s,%s, iRefXYZ = %s, %s, %s"
|
|
ARGFD6(iUw, 1, 6)
|
|
ARGFD6(iVw, 1, 6)
|
|
ARGFD6(iRefXw, 1, 6)
|
|
ARGFD6(iRefYw, 1, 6)
|
|
ARGFD6(iRefZw, 1, 6)));
|
|
|
|
DBGP_IF(DBGP_SHOWXFORM_ALL,
|
|
DBGP("oUVw = %s,%s, oRefXYZ = %s, %s, %s"
|
|
ARGFD6(oUw, 1, 6)
|
|
ARGFD6(oVw, 1, 6)
|
|
ARGFD6(oRefXw, 1, 6)
|
|
ARGFD6(oRefYw, 1, 6)
|
|
ARGFD6(oRefZw, 1, 6)));
|
|
|
|
if (pCRTX) {
|
|
|
|
DBGP_IF(DBGP_CCT,
|
|
DBGP("*** Allocate %u bytes RGB->XYZ xform table ***"
|
|
ARGU(pCRTX->SizeCRTX)));
|
|
|
|
if (pR_XYZ = (PFD6XYZ)HTAllocMem((LPVOID)pDCI,
|
|
HTMEM_RGBToXYZ,
|
|
NONZEROLPTR,
|
|
pCRTX->SizeCRTX)) {
|
|
|
|
Loop = (DWORD)(pCRTX->PrimMax + 1);
|
|
|
|
//
|
|
// Save current flags back before calling, since CachedRGBToXYZ
|
|
// may change this flags for DCA_xxx
|
|
//
|
|
|
|
pCRTX = CacheRGBToXYZ(pCRTX,
|
|
pR_XYZ,
|
|
&CRTXChecksum,
|
|
pDevClrAdj);
|
|
pG_XYZ = pR_XYZ + Loop;
|
|
pB_XYZ = pG_XYZ + Loop;
|
|
SrcClrTriad.PrimaryValueMax = 0;
|
|
|
|
DBGP_IF(DBGP_CCT, DBGP("*** Has RGB->XYZ xform table ***"));
|
|
|
|
} else {
|
|
|
|
DBGP_IF(DBGP_CCT, DBGP("Allocate RGB->XYZ xform table failed !!"));
|
|
}
|
|
}
|
|
|
|
if (SrcClrTriad.PrimaryValueMax == (LONG)FD6_1) {
|
|
|
|
SrcClrTriad.PrimaryValueMax = 0;
|
|
}
|
|
|
|
//
|
|
// Starting the big Loop, reset AutoCur = AutoMax so it recycle back to
|
|
// 0:0:0
|
|
//
|
|
|
|
MAKE_MULDIV_SIZE(MDPairs, 3);
|
|
MAKE_MULDIV_FLAG(MDPairs, MULDIV_NO_DIVISOR);
|
|
|
|
AutoPrims[0] =
|
|
AutoPrims[1] =
|
|
AutoPrims[2] = FD6_0;
|
|
Loop = SrcClrTriad.ColorTableEntries;
|
|
|
|
DBGP_IF(DBGP_CCT,
|
|
DBGP("Compute %ld COLOR of %s type [%p]"
|
|
ARGDW(Loop)
|
|
ARG(pSrcPrimTypeName[_SrcPrimType])
|
|
ARGPTR(pSrcPrims)));
|
|
|
|
//
|
|
// 0. Get The source prim into the Prim[]
|
|
//
|
|
|
|
while (Loop--) {
|
|
|
|
switch (_SrcPrimType) {
|
|
|
|
case SRC_BF_HT_RGB:
|
|
|
|
//
|
|
// This format always in BGR order
|
|
//
|
|
|
|
Prim[0] = AutoPrims[0]; // R
|
|
Prim[1] = AutoPrims[1]; // G
|
|
Prim[2] = AutoPrims[2]; // B
|
|
|
|
if (++AutoPrims[0] >= (FD6)HT_RGB_MAX_COUNT) {
|
|
|
|
AutoPrims[0] = FD6_0;
|
|
|
|
if (++AutoPrims[1] >= (FD6)HT_RGB_MAX_COUNT) {
|
|
|
|
AutoPrims[1] = FD6_0;
|
|
|
|
if (++AutoPrims[2] >= (FD6)HT_RGB_MAX_COUNT) {
|
|
|
|
AutoPrims[2] = FD6_0;
|
|
}
|
|
}
|
|
}
|
|
|
|
DBGP_IF(DBGP_SHOWXFORM_ALL, DBGP("HT555: Prim[3]= %2ld:%2ld:%2ld, %s:%s:%s, (%ld / %ld)"
|
|
ARGDW(Prim[0])
|
|
ARGDW(Prim[1])
|
|
ARGDW(Prim[2])
|
|
ARGFD6(DivFD6(Prim[0], (FD6)(HT_RGB_MAX_COUNT - 1)), 1, 6)
|
|
ARGFD6(DivFD6(Prim[1], (FD6)(HT_RGB_MAX_COUNT - 1)), 1, 6)
|
|
ARGFD6(DivFD6(Prim[2], (FD6)(HT_RGB_MAX_COUNT - 1)), 1, 6)
|
|
ARGDW(HT_RGB_MAX_COUNT)
|
|
ARGDW(SrcClrTriad.PrimaryValueMax)));
|
|
|
|
break;
|
|
|
|
case SRC_TABLE_BYTE:
|
|
|
|
*pPrimA = (FD6)(*(LPBYTE)(pSrcPrims ));
|
|
*pPrimB = (FD6)(*(LPBYTE)(pSrcPrims + (sizeof(BYTE) * 1)));
|
|
*pPrimC = (FD6)(*(LPBYTE)(pSrcPrims + (sizeof(BYTE) * 2)));
|
|
break;
|
|
|
|
case SRC_TABLE_WORD:
|
|
|
|
*pPrimA = (FD6)(*(LPSHORT)(pSrcPrims ));
|
|
*pPrimB = (FD6)(*(LPSHORT)(pSrcPrims + (sizeof(SHORT) * 1)));
|
|
*pPrimC = (FD6)(*(LPSHORT)(pSrcPrims + (sizeof(SHORT) * 2)));
|
|
break;
|
|
|
|
case SRC_TABLE_DWORD:
|
|
|
|
*pPrimA = (FD6)(*(PFD6)(pSrcPrims ));
|
|
*pPrimB = (FD6)(*(PFD6)(pSrcPrims + (sizeof(FD6) * 1)));
|
|
*pPrimC = (FD6)(*(PFD6)(pSrcPrims + (sizeof(FD6) * 2)));
|
|
break;
|
|
}
|
|
|
|
SETDBGVAR(dbgR, (BYTE)Prim[0]);
|
|
SETDBGVAR(dbgG, (BYTE)Prim[1]);
|
|
SETDBGVAR(dbgB, (BYTE)Prim[2]);
|
|
|
|
pSrcPrims += SrcClrTriad.BytesPerEntry;
|
|
|
|
//
|
|
// 1. First convert the Input value to FD6
|
|
//
|
|
|
|
if (SrcClrTriad.PrimaryValueMax) {
|
|
|
|
Prim[0] = DivFD6(Prim[0], SrcClrTriad.PrimaryValueMax);
|
|
Prim[1] = DivFD6(Prim[1], SrcClrTriad.PrimaryValueMax);
|
|
Prim[2] = DivFD6(Prim[2], SrcClrTriad.PrimaryValueMax);
|
|
}
|
|
|
|
//
|
|
// 2: Transform from RGB (gamma correction) -> XYZ -> L*A*B* or L*U*V*
|
|
// This only done if any of DCA_HAS_COLOR_ADJ or DCA_HAS_TINT_ADJ
|
|
//
|
|
|
|
if (PrimAdjFlags & (DCA_HAS_CLRSPACE_ADJ |
|
|
DCA_HAS_COLOR_ADJ |
|
|
DCA_HAS_TINT_ADJ)) {
|
|
|
|
// If we only doing monochrome, then we only need Y/L pair only,
|
|
// else convert it to the XYZ/LAB/LUV
|
|
//
|
|
|
|
if (pR_XYZ) {
|
|
|
|
X = pR_XYZ[Prim[0]].X +
|
|
pG_XYZ[Prim[1]].X +
|
|
pB_XYZ[Prim[2]].X;
|
|
|
|
Y = pR_XYZ[Prim[0]].Y +
|
|
pG_XYZ[Prim[1]].Y +
|
|
pB_XYZ[Prim[2]].Y;
|
|
|
|
Z = pR_XYZ[Prim[0]].Z +
|
|
pG_XYZ[Prim[1]].Z +
|
|
pB_XYZ[Prim[2]].Z;
|
|
|
|
DBGP_IF(DBGP_SHOWXFORM_ALL,
|
|
DBGP("Yrgb: %s:%s:%s"
|
|
ARGFD6(pR_XYZ[Prim[0]].Y, 1, 6)
|
|
ARGFD6(pG_XYZ[Prim[1]].Y, 1, 6)
|
|
ARGFD6(pB_XYZ[Prim[2]].Y, 1, 6)));
|
|
|
|
|
|
} else {
|
|
|
|
MAKE_MULDIV_FLAG(MDPairs, MULDIV_NO_DIVISOR);
|
|
|
|
MAKE_MULDIV_PAIR(
|
|
MDPairs, 1,
|
|
CIE_Xr(pDevClrAdj->PrimAdj.rgbCSXForm.M3x3),
|
|
Prim[0]);
|
|
MAKE_MULDIV_PAIR(
|
|
MDPairs, 2,
|
|
CIE_Xg(pDevClrAdj->PrimAdj.rgbCSXForm.M3x3),
|
|
Prim[1]);
|
|
MAKE_MULDIV_PAIR(
|
|
MDPairs, 3,
|
|
CIE_Xb(pDevClrAdj->PrimAdj.rgbCSXForm.M3x3),
|
|
Prim[2]);
|
|
|
|
X = MulDivFD6Pairs(MDPairs);
|
|
|
|
//
|
|
// Compute CIE L from CIE Y tristimulus value
|
|
//
|
|
// L* = (1.16 x f(Y/Yw)) - 0.16
|
|
//
|
|
// 1/3
|
|
// f(Y/Yw) = (Y/Yw) (Y/Yw) > 0.008856
|
|
// f(Y/Yw) = 9.033 x (Y/Yw) (Y/Yw) <= 0.008856
|
|
//
|
|
//
|
|
// Our L* is range from 0.0 to 1.0, not 0.0 to 100.0
|
|
//
|
|
|
|
MAKE_MULDIV_PAIR(
|
|
MDPairs, 1,
|
|
CIE_Yr(pDevClrAdj->PrimAdj.rgbCSXForm.M3x3),
|
|
Prim[0]);
|
|
MAKE_MULDIV_PAIR(
|
|
MDPairs, 2,
|
|
CIE_Yg(pDevClrAdj->PrimAdj.rgbCSXForm.M3x3),
|
|
Prim[1]);
|
|
MAKE_MULDIV_PAIR(
|
|
MDPairs, 3,
|
|
CIE_Yb(pDevClrAdj->PrimAdj.rgbCSXForm.M3x3),
|
|
Prim[2]);
|
|
|
|
Y = MulDivFD6Pairs(MDPairs);
|
|
|
|
MAKE_MULDIV_PAIR(
|
|
MDPairs, 1,
|
|
CIE_Zr(pDevClrAdj->PrimAdj.rgbCSXForm.M3x3),
|
|
Prim[0]);
|
|
MAKE_MULDIV_PAIR(
|
|
MDPairs, 2,
|
|
CIE_Zg(pDevClrAdj->PrimAdj.rgbCSXForm.M3x3),
|
|
Prim[1]);
|
|
MAKE_MULDIV_PAIR(
|
|
MDPairs, 3,
|
|
CIE_Zb(pDevClrAdj->PrimAdj.rgbCSXForm.M3x3),
|
|
Prim[2]);
|
|
|
|
Z = MulDivFD6Pairs(MDPairs);
|
|
|
|
}
|
|
|
|
switch (_ColorSpace) {
|
|
|
|
case CIELUV_1976:
|
|
|
|
//
|
|
// U' = 4X / (X + 15Y + 3Z)
|
|
// V' = 9Y / (X + 15Y + 3Z)
|
|
//
|
|
// U* = 13 x L x (U' - Uw)
|
|
// V* = 13 x L x (V' - Vw)
|
|
//
|
|
|
|
_X15Y3Z = X + FD6xL(Y, 15) + FD6xL(Z, 3);
|
|
U1 = DivFD6(FD6xL(X, 4), _X15Y3Z) - iUw;
|
|
V1 = DivFD6(FD6xL(Y, 9), _X15Y3Z) - iVw;
|
|
_L13 = FD6xL(CIE_I2L(Y), 13);
|
|
AU = MulFD6(_L13, U1);
|
|
BV = MulFD6(_L13, V1);
|
|
|
|
MAKE_MULDIV_DVSR(AUMDPairs, _L13);
|
|
MAKE_MULDIV_DVSR(BVMDPairs, _L13);
|
|
|
|
DBGP_IF(DBGP_SHOWXFORM_ALL,
|
|
DBGP(" << UV1: %s:%s [%s:%s], X15Y3Z=%s"
|
|
ARGFD6(U1, 2, 6)
|
|
ARGFD6(V1, 2, 6)
|
|
ARGFD6(U1 + iUw, 2, 6)
|
|
ARGFD6(V1 + iVw, 2, 6)
|
|
ARGFD6(_X15Y3Z, 2, 6)));
|
|
|
|
break;
|
|
|
|
case CIELAB_1976:
|
|
default:
|
|
|
|
//
|
|
// CIELAB 1976 L*A*B*
|
|
//
|
|
// A* = 500 x (fX - fY)
|
|
// B* = 200 x (fY - fZ)
|
|
//
|
|
// 1/3
|
|
// fX = (X/Xw) (X/Xw) > 0.008856
|
|
// fX = 7.787 x (X/Xw) + (16/116) (X/Xw) <= 0.008856
|
|
//
|
|
// 1/3
|
|
// fY = (Y/Yw) (Y/Yw) > 0.008856
|
|
// fY = 7.787 Y (Y/Yw) + (16/116) (Y/Yw) <= 0.008856
|
|
//
|
|
// 1/3
|
|
// fZ = (Z/Zw) (Z/Zw) > 0.008856
|
|
// fZ = 7.787 Z (Z/Zw) + (16/116) (Z/Zw) <= 0.008856
|
|
//
|
|
|
|
fXYZFromXYZ(_fX, X, iRefXw);
|
|
fXYZFromXYZ(_fY, Y, FD6_1);
|
|
fXYZFromXYZ(_fZ, Z, iRefZw);
|
|
|
|
DBGP_IF(DBGP_SHOWXFORM_ALL,
|
|
DBGP(" >> fXYZ: %s:%s:%s"
|
|
ARGFD6(_fX, 2, 6)
|
|
ARGFD6(_fY, 2, 6)
|
|
ARGFD6(_fZ, 2, 6)));
|
|
|
|
AU = _fX - _fY;
|
|
BV = _fY - _fZ;
|
|
|
|
//
|
|
// DO NOT Translate it now
|
|
//
|
|
|
|
if ((AU >= (FD6)-20) && (AU <= (FD6)20) &&
|
|
(BV >= (FD6)-20) && (BV <= (FD6)20)) {
|
|
|
|
DBGP_IF(DBGP_MONO_PRIM,
|
|
DBGP("*** MONO PRIMS: %s:%s:%s --> Y=%s"
|
|
ARGFD6(DivFD6(dbgR, 255), 1, 6)
|
|
ARGFD6(DivFD6(dbgG, 255), 1, 6)
|
|
ARGFD6(DivFD6(dbgB, 255), 1, 6)
|
|
ARGFD6(Y, 1, 6)));
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
DBGP_IF(DBGP_SHOWXFORM_ALL,
|
|
DBGP(" XYZ->%s: %s:%s:%s >> L:%s:%s"
|
|
ARG(pDbgCSName[_ColorSpace])
|
|
ARGFD6(X, 2, 6)
|
|
ARGFD6(Y, 1, 6)
|
|
ARGFD6(Z, 2, 6)
|
|
ARGFD6(AU, 4, 6)
|
|
ARGFD6(BV, 4, 6)));
|
|
|
|
//
|
|
// 5: Do any Color Adjustments (in LAB/LUV)
|
|
//
|
|
|
|
AUMDPairs[1].Pair2 =
|
|
BVMDPairs[2].Pair2 = AU;
|
|
AUMDPairs[2].Pair2 =
|
|
BVMDPairs[1].Pair2 = BV;
|
|
|
|
AU = MulDivFD6Pairs(AUMDPairs);
|
|
BV = MulDivFD6Pairs(BVMDPairs);
|
|
|
|
//
|
|
// 6: Transform From LAB/LUV->XYZ->RGB with possible gamma
|
|
// correction
|
|
//
|
|
// L* = (1.16 x f(Y/Yw)) - 0.16
|
|
//
|
|
// 1/3
|
|
// f(Y/Yw) = (Y/Yw) (Y/Yw) > 0.008856
|
|
// f(Y/Yw) = 9.033 x (Y/Yw) (Y/Yw) <= 0.008856
|
|
//
|
|
|
|
switch (_ColorSpace) {
|
|
|
|
case CIELUV_1976:
|
|
|
|
//
|
|
// U' = 4X / (X + 15Y + 3Z)
|
|
// V' = 9Y / (X + 15Y + 3Z)
|
|
//
|
|
// U* = 13 x L x (U' - Uw)
|
|
// V* = 13 x L x (V' - Vw)
|
|
//
|
|
|
|
if (((V1 = BV + oVw) < FD6_0) ||
|
|
((_X15Y3Z = DivFD6(FD6xL(Y, 9), V1)) < FD6_0)) {
|
|
|
|
_X15Y3Z = (FD6)2147000000;
|
|
}
|
|
|
|
if ((U1 = AU + oUw) < FD6_0) {
|
|
|
|
X =
|
|
U1 = FD6_0;
|
|
|
|
} else {
|
|
|
|
X = FD6DivL(MulFD6(_X15Y3Z, U1), 4);
|
|
}
|
|
|
|
Z = FD6DivL(_X15Y3Z - X - FD6xL(Y, 15), 3);
|
|
|
|
DBGP_IF(DBGP_SHOWXFORM_ALL,
|
|
DBGP(" >> UV1: %s:%s [%s:%s], X15Y3Z=%s"
|
|
ARGFD6(U1 - oUw, 2, 6)
|
|
ARGFD6(V1 - oVw, 2, 6)
|
|
ARGFD6(U1, 2, 6)
|
|
ARGFD6(V1, 2, 6)
|
|
ARGFD6(_X15Y3Z, 2, 6)));
|
|
|
|
break;
|
|
|
|
case CIELAB_1976:
|
|
default:
|
|
|
|
//
|
|
// CIELAB 1976 L*A*B*
|
|
//
|
|
// A* = 500 x (fX - fY)
|
|
// B* = 200 x (fY - fZ)
|
|
//
|
|
// 1/3
|
|
// fX = (X/Xw) (X/Xw) > 0.008856
|
|
// fX = 7.787 x (X/Xw) + (16/116) (X/Xw) <= 0.008856
|
|
//
|
|
// 1/3
|
|
// fY = (Y/Yw) (Y/Yw) > 0.008856
|
|
// fY = 7.787 Y (Y/Yw) + (16/116) (Y/Yw) <= 0.008856
|
|
//
|
|
// 1/3
|
|
// fZ = (Z/Zw) (Z/Zw) > 0.008856
|
|
// fZ = 7.787 Z (Z/Zw) + (16/116) (Z/Zw) <= 0.008856
|
|
//
|
|
|
|
// _fX = FD6DivL(AU, 500) + _fY;
|
|
// _fZ = _fY - FD6DivL(BV, 200);
|
|
|
|
_fX = AU + _fY;
|
|
_fZ = _fY - BV;
|
|
|
|
XYZFromfXYZ(X, _fX, oRefXw);
|
|
XYZFromfXYZ(Z, _fZ, oRefZw);
|
|
|
|
DBGP_IF(DBGP_SHOWXFORM_ALL,
|
|
DBGP(" << fXYZ: %s:%s:%s"
|
|
ARGFD6(_fX, 2, 6)
|
|
ARGFD6(_fY, 2, 6)
|
|
ARGFD6(_fZ, 2, 6)));
|
|
|
|
|
|
|
|
break;
|
|
}
|
|
|
|
DBGP_IF(DBGP_SHOWXFORM_ALL,
|
|
DBGP(" %s->XYZ: %s:%s:%s << L:%s:%s"
|
|
ARG(pDbgCSName[_ColorSpace])
|
|
ARGFD6(X, 2, 6)
|
|
ARGFD6(Y, 1, 6)
|
|
ARGFD6(Z, 2, 6)
|
|
ARGFD6(AU, 4, 6)
|
|
ARGFD6(BV, 4, 6)));
|
|
|
|
MAKE_MULDIV_FLAG(MDPairs, MULDIV_NO_DIVISOR);
|
|
|
|
MAKE_MULDIV_PAIR(MDPairs, 1,
|
|
CIE_Xr(pDevClrAdj->PrimAdj.DevCSXForm.M3x3), X);
|
|
MAKE_MULDIV_PAIR(MDPairs, 2,
|
|
CIE_Xg(pDevClrAdj->PrimAdj.DevCSXForm.M3x3), Y);
|
|
MAKE_MULDIV_PAIR(MDPairs, 3,
|
|
CIE_Xb(pDevClrAdj->PrimAdj.DevCSXForm.M3x3), Z);
|
|
|
|
Prim[0] = MulDivFD6Pairs(MDPairs);
|
|
|
|
MAKE_MULDIV_PAIR(MDPairs, 1,
|
|
CIE_Yr(pDevClrAdj->PrimAdj.DevCSXForm.M3x3), X);
|
|
MAKE_MULDIV_PAIR(MDPairs, 2,
|
|
CIE_Yg(pDevClrAdj->PrimAdj.DevCSXForm.M3x3), Y);
|
|
MAKE_MULDIV_PAIR(MDPairs, 3,
|
|
CIE_Yb(pDevClrAdj->PrimAdj.DevCSXForm.M3x3), Z);
|
|
|
|
Prim[1] = MulDivFD6Pairs(MDPairs);
|
|
|
|
MAKE_MULDIV_PAIR(MDPairs, 1,
|
|
CIE_Zr(pDevClrAdj->PrimAdj.DevCSXForm.M3x3), X);
|
|
MAKE_MULDIV_PAIR(MDPairs, 2,
|
|
CIE_Zg(pDevClrAdj->PrimAdj.DevCSXForm.M3x3), Y);
|
|
MAKE_MULDIV_PAIR(MDPairs, 3,
|
|
CIE_Zb(pDevClrAdj->PrimAdj.DevCSXForm.M3x3), Z);
|
|
|
|
Prim[2] = MulDivFD6Pairs(MDPairs);
|
|
|
|
//
|
|
// Make sure everthing is in the range
|
|
//
|
|
|
|
SCALE_PRIM_RGB(Prim, NULL);
|
|
|
|
DBGP_IF(DBGP_SHOWXFORM_ALL,
|
|
DBGP(" XYZ->RGB: %s:%s:%s >> %s:%s:%s"
|
|
ARGFD6(X, 2, 6) ARGFD6(Y, 1, 6)
|
|
ARGFD6(Z, 2, 6) ARGFD6(Prim[0], 1, 6)
|
|
ARGFD6(Prim[1], 1, 6) ARGFD6(Prim[2], 1, 6)));
|
|
}
|
|
|
|
//
|
|
// 3: Dye correction if necessary
|
|
//
|
|
|
|
if (PrimAdjFlags & DCA_NEED_DYES_CORRECTION) {
|
|
|
|
if (PrimAdjFlags & DCA_HAS_BLACK_DYE) {
|
|
|
|
MAX_OF_3(W, Prim[0], Prim[1], Prim[2]);
|
|
|
|
} else {
|
|
|
|
W = FD6_1;
|
|
}
|
|
|
|
p0 = W - Prim[0];
|
|
p1 = W - Prim[1];
|
|
p2 = W - Prim[2];
|
|
|
|
DBGP_IF(DBGP_DYE_CORRECT,
|
|
DBGP(" DYE_CORRECT: %s:%s:%s, W=%s --> %s:%s:%s"
|
|
ARGFD6(Prim[0], 2, 6) ARGFD6(Prim[1], 2, 6)
|
|
ARGFD6(Prim[2], 2, 6) ARGFD6(W, 1, 6)
|
|
ARGFD6(p0, 2, 6) ARGFD6(p1, 2, 6)
|
|
ARGFD6(p2, 2, 6)));
|
|
|
|
MAKE_MULDIV_FLAG(MDPairs, MULDIV_NO_DIVISOR);
|
|
|
|
MAKE_MULDIV_PAIR(MDPairs, 1, CIE_Xr((*pCMYDyeMasks)), p0);
|
|
MAKE_MULDIV_PAIR(MDPairs, 2, CIE_Xg((*pCMYDyeMasks)), p1);
|
|
MAKE_MULDIV_PAIR(MDPairs, 3, CIE_Xb((*pCMYDyeMasks)), p2);
|
|
|
|
Prim[0] = W - MulDivFD6Pairs(MDPairs);
|
|
|
|
MAKE_MULDIV_PAIR(MDPairs, 1, CIE_Yr((*pCMYDyeMasks)), p0);
|
|
MAKE_MULDIV_PAIR(MDPairs, 2, CIE_Yg((*pCMYDyeMasks)), p1);
|
|
MAKE_MULDIV_PAIR(MDPairs, 3, CIE_Yb((*pCMYDyeMasks)), p2);
|
|
|
|
Prim[1] = W - MulDivFD6Pairs(MDPairs);
|
|
|
|
MAKE_MULDIV_PAIR(MDPairs, 1, CIE_Zr((*pCMYDyeMasks)), p0);
|
|
MAKE_MULDIV_PAIR(MDPairs, 2, CIE_Zg((*pCMYDyeMasks)), p1);
|
|
MAKE_MULDIV_PAIR(MDPairs, 3, CIE_Zb((*pCMYDyeMasks)), p2);
|
|
|
|
Prim[2] = W - MulDivFD6Pairs(MDPairs);
|
|
|
|
DBGP_IF(DBGP_DYE_CORRECT,
|
|
DBGP(" DYE_CORRECT: %s:%s:%s << %s:%s:%s"
|
|
ARGFD6(Prim[0], 2, 6) ARGFD6(Prim[1], 2, 6)
|
|
ARGFD6(Prim[2], 2, 6) ARGFD6(p0, 2, 6)
|
|
ARGFD6(p1, 2, 6) ARGFD6(p2, 2, 6)));
|
|
|
|
CLAMP_01(Prim[0]);
|
|
CLAMP_01(Prim[1]);
|
|
CLAMP_01(Prim[2]);
|
|
}
|
|
|
|
//*******************************************************************
|
|
//
|
|
// 4: Compute Final Device DYE through device color mapping and
|
|
// Primary/Halftone Cell number computation, The Primaries (ie.
|
|
// Prim[]) are in ADDITIVE FORMAT
|
|
//
|
|
//*******************************************************************
|
|
|
|
//
|
|
// Store in BGRF in this order
|
|
//
|
|
|
|
(pbgr )->r = (BYTE)MulFD6(Prim[0], 0xFF);
|
|
(pbgr )->g = (BYTE)MulFD6(Prim[1], 0xFF);
|
|
(pbgr++)->b = (BYTE)MulFD6(Prim[2], 0xFF);
|
|
|
|
DBGP_IF(DBGP_SHOWXFORM_ALL,
|
|
DBGP(" MAPPING(%3ld:%3ld:%3ld): %s:%s:%s ---> %3ld:%3ld:%3ld"
|
|
ARGDW(dbgR) ARGDW(dbgG) ARGDW(dbgB)
|
|
ARGFD6(Prim[0], 2, 6) ARGFD6(Prim[1], 2, 6)
|
|
ARGFD6(Prim[2], 2, 6) ARGDW((pbgr - 1)->r)
|
|
ARGDW((pbgr - 1)->g) ARGDW((pbgr - 1)->b)));
|
|
}
|
|
|
|
if ((pR_XYZ) && (pCRTX)) {
|
|
|
|
if (!pCRTX->pFD6XYZ) {
|
|
|
|
DBGP_IF(DBGP_CCT,
|
|
DBGP("CCT: Allocate %ld bytes RGB->XYZ xform cached table"
|
|
ARGDW(pCRTX->SizeCRTX)));
|
|
|
|
if (!(pCRTX->pFD6XYZ =
|
|
(PFD6XYZ)HTAllocMem((LPVOID)pDCI,
|
|
HTMEM_CacheCRTX,
|
|
NONZEROLPTR,
|
|
pCRTX->SizeCRTX))) {
|
|
|
|
DBGP_IF(DBGP_CCT,
|
|
DBGP("Allocate %ld bytes of RGB->XYZ cached table failed"
|
|
ARGDW(pCRTX->SizeCRTX)));
|
|
}
|
|
}
|
|
|
|
if (pCRTX->pFD6XYZ) {
|
|
|
|
DBGP_IF(DBGP_CCT,
|
|
DBGP("CCT: *** Save computed RGB->XYZ xform to CACHE ***"));
|
|
|
|
pCRTX->Checksum = CRTXChecksum;
|
|
|
|
CopyMemory(pCRTX->pFD6XYZ, pR_XYZ, pCRTX->SizeCRTX);
|
|
}
|
|
}
|
|
|
|
if (pR_XYZ) {
|
|
|
|
DBGP_IF(DBGP_CCT,
|
|
DBGP("ColorTriadSrcToDev: Free Up pR_XYZ local cached table"));
|
|
|
|
HTFreeMem(pR_XYZ);
|
|
}
|
|
|
|
return((LONG)SrcClrTriad.ColorTableEntries);
|
|
|
|
|
|
#undef _SrcPrimType
|
|
#undef _DevBytesPerPrimary
|
|
#undef _DevBytesPerEntry
|
|
#undef _ColorSpace
|
|
#undef _fX
|
|
#undef _fY
|
|
#undef _fZ
|
|
#undef _X15Y3Z
|
|
#undef _L13
|
|
|
|
}
|
|
|
|
|
|
#if DBG
|
|
|
|
|
|
VOID
|
|
ShowBGRMC(
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
|
|
|
|
Author:
|
|
|
|
06-Oct-2000 Fri 17:01:25 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
LONG i;
|
|
|
|
ACQUIRE_HTMUTEX(HTGlobal.HTMutexBGRMC);
|
|
|
|
i = HTGlobal.cBGRMC;
|
|
|
|
DBGP_IF(DBGP_BGRMAPTABLE, DBGP("\n================"));
|
|
|
|
while (i-- > 0) {
|
|
|
|
DBGP_IF(DBGP_BGRMAPTABLE,
|
|
DBGP(" --- %3ld: pMap=%p, Checksum=%08lx, cRef=%4ld"
|
|
ARGDW(i)
|
|
ARGPTR(HTGlobal.pBGRMC[i].pMap)
|
|
ARGDW(HTGlobal.pBGRMC[i].Checksum)
|
|
ARGDW(HTGlobal.pBGRMC[i].cRef)));
|
|
}
|
|
|
|
DBGP_IF(DBGP_BGRMAPTABLE, DBGP("================\n"));
|
|
|
|
RELEASE_HTMUTEX(HTGlobal.HTMutexBGRMC);
|
|
}
|
|
|
|
|
|
#if 1
|
|
#define SHOW_BGRMC()
|
|
#else
|
|
#define SHOW_BGRMC() ShowBGRMC()
|
|
#endif
|
|
#else
|
|
#define SHOW_BGRMC()
|
|
#endif
|
|
|
|
|
|
|
|
LONG
|
|
TrimBGRMapCache(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function trim the BGRMAPCache back to BGRMC_MAX_COUNT if possible
|
|
|
|
Arguments:
|
|
|
|
VOID
|
|
|
|
|
|
Return Value:
|
|
|
|
Total count that removed
|
|
|
|
|
|
Author:
|
|
|
|
06-Oct-2000 Fri 14:24:14 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
PBGRMAPCACHE pSave;
|
|
PBGRMAPCACHE pCur;
|
|
LONG cb;
|
|
LONG Count = 0;
|
|
LONG cTot;
|
|
|
|
|
|
ACQUIRE_HTMUTEX(HTGlobal.HTMutexBGRMC);
|
|
|
|
if ((HTGlobal.cBGRMC > BGRMC_MAX_COUNT) && (HTGlobal.cIdleBGRMC)) {
|
|
|
|
pSave =
|
|
pCur = HTGlobal.pBGRMC;
|
|
cTot =
|
|
Count = HTGlobal.cBGRMC;
|
|
|
|
while ((cTot--) && (HTGlobal.cBGRMC > BGRMC_MAX_COUNT)) {
|
|
|
|
if (pCur->cRef == 0) {
|
|
|
|
DBGP_IF(DBGP_BGRMAPTABLE,
|
|
DBGP("Remove %ld, pMap=%p"
|
|
ARGDW((DWORD)(pCur - HTGlobal.pBGRMC))
|
|
ARGPTR(pCur->pMap)));
|
|
|
|
HTFreeMem(pCur->pMap);
|
|
|
|
--HTGlobal.cBGRMC;
|
|
--HTGlobal.cIdleBGRMC;
|
|
|
|
} else {
|
|
|
|
if (pSave != pCur) {
|
|
|
|
*pSave = *pCur;
|
|
}
|
|
|
|
++pSave;
|
|
}
|
|
|
|
++pCur;
|
|
}
|
|
|
|
DBGP_IF(DBGP_BGRMAPTABLE,
|
|
DBGP("pSave=%p, pCur=%p, (%ld), [%ld / %ld]"
|
|
ARGPTR(pSave) ARGPTR(pCur) ARGDW((DWORD)(pCur - pSave))
|
|
ARGDW((DWORD)(&HTGlobal.pBGRMC[Count] - pCur))
|
|
ARGDW((DWORD)((LPBYTE)&HTGlobal.pBGRMC[Count] - (LPBYTE)pCur))));
|
|
|
|
if (Count != HTGlobal.cBGRMC) {
|
|
|
|
if ((pCur > pSave) &&
|
|
((cb = (LONG)((LPBYTE)&HTGlobal.pBGRMC[Count] -
|
|
(LPBYTE)pCur)) > 0)) {
|
|
|
|
CopyMemory(pSave, pCur, cb);
|
|
}
|
|
|
|
Count -= HTGlobal.cBGRMC;
|
|
|
|
DBGP_IF(DBGP_BGRMAPTABLE,
|
|
DBGP("TriBGRMapCache=%ld" ARGDW(Count)));
|
|
|
|
} else {
|
|
|
|
DBGP_IF(DBGP_BGRMAPTABLE, DBGP("!!!! TriBGRMapCache=0"));
|
|
}
|
|
}
|
|
|
|
DBGP_IF(DBGP_BGRMAPTABLE,
|
|
DBGP(" TTrimBGRMapCache: pBGRMC=%p, cBGRMC=%ld, cIdleBGRMC=%ld, cAllocBGRMC=%ld"
|
|
ARGPTR(HTGlobal.pBGRMC) ARGDW(HTGlobal.cBGRMC)
|
|
ARGDW(HTGlobal.cIdleBGRMC) ARGDW(HTGlobal.cAllocBGRMC)));
|
|
|
|
RELEASE_HTMUTEX(HTGlobal.HTMutexBGRMC);
|
|
|
|
ASSERT(HTGlobal.cBGRMC >= 0);
|
|
ASSERT(HTGlobal.cIdleBGRMC <= HTGlobal.cBGRMC);
|
|
ASSERT(HTGlobal.cIdleBGRMC >= 0);
|
|
|
|
SHOW_BGRMC();
|
|
|
|
return(Count);
|
|
}
|
|
|
|
|
|
|
|
PBGR8
|
|
FindBGRMapCache(
|
|
PBGR8 pDeRefMap,
|
|
DWORD Checksum
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function found a BGRMapCache with same checksum and move that
|
|
link to the begining.
|
|
|
|
|
|
Arguments:
|
|
|
|
pDeRefMap - Find pMap for deference (NULL if not)
|
|
|
|
Checksum - Find checksum (only if pDeRefMap == NULL
|
|
|
|
|
|
Return Value:
|
|
|
|
PBGR8 - The map that found
|
|
|
|
|
|
Author:
|
|
|
|
06-Oct-2000 Fri 13:30:14 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
LONG Count;
|
|
PBGR8 pRet = NULL;
|
|
|
|
|
|
ACQUIRE_HTMUTEX(HTGlobal.HTMutexBGRMC);
|
|
|
|
if ((HTGlobal.pBGRMC) && (Count = HTGlobal.cBGRMC)) {
|
|
|
|
PBGRMAPCACHE pCur = &HTGlobal.pBGRMC[Count - 1];
|
|
|
|
while ((Count) && (!pRet)) {
|
|
|
|
if (pDeRefMap == pCur->pMap) {
|
|
|
|
ASSERT(pCur->cRef);
|
|
|
|
pRet = pDeRefMap;
|
|
|
|
if (pCur->cRef) {
|
|
|
|
if (--pCur->cRef == 0) {
|
|
|
|
++HTGlobal.cIdleBGRMC;
|
|
}
|
|
}
|
|
|
|
} else if (pCur->Checksum == Checksum) {
|
|
|
|
DBGP_IF(DBGP_BGRMAPTABLE,
|
|
DBGP("find Cached %08lx = %p at Index %ld, cRef=%ld"
|
|
ARGDW(Checksum) ARGPTR(pCur->pMap)
|
|
ARGDW((DWORD)(pCur - HTGlobal.pBGRMC))
|
|
ARGDW(pCur->cRef)));
|
|
|
|
pRet = pCur->pMap;
|
|
|
|
if (pCur->cRef++ == 0) {
|
|
|
|
--HTGlobal.cIdleBGRMC;
|
|
}
|
|
|
|
//
|
|
// Move this reference to the end of the list as most recent
|
|
//
|
|
|
|
if (Count < HTGlobal.cBGRMC) {
|
|
|
|
BGRMAPCACHE BGRMC = *pCur;
|
|
|
|
CopyMemory(pCur,
|
|
pCur + 1,
|
|
(HTGlobal.cBGRMC - Count) * sizeof(BGRMAPCACHE));
|
|
|
|
HTGlobal.pBGRMC[HTGlobal.cBGRMC - 1] = BGRMC;
|
|
}
|
|
}
|
|
|
|
--Count;
|
|
--pCur;
|
|
}
|
|
}
|
|
|
|
if ((pDeRefMap) && (!pRet)) {
|
|
|
|
DBGP_IF(DBGP_BGRMAPTABLE,
|
|
DBGP("Cannot find the pMap=%p that to be DeReference"
|
|
ARGPTR(pDeRefMap)));
|
|
}
|
|
|
|
DBGP_IF(DBGP_BGRMAPTABLE,
|
|
DBGP("%s_BGRMapCache(%p, %08lx): pBGRMC=%p, cBGRMC=%ld, cIdleBGRMC=%ld, cAllocBGRMC=%ld"
|
|
ARGPTR((pDeRefMap) ? "DEREF" : " FIND")
|
|
ARGPTR(pDeRefMap) ARGDW(Checksum)
|
|
ARGPTR(HTGlobal.pBGRMC) ARGDW(HTGlobal.cBGRMC)
|
|
ARGDW(HTGlobal.cIdleBGRMC) ARGDW(HTGlobal.cAllocBGRMC)));
|
|
|
|
if ((HTGlobal.cBGRMC > BGRMC_MAX_COUNT) && (HTGlobal.cIdleBGRMC)) {
|
|
|
|
TrimBGRMapCache();
|
|
}
|
|
|
|
RELEASE_HTMUTEX(HTGlobal.HTMutexBGRMC);
|
|
|
|
ASSERT(HTGlobal.cBGRMC >= 0);
|
|
ASSERT(HTGlobal.cIdleBGRMC <= HTGlobal.cBGRMC);
|
|
ASSERT(HTGlobal.cIdleBGRMC >= 0);
|
|
|
|
SHOW_BGRMC();
|
|
|
|
return(pRet);
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL
|
|
AddBGRMapCache(
|
|
PBGR8 pMap,
|
|
DWORD Checksum
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Add pMap with Checksum to the cache table
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
|
|
|
|
Author:
|
|
|
|
06-Oct-2000 Fri 13:29:52 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
PBGRMAPCACHE pBGRMC;
|
|
LONG cAlloc;
|
|
BOOL bRet = TRUE;
|
|
|
|
|
|
ACQUIRE_HTMUTEX(HTGlobal.HTMutexBGRMC);
|
|
|
|
if ((HTGlobal.cBGRMC > BGRMC_MAX_COUNT) && (HTGlobal.cIdleBGRMC)) {
|
|
|
|
TrimBGRMapCache();
|
|
}
|
|
|
|
ASSERT(HTGlobal.cBGRMC <= HTGlobal.cAllocBGRMC);
|
|
|
|
if (HTGlobal.cBGRMC >= (cAlloc = HTGlobal.cAllocBGRMC)) {
|
|
|
|
DBGP_IF(DBGP_BGRMAPTABLE,
|
|
DBGP("AddBGRMapCache() Increase cAllocBGRMC %ld to %ld"
|
|
ARGDW(HTGlobal.cAllocBGRMC)
|
|
ARGDW(HTGlobal.cAllocBGRMC + BGRMC_SIZE_INC)));
|
|
|
|
cAlloc += BGRMC_SIZE_INC;
|
|
|
|
if (pBGRMC = (PBGRMAPCACHE)HTAllocMem((LPVOID)NULL,
|
|
HTMEM_BGRMC_CACHE,
|
|
LPTR,
|
|
cAlloc * sizeof(BGRMAPCACHE))) {
|
|
|
|
if (HTGlobal.pBGRMC) {
|
|
|
|
CopyMemory(pBGRMC,
|
|
HTGlobal.pBGRMC,
|
|
HTGlobal.cBGRMC * sizeof(BGRMAPCACHE));
|
|
|
|
HTFreeMem(HTGlobal.pBGRMC);
|
|
}
|
|
|
|
HTGlobal.pBGRMC = pBGRMC;
|
|
HTGlobal.cAllocBGRMC = cAlloc;
|
|
|
|
} else {
|
|
|
|
DBGP_IF(DBGP_BGRMAPTABLE,
|
|
DBGP("AddBGRMapCache() Allocation %ld bytes of Memory Failed"
|
|
ARGDW(HTGlobal.cAllocBGRMC * sizeof(BGRMAPCACHE))));
|
|
}
|
|
}
|
|
|
|
if ((HTGlobal.pBGRMC) &&
|
|
(HTGlobal.cBGRMC < HTGlobal.cAllocBGRMC)) {
|
|
|
|
pBGRMC = &HTGlobal.pBGRMC[HTGlobal.cBGRMC++];
|
|
pBGRMC->pMap = pMap;
|
|
pBGRMC->Checksum = Checksum;
|
|
pBGRMC->cRef = 1;
|
|
|
|
DBGP_IF(DBGP_BGRMAPTABLE,
|
|
DBGP(" AddBGRMapCache() Added %p (%08lx) to Cache"
|
|
ARGPTR(pMap) ARGDW(Checksum)));
|
|
|
|
} else {
|
|
|
|
bRet = FALSE;
|
|
}
|
|
|
|
DBGP_IF(DBGP_BGRMAPTABLE,
|
|
DBGP(" AddBGRMapCache: pBGRMC=%p, cBGRMC=%ld, cIdleBGRMC=%ld, cAllocBGRMC=%ld"
|
|
ARGPTR(HTGlobal.pBGRMC) ARGDW(HTGlobal.cBGRMC)
|
|
ARGDW(HTGlobal.cIdleBGRMC) ARGDW(HTGlobal.cAllocBGRMC)));
|
|
|
|
RELEASE_HTMUTEX(HTGlobal.HTMutexBGRMC);
|
|
|
|
ASSERT(HTGlobal.cBGRMC >= 0);
|
|
ASSERT(HTGlobal.cIdleBGRMC <= HTGlobal.cBGRMC);
|
|
ASSERT(HTGlobal.cIdleBGRMC >= 0);
|
|
|
|
SHOW_BGRMC();
|
|
|
|
return(bRet);
|
|
}
|
|
|
|
|
|
|
|
|
|
LONG
|
|
HTENTRY
|
|
CreateDyesColorMappingTable(
|
|
PHALFTONERENDER pHR
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
this function allocate the memory for the dyes color mapping table depends
|
|
on the source surface type information, it then go throug the color table
|
|
and calculate dye densities for each RGB color in the color table.
|
|
|
|
|
|
Arguments:
|
|
|
|
pHalftoneRender - Pointer to the HALFTONERENDER data structure.
|
|
|
|
Return Value:
|
|
|
|
a negative return value indicate failue.
|
|
|
|
|
|
|
|
HTERR_INVALID_SRC_FORMAT - Invalid source surface format, this
|
|
function only recongnized 1/4/8/24 bits
|
|
per pel source surfaces.
|
|
|
|
HTERR_COLORTABLE_TOO_BIG - can not create the color table to map
|
|
the colors to the dyes' densities.
|
|
|
|
HTERR_INSUFFICIENT_MEMORY - not enough memory for the pattern.
|
|
|
|
HTERR_INTERNAL_ERRORS_START - any other negative number indicate
|
|
halftone internal failure.
|
|
|
|
else - size of the color table entries created.
|
|
|
|
|
|
Author:
|
|
|
|
29-Jan-1991 Tue 11:13:02 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
PAAHEADER pAAHdr;
|
|
PDEVICECOLORINFO pDCI;
|
|
PDEVCLRADJ pDevClrAdj;
|
|
CTSTD_UNION CTSTDUnion;
|
|
LONG Result;
|
|
|
|
|
|
pDCI = pHR->pDeviceColorInfo;
|
|
pDevClrAdj = pHR->pDevClrAdj;
|
|
pAAHdr = (PAAHEADER)pHR->pAAHdr;
|
|
CTSTDUnion.b = pDevClrAdj->DMI.CTSTDInfo;
|
|
CTSTDUnion.b.SrcOrder =
|
|
pDevClrAdj->DMI.CTSTDInfo.SrcOrder = PRIMARY_ORDER_BGR;
|
|
|
|
//
|
|
// Make sure these call are semaphore protected
|
|
//
|
|
|
|
ComputeRGBLUTAA(pDCI, pDevClrAdj, &(pDCI->rgbLUT));
|
|
|
|
if (!(pDevClrAdj->PrimAdj.Flags & DCA_NO_MAPPING_TABLE)) {
|
|
|
|
PBGR8 pBGRMap;
|
|
PBGR8 pNewMap = NULL;
|
|
DWORD Checksum;
|
|
|
|
|
|
ASSERT(CTSTDUnion.b.cbPrim == sizeof(BGR8));
|
|
ASSERT(pAAHdr->Flags & AAHF_DO_CLR_MAPPING);
|
|
|
|
|
|
//
|
|
// Compute checksum for all necessary component that computing it
|
|
// 1. rgbCSXForm (which is sRGB constant in GDI implementation)
|
|
// 2. DevCSXForm
|
|
// 3. ColorAdjustment (illum, colorfulness, tint)
|
|
//
|
|
|
|
Checksum = ComputeChecksum((LPBYTE)&pDevClrAdj->PrimAdj.rgbCSXForm,
|
|
0x12345678,
|
|
sizeof(COLORSPACEXFORM));
|
|
|
|
Checksum = ComputeChecksum((LPBYTE)&pDevClrAdj->PrimAdj.DevCSXForm,
|
|
Checksum,
|
|
sizeof(COLORSPACEXFORM));
|
|
|
|
Checksum = ComputeChecksum((LPBYTE)&(pDevClrAdj->ca),
|
|
Checksum,
|
|
sizeof(pDevClrAdj->ca));
|
|
|
|
if (!(pBGRMap = FIND_BGRMAPCACHE(Checksum))) {
|
|
|
|
DBGP_IF(DBGP_BGRMAPTABLE,
|
|
DBGP("*** No CACHE: Alloc %ld bytes of CACHE pBGRMap ***"
|
|
ARGDW(SIZE_BGR_MAPPING_TABLE)));
|
|
|
|
if (!(pBGRMap =
|
|
pNewMap = (PBGR8)HTAllocMem((LPVOID)NULL,
|
|
HTMEM_BGRMC_MAP,
|
|
NONZEROLPTR,
|
|
SIZE_BGR_MAPPING_TABLE))) {
|
|
|
|
DBGP_IF(DBGP_BGRMAPTABLE,
|
|
DBGP("\n*** FAILED Alloc %ld bytes of pBGRMap ***\n"));
|
|
|
|
return((LONG)HTERR_INSUFFICIENT_MEMORY);
|
|
}
|
|
}
|
|
|
|
if (pNewMap) {
|
|
|
|
DBGP_IF(DBGP_BGRMAPTABLE,
|
|
DBGP("Cached map Checksum (%08lx) not found, compute Re-Compute RGB555"
|
|
ARGDW(Checksum)));
|
|
|
|
if ((Result = ComputeBGRMappingTable(pDCI,
|
|
pDevClrAdj,
|
|
NULL,
|
|
pNewMap)) ==
|
|
HT_RGB_CUBE_COUNT) {
|
|
|
|
if (!(AddBGRMapCache(pNewMap, Checksum))) {
|
|
|
|
DBGP_IF(DBGP_BGRMAPTABLE,
|
|
DBGP("Adding BGRMapCache failed, Free pNewMap=%p"
|
|
ARGPTR(pNewMap)));
|
|
|
|
HTFreeMem(pNewMap);
|
|
|
|
return((LONG)HTERR_INSUFFICIENT_MEMORY);
|
|
}
|
|
|
|
} else {
|
|
|
|
DBGP_IF(DBGP_BGRMAPTABLE,
|
|
DBGP("ColorTriadSrcTodev() Failed, Result=%ld"
|
|
ARGDW(Result)));
|
|
|
|
return(INTERR_INVALID_DEVRGB_SIZE);
|
|
}
|
|
}
|
|
|
|
pAAHdr->pBGRMapTable = pBGRMap;
|
|
}
|
|
|
|
Result = CachedHalftonePattern(pDCI,
|
|
pDevClrAdj,
|
|
&(pAAHdr->AAPI),
|
|
pAAHdr->ptlBrushOrg.x,
|
|
pAAHdr->ptlBrushOrg.y,
|
|
(BOOL)(pAAHdr->Flags & AAHF_FLIP_Y));
|
|
|
|
return(Result);
|
|
}
|