mirror of https://github.com/lianthony/NT4.0
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.
4735 lines
134 KiB
4735 lines
134 KiB
/*++
|
|
|
|
Copyright (c) 1990-1991 Microsoft Corporation
|
|
|
|
|
|
Module Name:
|
|
|
|
htapi.c
|
|
|
|
|
|
Abstract:
|
|
|
|
This module contains all the halftone entry points which communicate
|
|
with caller to the halftone dll.
|
|
|
|
|
|
Author:
|
|
|
|
05-Feb-1991 Tue 10:52:03 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
[Environment:]
|
|
|
|
GDI Device Driver - Halftone.
|
|
|
|
|
|
[Notes:]
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
#define DBGP_VARNAME dbgpHTAPI
|
|
|
|
#define _HTAPI_ENTRY_
|
|
|
|
#include "htp.h"
|
|
#include "htmapclr.h"
|
|
#include "htpat.h"
|
|
#include "htsetbmp.h"
|
|
#include "htrender.h"
|
|
#include "htmath.h"
|
|
#include "stdio.h"
|
|
|
|
#define INCLUDE_DEF_CIEINFO
|
|
#include "htapi.h"
|
|
|
|
|
|
#define DBGP_SHOWPAT 0x0001
|
|
#define DBGP_TIMER 0x0002
|
|
#define DBGP_CACHED_DCI 0x0004
|
|
#define DBGP_CACHED_SMP 0x0008
|
|
#define DBGP_DYECORRECTION 0x0010
|
|
#define DBGP_8BPP_PAL 0x0020
|
|
#define DBGP_DHI_MEM 0x0040
|
|
#define DBGP_COMPUTE_L2I 0x0080
|
|
#define DBGP_HTMUTEX 0x0100
|
|
|
|
|
|
DEF_DBGPVAR(BIT_IF(DBGP_SHOWPAT, 0) |
|
|
BIT_IF(DBGP_TIMER, 0) |
|
|
BIT_IF(DBGP_CACHED_DCI, 0) |
|
|
BIT_IF(DBGP_CACHED_SMP, 0) |
|
|
BIT_IF(DBGP_DYECORRECTION, 0) |
|
|
BIT_IF(DBGP_8BPP_PAL, 0) |
|
|
BIT_IF(DBGP_DHI_MEM, 0) |
|
|
BIT_IF(DBGP_COMPUTE_L2I, 0) |
|
|
BIT_IF(DBGP_HTMUTEX, 0))
|
|
|
|
//
|
|
// Turn on TEST_3PLANES only for debugging mode
|
|
//
|
|
|
|
#define TEST_3PLANES 0
|
|
|
|
#if 0
|
|
#define HAS_FILL_MODE
|
|
#endif
|
|
|
|
|
|
HTGLOBAL HTGlobal = { (HMODULE)NULL,
|
|
(HTMUTEX)NULL,
|
|
(HTMUTEX)NULL,
|
|
(PCDCIDATA)NULL,
|
|
(PCSMPDATA)NULL,
|
|
(WORD)0,
|
|
(WORD)0
|
|
};
|
|
|
|
FD6 L2I_16bpp555[RGB555_C_LEVELS + 1];
|
|
FD6 L2I_VGA256Mono[VGA256_MONO_SIZE + 1];
|
|
|
|
DEFDBGVAR(BOOL, DisableCacheDCI_SMP = FALSE)
|
|
|
|
|
|
#define RGB_8BPP(rgb,Gamma) (BYTE)SCALE_FD6(Radical((rgb), Gamma), 255)
|
|
|
|
//
|
|
// Following are the constant for VGA16 half intensity and light gray color
|
|
//
|
|
|
|
|
|
//===========================================================================
|
|
|
|
#ifdef HAS_FILL_MODE
|
|
|
|
BYTERGB VGAPalette[] = {
|
|
|
|
// Index 0
|
|
|
|
{ 0, 0, 0 }, { 0, 0, 20 }, { 0, 0, 40 }, { 0, 0, 60 }, { 0, 0, 80 }, { 0, 0,100 },
|
|
{ 0, 20, 0 }, { 0, 20, 20 }, { 0, 20, 40 }, { 0, 20, 60 }, { 0, 20, 80 }, { 0, 20,100 },
|
|
{ 0, 40, 0 }, { 0, 40, 20 }, { 0, 40, 40 }, { 0, 40, 60 }, { 0, 40, 80 }, { 0, 40,100 },
|
|
{ 0, 60, 0 }, { 0, 60, 20 }, { 0, 60, 40 }, { 0, 60, 60 }, { 0, 60, 80 }, { 0, 60,100 },
|
|
{ 0, 80, 0 }, { 0, 80, 20 }, { 0, 80, 40 }, { 0, 80, 60 }, { 0, 80, 80 }, { 0, 80,100 },
|
|
{ 0,100, 0 }, { 0,100, 20 }, { 0,100, 40 }, { 0,100, 60 }, { 0,100, 80 }, { 0,100,100 },
|
|
|
|
// Index 36
|
|
|
|
{ 20, 0, 0 }, { 20, 0, 20 }, { 20, 0, 40 }, { 20, 0, 60 }, { 20, 0, 80 }, { 20, 0,100 },
|
|
{ 20, 20, 0 }, { 20, 20, 20 }, { 20, 20, 40 }, { 20, 20, 60 }, { 20, 20, 80 }, { 20, 20,100 },
|
|
{ 20, 40, 0 }, { 20, 40, 20 }, { 20, 40, 40 }, { 20, 40, 60 }, { 20, 40, 80 }, { 20, 40,100 },
|
|
{ 20, 60, 0 }, { 20, 60, 20 }, { 20, 60, 40 }, { 20, 60, 60 }, { 20, 60, 80 }, { 20, 60,100 },
|
|
{ 20, 80, 0 }, { 20, 80, 20 }, { 20, 80, 40 }, { 20, 80, 60 }, { 20, 80, 80 }, { 20, 80,100 },
|
|
{ 20,100, 0 }, { 20,100, 20 }, { 20,100, 40 }, { 20,100, 60 }, { 20,100, 80 }, { 20,100,100 },
|
|
|
|
// Index 72
|
|
|
|
{ 40, 0, 0 }, { 40, 0, 20 }, { 40, 0, 40 }, { 40, 0, 60 }, { 40, 0, 80 }, { 40, 0,100 },
|
|
{ 40, 20, 0 }, { 40, 20, 20 }, { 40, 20, 40 }, { 40, 20, 60 }, { 40, 20, 80 }, { 40, 20,100 },
|
|
{ 40, 40, 0 }, { 40, 40, 20 }, { 40, 40, 40 }, { 40, 40, 60 }, { 40, 40, 80 }, { 40, 40,100 },
|
|
{ 40, 60, 0 }, { 40, 60, 20 }, { 40, 60, 40 }, { 40, 60, 60 }, { 40, 60, 80 }, { 40, 60,100 },
|
|
{ 40, 80, 0 }, { 40, 80, 20 }, { 40, 80, 40 }, { 40, 80, 60 }, { 40, 80, 80 }, { 40, 80,100 },
|
|
{ 40,100, 0 }, { 40,100, 20 }, { 40,100, 40 }, { 40,100, 60 }, { 40,100, 80 }, { 40,100,100 },
|
|
|
|
// Index 108
|
|
|
|
{ 60, 0, 0 }, { 60, 0, 20 }, { 60, 0, 40 }, { 60, 0, 60 }, { 60, 0, 80 }, { 60, 0,100 },
|
|
{ 60, 20, 0 }, { 60, 20, 20 }, { 60, 20, 40 }, { 60, 20, 60 }, { 60, 20, 80 }, { 60, 20,100 },
|
|
{ 60, 40, 0 }, { 60, 40, 20 }, { 60, 40, 40 }, { 60, 40, 60 }, { 60, 40, 80 }, { 60, 40,100 },
|
|
{ 60, 60, 0 }, { 60, 60, 20 }, { 60, 60, 40 }, { 60, 60, 60 }, { 60, 60, 80 }, { 60, 60,100 },
|
|
{ 60, 80, 0 }, { 60, 80, 20 }, { 60, 80, 40 }, { 60, 80, 60 }, { 60, 80, 80 }, { 60, 80,100 },
|
|
{ 60,100, 0 }, { 60,100, 20 }, { 60,100, 40 }, { 60,100, 60 }, { 60,100, 80 }, { 60,100,100 },
|
|
|
|
// Index 144
|
|
|
|
{ 80, 0, 0 }, { 80, 0, 20 }, { 80, 0, 40 }, { 80, 0, 60 }, { 80, 0, 80 }, { 80, 0,100 },
|
|
{ 80, 20, 0 }, { 80, 20, 20 }, { 80, 20, 40 }, { 80, 20, 60 }, { 80, 20, 80 }, { 80, 20,100 },
|
|
{ 80, 40, 0 }, { 80, 40, 20 }, { 80, 40, 40 }, { 80, 40, 60 }, { 80, 40, 80 }, { 80, 40,100 },
|
|
{ 80, 60, 0 }, { 80, 60, 20 }, { 80, 60, 40 }, { 80, 60, 60 }, { 80, 60, 80 }, { 80, 60,100 },
|
|
{ 80, 80, 0 }, { 80, 80, 20 }, { 80, 80, 40 }, { 80, 80, 60 }, { 80, 80, 80 }, { 80, 80,100 },
|
|
{ 80,100, 0 }, { 80,100, 20 }, { 80,100, 40 }, { 80,100, 60 }, { 80,100, 80 }, { 80,100,100 },
|
|
|
|
// Index 180
|
|
|
|
{100, 0, 0 }, {100, 0, 20 }, {100, 0, 40 }, {100, 0, 60 }, {100, 0, 80 }, {100, 0,100 },
|
|
{100, 20, 0 }, {100, 20, 20 }, {100, 20, 40 }, {100, 20, 60 }, {100, 20, 80 }, {100, 20,100 },
|
|
{100, 40, 0 }, {100, 40, 20 }, {100, 40, 40 }, {100, 40, 60 }, {100, 40, 80 }, {100, 40,100 },
|
|
{100, 60, 0 }, {100, 60, 20 }, {100, 60, 40 }, {100, 60, 60 }, {100, 60, 80 }, {100, 60,100 },
|
|
{100, 80, 0 }, {100, 80, 20 }, {100, 80, 40 }, {100, 80, 60 }, {100, 80, 80 }, {100, 80,100 },
|
|
{100,100, 0 }, {100,100, 20 }, {100,100, 40 }, {100,100, 60 }, {100,100, 80 }, {100,100,100 },
|
|
|
|
// Index 216
|
|
|
|
{ 10, 0, 0 }, { 30, 0, 0 }, { 50, 0, 0 }, { 70, 0, 0 }, { 90, 0, 0 }, // R 216
|
|
{100, 10, 10 }, {100, 30, 30 }, {100, 50, 50 }, {100, 70, 70 }, {100, 90, 90 }, // 221
|
|
|
|
{ 0, 10, 0 }, { 0, 30, 0 }, { 0, 50, 0 }, { 0, 70, 0 }, { 0, 90, 0 }, // G 226
|
|
{ 10,100, 10 }, { 30,100, 30 }, { 50,100, 50 }, { 70,100, 70 }, { 90,100, 90 }, // 231
|
|
|
|
{ 0, 0, 10 }, { 0, 0, 30 }, { 0, 0, 50 }, { 0, 0, 70 }, { 0, 0, 90 }, // B 236
|
|
{ 10, 10,100 }, { 30, 30,100 }, { 50, 50,100 }, { 70, 70,100 }, { 90, 90,100 }, // 241
|
|
|
|
{ 7, 7, 7 }, { 14, 14, 14 }, { 27, 27, 27 }, { 34, 34, 34 }, { 47, 47, 47 }, // W 246
|
|
{ 54, 54, 54 }, { 67, 67, 67 }, { 74, 74, 74 }, { 87, 87, 87 }, { 94, 94, 94 } // 251
|
|
|
|
};
|
|
|
|
|
|
|
|
BYTE VGABmp1[] = {
|
|
|
|
0, 1, 2, 3, 4, 5, 36, 37, 38, 39, 40, 41, 72, 73, 74, 75, 76, 77,
|
|
6, 7, 8, 9, 10, 11, 42, 43, 44, 45, 46, 47, 78, 79, 80, 81, 82, 83,
|
|
12, 13, 14, 15, 16, 17, 48, 49, 50, 51, 52, 53, 84, 85, 86, 87, 88, 89,
|
|
18, 19, 20, 21, 22, 23, 54, 55, 56, 57, 58, 59, 90, 91, 92, 93, 94, 95,
|
|
24, 25, 26, 27, 28, 29, 60, 61, 62, 63, 64, 65, 96, 97, 98, 99,100,101,
|
|
30, 31, 32, 33, 34, 35, 66, 67, 68, 69, 70, 71, 102,103,104,105,106,107,
|
|
|
|
108,109,110,111,112,113, 144,145,146,147,148,149, 180,181,182,183,184,185,
|
|
114,115,116,117,118,119, 150,151,152,153,154,155, 186,187,188,189,190,191,
|
|
120,121,122,123,124,125, 156,157,158,159,160,161, 192,193,194,195,196,197,
|
|
126,127,128,129,130,131, 162,163,164,165,166,167, 198,199,200,201,202,203,
|
|
132,133,134,135,136,137, 168,169,170,171,172,173, 204,205,206,207,208,209,
|
|
138,139,140,141,142,143, 174,175,176,177,178,179, 210,211,212,213,214,215
|
|
};
|
|
|
|
|
|
BYTE VGABmp2[] = {
|
|
|
|
0,
|
|
246,247, 43,248,249, 86, 250,251,129,252,
|
|
253,172,254,255,215
|
|
|
|
};
|
|
|
|
|
|
BYTE VGABmp3[] = {
|
|
|
|
180, // R
|
|
186, 192, 198, 204, 210, // R -> Y
|
|
174, 138, 102, 66, 30, // Y -> G
|
|
31, 32, 33, 34, 35, // G -> C
|
|
29, 23, 17, 11, 5, // C -> B
|
|
41, 77, 113, 149, 185, // B -> M
|
|
184, 183, 182, 181, 180 // M -> R
|
|
};
|
|
|
|
|
|
BYTE VGABmp4[] = {
|
|
|
|
0,
|
|
216, 36,217, 72,218,108, 219,144,220,180, // Red
|
|
221,187,222,194,223,201, 224,208,225,215,
|
|
|
|
0,
|
|
226, 6,227, 12,228, 18, 229, 24,230, 30, // Green
|
|
231, 67,232,104,233,141, 234,178,235,215,
|
|
|
|
0,
|
|
236, 1,237, 2,238, 3, 239, 4,240, 5,
|
|
241, 47,242, 89,243,131, 244,173,245,215 // Blue
|
|
};
|
|
|
|
|
|
HTTESTDATA VGAData[] =
|
|
{
|
|
{ 18, 12, 650000, VGABmp1 },
|
|
{ sizeof(VGABmp2), 1, 70000, VGABmp2 },
|
|
{ sizeof(VGABmp3), 1, 100000, VGABmp3 },
|
|
{ sizeof(VGABmp4) / 3, 3, 180000, VGABmp4 }
|
|
};
|
|
|
|
|
|
|
|
|
|
SHORTRGB MemColorPalette[] = { // this is a xyz chart
|
|
|
|
{ 920, 810, 580 }, // 1/1 0 A: dark skin
|
|
{ 4110, 3760, 3030 }, // 1/2 1 B: light skin
|
|
{ 1830, 1860, 3730 }, // 1/3 2 C: blue sky
|
|
{ 940, 1170, 670 }, // 1/4 3 D: foliage
|
|
{ 2690, 2440, 5030 }, // 1/5 4 E: blue flower
|
|
{ 3500, 4600, 5310 }, // 1/6 5 F: bluish green
|
|
{ 3860, 3110, 660 }, // 2/1 6 G: orange
|
|
{ 1230, 1020, 3590 }, // 2/2 7 H: purplish blue
|
|
{ 2840, 1920, 1510 }, // 2/3 8 I: moderate red
|
|
{ 590, 400, 1020 }, // 2/4 9 J: purple
|
|
{ 3680, 4740, 1270 }, // 2/5 10 K: yellow green
|
|
{ 4970, 4600, 940 }, // 2/6 11 L: orange yellow
|
|
{ 500, 350, 1830 }, // 3/1 12 M: blue
|
|
{ 1490, 2340, 1060 }, // 3/2 13 N: green
|
|
{ 1760, 1020, 480 }, // 3/3 14 O: red
|
|
{ 6140, 6440, 1120 }, // 3/4 15 P: yellow
|
|
{ 3000, 1920, 3320 }, // 3/5 16 Q: magenta
|
|
{ 1490, 1920, 4210 }, // 3/6 17 R: cyan
|
|
{ 9810, 10000, 11840 }, // 4/1 18 S: white
|
|
{ 6320, 6440, 7630 }, // 4/2 19 T: neutral 8
|
|
{ 3740, 3810, 4510 }, // 4/3 10 U: neutral 6.5
|
|
{ 1890, 1920, 2270 }, // 4/4 21 V: neutral 5
|
|
{ 670, 680, 800 }, // 4/5 22 W: neutral 3.5
|
|
{ 0, 0, 0 } // 4/6 23 X: black
|
|
};
|
|
|
|
#if 0
|
|
BYTERGB SMPTEPalette[] = {
|
|
|
|
{ 191, 191, 191 }, // GY 0
|
|
{ 191, 191, 0 }, // Y 1
|
|
{ 0, 191, 191 }, // C 2
|
|
{ 0, 191, 0 }, // G 3
|
|
{ 191, 0, 191 }, // M 4
|
|
{ 191, 0, 0 }, // R 5
|
|
{ 0, 0, 191 }, // B 6
|
|
{ 0, 76, 127 }, // -I 7
|
|
{ 255, 255, 255 }, // W 8
|
|
{ 75, 0, 139 }, // +Q 9
|
|
{ 0, 0, 0 }, // BK 10
|
|
|
|
0.2, 0.4, 0.6, 0.8
|
|
|
|
{ 11, 11, 11 }, // BK+4 11
|
|
{ 22, 22, 22 } // BK+6 12
|
|
};
|
|
#endif
|
|
|
|
SHORTRGB SMPTEPalette[] = { // this is a YIQ chart
|
|
|
|
|
|
{ 5454, 0, 0 }, // 0: Gray
|
|
{ 4692, 1700, -1673 }, // 1: Yellow
|
|
{ 3871, -3156, -1149 }, // 2: Cyan
|
|
{ 3108, -1456, -2796 }, // 3: Green
|
|
{ 2346, 1456, 2769 }, // 4: Magenta
|
|
{ 1583, 3156, 1123 }, // 5: Red
|
|
{ 763, -1700, 1647 }, // 6: Blue
|
|
{ 723, -890, 309 }, // 7: -I // 2467
|
|
{ 10000, 0, 0 }, // 8: White
|
|
{ 581, -441, 962 }, // 9: +Q // 1665
|
|
{ 0, 0, 0 }, // 10: Black
|
|
{ 500, 0, 0 }, // 11: Black+1
|
|
{ 1000, 0, 0 }, // 12: Black+2
|
|
{ 1500, 0, 0 }, // 13: Black+3
|
|
{ 2000, 0, 0 }, // 14: Black+4
|
|
{ 2500, 0, 0 }, // 15: Black+5
|
|
{ 3000, 0, 0 }, // 16: Black+6
|
|
{ 3500, 0, 0 }, // 17: Black+7
|
|
{ 4000, 0, 0 } // 18: Black+8
|
|
};
|
|
|
|
BYTE SMPTEBmp1[] = {
|
|
|
|
0, 0, 0, 0, // GY
|
|
1, 1, 1, 1, // Y
|
|
2, 2, 2, 2, // C
|
|
3, 3, 3, 3, // G
|
|
4, 4, 4, 4, // M
|
|
5, 5, 5, 5, // R
|
|
6, 6, 6, 6 // B
|
|
};
|
|
|
|
BYTE SMPTEBmp2[] = {
|
|
|
|
6, 6, 6, 6, // B
|
|
10,10,10,10, // BK
|
|
4, 4, 4, 4, // M
|
|
10,10,10,10, // BK
|
|
2, 2, 2, 2, // C
|
|
10,10,10,10, // BK
|
|
0, 0, 0, 0 // GY
|
|
};
|
|
|
|
|
|
BYTE SMPTEBmp3[] = {
|
|
|
|
7, 7, 7, 7, 7, // -I
|
|
8, 8, 8, 8, 8, // W
|
|
9, 9, 9, 9, 9, // +Q
|
|
10,10,10,10,10, // BK
|
|
11,12,13,14,
|
|
15,16,17,18
|
|
};
|
|
|
|
HTTESTDATA SMPTEData[] =
|
|
{
|
|
{ sizeof(SMPTEBmp1), 1, 670000, SMPTEBmp1 },
|
|
{ sizeof(SMPTEBmp2), 1, 80000, SMPTEBmp2 },
|
|
{ sizeof(SMPTEBmp3), 1, 250000, SMPTEBmp3 }
|
|
};
|
|
|
|
#define TESTINFO_COLOR_TABLE 0
|
|
#define TESTINFO_SMPTE 1
|
|
#define TESTINFO_STD_CLR 2
|
|
#define TESTINFO_VGA 3
|
|
|
|
|
|
HTTESTINFO HTTestInfo[] = {
|
|
|
|
{ // **COLOR TABLE**
|
|
{
|
|
COLOR_TYPE_RGB, // Type
|
|
sizeof(SHORT), // BytesPerPrimary
|
|
sizeof(SHORTRGB), // BytesPerEntry,
|
|
PRIMARY_ORDER_RGB, // PrimaryOrder,
|
|
UDECI4_1, // PrimaryValueMax
|
|
0, // ColorTableEntries
|
|
NULL // no color table
|
|
},
|
|
|
|
NULL, // pTestData
|
|
BMF_16BPP, // SurfaceFormat
|
|
0, // TotalData
|
|
0, // cx
|
|
0 // cy
|
|
},
|
|
|
|
{ // **SMPTE**
|
|
{
|
|
COLOR_TYPE_YIQ,
|
|
sizeof(SHORT),
|
|
sizeof(SHORTRGB),
|
|
PRIMARY_ORDER_YIQ,
|
|
DECI4_1,
|
|
COUNT_ARRAY(SMPTEPalette), // ColorTableEntries
|
|
SMPTEPalette // pColorTable
|
|
},
|
|
|
|
SMPTEData,
|
|
BMF_8BPP,
|
|
COUNT_ARRAY(SMPTEData), // TotalData;
|
|
1, // cx
|
|
1 // cy
|
|
},
|
|
|
|
{ // **Memory Color PALETTE **
|
|
{
|
|
COLOR_TYPE_XYZ,
|
|
sizeof(SHORT),
|
|
sizeof(SHORTRGB),
|
|
PRIMARY_ORDER_XYZ,
|
|
DECI4_1,
|
|
COUNT_ARRAY(MemColorPalette), // ColorTableEntries
|
|
MemColorPalette // pColorTable
|
|
},
|
|
|
|
NULL, // pTestData
|
|
BMF_8BPP,
|
|
0, // no data
|
|
6, // cx
|
|
4 // cy
|
|
},
|
|
|
|
{ // **VGA PALETTE **
|
|
{
|
|
COLOR_TYPE_RGB,
|
|
sizeof(BYTE),
|
|
sizeof(BYTERGB),
|
|
PRIMARY_ORDER_RGB,
|
|
100,
|
|
COUNT_ARRAY(VGAPalette), // ColorTableEntries
|
|
VGAPalette // pColorTable
|
|
},
|
|
|
|
VGAData, // pTestData
|
|
BMF_8BPP,
|
|
COUNT_ARRAY(VGAData), // no data
|
|
1,
|
|
1
|
|
}
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
|
#if DBG
|
|
|
|
|
|
LONG
|
|
HTENTRY
|
|
HT_LOADDS
|
|
SetHalftoneError(
|
|
DWORD HT_FuncIndex,
|
|
LONG ErrorID
|
|
)
|
|
{
|
|
static LPSTR HTApiFuncName[] = {
|
|
|
|
"HalftoneInitProc",
|
|
"HT_CreateDeviceHalftoneInfo",
|
|
"HT_DestroyDeviceHalftoneInfo",
|
|
"HT_CreateHalftoneBrush",
|
|
"HT_ConvertColorTable",
|
|
"HT_CreateStandardMonoPattern",
|
|
"HT_HalftoneBitmap",
|
|
};
|
|
|
|
|
|
static LPSTR HTErrorStr[] = {
|
|
|
|
"WRONG_VERSION_HTINITINFO",
|
|
"INSUFFICIENT_MEMORY",
|
|
"CANNOT_DEALLOCATE_MEMORY",
|
|
"COLORTABLE_TOO_BIG",
|
|
"QUERY_SRC_BITMAP_FAILED",
|
|
"QUERY_DEST_BITMAP_FAILED",
|
|
"QUERY_SRC_MASK_FAILED",
|
|
"SET_DEST_BITMAP_FAILED",
|
|
"INVALID_SRC_FORMAT",
|
|
"INVALID_SRC_MASK_FORMAT",
|
|
"INVALID_DEST_FORMAT",
|
|
"INVALID_DHI_POINTER",
|
|
"SRC_MASK_BITS_TOO_SMALL",
|
|
"INVALID_HTPATTERN_INDEX",
|
|
"INVALID_HALFTONE_PATTERN",
|
|
"HTPATTERN_SIZE_TOO_BIG",
|
|
"NO_SRC_COLORTRIAD",
|
|
"INVALID_COLOR_TABLE",
|
|
"INVALID_COLOR_TYPE",
|
|
"INVALID_COLOR_TABLE_SIZE",
|
|
"INVALID_PRIMARY_SIZE",
|
|
"INVALID_PRIMARY_VALUE_MAX",
|
|
"INVALID_PRIMARY_ORDER",
|
|
"INVALID_COLOR_ENTRY_SIZE",
|
|
"INVALID_FILL_SRC_FORMAT",
|
|
"INVALID_FILL_MODE_INDEX",
|
|
"INVALID_STDMONOPAT_INDEX",
|
|
"INVALID_DEVICE_RESOLUTION",
|
|
"INVALID_TONEMAP_VALUE",
|
|
"NO_TONEMAP_DATA",
|
|
"TONEMAP_VALUE_IS_SINGULAR",
|
|
"INVALID_BANDRECT",
|
|
"STRETCH_RATIO_TOO_BIG",
|
|
"CHB_INV_COLORTABLE_SIZE",
|
|
"HALFTONE_INTERRUPTTED",
|
|
"HTERR_NO_SRC_HTSURFACEINFO",
|
|
"HTERR_NO_DEST_HTSURFACEINFO",
|
|
"HTERR_8BPP_PATSIZE_TOO_BIG",
|
|
"HTERR_16BPP_555_PATSIZE_TOO_BIG"
|
|
};
|
|
|
|
static LPSTR HTPErrorStr[] = {
|
|
|
|
"STRETCH_FACTOR_TOO_BIG",
|
|
"XSTRETCH_FACTOR_TOO_BIG",
|
|
"STRETCH_NEG_OVERHANG",
|
|
"REGRESS_INV_MODE",
|
|
"REGRESS_NO_YDATA",
|
|
"REGRESS_INV_XDATA",
|
|
"REGRESS_INV_YDATA",
|
|
"REGRESS_INV_DATACOUNT",
|
|
"COLORSPACE_NOT_MATCH",
|
|
"INVALID_SRCRGB_SIZE",
|
|
"INVALID_DEVRGB_SIZE"
|
|
};
|
|
|
|
|
|
LPSTR pFuncName;
|
|
LONG ErrorIdx;
|
|
BOOL MapErrorOk = FALSE;
|
|
|
|
if (ErrorID < 0) {
|
|
|
|
if (HT_FuncIndex < (sizeof(HTApiFuncName) / sizeof(LPSTR))) {
|
|
|
|
pFuncName = HTApiFuncName[HT_FuncIndex];
|
|
|
|
} else {
|
|
|
|
pFuncName = "Invalid HT API Function Name";
|
|
}
|
|
|
|
ErrorIdx = -ErrorID;
|
|
|
|
if (ErrorIdx <= (sizeof(HTErrorStr) / sizeof(LPSTR))) {
|
|
|
|
DBGP("%s failed: HTERR_%s (%ld)"
|
|
ARG(pFuncName)
|
|
ARG(HTErrorStr[ErrorIdx - 1])
|
|
ARGL(ErrorID));
|
|
DBGP("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
|
|
|
|
MapErrorOk = TRUE;
|
|
|
|
} else if (ErrorIdx >= -(LONG)HTERR_INTERNAL_ERRORS_START) {
|
|
|
|
ErrorIdx += (LONG)HTERR_INTERNAL_ERRORS_START;
|
|
|
|
if (ErrorIdx < (sizeof(HTPErrorStr) / sizeof(LPSTR))) {
|
|
|
|
DBGP("%s Internal Error: %s (%ld)"
|
|
ARG(pFuncName)
|
|
ARG(HTPErrorStr[ErrorIdx])
|
|
ARGL(ErrorID));
|
|
DBGP("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
|
|
|
|
MapErrorOk = TRUE;
|
|
}
|
|
|
|
}
|
|
|
|
if (!MapErrorOk) {
|
|
|
|
DBGP("%s failed: ??Invalid Error ID (%ld)"
|
|
ARG(pFuncName) ARGL(ErrorID));
|
|
DBGP("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
|
|
}
|
|
}
|
|
|
|
return(ErrorID);
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
//
|
|
//*****************************************************************************
|
|
// START RGB 3 planes device test code, this is testing for the planer format
|
|
//
|
|
|
|
#if DBG
|
|
#if TEST_3PLANES
|
|
|
|
|
|
VOID
|
|
Convert4BPPTo1BPP3Planes(
|
|
LPBYTE pSrcPlane,
|
|
LPBYTE pDstPlane,
|
|
DWORD BytesPerSrcScanLine,
|
|
DWORD BytesPerDstScanLine,
|
|
DWORD cx,
|
|
DWORD cy,
|
|
DWORD SizePerPlane
|
|
)
|
|
{
|
|
LPBYTE p1Plane;
|
|
LPBYTE pPlane1;
|
|
LPBYTE pPlane2;
|
|
LPBYTE pPlane3;
|
|
DWORD xLoop;
|
|
BYTE Load;
|
|
BYTE Mask;
|
|
BYTE DestNow;
|
|
BYTE DestNext;
|
|
BYTE Plane1Byte;
|
|
BYTE Plane2Byte;
|
|
BYTE Plane3Byte;
|
|
|
|
|
|
DBGP("\n\n* Convert4BPPTo1BPP3Planes [%ld x %ld] [%ld BytesPerPlane] *"
|
|
ARGDW(cx) ARGDW(cy) ARGDW(SizePerPlane));
|
|
DBGP("pSrcPlane = %08lx [%ld PerScan), pDstPlane = %08lx [%ld PerScan]"
|
|
ARGDW(pSrcPlane) ARGDW(BytesPerSrcScanLine)
|
|
ARGDW(pDstPlane) ARGDW(BytesPerDstScanLine));
|
|
|
|
|
|
while (cy--) {
|
|
|
|
p1Plane = pSrcPlane;
|
|
pPlane1 = pDstPlane;
|
|
pPlane2 = pPlane1 + SizePerPlane;
|
|
pPlane3 = pPlane2 + SizePerPlane;
|
|
|
|
Mask = 0x80;
|
|
xLoop = cx;
|
|
Load = 0x01;
|
|
Plane1Byte =
|
|
Plane2Byte =
|
|
Plane3Byte = 0;
|
|
|
|
while (xLoop--) {
|
|
|
|
if (Load ^= 0x01) {
|
|
|
|
DestNow = DestNext;
|
|
|
|
} else {
|
|
|
|
DestNext =
|
|
DestNow = *p1Plane++;
|
|
DestNow >>= 4;
|
|
DestNext &= 0x0f;
|
|
}
|
|
|
|
if (DestNow & 0x01) {
|
|
|
|
Plane1Byte |= Mask;
|
|
}
|
|
|
|
if (DestNow & 0x02) {
|
|
|
|
Plane2Byte |= Mask;
|
|
}
|
|
|
|
if (DestNow & 0x04) {
|
|
|
|
Plane3Byte |= Mask;
|
|
}
|
|
|
|
if (!(Mask >>= 1)) {
|
|
|
|
*pPlane1++ = Plane1Byte;
|
|
*pPlane2++ = Plane2Byte;
|
|
*pPlane3++ = Plane3Byte;
|
|
|
|
Plane1Byte =
|
|
Plane2Byte =
|
|
Plane3Byte = 0;
|
|
Mask = 0x80;
|
|
}
|
|
}
|
|
|
|
if (Mask != 0x80) {
|
|
|
|
*pPlane1 = Plane1Byte;
|
|
*pPlane2 = Plane2Byte;
|
|
*pPlane3 = Plane3Byte;
|
|
}
|
|
|
|
pSrcPlane += BytesPerSrcScanLine;
|
|
pDstPlane += BytesPerDstScanLine;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID
|
|
Convert1BPP3PlanesTo4BPP(
|
|
LPBYTE pSrcPlane,
|
|
LPBYTE pDstPlane,
|
|
DWORD BytesPerSrcScanLine,
|
|
DWORD BytesPerDstScanLine,
|
|
DWORD cx,
|
|
DWORD cy,
|
|
DWORD SizePerPlane
|
|
)
|
|
{
|
|
LPBYTE p1Plane;
|
|
LPBYTE pPlane1;
|
|
LPBYTE pPlane2;
|
|
LPBYTE pPlane3;
|
|
DWORD xLoop;
|
|
BYTE Save;
|
|
BYTE Mask;
|
|
BYTE DestByte;
|
|
BYTE Plane1Byte;
|
|
BYTE Plane2Byte;
|
|
BYTE Plane3Byte;
|
|
|
|
|
|
DBGP("\n\n* Convert1BPP3PlanesTo4BPP [%ld x %ld] [%ld BytesPerPlane] *"
|
|
ARGDW(cx) ARGDW(cy) ARGDW(SizePerPlane));
|
|
DBGP("pSrcPlane = %08lx [%ld PerScan), pDstPlane = %08lx [%ld PerScan]"
|
|
ARGDW(pSrcPlane) ARGDW(BytesPerSrcScanLine)
|
|
ARGDW(pDstPlane) ARGDW(BytesPerDstScanLine));
|
|
|
|
while (cy--) {
|
|
|
|
pPlane1 = pSrcPlane;
|
|
pPlane2 = pPlane1 + SizePerPlane;
|
|
pPlane3 = pPlane2 + SizePerPlane;
|
|
p1Plane = pDstPlane;
|
|
|
|
xLoop = cx;
|
|
Save = 1;
|
|
Mask = 0x0;
|
|
DestByte = 0x0;
|
|
|
|
while (xLoop--) {
|
|
|
|
if (!(Mask >>= 1)) {
|
|
|
|
Plane1Byte = *(pPlane1++);
|
|
Plane2Byte = *(pPlane2++);
|
|
Plane3Byte = *(pPlane3++);
|
|
Mask = 0x80;
|
|
}
|
|
|
|
if (Save ^= 0x01) {
|
|
|
|
if (Plane1Byte & Mask) {
|
|
|
|
DestByte |= 0x01;
|
|
}
|
|
|
|
if (Plane2Byte & Mask) {
|
|
|
|
DestByte |= 0x02;
|
|
}
|
|
|
|
if (Plane3Byte & Mask) {
|
|
|
|
DestByte |= 0x04;
|
|
}
|
|
|
|
*p1Plane++ = DestByte;
|
|
DestByte = 0x0;
|
|
|
|
} else {
|
|
|
|
if (Plane1Byte & Mask) {
|
|
|
|
DestByte |= 0x10;
|
|
}
|
|
|
|
if (Plane2Byte & Mask) {
|
|
|
|
DestByte |= 0x20;
|
|
}
|
|
|
|
if (Plane3Byte & Mask) {
|
|
|
|
DestByte |= 0x40;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!Save) {
|
|
|
|
*p1Plane = DestByte;
|
|
}
|
|
|
|
pSrcPlane += BytesPerSrcScanLine;
|
|
pDstPlane += BytesPerDstScanLine;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#endif // TEST_3PLANES
|
|
#endif // DBG
|
|
|
|
//
|
|
// END OF RGB 3 planes device test code, this is testing for the planer format
|
|
//*****************************************************************************
|
|
//
|
|
|
|
|
|
|
|
BOOL
|
|
PASCAL
|
|
HT_LOADDS
|
|
EnableHalftone(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function initialize all internal halftone global data to have
|
|
halftone DLL/LIB ready to be used
|
|
|
|
This function MUST called from ALL API entries which does not required
|
|
a PDEVICEHALFTONEINFO data pointer
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
Author:
|
|
|
|
02-Mar-1993 Tue 19:38:43 created -by- Daniel Chou (danielc)
|
|
|
|
15-Dec-1995 Fri 16:48:46 updated -by- Daniel Chou (danielc)
|
|
All initialization is done at here
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
FD6 L;
|
|
UINT i;
|
|
|
|
|
|
EnableHTMemLink();
|
|
|
|
if (!(HTGlobal.HTMutexCDCI = CREATE_HTMUTEX())) {
|
|
|
|
ASSERTMSG("InitHTInternalData: CREATE_HTMUTEX(HTMutexCDCI) failed!",
|
|
HTGlobal.HTMutexCDCI);
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
HTGlobal.CDCICount = 0;
|
|
|
|
if (!(HTGlobal.HTMutexCSMP = CREATE_HTMUTEX())) {
|
|
|
|
ASSERTMSG("InitHTInternalData: CREATE_HTMUTEX(HTMutexCSMP) failed!",
|
|
HTGlobal.HTMutexCSMP);
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
HTGlobal.CSMPCount = 0;
|
|
|
|
DBGP_IF(DBGP_HTMUTEX,
|
|
DBGP("\nINIT HTMutex: CDCI=%08lx, CSMP=%08lx"
|
|
ARGDW(HTGlobal.HTMutexCDCI)
|
|
ARGDW(HTGlobal.HTMutexCSMP)));
|
|
|
|
for (i = 1; i <= (UINT)(RGB555_C_LEVELS - 2); i++) {
|
|
|
|
L = DivFD6(i, (UINT)(RGB555_C_LEVELS - 1));
|
|
L2I_16bpp555[i] = CIE_L2I(L);
|
|
|
|
DBGP_IF(DBGP_COMPUTE_L2I,
|
|
DBGP("RGB555 %3u = %s"
|
|
ARGU(i)
|
|
ARGFD6(L2I_16bpp555[i], 1, 6)));
|
|
}
|
|
|
|
for (i = 1; i <= (UINT)(VGA256_MONO_SIZE - 2); i++) {
|
|
|
|
L = DivFD6(i, (UINT)(VGA256_MONO_SIZE - 1));
|
|
L2I_VGA256Mono[i] = CIE_L2I(L);
|
|
|
|
DBGP_IF(DBGP_COMPUTE_L2I,
|
|
DBGP("VGA MONO %3u = %s"
|
|
ARGU(i)
|
|
ARGFD6(L2I_VGA256Mono[i], 1, 6)));
|
|
}
|
|
|
|
L2I_16bpp555[0] =
|
|
L2I_VGA256Mono[0] = FD6_0;
|
|
L2I_16bpp555[RGB555_C_LEVELS] =
|
|
L2I_VGA256Mono[VGA256_MONO_SIZE] = FD6_1;
|
|
|
|
//
|
|
// The last one just to prevent from divide by 0
|
|
//
|
|
|
|
L2I_16bpp555[RGB555_C_LEVELS - 1] =
|
|
L2I_VGA256Mono[VGA256_MONO_SIZE - 1] = (FD6)(FD6_1 + 1);
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID
|
|
PASCAL
|
|
HT_LOADDS
|
|
DisableHalftone(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function free CDCI/CSMP cached data
|
|
|
|
Arguments:
|
|
|
|
none.
|
|
|
|
Return Value:
|
|
|
|
BOOL
|
|
|
|
This function must called when gdisrv.dll is unloaded, sinnce halftone
|
|
is a linked as a library not a individual DLL.
|
|
|
|
Author:
|
|
|
|
20-Feb-1991 Wed 18:42:11 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
HLOCAL hData;
|
|
PCDCIDATA pCDCIData;
|
|
PCSMPDATA pCSMPData;
|
|
PCSMPBMP pCSMPBmp;
|
|
|
|
|
|
DBGP_IF((DBGP_CACHED_DCI | DBGP_CACHED_SMP),
|
|
DBGP("FreeHTGlobal: UsedCount: CDCI=%u, CSMP=%u"
|
|
ARGU(HTGlobal.CDCICount)
|
|
ARGU(HTGlobal.CSMPCount)));
|
|
|
|
HTShowMemLink("Before DisableHalftone", 0, -1);
|
|
|
|
//
|
|
// Do the CDCI Data first
|
|
//
|
|
|
|
ACQUIRE_HTMUTEX(HTGlobal.HTMutexCDCI);
|
|
|
|
pCDCIData = HTGlobal.pCDCIDataHead;
|
|
|
|
while (hData = (HLOCAL)pCDCIData) {
|
|
|
|
DBGP_IF(DBGP_CACHED_DCI,
|
|
DBGP("FreeHTGlobal: HTLocalFree(pCDCIDATA=%08lx"
|
|
ARG(pCDCIData)));
|
|
|
|
pCDCIData = pCDCIData->pNextCDCIData;
|
|
hData = HTLocalFree(hData);
|
|
|
|
ASSERTMSG("FreeHTGlobal: HTLocalFree(CDCI) Failed",
|
|
!hData);
|
|
}
|
|
|
|
HTGlobal.pCDCIDataHead = NULL;
|
|
HTGlobal.CDCICount = 0;
|
|
|
|
RELEASE_HTMUTEX(HTGlobal.HTMutexCDCI);
|
|
DELETE_HTMUTEX(HTGlobal.HTMutexCDCI);
|
|
|
|
HTGlobal.HTMutexCDCI = (HTMUTEX)0;
|
|
|
|
//
|
|
// Do the bitmap pattern now
|
|
//
|
|
|
|
ACQUIRE_HTMUTEX(HTGlobal.HTMutexCSMP);
|
|
|
|
pCSMPData = HTGlobal.pCSMPDataHead;
|
|
|
|
while (pCSMPData) {
|
|
|
|
pCSMPBmp = pCSMPData->pCSMPBmpHead;
|
|
|
|
while (hData = (HLOCAL)pCSMPBmp) {
|
|
|
|
DBGP_IF(DBGP_CACHED_SMP,
|
|
DBGP("FreeHTGlobal: HTLocalFree(pCSMPBmp=%08lx"
|
|
ARG(pCSMPBmp)));
|
|
|
|
pCSMPBmp = pCSMPBmp->pNextCSMPBmp;
|
|
hData = HTLocalFree(hData);
|
|
|
|
ASSERTMSG("FreeHTGlobal: HTLocalFree(CSMPBMP) Failed",
|
|
!hData);
|
|
}
|
|
|
|
hData = (HLOCAL)pCSMPData;
|
|
pCSMPData = pCSMPData->pNextCSMPData;
|
|
hData = HTLocalFree(hData);
|
|
|
|
DBGP_IF(DBGP_CACHED_SMP,
|
|
DBGP("FreeHTGlobal: HTLocalFree(pCSMPData=%08lx"
|
|
ARG(pCSMPData)));
|
|
|
|
ASSERTMSG("FreeHTGlobal: HTLocalFree(CSMPDATA) Failed",
|
|
!hData);
|
|
}
|
|
|
|
HTGlobal.pCSMPDataHead = NULL;
|
|
HTGlobal.CSMPCount = 0;
|
|
|
|
RELEASE_HTMUTEX(HTGlobal.HTMutexCSMP);
|
|
DELETE_HTMUTEX(HTGlobal.HTMutexCSMP);
|
|
|
|
HTGlobal.HTMutexCSMP = (HTMUTEX)NULL;
|
|
|
|
HTShowMemLink("After DisableHalftone", 0, 0);
|
|
HTMEMLINK_SNAPSHOT;
|
|
DisableHTMemLink();
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL
|
|
HTENTRY
|
|
CleanUpDHI(
|
|
PDEVICEHALFTONEINFO pDeviceHalftoneInfo
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function clean up (free hMutex/memory) of a DeviceHalftoneInfo
|
|
|
|
Arguments:
|
|
|
|
pDeviceHalftoneInfo - the pDeviceHalftoneInfo must be valid
|
|
|
|
Return Value:
|
|
|
|
BOOL
|
|
|
|
|
|
Author:
|
|
|
|
20-Feb-1991 Wed 18:42:11 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
PDEVICECOLORINFO pDCI;
|
|
HTMUTEX HTMutex;
|
|
HLOCAL hData;
|
|
UINT Loop;
|
|
BOOL Ok = TRUE;
|
|
|
|
|
|
HTShowMemLink("Before CleanUpDHI", (DWORD)pDeviceHalftoneInfo, -1);
|
|
|
|
|
|
pDCI = PDHI_TO_PDCI(pDeviceHalftoneInfo);
|
|
|
|
ACQUIRE_HTMUTEX(pDCI->HTMutex);
|
|
|
|
HTMutex = pDCI->HTMutex;
|
|
|
|
//
|
|
// Free all memory assoicated with this device
|
|
//
|
|
|
|
if (pDCI->HTCell.pThresholds) {
|
|
|
|
DBGP_IF(DBGP_DHI_MEM,
|
|
DBGP("CleanUpDHI: HTLocalFree(pDCI->HTCell.pThresholds=%08lx)"
|
|
ARG(pDCI->HTCell.pThresholds)));
|
|
|
|
if (HTLocalFree((HLOCAL)pDCI->HTCell.pThresholds)) {
|
|
|
|
ASSERTMSG("CleanUpDHI: FreeMemory(pDCI->HTCell.pThresholds)", FALSE);
|
|
Ok = FALSE;
|
|
}
|
|
}
|
|
|
|
Loop = CMI_TOTAL_COUNT;
|
|
|
|
while (Loop--) {
|
|
|
|
if (hData = (HLOCAL)pDCI->CMI[Loop].pMappingTable) {
|
|
|
|
DBGP_IF(DBGP_DHI_MEM,
|
|
DBGP("CleanUpDHI: HTLocalFree(pDCI->CMI[%u]=%08lx)"
|
|
ARGU(Loop) ARGDW(hData)));
|
|
|
|
if (HTLocalFree(hData)) {
|
|
|
|
ASSERTMSG("CleanUpDHI: FreeMemory(pDCI->CMI[])", FALSE);
|
|
Ok = FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
Loop = CBFL_TOTAL_COUNT;
|
|
|
|
while (Loop--) {
|
|
|
|
if (hData = (HLOCAL)pDCI->CBFLUT[Loop].pLUT) {
|
|
|
|
DBGP_IF(DBGP_DHI_MEM,
|
|
DBGP("CleanUpDHI: HTLocalFree(pDCI->CBFLUT[%u].pLUT=%08lx)"
|
|
ARGU(Loop) ARGDW(hData)));
|
|
|
|
if (HTLocalFree(hData)) {
|
|
|
|
ASSERTMSG("CleanUpDHI: FreeMemory(pDCI->CBLUT[])", FALSE);
|
|
Ok = FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
Loop = CRTX_TOTAL_COUNT;
|
|
|
|
while (Loop--) {
|
|
|
|
if (hData = (HLOCAL)pDCI->CRTX[Loop].pFD6XYZ) {
|
|
|
|
DBGP_IF(DBGP_DHI_MEM,
|
|
DBGP("CleanUpDHI: HTLocalFree(pDCI->CRTX[%u].pFD6XYZ=%08lx)"
|
|
ARGU(Loop) ARGDW(hData)));
|
|
|
|
if (HTLocalFree(hData)) {
|
|
|
|
ASSERTMSG("CleanUpDHI: FreeMemory(pDCI->CRTX[])", FALSE);
|
|
Ok = FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
DBGP_IF(DBGP_DHI_MEM,
|
|
DBGP("CleanUpDHI: HTLocalFree(pDHI=%08lx)"
|
|
ARGDW(pDeviceHalftoneInfo)));
|
|
|
|
if (HTLocalFree((HLOCAL)pDeviceHalftoneInfo)) {
|
|
|
|
ASSERTMSG("CleanUpDHI: FreeMemory(pDeviceHalftoneInfo)", FALSE);
|
|
Ok = FALSE;
|
|
}
|
|
|
|
RELEASE_HTMUTEX(HTMutex);
|
|
DELETE_HTMUTEX(HTMutex);
|
|
|
|
HTShowMemLink("After CleanUpDHI", (DWORD)pDeviceHalftoneInfo, 0);
|
|
|
|
HTMEMLINK_SNAPSHOT;
|
|
|
|
return(Ok);
|
|
}
|
|
|
|
|
|
BOOL
|
|
APIENTRY
|
|
HT_LOADDS
|
|
HalftoneInitProc(
|
|
HMODULE hModule,
|
|
DWORD Reason,
|
|
LPVOID Reserved
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function is DLL main entry point, at here we will save the module
|
|
handle, in the future we will need to do other initialization stuff.
|
|
|
|
Arguments:
|
|
|
|
hModule - Handle to this moudle when get loaded.
|
|
|
|
Reason - may be DLL_PROCESS_ATTACH
|
|
|
|
Reserved - reserved
|
|
|
|
Return Value:
|
|
|
|
Always return 1L
|
|
|
|
|
|
Author:
|
|
|
|
20-Feb-1991 Wed 18:42:11 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
UNREFERENCED_PARAMETER(Reserved);
|
|
|
|
|
|
switch(Reason) {
|
|
|
|
case DLL_PROCESS_ATTACH:
|
|
|
|
DBGP_IF((DBGP_CACHED_DCI | DBGP_CACHED_SMP),
|
|
DBGP("\n****** DLL_PROCESS_ATTACH ******\n"));
|
|
|
|
HTGlobal.hModule = hModule;
|
|
EnableHalftone();
|
|
|
|
break;
|
|
|
|
|
|
case DLL_PROCESS_DETACH:
|
|
|
|
DBGP_IF((DBGP_CACHED_DCI | DBGP_CACHED_SMP),
|
|
DBGP("\n****** DLL_PROCESS_DETACH ******\n"));
|
|
|
|
DisableHalftone();
|
|
break;
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PCDCIDATA
|
|
HTENTRY
|
|
FindCachedDCI(
|
|
PDEVICECOLORINFO pDCI
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function will try to find the cached DEVICECOLORINFO and put the
|
|
cached data to the pDCI
|
|
|
|
Arguments:
|
|
|
|
pDCI - Pointer to current device color info
|
|
|
|
|
|
Return Value:
|
|
|
|
INT, Index number to the PCDCI.Header[] array, if return value is < 0 then
|
|
the CachedDCI data is not found.
|
|
|
|
Author:
|
|
|
|
01-May-1992 Fri 13:10:14 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
PCDCIDATA pCurCDCIData;
|
|
DEFDBGVAR(UINT, SearchIndex = 0)
|
|
|
|
|
|
#if DBG
|
|
if (DisableCacheDCI_SMP) {
|
|
|
|
return(NULL);
|
|
}
|
|
#endif
|
|
|
|
|
|
ACQUIRE_HTMUTEX(HTGlobal.HTMutexCDCI);
|
|
|
|
if (pCurCDCIData = HTGlobal.pCDCIDataHead) {
|
|
|
|
PCDCIDATA pPrevCDCIData = NULL;
|
|
DWORD Checksum = pDCI->HTInitInfoChecksum;
|
|
|
|
|
|
DBGP_IF(DBGP_CACHED_DCI,
|
|
DBGP("FindCDCI: Looking for Checksum (0x%08lx), Count=%u"
|
|
ARGDW(Checksum) ARGU(HTGlobal.CDCICount)));
|
|
|
|
ASSERT(HTGlobal.CDCICount);
|
|
|
|
while (pCurCDCIData) {
|
|
|
|
if (pCurCDCIData->Checksum == Checksum) {
|
|
|
|
DBGP_IF(DBGP_CACHED_DCI,
|
|
DBGP("FindCDCI: Found %08lx [CheckSum=%08lx] after %u links, pPrev=%08lx"
|
|
ARG(pCurCDCIData)
|
|
ARGDW(Checksum)
|
|
ARGU(SearchIndex)
|
|
ARG(pPrevCDCIData)));
|
|
|
|
if (pPrevCDCIData) {
|
|
|
|
//
|
|
// The most recent reference's DCI always as first entry,
|
|
// (ie. Link Head), the last is the longest unreferenced
|
|
// so that if we need to delete a DCI, we delete the
|
|
// last one.
|
|
//
|
|
|
|
DBGP_IF(DBGP_CACHED_DCI,
|
|
DBGP("FindCDCI: Move pCur to pHead"));
|
|
|
|
pPrevCDCIData->pNextCDCIData = pCurCDCIData->pNextCDCIData;
|
|
pCurCDCIData->pNextCDCIData = HTGlobal.pCDCIDataHead;
|
|
HTGlobal.pCDCIDataHead = pCurCDCIData;
|
|
}
|
|
|
|
return(pCurCDCIData);
|
|
}
|
|
|
|
SETDBGVAR(SearchIndex, SearchIndex + 1);
|
|
|
|
pPrevCDCIData = pCurCDCIData;
|
|
pCurCDCIData = pCurCDCIData->pNextCDCIData;
|
|
}
|
|
|
|
DBGP_IF(DBGP_CACHED_DCI, DBGP("FindCDCI: ??? NOT FOUND ???"));
|
|
|
|
} else {
|
|
|
|
DBGP_IF(DBGP_CACHED_DCI, DBGP("FindCDCI: ++No CDCIDATA cahced yet++"));
|
|
}
|
|
|
|
RELEASE_HTMUTEX(HTGlobal.HTMutexCDCI);
|
|
|
|
return(NULL);
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL
|
|
HTENTRY
|
|
AddCachedDCI(
|
|
PDEVICECOLORINFO pDCI
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function add the DEVICECOLORINFO information to the DCI cache
|
|
|
|
Arguments:
|
|
|
|
pDCI - Pointer to current device color info
|
|
|
|
Lock - TRUE if need to keep the hMutex locked, (only if add is
|
|
sucessfully)
|
|
|
|
Return Value:
|
|
|
|
INT, Index number to the PCDCI.Header[] array where the new data is added,
|
|
if return value is < 0 then the pDCI'CachedDCI data did not add to the
|
|
cached array.
|
|
|
|
NOTE: If AddCachedDCI() return value >= 0 and Lock=TRUE then caller must
|
|
release the PCDCI.hMutex after done with the data, if return value
|
|
is < 0 then no unlock is necessary.
|
|
|
|
|
|
Author:
|
|
|
|
01-May-1992 Fri 13:24:58 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
PCDCIDATA pCurCDCIData;
|
|
PCDCIDATA pPrevCDCIData;
|
|
DWORD AllocSize;
|
|
WORD SizeCell;
|
|
|
|
#if DBG
|
|
if (DisableCacheDCI_SMP) {
|
|
|
|
return(FALSE);
|
|
}
|
|
#endif
|
|
|
|
ACQUIRE_HTMUTEX(HTGlobal.HTMutexCDCI);
|
|
|
|
//
|
|
// We only cached CDCIDATA to certain extend, if we over that limit then
|
|
// delete the last entry in the link list before adding anything
|
|
//
|
|
|
|
if (HTGlobal.CDCICount >= MAX_CDCI_COUNT) {
|
|
|
|
ASSERT(HTGlobal.pCDCIDataHead);
|
|
|
|
pCurCDCIData = HTGlobal.pCDCIDataHead;
|
|
pPrevCDCIData = NULL;
|
|
|
|
while (pCurCDCIData->pNextCDCIData) {
|
|
|
|
pPrevCDCIData = pCurCDCIData;
|
|
pCurCDCIData = pCurCDCIData->pNextCDCIData;
|
|
}
|
|
|
|
ASSERT(pPrevCDCIData);
|
|
|
|
DBGP_IF(DBGP_CACHED_DCI,
|
|
DBGP("AddCDCI: CDCICount >= %u, Free pLast=%08lx"
|
|
ARGU(MAX_CDCI_COUNT)
|
|
ARGDW(pCurCDCIData)));
|
|
|
|
if (HTLocalFree((HLOCAL)pCurCDCIData)) {
|
|
|
|
ASSERTMSG("AddCDCI: HTLocalFree(pLastCDCIData) Failed", FALSE);
|
|
}
|
|
|
|
pPrevCDCIData->pNextCDCIData = NULL;
|
|
--HTGlobal.CDCICount;
|
|
}
|
|
|
|
SizeCell = (WORD)pDCI->HTCell.Size;
|
|
AllocSize = (DWORD)SizeCell + (DWORD)sizeof(CDCIDATA);
|
|
|
|
DBGP_IF(DBGP_CACHED_DCI,
|
|
DBGP(" AddCDCI: HTLocalAlloc(CDCIDATA(%ld) + Cell(%ld)) = %ld bytes"
|
|
ARGDW(sizeof(CDCIDATA))
|
|
ARGDW(SizeCell) ARGDW(AllocSize)));
|
|
|
|
if (pCurCDCIData = (PCDCIDATA)HTLocalAlloc(0,
|
|
"CurCDCIData",
|
|
NONZEROLPTR,
|
|
AllocSize)) {
|
|
|
|
//
|
|
// put this data at link list head
|
|
//
|
|
|
|
pCurCDCIData->Checksum = pDCI->HTInitInfoChecksum;
|
|
pCurCDCIData->pNextCDCIData = HTGlobal.pCDCIDataHead;
|
|
pCurCDCIData->ClrXFormBlock = pDCI->ClrXFormBlock;
|
|
pCurCDCIData->DCIFlags = pDCI->Flags;
|
|
pCurCDCIData->cxCell = pDCI->HTCell.Width;
|
|
pCurCDCIData->cyCell = pDCI->HTCell.Height;
|
|
pCurCDCIData->SizeCell = SizeCell;
|
|
pCurCDCIData->DensitySteps = pDCI->HTCell.DensitySteps;
|
|
pCurCDCIData->DevResXDPI = pDCI->DeviceResXDPI;
|
|
pCurCDCIData->DevResYDPI = pDCI->DeviceResYDPI;
|
|
pCurCDCIData->DevPelsDPI = pDCI->DevicePelsDPI;
|
|
|
|
CopyMemory((LPBYTE)pCurCDCIData + sizeof(CDCIDATA),
|
|
(LPBYTE)pDCI->HTCell.pThresholds,
|
|
SizeCell);
|
|
|
|
HTGlobal.pCDCIDataHead = pCurCDCIData;
|
|
++HTGlobal.CDCICount;
|
|
|
|
|
|
DBGP_IF(DBGP_CACHED_DCI,
|
|
DBGP(" AddCDCI: CDCIHeader, UsedCount=%u, pHead=%08lx, [%08lx]"
|
|
ARGU(HTGlobal.CDCICount)
|
|
ARGU(pCurCDCIData)
|
|
ARGDW(pCurCDCIData->Checksum)));
|
|
|
|
} else {
|
|
|
|
ASSERTMSG("AddCDCI: HTLocalAlloc(pCDCIData) Failed", FALSE);
|
|
}
|
|
|
|
RELEASE_HTMUTEX(HTGlobal.HTMutexCDCI);
|
|
|
|
return((BOOL)(pCurCDCIData));
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL
|
|
HTENTRY
|
|
GetCachedDCI(
|
|
PDEVICECOLORINFO pDCI
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function will try to find the cached DEVICECOLORINFO and put the
|
|
cached data to the pDCI
|
|
|
|
Arguments:
|
|
|
|
pDCI - Pointer to current device color info
|
|
|
|
|
|
Return Value:
|
|
|
|
BOOLEAN
|
|
|
|
Author:
|
|
|
|
01-May-1992 Fri 13:10:14 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
PCDCIDATA pCDCIData;
|
|
BOOL GetOk = FALSE;
|
|
|
|
|
|
if (pCDCIData = FindCachedDCI(pDCI)) {
|
|
|
|
WORD SizeCell = (WORD)pCDCIData->SizeCell;
|
|
|
|
|
|
if (pDCI->HTCell.pThresholds =
|
|
(LPBYTE)HTLocalAlloc((DWORD)PDCI_TO_PDHI(pDCI),
|
|
"Threshold",
|
|
NONZEROLPTR,
|
|
(DWORD)SizeCell)) {
|
|
|
|
pDCI->ClrXFormBlock = pCDCIData->ClrXFormBlock;
|
|
pDCI->Flags = pCDCIData->DCIFlags;
|
|
pDCI->HTCell.Width = pCDCIData->cxCell;
|
|
pDCI->HTCell.Height = pCDCIData->cyCell;
|
|
pDCI->HTCell.Size = SizeCell;
|
|
pDCI->HTCell.DensitySteps = pCDCIData->DensitySteps;
|
|
pDCI->DeviceResXDPI = pCDCIData->DevResXDPI;
|
|
pDCI->DeviceResYDPI = pCDCIData->DevResYDPI;
|
|
pDCI->DevicePelsDPI = pCDCIData->DevPelsDPI;
|
|
|
|
CopyMemory((LPBYTE)pDCI->HTCell.pThresholds,
|
|
(LPBYTE)pCDCIData + sizeof(CDCIDATA),
|
|
SizeCell);
|
|
|
|
GetOk = TRUE;
|
|
|
|
} else {
|
|
|
|
ASSERTMSG("GetCDCI: HTLocalAlloc(Thresholds) failed", FALSE);
|
|
}
|
|
|
|
RELEASE_HTMUTEX(HTGlobal.HTMutexCDCI);
|
|
}
|
|
|
|
return(GetOk);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PCSMPBMP
|
|
HTENTRY
|
|
FindCachedSMP(
|
|
PDEVICECOLORINFO pDCI,
|
|
UINT PatternIndex
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function will try to find the cached DEVICECOLORINFO and put the
|
|
cached data to the pDCI
|
|
|
|
Arguments:
|
|
|
|
pDCI - Pointer to current device color info
|
|
|
|
|
|
Return Value:
|
|
|
|
INT, Index number to the PCDCI.Header[] array, if return value is < 0 then
|
|
the CachedDCI data is not found.
|
|
|
|
Author:
|
|
|
|
01-May-1992 Fri 13:10:14 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
PCSMPDATA pPrevCSMPData;
|
|
PCSMPDATA pCurCSMPData;
|
|
PCSMPBMP pCurCSMPBmp;
|
|
DWORD Checksum = pDCI->HTSMPChecksum;
|
|
DEFDBGVAR(UINT, SearchIndex = 0)
|
|
|
|
#if DBG
|
|
if (DisableCacheDCI_SMP) {
|
|
|
|
return(NULL);
|
|
}
|
|
#endif
|
|
|
|
ACQUIRE_HTMUTEX(HTGlobal.HTMutexCSMP);
|
|
|
|
if (pCurCSMPData = HTGlobal.pCSMPDataHead) {
|
|
|
|
pPrevCSMPData = NULL;
|
|
|
|
DBGP_IF(DBGP_CACHED_DCI,
|
|
DBGP(">>FindCSMP: Looking for Checksum (0x%08lx), Count=%u"
|
|
ARGDW(Checksum) ARGU(HTGlobal.CSMPCount)));
|
|
|
|
ASSERT(HTGlobal.CSMPCount);
|
|
|
|
while (pCurCSMPData) {
|
|
|
|
if (pCurCSMPData->Checksum == Checksum) {
|
|
|
|
DBGP_IF(DBGP_CACHED_SMP,
|
|
DBGP(">>FindCSMP: Found after %u links, pPrev=%08lx"
|
|
ARGU(SearchIndex)
|
|
ARG(pPrevCSMPData)));
|
|
|
|
if (pPrevCSMPData) {
|
|
|
|
//
|
|
// The most recent reference's CSMPDATA always as first
|
|
// entry,(ie. Link Head), the last is the longest
|
|
// unreferenced so that if we need to delete a CSMPDATA,
|
|
// we delete the last one.
|
|
//
|
|
|
|
DBGP_IF(DBGP_CACHED_SMP,
|
|
DBGP(">>FindCSMP: Move pCur to pHead"));
|
|
|
|
pPrevCSMPData->pNextCSMPData = pCurCSMPData->pNextCSMPData;
|
|
pCurCSMPData->pNextCSMPData = HTGlobal.pCSMPDataHead;
|
|
HTGlobal.pCSMPDataHead = pCurCSMPData;
|
|
}
|
|
|
|
//
|
|
// See we cached any pattern for this group
|
|
//
|
|
|
|
pCurCSMPBmp = pCurCSMPData->pCSMPBmpHead;
|
|
|
|
SETDBGVAR(SearchIndex, 0);
|
|
|
|
while (pCurCSMPBmp) {
|
|
|
|
if ((UINT)pCurCSMPBmp->PatternIndex == PatternIndex) {
|
|
|
|
DBGP_IF(DBGP_CACHED_SMP,
|
|
DBGP(">>FindCSMP: Found Pat(%u) after %u links"
|
|
ARGU(PatternIndex)
|
|
ARGU(SearchIndex++)));
|
|
|
|
return(pCurCSMPBmp);
|
|
}
|
|
|
|
pCurCSMPBmp = pCurCSMPBmp->pNextCSMPBmp;
|
|
}
|
|
|
|
//
|
|
// Found in this group but no bitmap for PatternIndex is
|
|
// cached yet!
|
|
//
|
|
|
|
break;
|
|
}
|
|
|
|
SETDBGVAR(SearchIndex, SearchIndex + 1);
|
|
|
|
pPrevCSMPData = pCurCSMPData;
|
|
pCurCSMPData = pCurCSMPData->pNextCSMPData;
|
|
}
|
|
|
|
DBGP_IF(DBGP_CACHED_SMP, DBGP(">>FindCSMP: ??? NOT FOUND ???"));
|
|
|
|
} else {
|
|
|
|
DBGP_IF(DBGP_CACHED_DCI, DBGP(">>FindCSMP: ++No CSMPDATA cahced yet++"));
|
|
}
|
|
|
|
if (!pCurCSMPData) {
|
|
|
|
//
|
|
// Since we did not even found the CSMPDATA checksum group, we want to
|
|
// add it in there, but We only cached CSMPDATA to certain extend, if
|
|
// we over that limit then delete the last entry in the link list
|
|
// before adding anything
|
|
//
|
|
|
|
if (HTGlobal.CSMPCount >= MAX_CSMP_COUNT) {
|
|
|
|
HLOCAL hData;
|
|
|
|
|
|
ASSERT(HTGlobal.pCSMPDataHead);
|
|
|
|
pPrevCSMPData = NULL;
|
|
pCurCSMPData = HTGlobal.pCSMPDataHead;
|
|
|
|
while (pCurCSMPData->pNextCSMPData) {
|
|
|
|
pPrevCSMPData = pCurCSMPData;
|
|
pCurCSMPData = pCurCSMPData->pNextCSMPData;
|
|
}
|
|
|
|
ASSERT(pPrevCSMPData);
|
|
|
|
//
|
|
// Free all the allocated cached standard mono pattern bitmap for
|
|
// this group
|
|
//
|
|
|
|
pCurCSMPBmp = pCurCSMPData->pCSMPBmpHead;
|
|
|
|
DBGP_IF(DBGP_CACHED_SMP,
|
|
DBGP(">>FindCSMP: CSMPCount >= %u, Free pLast=%08lx"
|
|
ARGU(MAX_CSMP_COUNT)
|
|
ARGDW(pCurCSMPData)));
|
|
|
|
while (hData = (HLOCAL)pCurCSMPBmp) {
|
|
|
|
pCurCSMPBmp = pCurCSMPBmp->pNextCSMPBmp;
|
|
|
|
DBGP_IF(DBGP_CACHED_SMP,
|
|
DBGP(">>FindCSMP: Free pLastCSMPBmp=%08lx"
|
|
ARGDW(hData)));
|
|
|
|
if (HTLocalFree(hData)) {
|
|
|
|
ASSERTMSG(">>FindCSMP: HTLocalFree(pCurCSMBmp) Failed", FALSE);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Now free the header for the CSMPDATA
|
|
//
|
|
|
|
if (HTLocalFree((HLOCAL)pCurCSMPData)) {
|
|
|
|
ASSERTMSG(">>FindCSMP: HTLocalFree(pLastCSMPData) Failed", FALSE);
|
|
}
|
|
|
|
pPrevCSMPData->pNextCSMPData = NULL;
|
|
--HTGlobal.CSMPCount;
|
|
}
|
|
|
|
if (pCurCSMPData = (PCSMPDATA)HTLocalAlloc(0,
|
|
"CurCSMPData",
|
|
NONZEROLPTR,
|
|
sizeof(CSMPDATA))) {
|
|
|
|
//
|
|
// Make this one as the link list head
|
|
//
|
|
|
|
pCurCSMPData->Checksum = Checksum;
|
|
pCurCSMPData->pNextCSMPData = HTGlobal.pCSMPDataHead;
|
|
pCurCSMPData->pCSMPBmpHead = NULL;
|
|
|
|
HTGlobal.pCSMPDataHead = pCurCSMPData;
|
|
++HTGlobal.CSMPCount;
|
|
|
|
DBGP_IF(DBGP_CACHED_SMP,
|
|
DBGP(" >>FindCSMP: Add CSMPDATA, UsedCount=%u, pHead=%08lx"
|
|
ARGU(HTGlobal.CSMPCount)
|
|
ARGU(pCurCSMPData)));
|
|
|
|
} else {
|
|
|
|
ASSERTMSG(" >>FindCSMP: HTLocalAlloc(CSMPDATA) Failed", FALSE);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Do allocate new pattern only if we have header
|
|
//
|
|
|
|
if (pCurCSMPData) {
|
|
|
|
STDMONOPATTERN SMP;
|
|
DWORD Size;
|
|
|
|
|
|
SMP.Flags = SMP_TOPDOWN;
|
|
SMP.ScanLineAlignBytes = (BYTE)sizeof(BYTE);
|
|
SMP.PatternIndex = (BYTE)PatternIndex;
|
|
SMP.LineWidth = DEFAULT_SMP_LINE_WIDTH;
|
|
SMP.LinesPerInch = DEFAULT_SMP_LINES_PER_INCH;
|
|
SMP.pPattern = NULL;
|
|
|
|
//
|
|
// Find out the size for the pattern bitmap (BYTE Aligned)
|
|
//
|
|
|
|
Size = (DWORD)CreateStandardMonoPattern(pDCI, &SMP) +
|
|
(DWORD)sizeof(CSMPBMP);
|
|
|
|
DBGP_IF(DBGP_CACHED_SMP,
|
|
DBGP(">>FindCSMP: Add PatternIndex=%u, sz=%ld, DPI(X=%u, Y=%u, P=%u)"
|
|
ARGU(PatternIndex)
|
|
ARGU(Size)
|
|
ARGU(pDCI->DeviceResXDPI)
|
|
ARGU(pDCI->DeviceResYDPI)
|
|
ARGU(pDCI->DevicePelsDPI)));
|
|
|
|
if (pCurCSMPBmp = (PCSMPBMP)HTLocalAlloc(0,
|
|
"CurCSMPBmp",
|
|
NONZEROLPTR,
|
|
Size)) {
|
|
|
|
SMP.pPattern = (LPBYTE)pCurCSMPBmp + sizeof(CSMPBMP);
|
|
|
|
CreateStandardMonoPattern(pDCI, &SMP);
|
|
|
|
//
|
|
// Make this pattern index as link list head
|
|
//
|
|
|
|
pCurCSMPBmp->pNextCSMPBmp = pCurCSMPData->pCSMPBmpHead;
|
|
pCurCSMPBmp->PatternIndex = (WORD)PatternIndex;
|
|
pCurCSMPBmp->cxPels = (WORD)SMP.cxPels;
|
|
pCurCSMPBmp->cyPels = (WORD)SMP.cyPels;
|
|
pCurCSMPBmp->cxBytes = (WORD)SMP.BytesPerScanLine;
|
|
|
|
pCurCSMPData->pCSMPBmpHead = pCurCSMPBmp;
|
|
|
|
return(pCurCSMPBmp);
|
|
|
|
} else {
|
|
|
|
ASSERTMSG(" >>FindCSMP: HTLocalAlloc(CSMPBMP) Failed", FALSE);
|
|
}
|
|
}
|
|
|
|
RELEASE_HTMUTEX(HTGlobal.HTMutexCSMP);
|
|
|
|
return(NULL);
|
|
}
|
|
|
|
|
|
|
|
LONG
|
|
HTENTRY
|
|
GetCachedSMP(
|
|
PDEVICECOLORINFO pDCI,
|
|
PSTDMONOPATTERN pSMP
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function will try to find the cached DEVICECOLORINFO and put the
|
|
cached data to the pDCI
|
|
|
|
Arguments:
|
|
|
|
pDCI - Pointer to current device color info
|
|
|
|
|
|
pSMP - Pointer to the STDMONOPATTERN data structure, if PatIndex is
|
|
< CACHED_SMP_COUNT or, its not default size then it will be
|
|
computed on the fly.
|
|
|
|
|
|
|
|
Return Value:
|
|
|
|
The size of the SMP pattern.
|
|
|
|
Author:
|
|
|
|
01-May-1992 Fri 13:10:14 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
LONG SizeRet = 0;
|
|
UINT PatIndex;
|
|
|
|
|
|
if (!(pSMP->LineWidth)) {
|
|
|
|
pSMP->LineWidth = DEFAULT_SMP_LINE_WIDTH;
|
|
}
|
|
|
|
if (!(pSMP->LinesPerInch)) {
|
|
|
|
pSMP->LinesPerInch = DEFAULT_SMP_LINES_PER_INCH;
|
|
}
|
|
|
|
if (((PatIndex = (UINT)pSMP->PatternIndex) < HT_SMP_PERCENT_SCREEN_START) &&
|
|
(pSMP->LineWidth == DEFAULT_SMP_LINE_WIDTH) &&
|
|
(pSMP->LinesPerInch == DEFAULT_SMP_LINES_PER_INCH)) {
|
|
|
|
PCSMPBMP pCSMPBmp;
|
|
|
|
if (pCSMPBmp = FindCachedSMP(pDCI, PatIndex)) {
|
|
|
|
CSMPBMP CSMPBmp;
|
|
LPBYTE pPatRet;
|
|
LPBYTE pPat;
|
|
WORD cxBytesRet;
|
|
|
|
|
|
CSMPBmp = *pCSMPBmp;
|
|
pPat = (LPBYTE)pCSMPBmp + sizeof(CSMPBMP);
|
|
pSMP->cxPels = CSMPBmp.cxPels;
|
|
pSMP->cyPels = CSMPBmp.cyPels;
|
|
|
|
cxBytesRet =
|
|
pSMP->BytesPerScanLine =
|
|
(WORD)ComputeBytesPerScanLine(BMF_1BPP,
|
|
pSMP->ScanLineAlignBytes,
|
|
CSMPBmp.cxPels);
|
|
SizeRet = (LONG)cxBytesRet * (LONG)CSMPBmp.cyPels;
|
|
|
|
if (pPatRet = pSMP->pPattern) {
|
|
|
|
INT cxBytes;
|
|
INT PatInc;
|
|
WORD Flags;
|
|
|
|
|
|
PatInc =
|
|
cxBytes = (INT)CSMPBmp.cxBytes;
|
|
Flags = pSMP->Flags;
|
|
|
|
DBGP_IF(DBGP_CACHED_DCI,
|
|
DBGP(">> GetCSMP: *COPY* [%2u:%ux%u] @%u(%ld) -> @%u(%u) [%s] [%c=K]"
|
|
ARGU(PatIndex)
|
|
ARGU(CSMPBmp.cxPels)
|
|
ARGU(CSMPBmp.cyPels)
|
|
ARGU(cxBytes)
|
|
ARGU((LONG)cxBytes * (LONG)CSMPBmp.cyPels)
|
|
ARGU(cxBytesRet)
|
|
ARGU(SizeRet)
|
|
ARG((Flags & SMP_TOPDOWN) ? "TOP DOWN" : "BOTTOM UP ")
|
|
ARG((Flags & SMP_0_IS_BLACK) ? '0' : '1')));
|
|
|
|
//
|
|
// Start copying the cached pattern
|
|
//
|
|
|
|
if (!(Flags & SMP_TOPDOWN)) {
|
|
|
|
pPat += (LONG)cxBytes * (LONG)(CSMPBmp.cyPels - 1);
|
|
PatInc = -PatInc;
|
|
}
|
|
|
|
while (CSMPBmp.cyPels--) {
|
|
|
|
CopyMemory(pPatRet, pPat, cxBytes);
|
|
|
|
pPatRet += cxBytesRet;
|
|
pPat += PatInc;
|
|
}
|
|
|
|
if (Flags & SMP_0_IS_BLACK) {
|
|
|
|
LONG Count = SizeRet;
|
|
|
|
|
|
pPatRet = pSMP->pPattern;
|
|
|
|
while (Count--) {
|
|
|
|
*pPatRet++ ^= 0xff;
|
|
}
|
|
}
|
|
}
|
|
|
|
RELEASE_HTMUTEX(HTGlobal.HTMutexCSMP);
|
|
}
|
|
|
|
} else {
|
|
|
|
DBGP_IF(DBGP_CACHED_SMP,
|
|
DBGP(">> GetCSMP: NO CACHED FOR LineWidth=%u, LinesPerInch=%u"
|
|
ARGU(pSMP->LineWidth) ARGU(pSMP->LinesPerInch)));
|
|
}
|
|
|
|
if (!SizeRet) {
|
|
|
|
SizeRet = CreateStandardMonoPattern(pDCI, pSMP);
|
|
}
|
|
|
|
return(SizeRet);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DWORD
|
|
HTENTRY
|
|
ComputeHTINITINFOChecksum(
|
|
PDEVICECOLORINFO pDCI,
|
|
PHTINITINFO pHTInitInfo
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function compute 32-bit checksum for the HTINITINFO data structure
|
|
passed
|
|
|
|
Arguments:
|
|
|
|
pHTInitInfo - Pointer to the HTINITINFO data structure
|
|
|
|
Pointers and HTCOLORADJUSTMENT data structure are not part
|
|
of checksum computation, but content of pointers will be
|
|
included in the checksum calculation.
|
|
|
|
Return Value:
|
|
|
|
32-bit checksum
|
|
|
|
Author:
|
|
|
|
29-Apr-1992 Wed 18:44:42 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD Checksum;
|
|
WORD wBuf[8];
|
|
|
|
|
|
wBuf[0] = (WORD)'HT';
|
|
wBuf[1] = (WORD)pHTInitInfo->Flags;
|
|
wBuf[2] = (WORD)pHTInitInfo->HTPatternIndex;
|
|
wBuf[3] = (WORD)pHTInitInfo->DevicePowerGamma;
|
|
wBuf[4] = (WORD)pHTInitInfo->DeviceResXDPI;
|
|
wBuf[5] = (WORD)pHTInitInfo->DeviceResYDPI;
|
|
wBuf[6] = (WORD)pHTInitInfo->DevicePelsDPI;
|
|
wBuf[7] = (WORD)(((wBuf[4] + wBuf[6]) >> 1) + wBuf[5]);
|
|
|
|
Checksum = ComputeChecksum((LPBYTE)&(wBuf[0]),
|
|
pDCI->HTInitInfoChecksum,
|
|
sizeof(wBuf));
|
|
|
|
DBGP_IF(DBGP_CACHED_DCI,
|
|
DBGP(" HTINITINFO Checksum= %08lx [%08lx]"
|
|
ARGDW(Checksum) ARGDW(pDCI->HTInitInfoChecksum)));
|
|
|
|
if (pHTInitInfo->pHalftonePattern) {
|
|
|
|
HALFTONEPATTERN HTPat = *(pHTInitInfo->pHalftonePattern);
|
|
DWORD Size;
|
|
|
|
if (HTPat.Width > MAX_HTPATTERN_WIDTH) {
|
|
|
|
HTPat.Width = MAX_HTPATTERN_WIDTH;
|
|
}
|
|
|
|
if (HTPat.Height > MAX_HTPATTERN_HEIGHT) {
|
|
|
|
HTPat.Height = MAX_HTPATTERN_HEIGHT;
|
|
}
|
|
|
|
HTPat.pToneMap = NULL;
|
|
|
|
Checksum = ComputeChecksum((LPBYTE)pHTInitInfo->pHalftonePattern,
|
|
Checksum,
|
|
sizeof(HALFTONEPATTERN));
|
|
|
|
DBGP_IF(DBGP_CACHED_DCI,
|
|
DBGP(" HTPATTERN Checksum= %08lx" ARGDW(Checksum)));
|
|
|
|
|
|
if (HTPat.pToneMap = pHTInitInfo->pHalftonePattern->pToneMap) {
|
|
|
|
Size = (DWORD)HTPat.Width * (DWORD)HTPat.Height;
|
|
|
|
|
|
if (!(HTPat.Flags & HTPF_THRESHOLD_ARRAY)) {
|
|
|
|
Size *= 2;
|
|
}
|
|
|
|
Checksum = ComputeChecksum((LPBYTE)HTPat.pToneMap, Checksum, Size);
|
|
|
|
DBGP_IF(DBGP_CACHED_DCI,
|
|
DBGP(" TONEMAP Checksum= %08lx" ARGDW(Checksum)));
|
|
}
|
|
}
|
|
|
|
if (pHTInitInfo->pInputRGBInfo) {
|
|
|
|
Checksum = ComputeChecksum((LPBYTE)pHTInitInfo->pInputRGBInfo,
|
|
Checksum,
|
|
sizeof(CIEINFO));
|
|
DBGP_IF(DBGP_CACHED_DCI,
|
|
DBGP(" RGBINFO Checksum= %08lx" ARGDW(Checksum)));
|
|
}
|
|
|
|
if (pHTInitInfo->pDeviceCIEInfo) {
|
|
|
|
Checksum = ComputeChecksum((LPBYTE)pHTInitInfo->pDeviceCIEInfo,
|
|
Checksum,
|
|
sizeof(CIEINFO));
|
|
DBGP_IF(DBGP_CACHED_DCI,
|
|
DBGP(" CIEINFO Checksum= %08lx" ARGDW(Checksum)));
|
|
}
|
|
|
|
if (pHTInitInfo->pDeviceSolidDyesInfo) {
|
|
|
|
Checksum = ComputeChecksum((LPBYTE)pHTInitInfo->pDeviceSolidDyesInfo,
|
|
Checksum,
|
|
sizeof(SOLIDDYESINFO));
|
|
DBGP_IF(DBGP_CACHED_DCI,
|
|
DBGP(" SOLIDDYE Checksum= %08lx" ARGDW(Checksum)));
|
|
}
|
|
|
|
DBGP_IF(DBGP_CACHED_DCI,
|
|
DBGP("----------------- FINAL Checksum= %08lx" ARGDW(Checksum)));
|
|
|
|
return(pDCI->HTInitInfoChecksum = Checksum);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
HTCALLBACKFUNCTION
|
|
DefaultHTCallBack(
|
|
PHTCALLBACKPARAMS pHTCallBackParams
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This stuff function is provided when caller do not specified the halftone
|
|
callback function.
|
|
|
|
Arguments:
|
|
|
|
pHTCallBackParams - Pointer to the PHTCALLBACKPARAMS
|
|
|
|
Return Value:
|
|
|
|
always return false for the caller.
|
|
|
|
Author:
|
|
|
|
18-Mar-1992 Wed 12:28:13 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
UNREFERENCED_PARAMETER(pHTCallBackParams);
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID
|
|
HTENTRY
|
|
GetCIEPrims(
|
|
PCIEINFO pCIEInfo,
|
|
PCIEPRIMS pCIEPrims,
|
|
PCIEINFO pDefCIEInfo
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function take CIEINFO data structure and converted it to the CIEPRIMS
|
|
internal data type
|
|
|
|
Arguments:
|
|
|
|
pCIEInfo - Pointer to the CIEINFO data structure for conversion,
|
|
if this pointer is NULL then DefCIEPrimsIndex is used
|
|
to index into DefaultCIEPrims[].
|
|
|
|
pCIEPrims - Pointer to the CIEPRIMS data structure
|
|
|
|
pDefCIEInfo - Pointer to the CIEINFO for the default
|
|
|
|
Return Value:
|
|
|
|
VOID
|
|
|
|
Author:
|
|
|
|
20-Apr-1993 Tue 01:14:23 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
CIEINFO CIEInfo = (pCIEInfo) ? *pCIEInfo : *pDefCIEInfo;
|
|
|
|
|
|
if ((CIEInfo.Red.x < CIE_x_MIN) ||
|
|
(CIEInfo.Red.x > CIE_x_MAX) ||
|
|
(CIEInfo.Red.y < CIE_y_MIN) ||
|
|
(CIEInfo.Red.y > CIE_y_MAX) ||
|
|
(CIEInfo.Green.x < CIE_x_MIN) ||
|
|
(CIEInfo.Green.x > CIE_x_MAX) ||
|
|
(CIEInfo.Green.y < CIE_y_MIN) ||
|
|
(CIEInfo.Green.y > CIE_y_MAX) ||
|
|
(CIEInfo.Blue.x < CIE_x_MIN) ||
|
|
(CIEInfo.Blue.x > CIE_x_MAX) ||
|
|
(CIEInfo.Blue.y < CIE_y_MIN) ||
|
|
(CIEInfo.Blue.y > CIE_y_MAX) ||
|
|
(CIEInfo.AlignmentWhite.x < CIE_x_MIN) ||
|
|
(CIEInfo.AlignmentWhite.x > CIE_x_MAX) ||
|
|
(CIEInfo.AlignmentWhite.y < CIE_y_MIN) ||
|
|
(CIEInfo.AlignmentWhite.y > CIE_y_MAX) ||
|
|
(CIEInfo.AlignmentWhite.Y < (UDECI4)2500) ||
|
|
(CIEInfo.AlignmentWhite.Y > (UDECI4)40000)) {
|
|
|
|
CIEInfo = *pDefCIEInfo;
|
|
}
|
|
|
|
pCIEPrims->r.x = UDECI4ToFD6(CIEInfo.Red.x);
|
|
pCIEPrims->r.y = UDECI4ToFD6(CIEInfo.Red.y);
|
|
pCIEPrims->g.x = UDECI4ToFD6(CIEInfo.Green.x);
|
|
pCIEPrims->g.y = UDECI4ToFD6(CIEInfo.Green.y);
|
|
pCIEPrims->b.x = UDECI4ToFD6(CIEInfo.Blue.x);
|
|
pCIEPrims->b.y = UDECI4ToFD6(CIEInfo.Blue.y);
|
|
pCIEPrims->w.x = UDECI4ToFD6(CIEInfo.AlignmentWhite.x);
|
|
pCIEPrims->w.y = UDECI4ToFD6(CIEInfo.AlignmentWhite.y);
|
|
pCIEPrims->Yw = UDECI4ToFD6(CIEInfo.AlignmentWhite.Y);
|
|
}
|
|
|
|
|
|
|
|
|
|
LONG
|
|
APIENTRY
|
|
HT_LOADDS
|
|
HT_CreateDeviceHalftoneInfo(
|
|
PHTINITINFO pHTInitInfo,
|
|
PPDEVICEHALFTONEINFO ppDeviceHalftoneInfo
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function initialize a device to the halftone dll, it calculate all
|
|
the necessary parameters for the device and return a pointer points to
|
|
the DEVICEHALFTONEINFO data structure back to the caller.
|
|
|
|
NOTE: return pointer will not be particulary anchor to a single physucal
|
|
device, but rather to a group of physical devices, that is if the
|
|
caller has simillar devices which share the same characteristics
|
|
then it may use the same pointer to halftone the bitmap.
|
|
|
|
Arguments:
|
|
|
|
pHTInitInfo - Pointer to the HTINITINFO data structure which
|
|
describe the device characteristics and other
|
|
initialzation requests.
|
|
|
|
ppDeviceHalftoneInfo - Pointer to the DEVICEHALFTONEINFO pointer, if
|
|
content of this pointer is not NULL then halftone
|
|
dll assume the caller has previously cached
|
|
DEVICEHALFTONEINFO data pointed by it, if it
|
|
is NULL then halftone dll compute all the
|
|
DEVICEHALFTONEINFO datas for newly created
|
|
halftone info. for the device. (see following
|
|
'Return Value' for more detail)
|
|
|
|
Return Value:
|
|
|
|
The return value will be greater than 0L if the function sucessfully, and
|
|
it will be an error code (less than or equal to 0) if function failed.
|
|
|
|
Return value greater than 0
|
|
|
|
1. The pointer location points by the ppDeviceHalftoneInfo will be
|
|
updated to stored the pointer which points to the DEVICEHALFTONEINFO
|
|
data structure for later any HT_xxxx() api calls.
|
|
|
|
2. The Return value is the total bytes the caller can saved and used
|
|
as cached DeviceHalftoneInfo for next time calling this function,
|
|
the saved area is started from *(ppDeviceHalftoneInfo) and has
|
|
size in bytes as return value.
|
|
|
|
NOTE: if caller passed a pointer pointed by ppDeviceHalftoneInfo and
|
|
the return value is greater than zero then it signal that it
|
|
passed DEVICEHALFTONEINFO pointer is not correct of data has
|
|
been changed from HTINITINFO data structure, the caller can
|
|
continue to save the newly created DEVICEHALFTONEINFO cached
|
|
data.
|
|
|
|
In any cases the caller's passed pointer stored in the
|
|
ppDeviceHalftoneInfo is overwritten by newly created
|
|
DEVICEHALFTONEINFO data structure pointer.
|
|
|
|
|
|
Return value equal to 0
|
|
|
|
1. The caller passed pointer *(ppDeviceHalftoneInfo) is sucessfully
|
|
used as new device halftone info
|
|
|
|
2. The pointer location points by the ppDeviceHalftoneInfo will be
|
|
updated to stored the new pointer which points to the
|
|
DEVICEHALFTONEINFO data structure for later any HT_xxxx() api calls.
|
|
|
|
|
|
NOTE: The caller's passed pointer stored in the ppDeviceHalftoneInfo
|
|
is overwritten by newly created DEVICEHALFTONEINFO data structure
|
|
pointer.
|
|
|
|
Return value less than or equal to zero
|
|
|
|
The function failed, the storage points by the ppDeviceHalftoneInfo is
|
|
undefined.
|
|
|
|
This function may return following error codes.
|
|
|
|
HTERR_INSUFFICIENT_MEMORY - Not enough memory for halftone
|
|
process.
|
|
|
|
HTERR_HTPATTERN_SIZE_TOO_BIG - Caller defined halftone pattern's
|
|
width or height is excessed limit.
|
|
|
|
HTERR_INVALID_HALFTONEPATTERN - One or more HALFTONEPATTERN data
|
|
structure field specified invalid
|
|
values.
|
|
|
|
|
|
Note: The first field in the DEVICEHALFTONEINFO (DeviceOwnData) is a 32-bit
|
|
area which will be set to 0L upon sucessful returned, the caller can
|
|
put any data in this field.
|
|
|
|
Author:
|
|
|
|
05-Feb-1991 Tue 10:54:32 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
05-Jun-1991 Wed 10:22:07 updated -by- Daniel Chou (danielc)
|
|
|
|
Fixed the typing errors for halftone pattern default
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
PHT_DHI pHT_DHI;
|
|
PDEVICECOLORINFO pDCI;
|
|
WORD *pw;
|
|
BYTE HTInitInfoFlags;
|
|
BOOL UseCurNTDefault;
|
|
UDECI4 DevPowerGamma;
|
|
WORD DevPelsDPI;
|
|
DWORD dwBuf[4];
|
|
|
|
|
|
|
|
|
|
DBGP_IF(DBGP_CACHED_DCI,
|
|
DBGP("\n********* HT_CreateDeviceHalftoneInfo *************\n"));
|
|
|
|
//
|
|
// Now check if we have valid data
|
|
//
|
|
|
|
if (pHTInitInfo->Version != (DWORD)HTINITINFO_VERSION) {
|
|
|
|
HTAPI_RET(HTAPI_IDX_CREATE_DHI, HTERR_WRONG_VERSION_HTINITINFO);
|
|
}
|
|
|
|
DBGP_IF(DBGP_CACHED_DCI,
|
|
DBGP("*** Allocate HT_DHI(%ld) ***" ARGDW(sizeof(HT_DHI))));
|
|
|
|
if (!(pHT_DHI = (PHT_DHI)HTLocalAlloc(0xFFFFFFFF,
|
|
"HT_DHI",
|
|
LPTR,
|
|
sizeof(HT_DHI)))) {
|
|
|
|
HTAPI_RET(HTAPI_IDX_CREATE_DHI, HTERR_INSUFFICIENT_MEMORY);
|
|
}
|
|
|
|
pDCI = &(pHT_DHI->DCI);
|
|
pDCI->HalftoneDLLID = HALFTONE_DLL_ID;
|
|
|
|
if (!(pDCI->HTMutex = CREATE_HTMUTEX())) {
|
|
|
|
ASSERTMSG("InitHTInternalData: CREATE_HTMUTEX(pDCI->HTMutex) failed!",
|
|
pDCI->HTMutex);
|
|
|
|
HTAPI_RET(HTAPI_IDX_CREATE_DHI, (HTERR_INTERNAL_ERRORS_START - 999));
|
|
}
|
|
|
|
if (!(pDCI->HTCallBackFunction = pHTInitInfo->HTCallBackFunction)) {
|
|
|
|
pDCI->HTCallBackFunction = DefaultHTCallBack;
|
|
}
|
|
|
|
HTInitInfoFlags = (BYTE)(pHTInitInfo->Flags &= (HIF_SQUARE_DEVICE_PEL |
|
|
HIF_HAS_BLACK_DYE |
|
|
HIF_ADDITIVE_PRIMS));
|
|
|
|
// ****************************************************************
|
|
// * We want to check to see if this is a old data, if yes then *
|
|
// * update the caller to default *
|
|
// ****************************************************************
|
|
//
|
|
|
|
pDCI->HTInitInfoChecksum = HTINITINFO_INITIAL_CHECKSUM;
|
|
|
|
if ((DevPowerGamma = pHTInitInfo->DevicePowerGamma) <
|
|
(UDECI4)RGB_GAMMA_MIN) {
|
|
|
|
DevPowerGamma = (UDECI4)((HTInitInfoFlags & HIF_ADDITIVE_PRIMS) ?
|
|
10000 : HTStdSubDevGamma);
|
|
}
|
|
|
|
if ((!pHTInitInfo->pDeviceCIEInfo) ||
|
|
(pHTInitInfo->pDeviceCIEInfo->Cyan.Y == UDECI4_0)) {
|
|
|
|
//
|
|
// Let's munge around the printer info, to see if its an old def,
|
|
// if yes, then we now make this all into NT4.00 default
|
|
//
|
|
|
|
DBGP_IF(DBGP_CACHED_DCI,
|
|
DBGP("HT: *WARNING* Update Old Default COLORINFO to NT4.00 DEFAULT, DevGamma=%s"
|
|
ARGFD6(HTStdSubDevGamma * 100, 1, 4)));
|
|
|
|
UseCurNTDefault = TRUE;
|
|
|
|
if (!(HTInitInfoFlags & HIF_ADDITIVE_PRIMS)) {
|
|
|
|
DevPowerGamma = HTStdSubDevGamma;
|
|
}
|
|
|
|
dwBuf[0] = (DWORD)'NTHT';
|
|
dwBuf[1] = (DWORD)'4.00';
|
|
dwBuf[2] = (DWORD)'Dan.';
|
|
dwBuf[3] = (DWORD)'Chou';
|
|
DevPelsDPI = 0;
|
|
pDCI->HTInitInfoChecksum = ComputeChecksum((LPBYTE)&dwBuf[0],
|
|
pDCI->HTInitInfoChecksum,
|
|
sizeof(dwBuf));
|
|
|
|
} else {
|
|
|
|
DevPelsDPI = pHTInitInfo->DevicePelsDPI;
|
|
UseCurNTDefault = FALSE;
|
|
}
|
|
|
|
//
|
|
// Compute HTInitInfoChecksum, and check if we have any cached data
|
|
//
|
|
|
|
ComputeHTINITINFOChecksum(pDCI, pHTInitInfo);
|
|
|
|
if (!GetCachedDCI(pDCI)) {
|
|
|
|
FD6 VGAGamma;
|
|
LONG Result;
|
|
|
|
|
|
//
|
|
// Now start to checking the init information
|
|
//
|
|
|
|
pDCI->Flags = (WORD)((HTInitInfoFlags & HIF_SQUARE_DEVICE_PEL) ?
|
|
DCIF_SQUARE_DEVICE_PEL : 0);
|
|
|
|
if ((!(pDCI->DeviceResXDPI = pHTInitInfo->DeviceResXDPI)) ||
|
|
(!(pDCI->DeviceResYDPI = pHTInitInfo->DeviceResYDPI))) {
|
|
|
|
pDCI->DeviceResXDPI =
|
|
pDCI->DeviceResYDPI = 300;
|
|
DevPelsDPI = 0;
|
|
}
|
|
|
|
if ((DevPelsDPI & 0x8000) && (DevPelsDPI &= 0x7fff)) {
|
|
|
|
//
|
|
// This is a percentage ie. 1000 = 100.0%, 960=96.0%,
|
|
// on the DeviceResXDPI, Maximum number accepted is 300.0%
|
|
// The larger the percetage the larger the dot size and smaller
|
|
// the percentage the smaller the dot size, if specified as 1000
|
|
// which is 100.0% then it has same size as its X resolution
|
|
// The range is 33.3% to 1500%
|
|
//
|
|
|
|
if ((DevPelsDPI > MAX_RES_PERCENT) ||
|
|
(DevPelsDPI < MIN_RES_PERCENT)) {
|
|
|
|
DBGP_IF(DBGP_CACHED_DCI,
|
|
DBGP("HT: *WARNING* Invalid DevicePelsDPI=%ld (PERCENT) set to DEFAULT=0"
|
|
ARGDW(DevPelsDPI)));
|
|
DevPelsDPI = 0;
|
|
|
|
} else {
|
|
|
|
DBGP_IF(DBGP_CACHED_DCI,
|
|
DBGP("*** Percentage INPUT DevicePelsDPI=%ld *** "
|
|
ARGDW(DevPelsDPI)));
|
|
|
|
DevPelsDPI = (WORD)(((DWORD)pDCI->DeviceResXDPI * 1000L)
|
|
/ (DWORD)DevPelsDPI);
|
|
|
|
DBGP_IF(DBGP_CACHED_DCI,
|
|
DBGP("*** Percentage OUTPUT DevicePelsDPI=%ld *** "
|
|
ARGDW(DevPelsDPI)));
|
|
}
|
|
|
|
} else if ((DevPelsDPI > (pDCI->DeviceResXDPI * 3)) ||
|
|
(DevPelsDPI > (pDCI->DeviceResYDPI * 3))) {
|
|
|
|
DBGP_IF(DBGP_CACHED_DCI,
|
|
DBGP("HT: *WARNING* Invalid DevicePelsDPI=%ld (RES) set to DEFAULT=0"
|
|
ARGDW(DevPelsDPI)));
|
|
|
|
DevPelsDPI = 0;
|
|
|
|
}
|
|
|
|
//
|
|
// If the DevicePelsDPI is out of range then we will make it 0 (same as
|
|
// device resolution), so it can continue to work
|
|
//
|
|
|
|
if (HTInitInfoFlags & HIF_ADDITIVE_PRIMS) {
|
|
|
|
pDCI->ClrXFormBlock.ColorSpace = CIELUV_1976;
|
|
pDCI->Flags |= DCIF_ADDITIVE_PRIMS;
|
|
|
|
} else {
|
|
|
|
pDCI->ClrXFormBlock.ColorSpace = CIELAB_1976;
|
|
pDCI->Flags |= DCIF_NEED_DYES_CORRECTION;
|
|
|
|
if (HTInitInfoFlags & HIF_HAS_BLACK_DYE) {
|
|
|
|
pDCI->Flags |= DCIF_HAS_BLACK_DYE;
|
|
}
|
|
|
|
if (!(DevPelsDPI)) {
|
|
|
|
DevPelsDPI = (WORD)((((DWORD)pDCI->DeviceResXDPI +
|
|
(DWORD)pDCI->DeviceResYDPI) * 450) / 1000);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Save the DevPelsDPI back to PDCI
|
|
//
|
|
|
|
pDCI->DevicePelsDPI = DevPelsDPI;
|
|
|
|
if (DevPowerGamma != UDECI4_1) {
|
|
|
|
pDCI->Flags |= DCIF_HAS_DEV_GAMMA;
|
|
|
|
pDCI->ClrXFormBlock.DevRGBGamma =
|
|
VGAGamma = UDECI4ToFD6(DevPowerGamma);
|
|
|
|
|
|
} else {
|
|
|
|
pDCI->ClrXFormBlock.DevRGBGamma =
|
|
VGAGamma = FD6_1;
|
|
}
|
|
|
|
pDCI->ClrXFormBlock.VGA16_80h = Power((FD6)501961, VGAGamma);
|
|
pDCI->ClrXFormBlock.VGA16_c0h = Power((FD6)752941, VGAGamma);
|
|
|
|
//
|
|
// This is special for the standard screen
|
|
//
|
|
|
|
if ((HTInitInfoFlags & HIF_ADDITIVE_PRIMS) &&
|
|
(!(pHTInitInfo->pHalftonePattern)) &&
|
|
(pHTInitInfo->HTPatternIndex == HTPAT_SIZE_4x4_M)) {
|
|
|
|
pDCI->Flags |= DCIF_HAS_ALT_4x4_HTPAT;
|
|
}
|
|
|
|
//
|
|
// Check the input and device CIE info
|
|
//
|
|
|
|
GetCIEPrims((UseCurNTDefault) ? NULL : pHTInitInfo->pDeviceCIEInfo,
|
|
&(pDCI->ClrXFormBlock.DevCIEPrims),
|
|
(HTInitInfoFlags & HIF_ADDITIVE_PRIMS) ?
|
|
&HT_CIE_STD_MONITOR : &HT_CIE_STD_PRINTER);
|
|
|
|
GetCIEPrims(pHTInitInfo->pInputRGBInfo,
|
|
&(pDCI->ClrXFormBlock.rgbCIEPrims),
|
|
&HT_CIE_STD_MONITOR);
|
|
#if 0
|
|
//
|
|
// Default Alignement white is same as device
|
|
//
|
|
|
|
pDCI->ClrXFormBlock.rgbCIEPrims.w = pDCI->ClrXFormBlock.DevCIEPrims.w;
|
|
#endif
|
|
ComputeColorSpaceXForm(&(pDCI->ClrXFormBlock.DevCIEPrims),
|
|
&(pDCI->ClrXFormBlock.DevCSXForm),
|
|
pDCI->ClrXFormBlock.ColorSpace,
|
|
ILLUMINANT_MAX_INDEX + 1,
|
|
TRUE);
|
|
|
|
//
|
|
// Compute the solid dyes mixes information and its hue shifting
|
|
// correction factors.
|
|
//
|
|
|
|
if (pDCI->Flags & DCIF_NEED_DYES_CORRECTION) {
|
|
|
|
SOLIDDYESINFO SDI;
|
|
MATRIX3x3 FD6SDI;
|
|
BOOL HasDevSDI;
|
|
|
|
//
|
|
// We have make sure the solid dyes info passed from the caller can be
|
|
// inversed, if not we will use our default
|
|
//
|
|
|
|
if (HasDevSDI = (BOOL)pHTInitInfo->pDeviceSolidDyesInfo) {
|
|
|
|
SDI = *(pHTInitInfo->pDeviceSolidDyesInfo);
|
|
|
|
if ((SDI.MagentaInCyanDye > (UDECI4)9000) ||
|
|
(SDI.YellowInCyanDye > (UDECI4)9000) ||
|
|
(SDI.CyanInMagentaDye > (UDECI4)9000) ||
|
|
(SDI.YellowInMagentaDye > (UDECI4)9000) ||
|
|
(SDI.CyanInYellowDye > (UDECI4)9000) ||
|
|
(SDI.MagentaInYellowDye > (UDECI4)9000)) {
|
|
|
|
HasDevSDI = FALSE;
|
|
|
|
} else if ((SDI.MagentaInCyanDye == UDECI4_0) &&
|
|
(SDI.YellowInCyanDye == UDECI4_0) &&
|
|
(SDI.CyanInMagentaDye == UDECI4_0) &&
|
|
(SDI.YellowInMagentaDye == UDECI4_0) &&
|
|
(SDI.CyanInYellowDye == UDECI4_0) &&
|
|
(SDI.MagentaInYellowDye == UDECI4_0)) {
|
|
|
|
//
|
|
// Do not need any correction if it all zeros
|
|
//
|
|
|
|
pDCI->Flags &= (WORD)(~DCIF_NEED_DYES_CORRECTION);
|
|
}
|
|
}
|
|
|
|
if (pDCI->Flags & DCIF_NEED_DYES_CORRECTION) {
|
|
|
|
#define PDCI_CMYDYEMASKS pDCI->ClrXFormBlock.CMYDyeMasks
|
|
|
|
|
|
MULDIVPAIR MDPairs[4];
|
|
FD6 Y;
|
|
|
|
|
|
if ((UseCurNTDefault) || (!HasDevSDI)) {
|
|
|
|
SDI = DefaultSolidDyesInfo;
|
|
}
|
|
|
|
FD6SDI.m[0][1] = UDECI4ToFD6(SDI.CyanInMagentaDye);
|
|
FD6SDI.m[0][2] = UDECI4ToFD6(SDI.CyanInYellowDye);
|
|
|
|
FD6SDI.m[1][0] = UDECI4ToFD6(SDI.MagentaInCyanDye);
|
|
FD6SDI.m[1][2] = UDECI4ToFD6(SDI.MagentaInYellowDye);
|
|
|
|
FD6SDI.m[2][0] = UDECI4ToFD6(SDI.YellowInCyanDye);
|
|
FD6SDI.m[2][1] = UDECI4ToFD6(SDI.YellowInMagentaDye);
|
|
|
|
FD6SDI.m[0][0] =
|
|
FD6SDI.m[1][1] =
|
|
FD6SDI.m[2][2] = FD6_1;
|
|
|
|
ComputeInverseMatrix3x3(&FD6SDI, &(PDCI_CMYDYEMASKS));
|
|
|
|
if (!(pDCI->Flags & DCIF_HAS_BLACK_DYE)) {
|
|
|
|
MAKE_MULDIV_INFO(MDPairs, 3, MULDIV_NO_DIVISOR);
|
|
MAKE_MULDIV_PAIR(MDPairs, 1, CIE_Xr(PDCI_CMYDYEMASKS), FD6_1);
|
|
MAKE_MULDIV_PAIR(MDPairs, 2, CIE_Xg(PDCI_CMYDYEMASKS), FD6_1);
|
|
MAKE_MULDIV_PAIR(MDPairs, 3, CIE_Xb(PDCI_CMYDYEMASKS), FD6_1);
|
|
|
|
Y = FD6_1 - MulFD6(FD6_1 - MulDivFD6Pairs(MDPairs),
|
|
pDCI->ClrXFormBlock.DevCSXForm.Yrgb.R);
|
|
|
|
MAKE_MULDIV_PAIR(MDPairs, 1, CIE_Yr(PDCI_CMYDYEMASKS), FD6_1);
|
|
MAKE_MULDIV_PAIR(MDPairs, 2, CIE_Yg(PDCI_CMYDYEMASKS), FD6_1);
|
|
MAKE_MULDIV_PAIR(MDPairs, 3, CIE_Yb(PDCI_CMYDYEMASKS), FD6_1);
|
|
|
|
Y -= MulFD6(FD6_1 - MulDivFD6Pairs(MDPairs),
|
|
pDCI->ClrXFormBlock.DevCSXForm.Yrgb.G);
|
|
|
|
MAKE_MULDIV_PAIR(MDPairs, 1, CIE_Zr(PDCI_CMYDYEMASKS), FD6_1);
|
|
MAKE_MULDIV_PAIR(MDPairs, 2, CIE_Zg(PDCI_CMYDYEMASKS), FD6_1);
|
|
MAKE_MULDIV_PAIR(MDPairs, 3, CIE_Zb(PDCI_CMYDYEMASKS), FD6_1);
|
|
|
|
Y -= MulFD6(FD6_1 - MulDivFD6Pairs(MDPairs),
|
|
pDCI->ClrXFormBlock.DevCSXForm.Yrgb.B);
|
|
|
|
DBGP_IF(DBGP_DYECORRECTION,
|
|
DBGP("DYE: Maximum Y=%s, Make Luminance from %s to %s, Turn ON DCIF_HAS_BLACK_DYE"
|
|
ARGFD6(Y, 1, 6)
|
|
ARGFD6(pDCI->ClrXFormBlock.DevCIEPrims.Yw, 1, 6)
|
|
ARGFD6(MulFD6(Y,
|
|
pDCI->ClrXFormBlock.DevCIEPrims.Yw),
|
|
1, 6)));
|
|
|
|
pDCI->Flags |= DCIF_HAS_BLACK_DYE;
|
|
pDCI->ClrXFormBlock.DevCIEPrims.Yw =
|
|
MulFD6(pDCI->ClrXFormBlock.DevCIEPrims.Yw, Y);
|
|
|
|
ComputeColorSpaceXForm(&(pDCI->ClrXFormBlock.DevCIEPrims),
|
|
&(pDCI->ClrXFormBlock.DevCSXForm),
|
|
pDCI->ClrXFormBlock.ColorSpace,
|
|
ILLUMINANT_MAX_INDEX + 1,
|
|
TRUE);
|
|
}
|
|
|
|
DBGP_IF(DBGP_DYECORRECTION,
|
|
|
|
FD6 C;
|
|
FD6 M;
|
|
FD6 Y;
|
|
FD6 C1;
|
|
FD6 M1;
|
|
FD6 Y1;
|
|
static BYTE DyeName[] = "WCMBYGRK";
|
|
WORD Loop = 0;
|
|
|
|
DBGP("====== DyeCorrection 3x3 Matrix =======");
|
|
DBGP("[Cc Cm Cy] [%s %s %s] [%s %s %s]"
|
|
ARGFD6(FD6SDI.m[0][0], 2, 6)
|
|
ARGFD6(FD6SDI.m[0][1], 2, 6)
|
|
ARGFD6(FD6SDI.m[0][2], 2, 6)
|
|
ARGFD6(PDCI_CMYDYEMASKS.m[0][0], 2, 6)
|
|
ARGFD6(PDCI_CMYDYEMASKS.m[0][1], 2, 6)
|
|
ARGFD6(PDCI_CMYDYEMASKS.m[0][2], 2, 6));
|
|
DBGP("[Mc Mm My]=[%s %s %s]=[%s %s %s]"
|
|
ARGFD6(FD6SDI.m[1][0], 2, 6)
|
|
ARGFD6(FD6SDI.m[1][1], 2, 6)
|
|
ARGFD6(FD6SDI.m[1][2], 2, 6)
|
|
ARGFD6(PDCI_CMYDYEMASKS.m[1][0], 2, 6)
|
|
ARGFD6(PDCI_CMYDYEMASKS.m[1][1], 2, 6)
|
|
ARGFD6(PDCI_CMYDYEMASKS.m[1][2], 2, 6));
|
|
DBGP("[Yc Ym Yy] [%s %s %s] [%s %s %s]"
|
|
ARGFD6(FD6SDI.m[2][0], 2, 6)
|
|
ARGFD6(FD6SDI.m[2][1], 2, 6)
|
|
ARGFD6(FD6SDI.m[2][2], 2, 6)
|
|
ARGFD6(PDCI_CMYDYEMASKS.m[2][0], 2, 6)
|
|
ARGFD6(PDCI_CMYDYEMASKS.m[2][1], 2, 6)
|
|
ARGFD6(PDCI_CMYDYEMASKS.m[2][2], 2, 6));
|
|
DBGP("================================================");
|
|
|
|
MAKE_MULDIV_INFO(MDPairs, 3, MULDIV_NO_DIVISOR);
|
|
|
|
for (Loop = 0; Loop <= 7; Loop++) {
|
|
|
|
C = (FD6)((Loop & 0x01) ? FD6_1 : FD6_0);
|
|
M = (FD6)((Loop & 0x02) ? FD6_1 : FD6_0);
|
|
Y = (FD6)((Loop & 0x04) ? FD6_1 : FD6_0);
|
|
|
|
|
|
MAKE_MULDIV_PAIR(MDPairs,1,CIE_Xr(PDCI_CMYDYEMASKS),C);
|
|
MAKE_MULDIV_PAIR(MDPairs,2,CIE_Xg(PDCI_CMYDYEMASKS),M);
|
|
MAKE_MULDIV_PAIR(MDPairs,3,CIE_Xb(PDCI_CMYDYEMASKS),Y);
|
|
C1 = MulDivFD6Pairs(MDPairs);
|
|
|
|
MAKE_MULDIV_PAIR(MDPairs,1,CIE_Yr(PDCI_CMYDYEMASKS),C);
|
|
MAKE_MULDIV_PAIR(MDPairs,2,CIE_Yg(PDCI_CMYDYEMASKS),M);
|
|
MAKE_MULDIV_PAIR(MDPairs,3,CIE_Yb(PDCI_CMYDYEMASKS),Y);
|
|
M1 = MulDivFD6Pairs(MDPairs);
|
|
|
|
MAKE_MULDIV_PAIR(MDPairs,1,CIE_Zr(PDCI_CMYDYEMASKS),C);
|
|
MAKE_MULDIV_PAIR(MDPairs,2,CIE_Zg(PDCI_CMYDYEMASKS),M);
|
|
MAKE_MULDIV_PAIR(MDPairs,3,CIE_Zb(PDCI_CMYDYEMASKS),Y);
|
|
Y1 = MulDivFD6Pairs(MDPairs);
|
|
|
|
DBGP("%u:[%c] = [%s %s %s]"
|
|
ARGU(Loop) ARGB(DyeName[Loop])
|
|
ARGFD6(C1, 2, 6) ARGFD6(M1, 2, 6) ARGFD6(Y1, 2, 6));
|
|
}
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Re-compute
|
|
//
|
|
// Geneate internal HTCELL/REGRESS data structure based on the halftone
|
|
// pattern data passed.
|
|
//
|
|
|
|
|
|
if ((Result = ComputeHTCellRegress((WORD)pHTInitInfo->HTPatternIndex,
|
|
pHTInitInfo->pHalftonePattern,
|
|
pDCI)) < 0) {
|
|
|
|
CleanUpDHI((PDEVICEHALFTONEINFO)pHT_DHI);
|
|
HTAPI_RET(HTAPI_IDX_CREATE_DHI, Result);
|
|
}
|
|
|
|
AddCachedDCI(pDCI);
|
|
}
|
|
|
|
pDCI->CRTX[CRTX_LEVEL_255].PrimMax = 255;
|
|
pDCI->CRTX[CRTX_LEVEL_255].SizeCRTX = (WORD)(((255+1)*3) * sizeof(FD6XYZ));
|
|
pDCI->CRTX[CRTX_LEVEL_31].PrimMax = 31;
|
|
pDCI->CRTX[CRTX_LEVEL_31].SizeCRTX = (WORD)(((31+1)*3) * sizeof(FD6XYZ));
|
|
|
|
//
|
|
// Setting the public field so the caller can looked at
|
|
//
|
|
|
|
pHT_DHI->DHI.DeviceOwnData = 0;
|
|
pHT_DHI->DHI.cxPattern = (WORD)pDCI->HTCell.Width;
|
|
pHT_DHI->DHI.cyPattern = (WORD)pDCI->HTCell.Height;
|
|
|
|
if ((pHTInitInfo->DefHTColorAdjustment.caIlluminantIndex >
|
|
ILLUMINANT_MAX_INDEX) ||
|
|
(pHTInitInfo->DefHTColorAdjustment.caSize !=
|
|
sizeof(COLORADJUSTMENT)) ||
|
|
((pHTInitInfo->DefHTColorAdjustment.caRedGamma == 20000) &&
|
|
(pHTInitInfo->DefHTColorAdjustment.caGreenGamma == 20000) &&
|
|
(pHTInitInfo->DefHTColorAdjustment.caBlueGamma == 20000))) {
|
|
|
|
pHT_DHI->DHI.HTColorAdjustment = DefaultCA;
|
|
|
|
DBGP_IF(DBGP_CACHED_DCI,
|
|
DBGP("*** USE DEFAULT COLORADJUSTMENT in DCI *** "));
|
|
|
|
} else {
|
|
|
|
pHT_DHI->DHI.HTColorAdjustment = pHTInitInfo->DefHTColorAdjustment;
|
|
}
|
|
|
|
//
|
|
// Now compute the HTSMP checksum for the pattern
|
|
//
|
|
|
|
pw = (WORD *)&dwBuf[0];
|
|
pw[0] =
|
|
pw[3] =
|
|
pw[5] = pDCI->DeviceResXDPI;
|
|
pw[1] =
|
|
pw[2] =
|
|
pw[7] = pDCI->DeviceResYDPI;
|
|
pw[4] =
|
|
pw[6] = pDCI->DevicePelsDPI;
|
|
|
|
pDCI->HTSMPChecksum = ComputeChecksum((LPBYTE)pw,
|
|
HTSMP_INITIAL_CHECKSUM,
|
|
sizeof(dwBuf));
|
|
|
|
DBGP_IF(DBGP_CACHED_DCI,
|
|
DBGP("SMP Checksum = %08lx" ARGDW(pDCI->HTSMPChecksum)));
|
|
|
|
DBGP_IF(DBGP_CACHED_DCI,
|
|
DBGP("*** Final DevResDPI=%ld x %ld DevicePelsDPI=%ld, cx/cyPat=%ld x %ld=%ld, Step=%ld *** "
|
|
ARGDW(pDCI->DeviceResXDPI)
|
|
ARGDW(pDCI->DeviceResYDPI)
|
|
ARGDW(pDCI->DevicePelsDPI)
|
|
ARGDW(pDCI->HTCell.Width)
|
|
ARGDW(pDCI->HTCell.Height)
|
|
ARGDW(pDCI->HTCell.Size)
|
|
ARGDW(pDCI->HTCell.DensitySteps)));
|
|
|
|
//
|
|
// Set IlluminantIndex to a invalid value so we can re-compute RGBToXYZ
|
|
//
|
|
|
|
pDCI->ca.caIlluminantIndex = 0xffff;
|
|
*ppDeviceHalftoneInfo = (PDEVICEHALFTONEINFO)pHT_DHI;
|
|
|
|
HTShowMemLink("HT_CreateDeviceHalftoneInfo", (DWORD)pHT_DHI, -1);
|
|
HTMEMLINK_SNAPSHOT;
|
|
|
|
return(HALFTONE_DLL_ID);
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL
|
|
APIENTRY
|
|
HT_LOADDS
|
|
HT_DestroyDeviceHalftoneInfo(
|
|
PDEVICEHALFTONEINFO pDeviceHalftoneInfo
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function destroy the handle which returned from halftone initialize
|
|
function HT_CreateDeviceHalftoneInfo()
|
|
|
|
Arguments:
|
|
|
|
pDeviceHalftoneInfo - Pointer to the DEVICEHALFTONEINFO data structure
|
|
which returned from the HT_CreateDeviceHalftoneInfo.
|
|
|
|
Return Value:
|
|
|
|
TRUE - if function sucessed.
|
|
FALSE - if function failed.
|
|
|
|
Author:
|
|
|
|
05-Feb-1991 Tue 14:18:20 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
if (!pDCIAdjClr(pDeviceHalftoneInfo, NULL, NULL, 0)) {
|
|
|
|
SET_ERR(HTAPI_IDX_DESTROY_DHI, HTERR_INVALID_DHI_POINTER);
|
|
return(FALSE);
|
|
}
|
|
|
|
return(CleanUpDHI(pDeviceHalftoneInfo));
|
|
}
|
|
|
|
|
|
|
|
|
|
LONG
|
|
APIENTRY
|
|
HT_LOADDS
|
|
HT_CreateHalftoneBrush(
|
|
PDEVICEHALFTONEINFO pDeviceHalftoneInfo,
|
|
PHTCOLORADJUSTMENT pHTColorAdjustment,
|
|
PCOLORTRIAD pColorTriad,
|
|
CHBINFO CHBInfo,
|
|
LPVOID pOutputBuffer
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function create halftone mask for the requested solid color.
|
|
|
|
Arguments:
|
|
|
|
pDeviceHalftoneInfo - Pointer to the DEVICEHALFTONEINFO data structure
|
|
which returned from the HT_CreateDeviceHalftoneInfo.
|
|
|
|
pHTColorAdjustment - Pointer to the HTCOLORADJUSTMENT data structure to
|
|
specified the input/output color adjustment/transform,
|
|
if this pointer is NULL then a default color
|
|
adjustments is applied.
|
|
|
|
pColorTriad - Pointer to the COLORTRIAD data structure to describe
|
|
the brush colors.
|
|
|
|
CHBInfo - CHBINFO data structure, specified following:
|
|
|
|
Flags: CHBF_BW_ONLY
|
|
CHBF_USE_ADDITIVE_PRIMS
|
|
CHBF_NEGATIVE_PATTERN
|
|
|
|
|
|
DestSurfaceFormat: BMF_1BPP
|
|
BMF_1BPP_3PLANES
|
|
BMF_4BPP
|
|
BMF_4BPP_VGA16
|
|
BMF_8BPP_VGA256
|
|
|
|
ScanLineAlignBytes: 0 - 255
|
|
|
|
DestPrimaryOrder: One of PRIMARY_ORDER_xxx
|
|
|
|
|
|
|
|
pOutputBuffer - Pointer to the buffer area to received indices/mask.
|
|
in bytes needed to stored the halftone pattern.
|
|
|
|
|
|
Return Value:
|
|
|
|
if the return value is negative or zero then an error was encountered,
|
|
possible error codes are
|
|
|
|
HTERR_INVALID_DHI_POINTER - Invalid pDevideHalftoneInfo is
|
|
passed.
|
|
|
|
HTERR_INVALID_DEST_FORMAT - the Format of the destination
|
|
surface is not one of the defined
|
|
HSC_FORMAT_xxxx
|
|
|
|
HTERR_CHB_INV_COLORTABLE_SIZE - Color table size is not 1
|
|
|
|
otherwise
|
|
|
|
If pSurface is NULL, it return the bytes count which need to stored
|
|
the pattern, otherwise it return the size in byte copied to the output
|
|
buffer.
|
|
|
|
form BMF_1BPP_3PLANES, the return value is the size for one plane, the
|
|
caller should multiply it by 3 to get the correct buffer size.
|
|
|
|
Author:
|
|
|
|
05-Feb-1991 Tue 14:28:23 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
PDEVICECOLORINFO pDCI;
|
|
HTCOLORADJUSTMENT ca;
|
|
HTBRUSHDATA HTBrushData;
|
|
DEVCLRADJ DevClrAdj;
|
|
CTSTD_UNION CTSTDUnion;
|
|
HTCELL HTCell;
|
|
PRIMCOLOR_COUNT PCC;
|
|
WORD ForceFlags;
|
|
SHORT SizePerScan;
|
|
extern HTCELL HTCell_OD4x4;
|
|
|
|
|
|
|
|
ForceFlags = ADJ_FORCE_BRUSH;
|
|
ca.caSize = sizeof(HTCOLORADJUSTMENT);
|
|
ca.caFlags = 0;
|
|
ca.caIlluminantIndex = (pHTColorAdjustment) ?
|
|
pHTColorAdjustment->caIlluminantIndex :
|
|
ILLUMINANT_DEFAULT;
|
|
ca.caRedGamma =
|
|
ca.caGreenGamma =
|
|
ca.caBlueGamma = 10000;
|
|
ca.caReferenceBlack = 0;
|
|
ca.caReferenceWhite = 10000;
|
|
ca.caContrast =
|
|
ca.caBrightness =
|
|
ca.caColorfulness =
|
|
ca.caRedGreenTint = 0;
|
|
|
|
if ((CHBInfo.Flags & CHBF_BW_ONLY) ||
|
|
(CHBInfo.DestSurfaceFormat == BMF_1BPP)) {
|
|
|
|
ForceFlags |= ADJ_FORCE_MONO;
|
|
}
|
|
|
|
if (CHBInfo.Flags & CHBF_NEGATIVE_BRUSH) {
|
|
|
|
ForceFlags |= ADJ_FORCE_NEGATIVE;
|
|
}
|
|
|
|
if ((CHBInfo.Flags & CHBF_USE_ADDITIVE_PRIMS) ||
|
|
(CHBInfo.DestSurfaceFormat == BMF_4BPP_VGA16) ||
|
|
(CHBInfo.DestSurfaceFormat == BMF_8BPP_VGA256) ||
|
|
(CHBInfo.DestSurfaceFormat == BMF_16BPP_555)) {
|
|
|
|
ForceFlags |= ADJ_FORCE_ADDITIVE_PRIMS;
|
|
}
|
|
|
|
|
|
if (!(pDCI = pDCIAdjClr(pDeviceHalftoneInfo,
|
|
&ca,
|
|
(PDEVCLRADJ)&DevClrAdj,
|
|
ForceFlags))) {
|
|
|
|
HTAPI_RET(HTAPI_IDX_CHB, HTERR_INVALID_DHI_POINTER);
|
|
}
|
|
|
|
if (pColorTriad->ColorTableEntries != 1) {
|
|
|
|
HTAPI_RET(HTAPI_IDX_CHB, HTERR_CHB_INV_COLORTABLE_SIZE);
|
|
}
|
|
|
|
if ((pDCI->Flags & DCIF_HAS_ALT_4x4_HTPAT) &&
|
|
((CHBInfo.DestSurfaceFormat == BMF_8BPP_VGA256) ||
|
|
(CHBInfo.DestSurfaceFormat == BMF_16BPP_555))) {
|
|
|
|
HTCell = HTCell_OD4x4;
|
|
|
|
} else {
|
|
|
|
HTCell = pDCI->HTCell;
|
|
}
|
|
|
|
CTSTDUnion.b.Flags = CTSTDF_CHKNONWHITE;
|
|
CTSTDUnion.b.SrcOrder = pColorTriad->PrimaryOrder;
|
|
CTSTDUnion.b.DestOrder = CHBInfo.DestPrimaryOrder;
|
|
|
|
HTBrushData.Flags = 0;
|
|
HTBrushData.cxHTCell = (BYTE)HTCell.Width;
|
|
HTBrushData.cyHTCell = (BYTE)HTCell.Height;
|
|
|
|
SizePerScan =
|
|
HTBrushData.ScanLinePadBytes =
|
|
(SHORT)ComputeBytesPerScanLine(CHBInfo.DestSurfaceFormat,
|
|
(WORD)CHBInfo.DestScanLineAlignBytes,
|
|
(DWORD)HTCell.Width);
|
|
|
|
HTBrushData.SizePerPlane = (WORD)((WORD)HTBrushData.cyHTCell *
|
|
(WORD)SizePerScan);
|
|
|
|
CTSTDUnion.b.BMFDest =
|
|
HTBrushData.SurfaceFormat = CHBInfo.DestSurfaceFormat;
|
|
|
|
|
|
switch (CTSTDUnion.b.BMFDest) {
|
|
|
|
case BMF_1BPP:
|
|
case BMF_1BPP_3PLANES:
|
|
|
|
HTBrushData.ScanLinePadBytes -= (SHORT)((HTCell.Width + 7) >> 3);
|
|
break;
|
|
|
|
case BMF_4BPP_VGA16:
|
|
case BMF_4BPP:
|
|
|
|
HTBrushData.ScanLinePadBytes -= (SHORT)((HTCell.Width + 1) >> 1);
|
|
break;
|
|
|
|
case BMF_8BPP_VGA256:
|
|
|
|
HTBrushData.ScanLinePadBytes -= (SHORT)HTCell.Width;
|
|
break;
|
|
|
|
case BMF_16BPP_555:
|
|
|
|
HTBrushData.ScanLinePadBytes -= (SHORT)(HTCell.Width << 1);
|
|
break;
|
|
|
|
default:
|
|
|
|
HTAPI_RET(HTAPI_IDX_CHB, HTERR_INVALID_DEST_FORMAT);
|
|
}
|
|
|
|
|
|
if (pOutputBuffer) {
|
|
|
|
LPBYTE pThresholds;
|
|
LPBYTE pbSrc;
|
|
LPBYTE pbDst = NULL;
|
|
UINT SizeToCopy;
|
|
LONG Result;
|
|
BYTE SubValue;
|
|
BYTE OldValue;
|
|
|
|
|
|
if ((Result = ColorTriadSrcToDev(pDCI,
|
|
CTSTDUnion,
|
|
NULL, // no abort
|
|
pColorTriad,
|
|
(LPVOID)&(PCC.Color),
|
|
&DevClrAdj)) != 1) {
|
|
|
|
HTAPI_RET(HTAPI_IDX_CHB, Result);
|
|
}
|
|
|
|
|
|
if (ForceFlags & ADJ_FORCE_ADDITIVE_PRIMS) {
|
|
|
|
//
|
|
// We need to invert the pattern
|
|
//
|
|
|
|
pbSrc = HTCell.pThresholds;
|
|
SizeToCopy = (UINT)HTCell.Size;
|
|
|
|
if (pThresholds = (LPBYTE)HTLocalAlloc((DWORD)pDeviceHalftoneInfo,
|
|
"Brush-Threshold",
|
|
LPTR,
|
|
SizeToCopy)) {
|
|
|
|
pbDst = pThresholds;
|
|
SubValue = (BYTE)(HTCell.DensitySteps + 1);
|
|
|
|
while (SizeToCopy--) {
|
|
|
|
if ((OldValue = *pbSrc++) == 255) {
|
|
|
|
*pbDst++ = (BYTE)0;
|
|
|
|
} else {
|
|
|
|
*pbDst++ = (BYTE)(SubValue - OldValue);
|
|
}
|
|
}
|
|
|
|
} else {
|
|
|
|
HTAPI_RET(HTAPI_IDX_CHB, HTERR_INSUFFICIENT_MEMORY);
|
|
}
|
|
|
|
} else {
|
|
|
|
pThresholds = HTCell.pThresholds;
|
|
}
|
|
|
|
if (CHBInfo.Flags & CHBF_BOTTOMUP_BRUSH) {
|
|
|
|
(LPBYTE)pOutputBuffer += (HTBrushData.SizePerPlane -
|
|
SizePerScan);
|
|
HTBrushData.ScanLinePadBytes += -(SizePerScan << 1);
|
|
}
|
|
|
|
MakeHalftoneBrush(pThresholds, pOutputBuffer, PCC, HTBrushData);
|
|
|
|
if (pbDst) {
|
|
|
|
HTLocalFree((HLOCAL)pThresholds);
|
|
}
|
|
}
|
|
|
|
HTShowMemLink("HT_CreateHalftoneBrush", (DWORD)pDeviceHalftoneInfo, -1);
|
|
|
|
return((LONG)HTBrushData.SizePerPlane);
|
|
}
|
|
|
|
|
|
|
|
|
|
LONG
|
|
APIENTRY
|
|
HT_LOADDS
|
|
HT_ComputeRGBGammaTable(
|
|
WORD GammaTableEntries,
|
|
WORD GammaTableType,
|
|
UDECI4 RedGamma,
|
|
UDECI4 GreenGamma,
|
|
UDECI4 BlueGamma,
|
|
LPBYTE pGammaTable
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function compute device gamma correction table based on the lightness
|
|
|
|
(1/RedGamma)
|
|
Gamma[N] = INT((LIGHTNESS(N / GammaTableEntries-1)) x 255)
|
|
|
|
3
|
|
LIGHTNESS(x) = ((x + 0.16) / 1.16) if x >= 0.007996
|
|
(x / 9.033) if x < 0.007996
|
|
|
|
|
|
1. INT() is a integer function which round up to next integer number if
|
|
resulting fraction is 0.5 or higher, the final result always limit
|
|
to have range between 0 and 255.
|
|
|
|
2. N is a integer step number and range from 0 to (GammaTableEntries-1)
|
|
in one (1) increment.
|
|
|
|
|
|
Arguments:
|
|
|
|
GammaTableEntries - Total gamma table entries for each of red, green
|
|
and blue gamma table, halftone dll normalized
|
|
the gamma table with step value computed as
|
|
1/GammaTableEntries.
|
|
|
|
This value must range from 3 to 255 else a 0
|
|
is returned and no table is updated.
|
|
|
|
GammaTableType - red, green and blue gamma table organizations
|
|
|
|
0 - The gamma table is Red, Green, Blue 3 bytes
|
|
for each gamma step entries and total of
|
|
GammaTableEntries entries.
|
|
|
|
1 - The gamma table is Red Gamma tables follow
|
|
by green gamma table then follow by blue
|
|
gamma table, each table has total of
|
|
GammaTableEntries bytes.
|
|
|
|
Other value default to 0.
|
|
|
|
RedGamma - Red gamma number in UDECI4 format
|
|
|
|
GreenGamma - Green gamma number in UDECI4 format
|
|
|
|
BlueGamma - Blue gamma number in UDECI4 format
|
|
|
|
pGammaTable - pointer to the gamma table byte array.
|
|
each output gamma number is range from 0 to 255.
|
|
|
|
|
|
Return Value:
|
|
|
|
Return value is the total table entries updated.
|
|
|
|
Author:
|
|
|
|
15-Sep-1992 Tue 17:49:20 updated -by- Daniel Chou (danielc)
|
|
Fixed bug# 6257
|
|
|
|
17-Jul-1992 Fri 19:04:31 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
LPBYTE pRGamma;
|
|
LPBYTE pGGamma;
|
|
LPBYTE pBGamma;
|
|
FD6 L_StepInc;
|
|
FD6 IValue;
|
|
FD6 Lightness;
|
|
LONG Result;
|
|
UINT NextEntry;
|
|
RGBGAMMA RGBGamma;
|
|
|
|
|
|
//
|
|
// Initialize All internal data first
|
|
//
|
|
|
|
if (((Result = GammaTableEntries) > 256) ||
|
|
(Result < 2)) {
|
|
|
|
return(0);
|
|
}
|
|
|
|
Lightness = FD6_0;
|
|
L_StepInc = DivFD6((FD6)1, (FD6)(GammaTableEntries - 1));
|
|
RGBGamma.R = UDECI4ToFD6(RedGamma);
|
|
RGBGamma.G = UDECI4ToFD6(GreenGamma);
|
|
RGBGamma.B = UDECI4ToFD6(BlueGamma);
|
|
|
|
pRGamma = pGammaTable;
|
|
|
|
if (GammaTableType == 1) {
|
|
|
|
pGGamma = pRGamma + GammaTableEntries;
|
|
pBGamma = pGGamma + GammaTableEntries;
|
|
NextEntry = 1;
|
|
|
|
} else {
|
|
|
|
pGGamma = pRGamma + 1;
|
|
pBGamma = pGGamma + 1;
|
|
NextEntry = 3;
|
|
}
|
|
|
|
while (--GammaTableEntries) {
|
|
|
|
IValue = CIE_L2I(Lightness);
|
|
*pRGamma = RGB_8BPP(IValue, RGBGamma.R);
|
|
*pGGamma = RGB_8BPP(IValue, RGBGamma.G);
|
|
*pBGamma = RGB_8BPP(IValue, RGBGamma.B);
|
|
pRGamma += NextEntry;
|
|
pGGamma += NextEntry;
|
|
pBGamma += NextEntry;
|
|
Lightness += L_StepInc;
|
|
}
|
|
|
|
*pRGamma =
|
|
*pGGamma =
|
|
*pBGamma = 255;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
|
|
|
|
|
|
LONG
|
|
APIENTRY
|
|
HT_LOADDS
|
|
HT_Get8BPPFormatPalette(
|
|
LPPALETTEENTRY pPaletteEntry,
|
|
UDECI4 RedGamma,
|
|
UDECI4 GreenGamma,
|
|
UDECI4 BlueGamma
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This functions retrieve a halftone's VGA256 color table definitions
|
|
|
|
Arguments:
|
|
|
|
pPaletteEntry - Pointer to PALETTEENTRY data structure array,
|
|
|
|
RedGamma - The monitor's red gamma value in UDECI4 format
|
|
|
|
GreenGamma - The monitor's green gamma value in UDECI4 format
|
|
|
|
BlueGamma - The monitor's blue gamma value in UDECI4 format
|
|
|
|
|
|
Return Value:
|
|
|
|
if pPaletteEntry is NULL then it return the PALETTEENTRY count needed for
|
|
VGA256 halftone process, if it is not NULL then it return the total
|
|
paletteEntry updated.
|
|
|
|
If the pPaletteEntry is not NULL then halftone.dll assume it has enough
|
|
space for the size returned when this pointer is NULL.
|
|
|
|
Author:
|
|
|
|
14-Apr-1992 Tue 13:03:21 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
PFD6 pFD6;
|
|
RGBGAMMA RGBGamma;
|
|
FD6 IValue;
|
|
UINT RIndex;
|
|
UINT GIndex;
|
|
UINT BIndex;
|
|
UINT TableSize;
|
|
|
|
DEFDBGVAR(UINT, PaletteIdx = 0)
|
|
|
|
|
|
//
|
|
// Initialize All internal data first
|
|
//
|
|
|
|
if (pPaletteEntry) {
|
|
|
|
static FD6 VGA256_RS[] = { VGA256_R0,
|
|
VGA256_R1,
|
|
VGA256_R2,
|
|
VGA256_R3,
|
|
VGA256_R4,
|
|
VGA256_R5,
|
|
VGA256_R6,
|
|
VGA256_R7 };
|
|
|
|
static FD6 VGA256_GS[] = { VGA256_G0,
|
|
VGA256_G1,
|
|
VGA256_G2,
|
|
VGA256_G3,
|
|
VGA256_G4,
|
|
VGA256_G5,
|
|
VGA256_G6,
|
|
VGA256_G7 };
|
|
|
|
static FD6 VGA256_BS[] = { VGA256_B0,
|
|
VGA256_B1,
|
|
VGA256_B2,
|
|
VGA256_B3,
|
|
VGA256_B4,
|
|
VGA256_B5,
|
|
VGA256_B6,
|
|
VGA256_B7 };
|
|
|
|
|
|
RGBGamma.R = UDECI4ToFD6(RedGamma);
|
|
RGBGamma.G = UDECI4ToFD6(GreenGamma);
|
|
RGBGamma.B = UDECI4ToFD6(BlueGamma);
|
|
|
|
DBGP_IF(DBGP_8BPP_PAL,
|
|
DBGP("HT_Get8BPPFormatPalette: %s:%s:%s"
|
|
ARGFD6(RGBGamma.R, 1, 4)
|
|
ARGFD6(RGBGamma.G, 1, 4)
|
|
ARGFD6(RGBGamma.B, 1, 4)));
|
|
|
|
//
|
|
// Our VGA256 format is BGR type of Primary order.
|
|
//
|
|
|
|
RIndex =
|
|
GIndex =
|
|
BIndex = 0;
|
|
|
|
TableSize = VGA256_CUBE_SIZE;
|
|
|
|
while (TableSize--) {
|
|
|
|
pPaletteEntry->peRed = RGB_8BPP(VGA256_RS[RIndex], RGBGamma.R);
|
|
pPaletteEntry->peGreen = RGB_8BPP(VGA256_GS[GIndex], RGBGamma.G);
|
|
pPaletteEntry->peBlue = RGB_8BPP(VGA256_BS[BIndex], RGBGamma.B);
|
|
pPaletteEntry->peFlags = 0;
|
|
|
|
DBGP_IF(DBGP_8BPP_PAL,
|
|
DBGP("%3u - %3u:%3u:%3u"
|
|
ARGU(PaletteIdx++)
|
|
ARGU(pPaletteEntry->peRed )
|
|
ARGU(pPaletteEntry->peGreen)
|
|
ARGU(pPaletteEntry->peBlue )));
|
|
|
|
++pPaletteEntry;
|
|
|
|
if ((++RIndex) > VGA256_R_IDX_MAX) {
|
|
|
|
RIndex = 0;
|
|
|
|
if ((++GIndex) > VGA256_G_IDX_MAX) {
|
|
|
|
GIndex = 0;
|
|
++BIndex;
|
|
}
|
|
}
|
|
}
|
|
|
|
pFD6 = L2I_VGA256Mono;
|
|
TableSize = VGA256_MONO_SIZE;
|
|
|
|
while (TableSize--) {
|
|
|
|
IValue = *pFD6++;
|
|
|
|
pPaletteEntry->peRed = RGB_8BPP(IValue, RGBGamma.R);
|
|
pPaletteEntry->peGreen = RGB_8BPP(IValue, RGBGamma.G);
|
|
pPaletteEntry->peBlue = RGB_8BPP(IValue, RGBGamma.B);
|
|
pPaletteEntry->peFlags = 0;
|
|
|
|
DBGP_IF(DBGP_8BPP_PAL,
|
|
DBGP("%3u - %3u:%3u:%3u"
|
|
ARGU(PaletteIdx++)
|
|
ARGU(pPaletteEntry->peRed )
|
|
ARGU(pPaletteEntry->peGreen)
|
|
ARGU(pPaletteEntry->peBlue )));
|
|
|
|
++pPaletteEntry;
|
|
}
|
|
}
|
|
|
|
return((LONG)VGA256_PALETTE_COUNT);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LONG
|
|
APIENTRY
|
|
HT_LOADDS
|
|
HT_ConvertColorTable(
|
|
PDEVICEHALFTONEINFO pDeviceHalftoneInfo,
|
|
PHTCOLORADJUSTMENT pHTColorAdjustment,
|
|
PCOLORTRIAD pColorTriad,
|
|
DWORD Flags
|
|
)
|
|
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function modified input color table entries base on the
|
|
pHTColorAdjustment data structure specification.
|
|
|
|
Arguments:
|
|
|
|
pDeviceHalftoneInfo - Pointer to the DEVICEHALFTONEINFO data structure
|
|
which returned from the HT_CreateDeviceHalftoneInfo.
|
|
|
|
pHTColorAdjustment - Pointer to the HTCOLORADJUSTMENT data structure to
|
|
specified the input/output color adjustment/transform,
|
|
if this pointer is NULL then a default color
|
|
adjustments is applied.
|
|
|
|
pColorTriad - Specified the source color table format and location.
|
|
|
|
Flags - One of the following may be specified
|
|
|
|
CCTF_BW_ONLY
|
|
|
|
Create grayscale of the color table.
|
|
|
|
CCTF_NEGATIVE
|
|
|
|
Create negative version of the original color
|
|
table.
|
|
|
|
Return Value:
|
|
|
|
if the return value is negative or zero then an error was encountered,
|
|
possible error codes are
|
|
|
|
HTERR_INVALID_COLOR_TABLE - The ColorTableEntries field is = 0 or
|
|
CCTInfo.SizePerColorTableEntry is not
|
|
between 3 to 255, or if the
|
|
CCTInfo.FirstColorIndex in CCTInfo is
|
|
not in the range of 0 to
|
|
(SizePerColorTableEntry - 3).
|
|
|
|
HTERR_INVALID_DHI_POINTER - Invalid pDevideHalftoneInfo is passed.
|
|
|
|
otherwise
|
|
|
|
Total entries of the converted color table is returned.
|
|
|
|
|
|
Author:
|
|
|
|
14-Aug-1991 Wed 12:43:29 updated -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
16-Feb-1993 Tue 00:10:56 updated -by- Daniel Chou (danielc)
|
|
Fixes bug #10448 which create all black densitities brushes, this
|
|
was caused by not initialized ColorTriad.PrimaryOrder.
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
PDEVICECOLORINFO pDCI;
|
|
DEVCLRADJ DevClrAdj;
|
|
CTSTD_UNION CTSTDUnion;
|
|
WORD ForceFlags;
|
|
LONG Result;
|
|
|
|
|
|
DEFDBGVAR(DBG_TIMER, DbgTimer)
|
|
|
|
|
|
DBGP_IF(DBGP_TIMER, DBG_TIMER_RESET(&DbgTimer));
|
|
|
|
ForceFlags = ADJ_FORCE_ADDITIVE_PRIMS;
|
|
|
|
if (Flags & CCTF_NEGATIVE) {
|
|
|
|
ForceFlags |= ADJ_FORCE_NEGATIVE;
|
|
}
|
|
|
|
if (Flags & CCTF_BW_ONLY) {
|
|
|
|
ForceFlags |= ADJ_FORCE_MONO;
|
|
}
|
|
|
|
if (!(pDCI = pDCIAdjClr(pDeviceHalftoneInfo,
|
|
pHTColorAdjustment,
|
|
(PDEVCLRADJ)&DevClrAdj,
|
|
ForceFlags))) {
|
|
|
|
HTAPI_RET(HTAPI_IDX_CCT, HTERR_INVALID_DHI_POINTER);
|
|
}
|
|
|
|
|
|
CTSTDUnion.b.Flags = 0;
|
|
CTSTDUnion.b.DestOrder =
|
|
CTSTDUnion.b.SrcOrder = pColorTriad->PrimaryOrder;
|
|
|
|
if ((Result = ColorTriadSrcToDev(pDCI,
|
|
CTSTDUnion,
|
|
NULL, // no abort
|
|
pColorTriad,
|
|
NULL,
|
|
&DevClrAdj)) <= 0) {
|
|
|
|
HTAPI_RET(HTAPI_IDX_CCT, Result);
|
|
}
|
|
|
|
DBGP_IF(DBGP_TIMER,
|
|
DBG_ELAPSETIME(&DbgTimer);
|
|
DBGP("HT_ConvertColorTable: %s (%ld colors)"
|
|
ARGTIME(DbgTimer.Time[0].dw)
|
|
ARGDW(Result)));
|
|
|
|
HTShowMemLink("HT_ConvertColorTable", (DWORD)pDeviceHalftoneInfo, -1);
|
|
|
|
return(Result);
|
|
}
|
|
|
|
|
|
|
|
LONG
|
|
APIENTRY
|
|
HT_LOADDS
|
|
HT_CreateStandardMonoPattern(
|
|
PDEVICEHALFTONEINFO pDeviceHalftoneInfo,
|
|
PSTDMONOPATTERN pStdMonoPattern
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function create standard predefined monochrome pattern for the device.
|
|
|
|
Arguments:
|
|
|
|
pDeviceHalftoneInfo - Pointer to the DEVICEHALFTONEINFO data structure
|
|
which returned from the HT_CreateDeviceHalftoneInfo.
|
|
|
|
pStdMonoPattern - Pointer to the STDMONOPATTERN data structure, the
|
|
pPattern in this data structure is optional.
|
|
|
|
Return Value:
|
|
|
|
if the return value is negative or zero then an error was encountered,
|
|
possible error codes are
|
|
|
|
HTERR_INVALID_DHI_POINTER - Invalid pDevideHalftoneInfo is
|
|
passed.
|
|
|
|
HTERR_INVALID_STDMONOPAT_INDEX - The PatternIndex field in
|
|
STDMONOPATTERN data structure is
|
|
invalid.
|
|
otherwise
|
|
|
|
If pPattern field in STDMONOPATTERN data structure Surface is NULL, it
|
|
return the bytes count which need to stored the pattern, otherwise it
|
|
return the size in byte copied to the pattern buffer.
|
|
|
|
Author:
|
|
|
|
05-Feb-1991 Tue 14:28:23 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
05-Jun-1991 Wed 10:22:41 updated -by- Daniel Chou (danielc)
|
|
|
|
Fixed the bugs when the pStdMonoPattern is NULL, it was used without
|
|
checking it.
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
PDEVICECOLORINFO pDCI;
|
|
CHBINFO CHBInfo;
|
|
LONG Result;
|
|
WORD PatCX;
|
|
WORD PatCY;
|
|
BYTE PatIndex;
|
|
|
|
|
|
if (!(pDCI = pDCIAdjClr(pDeviceHalftoneInfo, NULL, NULL, 0))) {
|
|
|
|
HTAPI_RET(HTAPI_IDX_CREATE_SMP, HTERR_INVALID_DHI_POINTER);
|
|
}
|
|
|
|
if ((PatIndex = pStdMonoPattern->PatternIndex) > HT_SMP_MAX_INDEX) {
|
|
|
|
HTAPI_RET(HTAPI_IDX_CREATE_SMP, HTERR_INVALID_STDMONOPAT_INDEX);
|
|
}
|
|
|
|
if (PatIndex >= HT_SMP_PERCENT_SCREEN_START) {
|
|
|
|
CHBInfo.DestScanLineAlignBytes = pStdMonoPattern->ScanLineAlignBytes;
|
|
PatCX = pStdMonoPattern->cxPels = pDCI->HTCell.Width;
|
|
PatCY = pStdMonoPattern->cyPels = pDCI->HTCell.Height;
|
|
|
|
pStdMonoPattern->BytesPerScanLine = (WORD)
|
|
ComputeBytesPerScanLine(BMF_1BPP,
|
|
CHBInfo.DestScanLineAlignBytes,
|
|
(DWORD)PatCX);
|
|
CHBInfo.Flags = CHBF_BW_ONLY;
|
|
|
|
if (pStdMonoPattern->pPattern) {
|
|
|
|
BYTE rgb[3];
|
|
COLORTRIAD ColorTriad;
|
|
|
|
rgb[0] =
|
|
rgb[1] =
|
|
rgb[0] = (BYTE)(HT_SMP_MAX_INDEX - PatIndex);
|
|
|
|
ColorTriad.Type = (BYTE)COLOR_TYPE_RGB;
|
|
ColorTriad.BytesPerPrimary = (BYTE)sizeof(BYTE);
|
|
ColorTriad.BytesPerEntry = (BYTE)(sizeof(BYTE) * 3);
|
|
ColorTriad.PrimaryOrder = PRIMARY_ORDER_RGB;
|
|
ColorTriad.PrimaryValueMax = (FD6)100;
|
|
ColorTriad.ColorTableEntries = 1;
|
|
ColorTriad.pColorTable = (LPVOID)rgb;
|
|
|
|
if (pStdMonoPattern->Flags & SMP_0_IS_BLACK) {
|
|
|
|
CHBInfo.Flags |= CHBF_USE_ADDITIVE_PRIMS;
|
|
}
|
|
|
|
if (!(pStdMonoPattern->Flags & SMP_TOPDOWN)) {
|
|
|
|
CHBInfo.Flags |= CHBF_BOTTOMUP_BRUSH;
|
|
}
|
|
|
|
CHBInfo.DestSurfaceFormat = BMF_1BPP;
|
|
CHBInfo.DestPrimaryOrder = PRIMARY_ORDER_123;
|
|
|
|
Result = HT_CreateHalftoneBrush(pDeviceHalftoneInfo,
|
|
NULL,
|
|
&ColorTriad,
|
|
CHBInfo,
|
|
(LPVOID)pStdMonoPattern->pPattern);
|
|
|
|
} else {
|
|
|
|
Result = (LONG)pStdMonoPattern->BytesPerScanLine *
|
|
(LONG)PatCY;
|
|
}
|
|
|
|
} else {
|
|
|
|
Result = GetCachedSMP(pDCI, pStdMonoPattern);
|
|
}
|
|
|
|
#if 1
|
|
|
|
DBGP_IF(DBGP_SHOWPAT,
|
|
|
|
LPBYTE pCurPat;
|
|
LPBYTE pPatScan;
|
|
BYTE Buf1[80];
|
|
BYTE Buf2[80];
|
|
BYTE Buf3[80];
|
|
BYTE Digit1;
|
|
BYTE Digit2;
|
|
WORD Index;
|
|
WORD XInc;
|
|
WORD YInc;
|
|
BYTE Mask;
|
|
BOOL Swap;
|
|
|
|
|
|
DBGP("HT_CreateStandardMonoPattern(%d) = %ld"
|
|
ARGI(PatIndex - HT_SMP_PERCENT_SCREEN_START)
|
|
ARGDW(Result));
|
|
|
|
if ((Result > 0) && (pPatScan = pStdMonoPattern->pPattern)) {
|
|
|
|
Swap = (BOOL)(pStdMonoPattern->Flags & SMP_0_IS_BLACK);
|
|
|
|
FillMemory(Buf1, 80, ' ');
|
|
FillMemory(Buf2, 80, ' ');
|
|
Digit1 = 0;
|
|
Digit2 = 0;
|
|
Index = 4;
|
|
XInc = pStdMonoPattern->cxPels;
|
|
|
|
while ((XInc--) && (Index < 79)) {
|
|
|
|
if (!Digit2) {
|
|
|
|
Buf1[Index] = (BYTE)(Digit1 + '0');
|
|
|
|
if (++Digit1 == 10) {
|
|
|
|
Digit1 = 0;
|
|
}
|
|
}
|
|
|
|
Buf2[Index] = (BYTE)(Digit2 + '0');
|
|
|
|
if (++Digit2 == 10) {
|
|
|
|
Digit2 = 0;
|
|
}
|
|
|
|
++Index;
|
|
}
|
|
|
|
Buf1[Index] = Buf2[Index] = 0;
|
|
|
|
DBGP("%s" ARG(Buf1));
|
|
DBGP("%s\r\n" ARG(Buf2));
|
|
|
|
for (YInc = 0; YInc < pStdMonoPattern->cyPels; YInc++) {
|
|
|
|
Index = (WORD)sprintf(Buf3, "%3u ", YInc);
|
|
|
|
pCurPat = pPatScan;
|
|
|
|
for (XInc = 0, Mask = 0x80;
|
|
XInc < pStdMonoPattern->cxPels;
|
|
XInc++) {
|
|
|
|
if (Swap) {
|
|
|
|
Buf3[Index] = (BYTE)((*pCurPat & Mask) ? '°' : 'Û');
|
|
|
|
} else {
|
|
|
|
Buf3[Index] = (BYTE)((*pCurPat & Mask) ? 'Û' : '°');
|
|
}
|
|
|
|
if (!(Mask >>= 1)) {
|
|
|
|
Mask = 0x80;
|
|
++pCurPat;
|
|
}
|
|
|
|
if (++Index > 75) {
|
|
|
|
Index = 75;
|
|
}
|
|
}
|
|
|
|
sprintf(&Buf3[Index], " %-3u", YInc);
|
|
DBGP("%s" ARG(Buf3));
|
|
|
|
pPatScan += pStdMonoPattern->BytesPerScanLine;
|
|
}
|
|
|
|
DBGP("\r\n%s" ARG(Buf2));
|
|
DBGP("%s" ARG(Buf1));
|
|
}
|
|
)
|
|
|
|
#endif
|
|
|
|
HTShowMemLink("HT_CreateStandardMonoPattern",
|
|
(DWORD)pDeviceHalftoneInfo,
|
|
-1);
|
|
|
|
HTAPI_RET(HTAPI_IDX_CREATE_SMP, Result);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LONG
|
|
APIENTRY
|
|
HT_LOADDS
|
|
HT_HalftoneBitmap(
|
|
PDEVICEHALFTONEINFO pDeviceHalftoneInfo,
|
|
PHTCOLORADJUSTMENT pHTColorAdjustment,
|
|
PHTSURFACEINFO pSourceHTSurfaceInfo,
|
|
PHTSURFACEINFO pSourceMaskHTSurfaceInfo,
|
|
PHTSURFACEINFO pDestinationHTSurfaceInfo,
|
|
PBITBLTPARAMS pBitbltParams
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function halftone the source bitmap and output to the destination
|
|
surface depends on the surface type and bitblt parameters
|
|
|
|
The source surface type must one of the following:
|
|
|
|
1-bit per pel. (BMF_1BPP)
|
|
4-bit per pel. (BMF_4BPP)
|
|
8-bit per pel. (BMF_8BPP)
|
|
16-bit per pel. (BMF_16BPP)
|
|
24-bit per pel. (BMF_24BPP)
|
|
32-bit per pel. (BMF_32BPP)
|
|
|
|
The destination surface type must one of the following:
|
|
|
|
1-bit per pel. (BMF_1BPP)
|
|
4-bit per pel. (BMF_4BPP)
|
|
3 plane and 1 bit per pel. (BMF_1BPP_3PLANES)
|
|
|
|
Arguments:
|
|
|
|
pDeviceHalftoneInfo - pointer to the DEVICEHALFTONEINFO data
|
|
structure
|
|
|
|
pHTColorAdjustment - Pointer to the HTCOLORADJUSTMENT data
|
|
structure to specified the input/output color
|
|
adjustment/transform, if this pointer is NULL
|
|
then a default color adjustments is applied.
|
|
|
|
pSourceHTSurfaceInfo - pointer to the source surface infomation.
|
|
|
|
pSourceMaskHTSurfaceInfo - pointer to the source mask surface infomation,
|
|
if this pointer is NULL then there is no
|
|
source mask for the halftoning.
|
|
|
|
pDestinationHTSurfaceInfo - pointer to the destination surface infomation.
|
|
|
|
pBitbltParams - pointer to the BITBLTPARAMS data structure to
|
|
specified the source, destination, source
|
|
mask and clipping rectangle information, the
|
|
content of this data structure will not be
|
|
modified by this function.
|
|
|
|
|
|
Return Value:
|
|
|
|
if the return value is less than zero then an error has occurred,
|
|
the error code is one of the following #define which start with HTERR_.
|
|
|
|
HTERR_INSUFFICIENT_MEMORY - not enough memory to do the halftone
|
|
process.
|
|
|
|
HTERR_COLORTABLE_TOO_BIG - can not create the color table to map
|
|
the colors to the dyes' densities.
|
|
|
|
HTERR_QUERY_SRC_BITMAP_FAILED - callback function return FALSE when
|
|
query the source bitmap pointer.
|
|
|
|
HTERR_QUERY_DEST_BITMAP_FAILED - callback function return FALSE when
|
|
query the destination bitmap pointers.
|
|
|
|
HTERR_INVALID_SRC_FORMAT - Invalid source surface format.
|
|
|
|
HTERR_INVALID_DEST_FORMAT - Invalid destination surface type,
|
|
this function only recongnized 1/4/
|
|
bits per pel source surfaces or 1 bit
|
|
per pel 3 planes.
|
|
|
|
HTERR_INVALID_DHI_POINTER - Invalid pDevideHalftoneInfo is passed.
|
|
|
|
HTERR_SRC_MASK_BITS_TOO_SMALL - If the source mask bitmap is too
|
|
small to cover the visible region of
|
|
the source bitmap.
|
|
|
|
HTERR_INVALID_MAX_QUERYLINES - One or more of Source/Destination
|
|
SourceMasks' maximum query scan line
|
|
is < 0
|
|
|
|
HTERR_INTERNAL_ERRORS_START - any other negative numbers indicate
|
|
a halftone internal failue.
|
|
|
|
else - the total destination scan lines
|
|
halftoned.
|
|
|
|
|
|
Author:
|
|
|
|
05-Feb-1991 Tue 15:23:07 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
HR_HEADER HR_Header;
|
|
DEVCLRADJ DevClrAdj;
|
|
WORD ForceFlags;
|
|
LONG Result;
|
|
BYTE SurfaceFormat;
|
|
#ifdef HAS_FILL_MODE
|
|
UINT TestInfoIndex;
|
|
HTCOLORADJUSTMENT HTClrAdj;
|
|
BOOL IsFillMode;
|
|
#endif
|
|
|
|
//
|
|
//*****************************************************************************
|
|
// START RGB 3 planes device test data, this is testing for the planer format
|
|
//
|
|
|
|
#if DBG
|
|
#if TEST_3PLANES
|
|
DEFDBGVAR(LPBYTE, p1Plane)
|
|
DEFDBGVAR(HTSURFACEINFO, DestSI)
|
|
DEFDBGVAR(DWORD, DestCX)
|
|
DEFDBGVAR(DWORD, DestCY)
|
|
DEFDBGVAR(DWORD, BytesPerPlane)
|
|
DEFDBGVAR(DWORD, BytesPerScanLine1Plane)
|
|
DEFDBGVAR(DWORD, BytesPerScanLine3Planes)
|
|
DEFDBGVAR(BOOL, Simulate3Planes = FALSE)
|
|
#endif
|
|
#endif
|
|
|
|
//
|
|
// END OF RGB 3 planes device test data, this is testing for the planer format
|
|
//*****************************************************************************
|
|
//
|
|
|
|
DBGP_IF(DBGP_TIMER, DBG_TIMER_RESET(&HR_Header.DbgTimer));
|
|
|
|
|
|
ForceFlags = ADJ_FORCE_SUB_COLOR;
|
|
SurfaceFormat = pDestinationHTSurfaceInfo->SurfaceFormat;
|
|
|
|
if ((pBitbltParams->Flags & BBPF_USE_ADDITIVE_PRIMS) ||
|
|
(SurfaceFormat == BMF_4BPP_VGA16) ||
|
|
(SurfaceFormat == BMF_8BPP_VGA256) ||
|
|
(SurfaceFormat == BMF_16BPP_555)) {
|
|
|
|
ForceFlags |= ADJ_FORCE_ADDITIVE_PRIMS;
|
|
}
|
|
|
|
if (pBitbltParams->Flags & BBPF_NEGATIVE_DEST) {
|
|
|
|
ForceFlags |= ADJ_FORCE_NEGATIVE;
|
|
}
|
|
|
|
if ((pBitbltParams->Flags & BBPF_BW_ONLY) ||
|
|
(SurfaceFormat == BMF_1BPP)) {
|
|
|
|
ForceFlags |= ADJ_FORCE_MONO;
|
|
}
|
|
|
|
//
|
|
// Firstable check if we have valid pDeviceHalftoneInfo, if not then
|
|
// return error now
|
|
//
|
|
|
|
#ifdef HAS_FILL_MODE
|
|
|
|
if (!(HR_Header.pDeviceColorInfo = pDCIAdjClr(pDeviceHalftoneInfo,
|
|
NULL,
|
|
NULL,
|
|
ForceFlags))) {
|
|
|
|
HTAPI_RET(HTAPI_IDX_HALFTONE_BMP, HTERR_INVALID_DHI_POINTER);
|
|
}
|
|
|
|
if (IsFillMode = (BOOL)(pBitbltParams->Flags & BBPF_FILL_MODE)) {
|
|
|
|
BYTE FillModeIndex;
|
|
|
|
if ((FillModeIndex = pBitbltParams->FillModeIndex) ==
|
|
BBP_FILL_COLOR_TABLE) {
|
|
|
|
if ((!pSourceHTSurfaceInfo) ||
|
|
(pSourceHTSurfaceInfo->SurfaceFormat >= BMF_24BPP) ||
|
|
(!pSourceHTSurfaceInfo->pColorTriad) ||
|
|
(!(pSourceHTSurfaceInfo->pColorTriad->ColorTableEntries))) {
|
|
|
|
//
|
|
// Some how we have invalid color table, or the source surface
|
|
// format is 24-bit or greater then make it show the VGA color
|
|
//
|
|
|
|
FillModeIndex = BBP_FILL_VGA_16_PALETTE;
|
|
}
|
|
}
|
|
|
|
if (FillModeIndex == BBP_FILL_COLOR_TABLE) { // still is!!
|
|
|
|
//
|
|
// Same as the bitmap adjustment, we will not change the color
|
|
// adjustment
|
|
//
|
|
|
|
TestInfoIndex = TESTINFO_COLOR_TABLE;
|
|
|
|
} else {
|
|
|
|
//
|
|
// We will use local color adjustments
|
|
//
|
|
|
|
HTClrAdj = (pHTColorAdjustment) ?
|
|
*pHTColorAdjustment :
|
|
pDeviceHalftoneInfo->HTColorAdjustment;
|
|
|
|
pHTColorAdjustment = &HTClrAdj;
|
|
|
|
//
|
|
// Make sure we have valid fill mode
|
|
//
|
|
|
|
switch (FillModeIndex) {
|
|
|
|
case BBP_FILL_NTSC_COLOR_BAR:
|
|
|
|
//
|
|
// This is a YIQ data, so no RGB gamma is ever computed, the
|
|
// Reflect density mode must be LOG (Normal), the input color
|
|
// adjustment is NTSC (D65)
|
|
//
|
|
|
|
TestInfoIndex = TESTINFO_SMPTE;
|
|
// HTClrAdj.IlluminantIndex = ILLUMINANT_D65;
|
|
// HTClrAdj.Flags |= CLRADJF_LOG_FILTER;
|
|
break;
|
|
|
|
case BBP_FILL_MEMORY_COLORS:
|
|
|
|
//
|
|
// This is a XYZ data computed from NTSC (D65) and Y is
|
|
// normalized,
|
|
//
|
|
|
|
TestInfoIndex = TESTINFO_STD_CLR;
|
|
// HTClrAdj.IlluminantIndex = ILLUMINANT_D65;
|
|
// HTClrAdj.Flags |= CLRADJF_LOG_FILTER;
|
|
break;
|
|
|
|
case BBP_FILL_VGA_16_PALETTE:
|
|
|
|
//
|
|
// This is a normalized RGB (ie. no input RGB gamma correction)
|
|
// and it can be under any illuminant, the DensityMode is set
|
|
// to linear mode.
|
|
//
|
|
|
|
TestInfoIndex = TESTINFO_VGA;
|
|
|
|
if (HR_Header.pDeviceColorInfo->Flags & DCIF_ADDITIVE_PRIMS) {
|
|
|
|
HTClrAdj.Flags &= ~CLRADJF_LOG_FILTER;
|
|
|
|
} else {
|
|
|
|
HTClrAdj.Flags |= CLRADJF_LOG_FILTER;
|
|
}
|
|
|
|
HTClrAdj.RedGamma =
|
|
HTClrAdj.GreenGamma =
|
|
HTClrAdj.BlueGamma = UDECI4_1;
|
|
break;
|
|
|
|
default:
|
|
|
|
return(HTERR_INVALID_FILL_MODE_INDEX);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
//
|
|
// Now Compute the Device Color Adjusment data
|
|
//
|
|
|
|
if (!(HR_Header.pDeviceColorInfo = pDCIAdjClr(pDeviceHalftoneInfo,
|
|
pHTColorAdjustment,
|
|
&DevClrAdj,
|
|
ForceFlags))) {
|
|
|
|
HTAPI_RET(HTAPI_IDX_HALFTONE_BMP, HTERR_INVALID_DHI_POINTER);
|
|
}
|
|
|
|
//
|
|
// We will mask out the more flags, since this flag is currently used
|
|
// internally.
|
|
//
|
|
|
|
HR_Header.pDevClrAdj = &DevClrAdj;
|
|
HR_Header.pBitbltParams = pBitbltParams;
|
|
HR_Header.pSrcSI = pSourceHTSurfaceInfo;
|
|
HR_Header.pSrcMaskSI = pSourceMaskHTSurfaceInfo;
|
|
HR_Header.pDestSI = pDestinationHTSurfaceInfo;
|
|
|
|
//
|
|
//*****************************************************************************
|
|
// START RGB 3 planes device test code, this is testing for the planer format
|
|
//
|
|
|
|
#if DBG
|
|
#if TEST_3PLANES
|
|
|
|
if ((HR_Header.pDestSI->SurfaceFormat == BMF_4BPP) &&
|
|
(HR_Header.pDestSI->MaximumQueryScanLines == 0)) {
|
|
|
|
DWORD AllocateSize;
|
|
|
|
DestSI = *pDestinationHTSurfaceInfo;
|
|
|
|
if (pBitbltParams->Flags & BBPF_HAS_BANDRECT) {
|
|
|
|
DestCX = pBitbltParams->rclBand.right - pBitbltParams->rclBand.left;
|
|
DestCY = pBitbltParams->rclBand.bottom - pBitbltParams->rclBand.top;
|
|
|
|
} else {
|
|
|
|
DestCX = DestSI.Width;
|
|
DestCY = DestSI.Height;
|
|
}
|
|
|
|
|
|
BytesPerScanLine1Plane =
|
|
(DWORD)ComputeBytesPerScanLine(DestSI.SurfaceFormat,
|
|
DestSI.ScanLineAlignBytes,
|
|
DestCX);
|
|
BytesPerScanLine3Planes =
|
|
(DWORD)ComputeBytesPerScanLine(BMF_1BPP_3PLANES,
|
|
DestSI.ScanLineAlignBytes,
|
|
DestCX);
|
|
|
|
p1Plane = DestSI.pPlane;
|
|
BytesPerPlane = (DWORD)(BytesPerScanLine3Planes * DestCY);
|
|
DestSI.BytesPerPlane = 0;
|
|
AllocateSize = (DWORD)(BytesPerPlane * 3);
|
|
|
|
if (DestSI.pPlane = (LPBYTE)HTLocalAlloc((DWORD)pDeviceHalftoneInfo,
|
|
"DestSI.pPlane",
|
|
LPTR,
|
|
AllocateSize)) {
|
|
|
|
DestSI.SurfaceFormat = BMF_1BPP_3PLANES;
|
|
HR_Header.pDestSI = &DestSI;
|
|
Simulate3Planes = TRUE;
|
|
|
|
DBGP("\n\n====== INTERNAL 3 PLANES SIMULATION ======");
|
|
|
|
Convert4BPPTo1BPP3Planes(p1Plane,
|
|
DestSI.pPlane,
|
|
BytesPerScanLine1Plane,
|
|
BytesPerScanLine3Planes,
|
|
DestCX,
|
|
DestCY,
|
|
BytesPerPlane);
|
|
|
|
} else {
|
|
|
|
DBGP("HTLocalAlloc(%ld) FAILED for Simulate 3 planer"
|
|
ARGDW(AllocateSize));
|
|
}
|
|
}
|
|
|
|
#endif // TEST_3PLANES
|
|
#endif // DBG
|
|
|
|
//
|
|
// END OF RGB 3 planes device test code, this is testing for the planer format
|
|
//*****************************************************************************
|
|
//
|
|
|
|
|
|
#ifdef HAS_FILL_MODE
|
|
|
|
if (IsFillMode) {
|
|
|
|
Result = FillTestPattern(&HR_Header, TestInfoIndex);
|
|
|
|
} else {
|
|
#else
|
|
{
|
|
#endif
|
|
|
|
Result = HalftoneBitmap(&HR_Header);
|
|
}
|
|
|
|
|
|
if ((Result >= 0) && (pBitbltParams->pAbort)) {
|
|
|
|
*(pBitbltParams->pAbort) = (WORD)0;
|
|
}
|
|
|
|
//
|
|
//*****************************************************************************
|
|
// START RGB 3 planes device test code, this is testing for the planer format
|
|
//
|
|
|
|
#if DBG
|
|
#if TEST_3PLANES
|
|
|
|
if (Simulate3Planes) {
|
|
|
|
Convert1BPP3PlanesTo4BPP(DestSI.pPlane,
|
|
p1Plane,
|
|
BytesPerScanLine3Planes,
|
|
BytesPerScanLine1Plane,
|
|
DestCX,
|
|
DestCY,
|
|
BytesPerPlane);
|
|
|
|
|
|
if (HTLocalFree((HLOCAL)DestSI.pPlane)) {
|
|
|
|
DBGP("HTLocalFree(%8lx) FAILED for Simulated 3 planer"
|
|
ARGDW(DestSI.pPlane));
|
|
}
|
|
}
|
|
|
|
#endif
|
|
#endif
|
|
|
|
//
|
|
// END OF RGB 3 planes device test code, this is testing for the planer format
|
|
//*****************************************************************************
|
|
//
|
|
|
|
DBGP_IF(DBGP_TIMER,
|
|
|
|
{
|
|
|
|
DWORD TotTime;
|
|
DWORD SrcSize;
|
|
DWORD DstSize;
|
|
DWORD SrcKB;
|
|
DWORD DstKB;
|
|
DWORD KBPerSec;
|
|
|
|
|
|
DBG_ELAPSETIME(&HR_Header.DbgTimer);
|
|
|
|
SrcSize = (DWORD)
|
|
ComputeBytesPerScanLine(HR_Header.pSrcSI->SurfaceFormat,
|
|
HR_Header.pSrcSI->ScanLineAlignBytes,
|
|
HR_Header.pSrcSI->Width) *
|
|
(DWORD)HR_Header.pSrcSI->Height;
|
|
|
|
DstSize = (DWORD)
|
|
ComputeBytesPerScanLine(HR_Header.pDestSI->SurfaceFormat,
|
|
HR_Header.pDestSI->ScanLineAlignBytes,
|
|
HR_Header.pDestSI->Width) *
|
|
(DWORD)HR_Header.pDestSI->Height;
|
|
|
|
SrcKB = (DWORD)(((SrcSize * 100) + 512) / 1024);
|
|
DstKB = (DWORD)(((DstSize * 100) + 512) / 1024);
|
|
TotTime = HR_Header.DbgTimer.Time[0].dw +
|
|
HR_Header.DbgTimer.Time[1].dw;
|
|
|
|
KBPerSec = (DWORD)((((SrcKB + DstKB) * 1000L) + (TotTime / 2))
|
|
/ TotTime);
|
|
|
|
DBGP("HT_BMP=%5ld, %s (%s:%s) S=%5ld.%02uk, D=%5ld.%02uk, %6ld.%02u k/s"
|
|
ARGL(Result)
|
|
ARGTIME(TotTime)
|
|
ARGTIME(HR_Header.DbgTimer.Time[0].dw)
|
|
ARGTIME(HR_Header.DbgTimer.Time[1].dw)
|
|
ARGDW(SrcKB / 100)
|
|
ARGDW(SrcKB % 100)
|
|
ARGDW(DstKB / 100)
|
|
ARGDW(DstKB % 100)
|
|
ARGDW(KBPerSec / 100)
|
|
ARGDW(KBPerSec % 100));
|
|
}
|
|
)
|
|
|
|
HTShowMemLink("HT_HalftoneBitmap", (DWORD)pDeviceHalftoneInfo, -1);
|
|
|
|
HTAPI_RET(HTAPI_IDX_HALFTONE_BMP, Result);
|
|
}
|
|
|
|
|
|
#ifdef HAS_FILL_MODE
|
|
|
|
|
|
LONG
|
|
HTENTRY
|
|
FillTestPattern(
|
|
PHR_HEADER pHR,
|
|
UINT TestInfoIndex
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function generate test pattern.
|
|
|
|
Arguments:
|
|
|
|
pHR - Ponter the HR_HEADER block
|
|
|
|
TestInfoIndex - The TESTINFO_xxxx indices number
|
|
|
|
|
|
Return Value:
|
|
|
|
if the return value is less than zero then an error has occurred,
|
|
the error code is one of the following #define which start with HTERR_.
|
|
|
|
HTERR_INSUFFICIENT_MEMORY - not enough memory to do the halftone
|
|
process.
|
|
|
|
HTERR_COLORTABLE_TOO_BIG - can not create the color table to map
|
|
the colors to the dyes' densities.
|
|
|
|
HTERR_QUERY_SRC_BITMAP_FAILED - callback function return FALSE when
|
|
query the source bitmap pointer.
|
|
|
|
HTERR_QUERY_DEST_BITMAP_FAILED - callback function return FALSE when
|
|
query the destination bitmap pointers.
|
|
|
|
HTERR_INVALID_SRC_FORMAT - Invalid source surface format.
|
|
|
|
HTERR_INVALID_DEST_FORMAT - Invalid destination surface type,
|
|
this function only recongnized 1/4/
|
|
bits per pel source surfaces or 1 bit
|
|
per pel 3 planes.
|
|
|
|
HTERR_INVALID_DHI_POINTER - Invalid pDevideHalftoneInfo is passed.
|
|
|
|
HTERR_SRC_MASK_BITS_TOO_SMALL - If the source mask bitmap is too
|
|
small to cover the visible region of
|
|
the source bitmap.
|
|
|
|
HTERR_INVALID_MAX_QUERYLINES - One or more of Source/Destination
|
|
SourceMasks' maximum query scan line
|
|
is < 0
|
|
|
|
HTERR_INTERNAL_ERRORS_START - any other negative numbers indicate
|
|
a halftone internal failue.
|
|
|
|
else - the total destination scan lines
|
|
halftoned.
|
|
|
|
|
|
Author:
|
|
|
|
05-Feb-1991 Tue 15:23:07 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
09-Jun-1992 Tue 18:41:01 updated -by- Daniel Chou (danielc)
|
|
1. Fixed bug 'SrcSI.SurfaceFormat' to 'pOldSrcSI->SurfaceFormat'
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
PHTSURFACEINFO pOldSrcSI;
|
|
HTSURFACEINFO SrcSI;
|
|
BITBLTPARAMS BBP;
|
|
PHTTESTDATA pTestData;
|
|
PHTTESTINFO pTestInfo;
|
|
HTTESTDATA TestData;
|
|
COLORTRIAD ColorTriad;
|
|
LPWORD pBmp;
|
|
LONG Result;
|
|
LONG SizeBmp;
|
|
UINT Loop;
|
|
WORD Color;
|
|
LONG cyDest;
|
|
LONG yMax;
|
|
WORD TotalData;
|
|
WORD cx;
|
|
WORD cy;
|
|
|
|
|
|
|
|
pBmp = NULL;
|
|
pOldSrcSI = pHR->pSrcSI;
|
|
BBP = *(pHR->pBitbltParams);
|
|
SrcSI.pColorTriad = &ColorTriad;
|
|
pHR->pSrcSI = &SrcSI;
|
|
pHR->pBitbltParams = &BBP;
|
|
pHR->pSrcMaskSI = NULL; // disable source masking mode
|
|
|
|
pTestInfo = &HTTestInfo[TestInfoIndex];
|
|
|
|
SrcSI.hSurface = 'Fill';
|
|
SrcSI.Flags = HTSIF_SCANLINES_TOPDOWN;
|
|
SrcSI.SurfaceFormat = (BYTE)pTestInfo->SurfaceFormat;
|
|
SrcSI.ScanLineAlignBytes = (BYTE)BMF_ALIGN_BYTE;
|
|
SrcSI.MaximumQueryScanLines = 0;
|
|
|
|
TotalData = (WORD)pTestInfo->TotalData;
|
|
cx = (WORD)pTestInfo->cx;
|
|
cy = (WORD)pTestInfo->cy;
|
|
|
|
if (TestInfoIndex == TESTINFO_COLOR_TABLE) {
|
|
|
|
TotalData = 0;
|
|
ColorTriad = *(pOldSrcSI->pColorTriad);
|
|
|
|
if (!(Result = (LONG)((LONG)(SquareRoot(ColorTriad.ColorTableEntries) +
|
|
500L) / 1000L))) {
|
|
|
|
Result = 1;
|
|
}
|
|
|
|
cy = (WORD)((ColorTriad.ColorTableEntries +
|
|
((DWORD)Result >> 1)) / (DWORD)Result);
|
|
cx = (WORD)Result;
|
|
|
|
} else {
|
|
|
|
ColorTriad = pTestInfo->ColorTriad;
|
|
}
|
|
|
|
//
|
|
// Using Local copy
|
|
//
|
|
|
|
BBP.rclSrc.left =
|
|
BBP.rclSrc.top = 0;
|
|
cyDest = (yMax = BBP.rclDest.bottom) - BBP.rclDest.top;
|
|
|
|
if (!(Loop = (UINT)TotalData)) {
|
|
|
|
if ((!cx) || (!cy)) {
|
|
|
|
cx = 1;
|
|
cy = (WORD)ColorTriad.ColorTableEntries;
|
|
}
|
|
|
|
SrcSI.SurfaceFormat = BMF_16BPP;
|
|
SrcSI.ScanLineAlignBytes = (BYTE)BMF_ALIGN_WORD;
|
|
|
|
SizeBmp = (TestData.cx = cx) * (TestData.cy = cy);
|
|
|
|
if (!(pBmp = (LPWORD)HTLocalAlloc((DWORD)pDeviceHalftoneInfo,
|
|
"FillTest:pBmp",
|
|
NONZEROLPTR,
|
|
SizeBmp * sizeof(WORD)))) {
|
|
|
|
return(HTERR_INSUFFICIENT_MEMORY);
|
|
}
|
|
|
|
|
|
for (Loop = 0, Color = 0; Loop < (UINT)SizeBmp; Loop++) {
|
|
|
|
pBmp[Loop] = (WORD)Color;
|
|
|
|
if (++Color >= (WORD)ColorTriad.ColorTableEntries) {
|
|
|
|
Color = 0;
|
|
}
|
|
}
|
|
|
|
Loop = 1;
|
|
TestData.pBitmap = (LPBYTE)pBmp;
|
|
TestData.cyRatio = FD6_1;
|
|
pTestData = &TestData;
|
|
|
|
} else {
|
|
|
|
pTestData = pTestInfo->pTestData;
|
|
}
|
|
|
|
while (Loop--) {
|
|
|
|
TestData = *pTestData++;
|
|
|
|
BBP.rclSrc.right = SrcSI.Width = (LONG)TestData.cx;
|
|
BBP.rclSrc.bottom = SrcSI.Height = (LONG)TestData.cy;
|
|
SrcSI.pPlane = (LPBYTE)TestData.pBitmap;
|
|
|
|
if (!(BBP.rclDest.bottom = BBP.rclDest.top +
|
|
(LONG)MulFD6(TestData.cyRatio, cyDest))) {
|
|
|
|
BBP.rclDest.bottom = 1;
|
|
|
|
} else if (BBP.rclDest.bottom > yMax) {
|
|
|
|
BBP.rclDest.bottom = yMax;
|
|
}
|
|
|
|
if ((Result = HalftoneBitmap(pHR)) < 0) {
|
|
|
|
break;
|
|
}
|
|
|
|
BBP.rclDest.top = BBP.rclDest.bottom;
|
|
}
|
|
|
|
if (pBmp) {
|
|
|
|
HTLocalFree((HLOCAL)pBmp);
|
|
}
|
|
|
|
HTShowMemLink("FillTestPattern", (DWORD)pDeviceHalftoneInfo, -1);
|
|
|
|
return(Result);
|
|
|
|
}
|
|
|
|
#endif
|