픽셀당 8비트 하프톤 인덱스를 잉크 수준으로 변환
여기에 표시된 GenerateInkLevels 함수는 픽셀당 8비트 하프톤 인덱스를 잉크 수준으로 변환하는 방법의 예를 제공합니다. 이러한 인덱스는 GDI의 HT_Get8BPPMaskPalette 함수가 pPaletteEntry 매개 변수에서 반환하는 CMY 모드 및 CMY_INVERTED 모드 팔레트에 포함되어 있습니다. GenerateInkLevels 는 INKLEVELS 구조체의 256개 요소 배열을 생성합니다.
이 함수는 Windows 2000 CMY 모드 또는 Windows 2000 CMY_INVERTED 모드 변환 테이블을 생성하는 데 사용할 수 있습니다. 이 함수를 사용하여 Windows 2000 CMY 모드 CMY332 역방향 매핑 인덱스 테이블을 생성할 수도 있습니다. (CMY332는 시안과 마젠타에 각각 3비트, 노란색의 경우 2비트 사용) CMYMask 값이 3에서 255 범위인 경우 함수의 호출자는 이 테이블을 사용하여 Windows 2000개의 CMY_INVERTED 인덱스를 현재 기존 드라이버에 대한 2000 CMY 인덱스를 Windows 매핑할 수 있습니다.
INKLEVELS 구조체
typedef struct _INKLEVELS {
BYTE Cyan; // Cyan level from 0 to max
BYTE Magenta; // Magenta level from 0 to max
BYTE Yellow; // Yellow level from 0 to max
BYTE CMY332Idx; // Original windows 2000 CMY332 Index
} INKLEVELS, *PINKLEVELS;
GenerateInkLevels 함수 예제
GenerateInkLevels 함수는 CMYMask 및 CMYInverted 매개 변수의 값을 기반으로 INKLEVELS 구조체의 픽셀당 8비트 변환 테이블을 계산합니다. 이 함수는 0에서 255 범위의 유효한 CMYMask 값에 대한 INKLEVELS 변환 테이블을 생성합니다.
이 함수가 호출되면 pInkLevels 매개 변수는 256개의 INKLEVELS 항목의 유효한 메모리 위치를 가리킵니다. 함수가 TRUE를 반환하는 경우 pInkLevels 를 사용하여 픽셀당 8비트 인덱스를 잉크 수준으로 변환하거나 이전 CMY332 인덱스에 매핑할 수 있습니다. CMYMask를 잘못된 값으로 설정하여 함수를 호출하는 경우(시안, 마젠타 또는 노란색 수준이 0인 3에서 255까지의 값) 함수는 FALSE를 반환합니다.
BOOL
GenerateInkLevels(
PINKLEVELS pInkLevels, // Pointer to 256 INKLEVELS table
BYTE CMYMask, // CMYMask mode
BOOL CMYInverted // TRUE for CMY_INVERTED mode
)
{
PINKLEVELS pILDup;
PINKLEVELS pILEnd;
INKLEVELS InkLevels;
INT Count;
INT IdxInc;
INT cC; // Number of Cyan levels
INT cM; // Number of Magenta levels
INT cY; // Number of Yellow levels
INT xC; // Max. number Cyan levels
INT xM; // Max. number Magenta levels
INT xY; // Max. number Yellow levels
INT iC;
INT iM;
INT iY;
INT mC;
INT mM;
switch (CMYMask) {
case 0:
cC =
cM =
xC =
xM = 0;
cY =
xY = 255;
break;
case 1:
case 2:
cC =
cM =
cY =
xC =
xM =
xY = 3 + (INT)CMYMask;
break;
default:
cC = (INT)((CMYMask >> 5) & 0x07);
cM = (INT)((CMYMask >> 2) & 0x07);
cY = (INT)( CMYMask & 0x03);
xC = 7;
xM = 7;
xY = 3;
break;
} // end switch statement
Count = (cC + 1) * (cM + 1) * (cY + 1);
if ((Count < 1) || (Count > 256)) {
return(FALSE);
}
InkLevels.Cyan =
InkLevels.Magenta =
InkLevels.Yellow =
InkLevels.CMY332Idx = 0;
mC = (xM + 1) * (xY + 1);
mM = xY + 1;
pILDup = NULL;
if (CMYInverted) {
//
// Move the pInkLevels to the first entry following
// the centered embedded entries.
// Skipped entries are set to white (zero). Because this
// is a CMY_INVERTED mode, entries start from back of the
// table and move toward the beginning of the table.
//
pILEnd = pInkLevels - 1;
IdxInc = ((256 - Count - (Count & 0x01)) / 2);
pInkLevels += 255;
while (IdxInc--) {
*pInkLevels-- = InkLevels;
}
if (Count & 0x01) {
//
// If we have an odd number of entries, we need to
// duplicate the center one for the XOR ROP to
// operate correctly. pILDup will always be index
// 127, and the duplicates are at indexes 127 and 128.
//
pILDup = pInkLevels - (Count / 2) - 1;
}
//
// We are running from the end of table to the beginning,
// because in CMY_INVERTED mode, index 0 is black and
// index 255 is white. Since we generate only Count
// white, black, and colored indexes, and place them at
// the center, we will change xC, xM, xY max. indexes
// to the same as cC, cM and cY
// so we only compute cC*cM*cY entries.
//
IdxInc = -1;
xC = cC;
xM = cM;
xY = cY;
} else {
IdxInc = 1;
pILEnd = pInkLevels + 256;
}
//
// In the following composition of ink levels, the index
// always runs from 0 ink level (white) to maximum ink
// levels (black). With CMY_INVERTED mode, we compose ink
// levels from index 255 to index 0 rather than from index
// 0 to 255.
//
if (CMYMask) {
INT Idx332C;
INT Idx332M;
for (iC = 0, Idx332C = -mC; iC <= xC; iC++) {
if (iC <= cC) {
InkLevels.Cyan = (BYTE)iC;
Idx332C += mC;
}
for (iM = 0, Idx332M = -mM; iM <= xM; iM++) {
if (iM <= cM) {
InkLevels.Magenta = (BYTE)iM;
Idx332M += mM;
}
for (iY = 0; iY <= xY; iY++) {
if (iY <= cY) {
InkLevels.Yellow = (BYTE)iY;
}
InkLevels.CMY332Idx = (BYTE)(Idx332C +
Idx332M) +
InkLevels.Yellow;
*pInkLevels = InkLevels;
if ((pInkLevels += IdxInc) == pILDup) {
*pInkLevels = InkLevels;
pInkLevels += IdxInc;
}
}
}
}
//
// Now, if we need to pad black at the other end of the
// translation table, then do it here. Notice that
// InkLevels are at cC, cM and cY here and CMY332Idx
// is at black.
//
while (pInkLevels != pILEnd) {
*pInkLevels = InkLevels;
pInkLevels += IdxInc;
}
} else {
//
// Gray Scale case
//
for (iC = 0; iC < 256; iC++, pInkLevels += IdxInc) {
pInkLevels->Cyan =
pInkLevels->Magenta =
pInkLevels->Yellow =
pInkLevels->CMY332Idx = (BYTE)iC;
}
}
return(TRUE);
}