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.
1285 lines
29 KiB
1285 lines
29 KiB
/*++
|
|
|
|
Copyright (c) 1997-1999 Microsoft Corporation
|
|
|
|
--*/
|
|
|
|
// NTRAID#NTBUG9-576656-2002/03/14-yasuho-: Possible buffer overrun
|
|
// NTRAID#NTBUG9-576658-2002/03/14-yasuho-: Possible divide by zero
|
|
// NTRAID#NTBUG9-576661-2002/03/14-yasuho-: Remove the dead codes
|
|
|
|
#include "pdev.h"
|
|
#include "alpsres.h"
|
|
#include "dither.h"
|
|
#include "dtable.h"
|
|
|
|
int Calc_degree(int x, int y);
|
|
|
|
/*************************** Function Header *******************************
|
|
* bInitialDither
|
|
*
|
|
* Pre-processing of dither tables.
|
|
*
|
|
* HISTORY:
|
|
* 24 Jun 1996 -by- Sueya Sugihara [sueyas]
|
|
* Created.
|
|
*
|
|
***************************************************************************/
|
|
BOOL bInitialDither(
|
|
PDEVOBJ pdevobj)
|
|
{
|
|
|
|
PCURRENTSTATUS lpnp;
|
|
|
|
lpnp = (PCURRENTSTATUS)MINIDEV_DATA(pdevobj);
|
|
|
|
// Already created the NewTable[][][] by dither.exe.
|
|
|
|
if( lpnp->iTextQuality != CMDID_TEXTQUALITY_GRAY ){
|
|
|
|
int B_LOW;
|
|
int B_R;
|
|
int UCR;
|
|
int YUCR;
|
|
int B_GEN;
|
|
int i;
|
|
// FLOATOBJ f1,f2;
|
|
float f1,f2;
|
|
|
|
// initialize.
|
|
|
|
if( lpnp->iTextQuality == CMDID_TEXTQUALITY_PHOTO ){
|
|
|
|
B_LOW = 0;
|
|
B_R = 70;
|
|
UCR = 50;
|
|
YUCR = 4;
|
|
B_GEN = 2;
|
|
|
|
}else{
|
|
|
|
B_LOW = 0;
|
|
B_R = 100;
|
|
UCR = 60;
|
|
YUCR = 4;
|
|
B_GEN = 3;
|
|
}
|
|
|
|
// Create KuroTBL[] to get black from YMC.
|
|
|
|
for( i=0; i< 256; i++){
|
|
|
|
if( i < B_LOW )
|
|
|
|
lpnp->KuroTBL[i] = 0;
|
|
|
|
else{
|
|
|
|
int k;
|
|
|
|
FLOATOBJ_SetLong(&f1, (i - B_LOW));
|
|
FLOATOBJ_DivLong(&f1, (255 - B_LOW));
|
|
|
|
f2 = f1;
|
|
|
|
for(k=0; k<(B_GEN - 1); k++){
|
|
|
|
FLOATOBJ_Mul(&f1, &f2);
|
|
|
|
}
|
|
|
|
FLOATOBJ_MulLong(&f1, 255);
|
|
|
|
FLOATOBJ_MulLong(&f1, B_R);
|
|
|
|
FLOATOBJ_DivLong(&f1, 100);
|
|
|
|
FLOATOBJ_AddFloat(&f1,(FLOAT)0.5);
|
|
|
|
lpnp->KuroTBL[i] = (unsigned char)FLOATOBJ_GetLong(&f1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Create UcrTBL[] to reduce extracting black density from YMC
|
|
|
|
for( i=0; i< 256; i++){
|
|
|
|
if( i < B_LOW )
|
|
|
|
lpnp->UcrTBL[i] = 0;
|
|
|
|
else{
|
|
|
|
FLOATOBJ_SetLong(&f1, (i - B_LOW));
|
|
|
|
FLOATOBJ_MulLong(&f1, UCR);
|
|
|
|
FLOATOBJ_DivLong(&f1, 100);
|
|
|
|
lpnp->UcrTBL[i] = (unsigned char)FLOATOBJ_GetLong(&f1);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
lpnp->YellowUcr = (unsigned char)((unsigned int)(100 - YUCR) * 255 / 100);
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/*************************** Function Header *******************************
|
|
* bInitialColorConvert
|
|
*
|
|
* Pre-processing of color conversion process.
|
|
*
|
|
* HISTORY:
|
|
* 24 Jun 1996 -by- Sueya Sugihara [sueyas]
|
|
* Created.
|
|
*
|
|
***************************************************************************/
|
|
BOOL bInitialColorConvert(
|
|
PDEVOBJ pdevobj)
|
|
{
|
|
|
|
PCURRENTSTATUS lpnp;
|
|
int i;
|
|
BYTE *RedHosei;
|
|
BYTE *GreenHosei;
|
|
BYTE *BlueHosei;
|
|
|
|
lpnp = (PCURRENTSTATUS)MINIDEV_DATA(pdevobj);
|
|
|
|
// Color definitions.
|
|
|
|
lpnp->RGB_Rx = 6400; // X value of Red 100% on monitor
|
|
lpnp->RGB_Ry = 3300; // Y value of Red 100% on monitor
|
|
lpnp->RGB_Gx = 2900; // X value of Green 100% on monitor
|
|
lpnp->RGB_Gy = 6000; // Y value of Green 100% on monitor
|
|
lpnp->RGB_Bx = 1500; // X value of Blue 100% on monitor
|
|
lpnp->RGB_By = 600; // Y value of Blue 100% on monitor
|
|
lpnp->RGB_Wx = 3127; // X value of White 100% on monitor
|
|
lpnp->RGB_Wy = 3290; // Y value of White 100% on monitor
|
|
|
|
lpnp->CMY_Cx = 1726; // X value of Cyan 100% on ribbon
|
|
lpnp->CMY_Cy = 2248; // Y value of Cyan 100% on ribbon
|
|
lpnp->CMY_Mx = 3923; // X value of Magenta 100% on ribbon
|
|
lpnp->CMY_My = 2295; // Y value of Magenta 100% on ribbon
|
|
lpnp->CMY_Yx = 4600; // X value of Yellow 100% on ribbon
|
|
lpnp->CMY_Yy = 4600; // Y value of Yellow 100% on ribbon
|
|
lpnp->CMY_Rx = 6000; // X value of Red (MY) 100% on ribbon
|
|
lpnp->CMY_Ry = 3200; // Y value of Red (MY) 100% on ribbon
|
|
lpnp->CMY_Gx = 2362; // X value of Green (CY) 100% on ribbon
|
|
lpnp->CMY_Gy = 5024; // Y value of Green (CY) 100% on ribbon
|
|
lpnp->CMY_Bx = 2121; // X value of Blue (CM) 100% on ribbon
|
|
lpnp->CMY_By = 1552; // Y value of Blue (CM) 100% on ribbon
|
|
lpnp->CMY_Wx = 3148; // X value of White on paper
|
|
lpnp->CMY_Wy = 3317; // Y value of White on paper
|
|
|
|
lpnp->RedAdj = 0; // Param for density adjust
|
|
lpnp->RedStart = 0; // Position of start for density adjust
|
|
lpnp->GreenAdj = 400; // Param for density adjust
|
|
lpnp->GreenStart = 50; // Position of start for density adjust
|
|
lpnp->BlueAdj = 0; // Param for density adjust
|
|
lpnp->BlueStart = 0; // Position of start for density adjust
|
|
|
|
|
|
// Calculation of density adjustment table.
|
|
|
|
RedHosei = lpnp->RedHosei;
|
|
GreenHosei = lpnp->GreenHosei;
|
|
BlueHosei = lpnp->BlueHosei;
|
|
|
|
for(i = 0; i < 256; i ++){
|
|
|
|
RedHosei[i] = GreenHosei[i] = BlueHosei[i] = 0;
|
|
}
|
|
|
|
if( lpnp->RedAdj != 0 ){
|
|
|
|
for(i = lpnp->RedStart; i < 255; i++)
|
|
|
|
RedHosei[i] = (unsigned char)((255 - i) * (i - lpnp->RedStart) / lpnp->RedAdj);
|
|
|
|
}
|
|
|
|
if( lpnp->GreenAdj != 0 ){
|
|
|
|
for(i = lpnp->GreenStart; i < 255; i++)
|
|
|
|
GreenHosei[i] = (unsigned char)((255 - i) * (i - lpnp->GreenStart) / lpnp->GreenAdj);
|
|
|
|
}
|
|
|
|
if( lpnp->BlueAdj != 0 ){
|
|
|
|
for(i = lpnp->BlueStart; i < 255; i++)
|
|
|
|
BlueHosei[i] = (unsigned char)((255 - i) * (i - lpnp->BlueStart) / lpnp->BlueAdj);
|
|
|
|
}
|
|
|
|
// Calculation of color definition data.
|
|
|
|
lpnp->RGB_Rx -= lpnp->RGB_Wx; lpnp->RGB_Ry -= lpnp->RGB_Wy;
|
|
lpnp->RGB_Gx -= lpnp->RGB_Wx; lpnp->RGB_Gy -= lpnp->RGB_Wy;
|
|
lpnp->RGB_Bx -= lpnp->RGB_Wx; lpnp->RGB_By -= lpnp->RGB_Wy;
|
|
|
|
lpnp->RGB_Cx = ( lpnp->RGB_Gx - lpnp->RGB_Bx ) / 2 + lpnp->RGB_Bx;
|
|
lpnp->RGB_Cy = ( lpnp->RGB_Gy - lpnp->RGB_By ) / 2 + lpnp->RGB_By;
|
|
lpnp->RGB_Mx = ( lpnp->RGB_Rx - lpnp->RGB_Bx ) / 2 + lpnp->RGB_Bx;
|
|
lpnp->RGB_My = ( lpnp->RGB_Ry - lpnp->RGB_By ) / 2 + lpnp->RGB_By;
|
|
lpnp->RGB_Yx = ( lpnp->RGB_Rx - lpnp->RGB_Gx ) / 2 + lpnp->RGB_Gx;
|
|
lpnp->RGB_Yy = ( lpnp->RGB_Ry - lpnp->RGB_Gy ) / 2 + lpnp->RGB_Gy;
|
|
|
|
lpnp->CMY_Cx -= lpnp->CMY_Wx; lpnp->CMY_Cy -= lpnp->CMY_Wy;
|
|
lpnp->CMY_Mx -= lpnp->CMY_Wx; lpnp->CMY_My -= lpnp->CMY_Wy;
|
|
lpnp->CMY_Yx -= lpnp->CMY_Wx; lpnp->CMY_Yy -= lpnp->CMY_Wy;
|
|
lpnp->CMY_Rx -= lpnp->CMY_Wx; lpnp->CMY_Ry -= lpnp->CMY_Wy;
|
|
lpnp->CMY_Gx -= lpnp->CMY_Wx; lpnp->CMY_Gy -= lpnp->CMY_Wy;
|
|
lpnp->CMY_Bx -= lpnp->CMY_Wx; lpnp->CMY_By -= lpnp->CMY_Wy;
|
|
|
|
// Calculation of data for color dimension judgement
|
|
|
|
lpnp->CMY_Cd = Calc_degree( lpnp->CMY_Cx, lpnp->CMY_Cy );
|
|
lpnp->CMY_Md = Calc_degree( lpnp->CMY_Mx, lpnp->CMY_My );
|
|
lpnp->CMY_Yd = Calc_degree( lpnp->CMY_Yx, lpnp->CMY_Yy );
|
|
lpnp->CMY_Rd = Calc_degree( lpnp->CMY_Rx, lpnp->CMY_Ry );
|
|
lpnp->CMY_Gd = Calc_degree( lpnp->CMY_Gx, lpnp->CMY_Gy );
|
|
lpnp->CMY_Bd = Calc_degree( lpnp->CMY_Bx, lpnp->CMY_By );
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
int Calc_degree( int x, int y)
|
|
{
|
|
register int val;
|
|
|
|
if( x == 0 ){
|
|
|
|
if( y == 0 )
|
|
|
|
val = 0;
|
|
|
|
else if( y > 0 )
|
|
|
|
val = 30000;
|
|
|
|
else
|
|
|
|
val = -30000;
|
|
|
|
}else{
|
|
|
|
val = y / x;
|
|
|
|
if( val > 300 )
|
|
|
|
val = 30000;
|
|
|
|
else if( val < -300 )
|
|
|
|
val = -30000;
|
|
|
|
else
|
|
|
|
val = (y * 100) / x;
|
|
|
|
}
|
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
|
// bOHPConvert() - No longer used.
|
|
|
|
|
|
/*************************** Function Header *******************************
|
|
* bPhotoConvert
|
|
*
|
|
* Convert RGB to CMYK for photo graphics.
|
|
*
|
|
*
|
|
* HISTORY:
|
|
* 24 Jun 1996 -by- Sueya Sugihara [sueyas]
|
|
* Created.
|
|
*
|
|
***************************************************************************/
|
|
BOOL bPhotoConvert(
|
|
PDEVOBJ pdevobj,
|
|
BYTE bRed,
|
|
BYTE bGreen,
|
|
BYTE bBlue,
|
|
BYTE *ppy,
|
|
BYTE *ppm,
|
|
BYTE *ppc,
|
|
BYTE *ppk)
|
|
{
|
|
|
|
int k, w, pk, r, g, b;
|
|
int Est_x, Est_y;
|
|
int p1, p2;
|
|
int deg, area;
|
|
register int val_a, val_b, val_c, val_d;
|
|
register int val1, val2;
|
|
BYTE hosei;
|
|
int py, pm, pc;
|
|
int wx, wy;
|
|
PCURRENTSTATUS lpnp;
|
|
|
|
lpnp = (PCURRENTSTATUS)MINIDEV_DATA(pdevobj);
|
|
|
|
k = max( bRed, bGreen );
|
|
k = max( k, bBlue );
|
|
|
|
// Set black element
|
|
|
|
pk = 255 - k;
|
|
|
|
w = min( bRed, bGreen );
|
|
w = min( w, bBlue );
|
|
|
|
// Cut white element from each color
|
|
|
|
r = bRed - w;
|
|
g = bGreen - w;
|
|
b = bBlue - w;
|
|
|
|
// Get estimation for Est_x and Est_y
|
|
|
|
if( r == 0 ){ // G->C->B
|
|
|
|
if(( g == 0 ) && ( b == 0 )){ // no color
|
|
|
|
Est_x = 0;
|
|
Est_y = 0;
|
|
|
|
}
|
|
else if( g >= b ){ // G->C dimension
|
|
|
|
p1 = (lpnp->RGB_Gx * g) / 255;
|
|
p2 = (lpnp->RGB_Cx * g) / 255;
|
|
Est_x = ((p2 - p1) * b) / g + p1;
|
|
p1 = (lpnp->RGB_Gy * g) / 255;
|
|
p2 = (lpnp->RGB_Cy * g) / 255;
|
|
Est_y = ((p2 - p1) * b) / g + p1;
|
|
|
|
}
|
|
else { // B->C dimension
|
|
|
|
p1 = (lpnp->RGB_Bx * b) / 255;
|
|
p2 = (lpnp->RGB_Cx * b) / 255;
|
|
Est_x = ((p2 - p1) * g) / b + p1;
|
|
p1 = (lpnp->RGB_By * b) / 255;
|
|
p2 = (lpnp->RGB_Cy * b) / 255;
|
|
Est_y = ((p2 - p1) * g) / b + p1;
|
|
|
|
}
|
|
|
|
}
|
|
else if( g == 0 ){ // B->M->R
|
|
|
|
if( b >= r ){ // B->M dimension
|
|
|
|
p1 = (lpnp->RGB_Bx * b) / 255;
|
|
p2 = (lpnp->RGB_Mx * b) / 255;
|
|
Est_x = ((p2 - p1) * r) / b + p1;
|
|
p1 = (lpnp->RGB_By * b) / 255;
|
|
p2 = (lpnp->RGB_My * b) / 255;
|
|
Est_y = ((p2 - p1) * r) / b + p1;
|
|
|
|
}
|
|
else{ // R->M dimension
|
|
|
|
p1 = (lpnp->RGB_Rx * r) / 255;
|
|
p2 = (lpnp->RGB_Mx * r) / 255;
|
|
Est_x = ((p2 - p1) * b) / r + p1;
|
|
p1 = (lpnp->RGB_Ry * r) / 255;
|
|
p2 = (lpnp->RGB_My * r) / 255;
|
|
Est_y = ((p2 - p1) * b) / r + p1;
|
|
|
|
}
|
|
|
|
}
|
|
else{ // G->Y->R
|
|
|
|
if( g >= r ){ // G->Y dimension
|
|
|
|
p1 = (lpnp->RGB_Gx * g) / 255;
|
|
p2 = (lpnp->RGB_Yx * g) / 255;
|
|
Est_x = ((p2 - p1) * r) / g + p1;
|
|
p1 = (lpnp->RGB_Gy * g) / 255;
|
|
p2 = (lpnp->RGB_Yy * g) / 255;
|
|
Est_y = ((p2 - p1) * r) / g + p1;
|
|
|
|
}
|
|
else{ // R->Y dimension
|
|
|
|
p1 = (lpnp->RGB_Rx * r) / 255;
|
|
p2 = (lpnp->RGB_Yx * r) / 255;
|
|
Est_x = ((p2 - p1) * g) / r + p1;
|
|
p1 = (lpnp->RGB_Ry * r) / 255;
|
|
p2 = (lpnp->RGB_Yy * r) / 255;
|
|
Est_y = ((p2 - p1) * g) / r + p1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Convert origin of Est_x and Est_y to paper color
|
|
|
|
wx = lpnp->RGB_Wx ? lpnp->RGB_Wx : 1;
|
|
wy = lpnp->RGB_Wy ? lpnp->RGB_Wy : 1;
|
|
|
|
Est_x += lpnp->RGB_Wx;
|
|
Est_y += lpnp->RGB_Wy;
|
|
Est_x = Est_x * lpnp->CMY_Wx / wx;
|
|
Est_y = Est_y * lpnp->CMY_Wy / wy;
|
|
Est_x -= lpnp->CMY_Wx;
|
|
Est_y -= lpnp->CMY_Wy;
|
|
|
|
pc = pm = py = 0;
|
|
|
|
if( !((Est_x == 0) && (Est_y == 0)) ){
|
|
|
|
// Get deg on CMY color dimension from Est_x and Est_y
|
|
|
|
if( Est_x == 0 ){
|
|
|
|
if( Est_y > 0 )
|
|
|
|
deg = 30000;
|
|
|
|
else
|
|
|
|
deg = -30000;
|
|
|
|
}
|
|
else{
|
|
|
|
deg = Est_y / Est_x;
|
|
|
|
if( deg > 300 )
|
|
|
|
deg = 30000;
|
|
|
|
else if( deg < -300 )
|
|
|
|
deg = -30000;
|
|
|
|
else
|
|
|
|
deg = ( Est_y * 100 ) / Est_x;
|
|
|
|
}
|
|
|
|
|
|
if( Est_x >= 0 ){
|
|
|
|
if( deg <= lpnp->CMY_Md ) // M->B dimension
|
|
|
|
area = 1;
|
|
|
|
else if( deg <= lpnp->CMY_Rd ) // M->R dimension
|
|
|
|
area = 2;
|
|
|
|
else if( deg <= lpnp->CMY_Yd ) // Y->R dimension
|
|
|
|
area = 3;
|
|
|
|
else // Y->G dimension
|
|
|
|
area = 4;
|
|
|
|
}
|
|
else{
|
|
|
|
if( deg <= lpnp->CMY_Gd ) // Y->G dimension
|
|
|
|
area = 4;
|
|
|
|
else if( deg <= lpnp->CMY_Cd ) // C->G dimension
|
|
|
|
area = 5;
|
|
|
|
else if( deg <= lpnp->CMY_Bd ) // C->B dimension
|
|
|
|
area = 6;
|
|
|
|
else // M->B dimension
|
|
|
|
area = 1;
|
|
|
|
}
|
|
|
|
switch ( area ){
|
|
|
|
case 1: // M->B dimension
|
|
|
|
val_a = lpnp->CMY_Bx - lpnp->CMY_Mx;
|
|
val_b = lpnp->CMY_By - lpnp->CMY_My;
|
|
val_c = lpnp->CMY_Mx;
|
|
val_d = lpnp->CMY_My;
|
|
|
|
val1 = val_b * val_c - val_a * val_d;
|
|
val2 = ( val_b * Est_x - val_a * Est_y ) * 255;
|
|
|
|
val1 = val1 ? val1 : 1;
|
|
|
|
pm = val2 / val1;
|
|
|
|
if( pm < 0 )
|
|
pm = 0;
|
|
|
|
val1 = val_a * val_d - val_b * val_c;
|
|
val2 = ( val_d * Est_x - val_c * Est_y ) * 255;
|
|
|
|
val1 = val1 ? val1 : 1;
|
|
|
|
pc = val2 / val1;
|
|
|
|
if( pc < 0 )
|
|
pc = 0;
|
|
|
|
if( pc > 255 )
|
|
pc = 255;
|
|
|
|
hosei = lpnp->BlueHosei[pc];
|
|
|
|
pc += hosei;
|
|
pm += hosei;
|
|
|
|
if( pc > 255 )
|
|
pc = 255;
|
|
|
|
if( pm > 255 )
|
|
pm = 255;
|
|
|
|
break;
|
|
|
|
case 2: // M->R dimension
|
|
|
|
val_a = lpnp->CMY_Rx - lpnp->CMY_Mx;
|
|
val_b = lpnp->CMY_Ry - lpnp->CMY_My;
|
|
val_c = lpnp->CMY_Mx;
|
|
val_d = lpnp->CMY_My;
|
|
|
|
val1 = val_b * val_c - val_a * val_d;
|
|
val2 = ( val_b * Est_x - val_a * Est_y ) * 255;
|
|
|
|
val1 = val1 ? val1 : 1;
|
|
|
|
pm = val2 / val1;
|
|
|
|
if( pm < 0 )
|
|
pm = 0;
|
|
|
|
val1 = val_a * val_d - val_b * val_c;
|
|
val2 = ( val_d * Est_x - val_c * Est_y ) * 255;
|
|
|
|
val1 = val1 ? val1 : 1;
|
|
|
|
py = val2 / val1;
|
|
|
|
if( py < 0 )
|
|
py = 0;
|
|
|
|
if( py > 255 )
|
|
py = 255;
|
|
|
|
hosei = lpnp->RedHosei[py];
|
|
|
|
py += hosei;
|
|
pm += hosei;
|
|
|
|
if( pm > 255 )
|
|
pm = 255;
|
|
|
|
if( py > 255 )
|
|
py = 255;
|
|
|
|
break;
|
|
|
|
case 3: // Y->R dimension
|
|
|
|
val_a = lpnp->CMY_Rx - lpnp->CMY_Yx;
|
|
val_b = lpnp->CMY_Ry - lpnp->CMY_Yy;
|
|
val_c = lpnp->CMY_Yx;
|
|
val_d = lpnp->CMY_Yy;
|
|
|
|
val1 = val_b * val_c - val_a * val_d;
|
|
val2 = ( val_b * Est_x - val_a * Est_y ) * 255;
|
|
|
|
val1 = val1 ? val1 : 1;
|
|
|
|
py = val2 / val1;
|
|
|
|
if( py < 0 )
|
|
py = 0;
|
|
|
|
val1 = val_a * val_d - val_b * val_c;
|
|
val2 = ( val_d * Est_x - val_c * Est_y ) * 255;
|
|
|
|
val1 = val1 ? val1 : 1;
|
|
|
|
pm = val2 / val1;
|
|
|
|
if( pm < 0 )
|
|
pm = 0;
|
|
|
|
if( pm > 255 )
|
|
pm = 255;
|
|
|
|
hosei = lpnp->RedHosei[pm];
|
|
|
|
py += hosei;
|
|
pm += hosei;
|
|
|
|
if( pm > 255 )
|
|
pm = 255;
|
|
|
|
if( py > 255 )
|
|
py = 255;
|
|
|
|
break;
|
|
|
|
case 4: // Y->G dimension
|
|
|
|
val_a = lpnp->CMY_Gx - lpnp->CMY_Yx;
|
|
val_b = lpnp->CMY_Gy - lpnp->CMY_Yy;
|
|
val_c = lpnp->CMY_Yx;
|
|
val_d = lpnp->CMY_Yy;
|
|
|
|
val1 = val_b * val_c - val_a * val_d;
|
|
val2 = ( val_b * Est_x - val_a * Est_y ) * 255;
|
|
|
|
val1 = val1 ? val1 : 1;
|
|
|
|
py = val2 / val1;
|
|
|
|
if( py < 0 )
|
|
py = 0;
|
|
|
|
val1 = val_a * val_d - val_b * val_c;
|
|
val2 = ( val_d * Est_x - val_c * Est_y ) * 255;
|
|
|
|
val1 = val1 ? val1 : 1;
|
|
|
|
pc = val2 / val1;
|
|
|
|
if( pc < 0 )
|
|
pc = 0;
|
|
|
|
if( pc > 255 )
|
|
pc = 255;
|
|
|
|
hosei = lpnp->GreenHosei[pc];
|
|
|
|
py += hosei;
|
|
pc += hosei;
|
|
|
|
if( pc > 255 )
|
|
pc = 255;
|
|
|
|
if( py > 255 )
|
|
py = 255;
|
|
|
|
break;
|
|
|
|
case 5: // C->G dimension
|
|
|
|
val_a = lpnp->CMY_Gx - lpnp->CMY_Cx;
|
|
val_b = lpnp->CMY_Gy - lpnp->CMY_Cy;
|
|
val_c = lpnp->CMY_Cx;
|
|
val_d = lpnp->CMY_Cy;
|
|
|
|
val1 = val_b * val_c - val_a * val_d;
|
|
val2 = ( val_b * Est_x - val_a * Est_y ) * 255;
|
|
|
|
val1 = val1 ? val1 : 1;
|
|
|
|
pc = val2 / val1;
|
|
|
|
if( pc < 0 )
|
|
pc = 0;
|
|
|
|
val1 = val_a * val_d - val_b * val_c;
|
|
val2 = ( val_d * Est_x - val_c * Est_y ) * 255;
|
|
|
|
val1 = val1 ? val1 : 1;
|
|
|
|
py = val2 / val1;
|
|
|
|
if( py < 0 )
|
|
py = 0;
|
|
|
|
if( py > 255 )
|
|
py = 255;
|
|
|
|
// Dwnsity adjustment for green
|
|
hosei = lpnp->GreenHosei[py];
|
|
|
|
py += hosei;
|
|
pc += hosei;
|
|
|
|
if( pc > 255 )
|
|
pc = 255;
|
|
|
|
if( py > 255 )
|
|
py = 255;
|
|
|
|
break;
|
|
|
|
case 6: // C->B dimension
|
|
|
|
val_a = lpnp->CMY_Bx - lpnp->CMY_Cx;
|
|
val_b = lpnp->CMY_By - lpnp->CMY_Cy;
|
|
val_c = lpnp->CMY_Cx;
|
|
val_d = lpnp->CMY_Cy;
|
|
|
|
val1 = val_b * val_c - val_a * val_d;
|
|
val2 = ( val_b * Est_x - val_a * Est_y ) * 255;
|
|
|
|
val1 = val1 ? val1 : 1;
|
|
|
|
pc = val2 / val1;
|
|
|
|
if( pc < 0 )
|
|
pc = 0;
|
|
|
|
val1 = val_a * val_d - val_b * val_c;
|
|
val2 = ( val_d * Est_x - val_c * Est_y ) * 255;
|
|
|
|
val1 = val1 ? val1 : 1;
|
|
|
|
pm = val2 / val1;
|
|
|
|
if( pm < 0 )
|
|
pm = 0;
|
|
|
|
if( pm > 255 )
|
|
pm = 255;
|
|
|
|
hosei = lpnp->BlueHosei[pm];
|
|
|
|
pc += hosei;
|
|
pm += hosei;
|
|
|
|
if( pc > 255 )
|
|
pc = 255;
|
|
|
|
if( pm > 255 )
|
|
pm = 255;
|
|
|
|
} // switch area
|
|
|
|
}
|
|
|
|
// Add pk to color
|
|
|
|
k = pc;
|
|
|
|
if( k < pm )
|
|
k = pm;
|
|
|
|
if( k < py )
|
|
k = py;
|
|
|
|
r = ( pk + k > 255) ? 255 - k : pk;
|
|
|
|
pk -= r;
|
|
pc += r;
|
|
pm += r;
|
|
py += r;
|
|
|
|
|
|
// Extract K and adjust to other color for its extracting value
|
|
|
|
if (bPlaneSendOrderCMYK(lpnp)) {
|
|
|
|
int min_p;
|
|
BYTE ucr_sub, ucr_div;
|
|
|
|
min_p = min( py, pm );
|
|
min_p = min( min_p, pc );
|
|
|
|
#ifdef BLACK_RIBBON_HACK
|
|
if( min_p == 255 ){
|
|
pk = 255;
|
|
pc = pm = py = 0;
|
|
}
|
|
else{
|
|
#endif // BLACK_RIBBOM_HACK
|
|
|
|
pk += lpnp->KuroTBL[min_p];
|
|
pk = ( pk > 255 ) ? 255 : pk;
|
|
|
|
ucr_sub = lpnp->UcrTBL[min_p];
|
|
ucr_div = 255 - ucr_sub;
|
|
|
|
ucr_div = ucr_div ? ucr_div : 1;
|
|
|
|
py = (BYTE)((UINT)(py - ucr_sub) * lpnp->YellowUcr / ucr_div);
|
|
pm = (BYTE)((UINT)(pm - ucr_sub) * 255 / ucr_div);
|
|
pc = (BYTE)((UINT)(pc - ucr_sub) * 255 / ucr_div);
|
|
|
|
#ifdef BLACK_RIBBON_HACK
|
|
}
|
|
#endif // BLACK_RIBBON_HACK
|
|
|
|
}
|
|
|
|
py = 255 - py;
|
|
pm = 255 - pm;
|
|
pc = 255 - pc;
|
|
pk = 255 - pk;
|
|
|
|
*ppy = (BYTE)py;
|
|
*ppm = (BYTE)pm;
|
|
*ppc = (BYTE)pc;
|
|
*ppk = (BYTE)pk;
|
|
|
|
return TRUE;
|
|
}
|
|
/*************************** Function Header *******************************
|
|
* bBusinessConvert
|
|
*
|
|
* Convert RGB to CMYK for business graphics.
|
|
*
|
|
*
|
|
* HISTORY:
|
|
* 24 Jun 1996 -by- Sueya Sugihara [sueyas]
|
|
* Created.
|
|
*
|
|
***************************************************************************/
|
|
BOOL bBusinessConvert(
|
|
PDEVOBJ pdevobj,
|
|
BYTE bRed,
|
|
BYTE bGreen,
|
|
BYTE bBlue,
|
|
BYTE *ppy,
|
|
BYTE *ppm,
|
|
BYTE *ppc,
|
|
BYTE *ppk)
|
|
{
|
|
int py, pm, pc, pk;
|
|
int min_p;
|
|
BYTE ucr_sub, ucr_div;
|
|
PCURRENTSTATUS lpnp;
|
|
|
|
lpnp = (PCURRENTSTATUS)MINIDEV_DATA(pdevobj);
|
|
|
|
// Simple convert RGB to CMY
|
|
|
|
py = 255 - bBlue;
|
|
pm = 255 - bGreen;
|
|
pc = 255 - bRed;
|
|
pk = 0;
|
|
|
|
// Extract K and adjust to other color for its extracting value
|
|
|
|
// Extract pk from py, pm and pc by using followings, and erase black element.
|
|
|
|
// When this media is 3 plane type, we do not extract black.
|
|
|
|
if (bPlaneSendOrderCMYK(lpnp)) {
|
|
|
|
min_p = min( py, pm );
|
|
min_p = min( min_p, pc );
|
|
|
|
#ifdef BLACK_RIBBON_HACK
|
|
if( min_p == 255 ){
|
|
pk = 255;
|
|
pc = pm = py = 0;
|
|
}
|
|
else{
|
|
#endif // BLACK_RIBBON_HACK
|
|
|
|
pk = lpnp->KuroTBL[min_p];
|
|
|
|
ucr_sub = lpnp->UcrTBL[min_p];
|
|
|
|
ucr_div = 255 - ucr_sub;
|
|
|
|
ucr_div = ucr_div ? ucr_div : 1;
|
|
|
|
py = (BYTE)((UINT)(py - ucr_sub) * lpnp->YellowUcr / ucr_div);
|
|
pm = (BYTE)((UINT)(pm - ucr_sub) * 255 / ucr_div);
|
|
pc = (BYTE)((UINT)(pc - ucr_sub) * 255 / ucr_div);
|
|
|
|
#ifdef BLACK_RIBBON_HACK
|
|
}
|
|
#endif // BLACK_RIBBON_HACK
|
|
|
|
}
|
|
|
|
py = 255 - py;
|
|
pm = 255 - pm;
|
|
pc = 255 - pc;
|
|
pk = 255 - pk;
|
|
|
|
*ppy = (BYTE)py;
|
|
*ppm = (BYTE)pm;
|
|
*ppc = (BYTE)pc;
|
|
*ppk = (BYTE)pk;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/*************************** Function Header *******************************
|
|
* bCharacterConvert
|
|
*
|
|
* Convert RGB to CMYK for character graphics.
|
|
*
|
|
*
|
|
* HISTORY:
|
|
* 24 Jun 1996 -by- Sueya Sugihara [sueyas]
|
|
* Created.
|
|
*
|
|
***************************************************************************/
|
|
BOOL bCharacterConvert(
|
|
PDEVOBJ pdevobj,
|
|
BYTE bRed,
|
|
BYTE bGreen,
|
|
BYTE bBlue,
|
|
BYTE *ppy,
|
|
BYTE *ppm,
|
|
BYTE *ppc,
|
|
BYTE *ppk)
|
|
{
|
|
int py, pm, pc, pk;
|
|
int min_p;
|
|
BYTE ucr_sub, ucr_div;
|
|
PCURRENTSTATUS lpnp;
|
|
|
|
lpnp = (PCURRENTSTATUS)MINIDEV_DATA(pdevobj);
|
|
|
|
// Simple convert RGB to CMY
|
|
|
|
py = 255 - bBlue;
|
|
pm = 255 - bGreen;
|
|
pc = 255 - bRed;
|
|
pk = 0;
|
|
|
|
// Extract K and adjust to other color for its extracting value
|
|
|
|
// Extract pk from py, pm and pc by using followings, and erase black element.
|
|
|
|
// When this media is 3 plane type, we do not extract black.
|
|
|
|
if (bPlaneSendOrderCMYK(lpnp)) {
|
|
|
|
min_p = min( py, pm );
|
|
min_p = min( min_p, pc );
|
|
|
|
if( min_p == 255 ){
|
|
|
|
pk = 255;
|
|
pc = pm = py = 0;
|
|
|
|
}
|
|
else{
|
|
|
|
pk = lpnp->KuroTBL[min_p];
|
|
|
|
ucr_sub = lpnp->UcrTBL[min_p];
|
|
|
|
ucr_div = 255 - ucr_sub;
|
|
|
|
ucr_div = ucr_div ? ucr_div : 1;
|
|
|
|
py = (BYTE)((UINT)(py - ucr_sub) * lpnp->YellowUcr / ucr_div);
|
|
pm = (BYTE)((UINT)(pm - ucr_sub) * 255 / ucr_div);
|
|
pc = (BYTE)((UINT)(pc - ucr_sub) * 255 / ucr_div);
|
|
|
|
}
|
|
}
|
|
|
|
py = 255 - py;
|
|
pm = 255 - pm;
|
|
pc = 255 - pc;
|
|
pk = 255 - pk;
|
|
|
|
*ppy = (BYTE)py;
|
|
*ppm = (BYTE)pm;
|
|
*ppc = (BYTE)pc;
|
|
*ppk = (BYTE)pk;
|
|
|
|
return TRUE;
|
|
}
|
|
/*************************** Function Header *******************************
|
|
* bMonoConvert
|
|
*
|
|
* Convert RGB to Grayscale.
|
|
*
|
|
*
|
|
* HISTORY:
|
|
* 24 Jun 1996 -by- Sueya Sugihara [sueyas]
|
|
* Created.
|
|
*
|
|
***************************************************************************/
|
|
BOOL bMonoConvert(
|
|
PDEVOBJ pdevobj,
|
|
BYTE bRed,
|
|
BYTE bGreen,
|
|
BYTE bBlue,
|
|
BYTE *ppk)
|
|
{
|
|
int mono;
|
|
|
|
mono = ( 30 * bRed + 59 * bGreen + 11 * bBlue ) / 100;
|
|
|
|
*ppk = 0xff - (BYTE)( mono & 0xff );
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
/*************************** Function Header *******************************
|
|
* cVDColorDither
|
|
*
|
|
* VD Color Dither processing
|
|
*
|
|
*
|
|
* HISTORY:
|
|
* 11 Jan 1999 -by- Yoshitaka Oku [yoshitao]
|
|
* Created.
|
|
*
|
|
* BYTE Color : Plane Color <Yellow, Cyan, Magenta, Black>
|
|
* BYTE c : oliginal tone of the pixel
|
|
* int x : X position of the pixel
|
|
* int y : Y position of the pixel
|
|
*
|
|
***************************************************************************/
|
|
cVDColorDither(
|
|
BYTE Color,
|
|
BYTE c,
|
|
int x,
|
|
int y)
|
|
{
|
|
int m, n;
|
|
short Base;
|
|
BYTE Tone;
|
|
BYTE C_Thresh, Thresh;
|
|
short AdjustedColor;
|
|
BYTE TempTone;
|
|
BYTE BaseTone;
|
|
|
|
switch (Color) {
|
|
case Yellow:
|
|
Base = 112;
|
|
m = n = 12;
|
|
break;
|
|
|
|
case Cyan:
|
|
case Magenta:
|
|
Base = 208;
|
|
m = n = 40;
|
|
break;
|
|
|
|
case Black:
|
|
Base = 96;
|
|
m = n = 24;
|
|
break;
|
|
default:
|
|
Color = Black;
|
|
Base = 96;
|
|
m = n = 24;
|
|
break;
|
|
}
|
|
|
|
Tone = 0; /* Clear Tone value */
|
|
c = VD_ColorAdjustTable[Color][c]; /* Convert orignal color */
|
|
if (c != 0) {
|
|
C_Thresh = (VD_DitherTable[Color][y % m][x % n]);
|
|
if ( C_Thresh < 16 )
|
|
Thresh = 1;
|
|
else {
|
|
C_Thresh -= 16;
|
|
Thresh = (C_Thresh >> 2) + 1;
|
|
}
|
|
AdjustedColor = VD_ExpandValueTable[Color][c] - 1;
|
|
if ( AdjustedColor < Base )
|
|
TempTone = ( AdjustedColor >> 4 ) + 1;
|
|
else {
|
|
AdjustedColor -= Base;
|
|
TempTone = ( AdjustedColor >> 2 ) + ( Base >> 4 ) + 1;
|
|
}
|
|
if (TempTone >= 232) TempTone = 232-1;
|
|
BaseTone = VD_ToneOptimaizeTable[Color][TempTone].base;
|
|
if ( BaseTone > Thresh ) {
|
|
Tone = 15;
|
|
} else {
|
|
if ( BaseTone == Thresh ) {
|
|
if ( BaseTone == 1 ) {
|
|
if (( AdjustedColor & 0x0f ) >= C_Thresh )
|
|
Tone = VD_ToneOptimaizeTable[Color][(( AdjustedColor >> 4) & 0x0f )+ 1 ].offset;
|
|
else
|
|
Tone = VD_ToneOptimaizeTable[Color][( AdjustedColor >> 4) & 0x0f ].offset ;
|
|
} else {
|
|
if ((AdjustedColor & 0x03) >= (C_Thresh & 0x03))
|
|
Tone = VD_ToneOptimaizeTable[Color][TempTone].offset;
|
|
else {
|
|
if (TempTone < 1) TempTone = 1;
|
|
if (VD_ToneOptimaizeTable[Color][TempTone -1].base == BaseTone)
|
|
Tone = VD_ToneOptimaizeTable[Color][TempTone -1].offset;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return (Tone);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*************************** Function Header *******************************
|
|
* bDitherProcess
|
|
*
|
|
* Dither processing
|
|
*
|
|
*
|
|
* HISTORY:
|
|
* 24 Jun 1996 -by- Sueya Sugihara [sueyas]
|
|
* Created.
|
|
*
|
|
***************************************************************************/
|
|
BOOL bDitherProcess(
|
|
PDEVOBJ pdevobj,
|
|
int x,
|
|
BYTE py,
|
|
BYTE pm,
|
|
BYTE pc,
|
|
BYTE pk,
|
|
BYTE *pby,
|
|
BYTE *pbm,
|
|
BYTE *pbc,
|
|
BYTE *pbk)
|
|
{
|
|
|
|
PCURRENTSTATUS lpnp;
|
|
BYTE rm;
|
|
|
|
lpnp = (PCURRENTSTATUS)MINIDEV_DATA(pdevobj);
|
|
|
|
|
|
if( lpnp->iDither == DITHER_VD ){
|
|
|
|
// Yellow
|
|
*pby = (BYTE)cVDColorDither(Yellow, (BYTE)(255 - py), x, lpnp->y);
|
|
|
|
// Magenta
|
|
*pbm = (BYTE)cVDColorDither(Magenta, (BYTE)(255 - pm), x, lpnp->y);
|
|
|
|
// Cyan
|
|
*pbc = (BYTE)cVDColorDither(Cyan, (BYTE)(255 - pc), x, lpnp->y);
|
|
|
|
// Black
|
|
*pbk = (BYTE)cVDColorDither(Black, (BYTE)(255 - pk), x, lpnp->y);
|
|
|
|
}else if( lpnp->iDither == DITHER_DYE ){
|
|
|
|
rm = DYE_NewTable[lpnp->y % DYE_MaxY][x % DYE_MaxX];
|
|
|
|
// Yellow
|
|
*pby = ( (255 - py) / kToneLevel ) + ( ( ( (255 - py) % kToneLevel ) > rm ) ? 1 : 0 );
|
|
|
|
// Magenta
|
|
*pbm = ( (255 - pm) / kToneLevel ) + ( ( ( (255 - pm) % kToneLevel ) > rm ) ? 1 : 0 );
|
|
|
|
// Cyan
|
|
*pbc = ( (255 - pc) / kToneLevel ) + ( ( ( (255 - pc) % kToneLevel ) > rm ) ? 1 : 0 );
|
|
|
|
// Black
|
|
*pbk = 0;
|
|
|
|
}else if( lpnp->iDither == DITHER_HIGH ){
|
|
|
|
// Yellow
|
|
rm = H_NewTable[Yellow][lpnp->y % H_MaxY[Yellow]][x % H_MaxX[Yellow]];
|
|
|
|
*pby = ( py <= rm ) ? 1 : 0;
|
|
|
|
// Magenta
|
|
rm = H_NewTable[Magenta][lpnp->y % H_MaxY[Magenta]][x % H_MaxX[Magenta]];
|
|
|
|
*pbm = ( pm <= rm ) ? 1 : 0;
|
|
|
|
// Cyan
|
|
rm = H_NewTable[Cyan][lpnp->y % H_MaxY[Cyan]][x % H_MaxX[Cyan]];
|
|
|
|
*pbc = ( pc <= rm ) ? 1 : 0;
|
|
|
|
// Black
|
|
rm = H_NewTable[Black][lpnp->y % H_MaxY[Black]][x % H_MaxX[Black]];
|
|
|
|
if( lpnp->iTextQuality == CMDID_TEXTQUALITY_PHOTO )
|
|
*pbk = ( pk < rm ) ? 1 : 0;
|
|
else
|
|
*pbk = ( pk <= rm ) ? 1 : 0;
|
|
|
|
}else if( lpnp->iDither == DITHER_LOW ){
|
|
|
|
// Yellow
|
|
rm = L_NewTable[Yellow][lpnp->y % L_MaxY[Yellow]][x % L_MaxX[Yellow]];
|
|
|
|
*pby = ( py <= rm ) ? 1 : 0;
|
|
|
|
// Magenta
|
|
rm = L_NewTable[Magenta][lpnp->y % L_MaxY[Magenta]][x % L_MaxX[Magenta]];
|
|
|
|
*pbm = ( pm <= rm ) ? 1 : 0;
|
|
|
|
// Cyan
|
|
rm = L_NewTable[Cyan][lpnp->y % L_MaxY[Cyan]][x % L_MaxX[Cyan]];
|
|
|
|
*pbc = ( pc <= rm ) ? 1 : 0;
|
|
|
|
// Black
|
|
rm = L_NewTable[Black][lpnp->y % L_MaxY[Black]][x % L_MaxX[Black]];
|
|
|
|
if( lpnp->iTextQuality == CMDID_TEXTQUALITY_PHOTO )
|
|
*pbk = ( pk < rm ) ? 1 : 0;
|
|
else
|
|
*pbk = ( pk <= rm ) ? 1 : 0;
|
|
|
|
}else{ // DITHER_HIGH_DIV2
|
|
|
|
// Yellow
|
|
rm = H_NewTable[Yellow][(lpnp->y/2) % H_MaxY[Yellow]][(x/2) % H_MaxX[Yellow]];
|
|
|
|
*pby = ( py <= rm ) ? 1 : 0;
|
|
|
|
// Magenta
|
|
rm = H_NewTable[Magenta][(lpnp->y/2) % H_MaxY[Magenta]][(x/2) % H_MaxX[Magenta]];
|
|
|
|
*pbm = ( pm <= rm ) ? 1 : 0;
|
|
|
|
// Cyan
|
|
rm = H_NewTable[Cyan][(lpnp->y/2) % H_MaxY[Cyan]][(x/2) % H_MaxX[Cyan]];
|
|
|
|
*pbc = ( pc <= rm ) ? 1 : 0;
|
|
|
|
// Black
|
|
rm = H_NewTable[Black][(lpnp->y/2) % H_MaxY[Black]][(x/2) % H_MaxX[Black]];
|
|
|
|
if( lpnp->iTextQuality == CMDID_TEXTQUALITY_PHOTO )
|
|
*pbk = ( pk < rm ) ? 1 : 0;
|
|
else
|
|
*pbk = ( pk <= rm ) ? 1 : 0;
|
|
}
|
|
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|