Leaked source code of windows server 2003
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

  1. /*++
  2. Copyright (c) 1997-1999 Microsoft Corporation
  3. --*/
  4. // NTRAID#NTBUG9-576656-2002/03/14-yasuho-: Possible buffer overrun
  5. // NTRAID#NTBUG9-576658-2002/03/14-yasuho-: Possible divide by zero
  6. // NTRAID#NTBUG9-576661-2002/03/14-yasuho-: Remove the dead codes
  7. #include "pdev.h"
  8. #include "alpsres.h"
  9. #include "dither.h"
  10. #include "dtable.h"
  11. int Calc_degree(int x, int y);
  12. /*************************** Function Header *******************************
  13. * bInitialDither
  14. *
  15. * Pre-processing of dither tables.
  16. *
  17. * HISTORY:
  18. * 24 Jun 1996 -by- Sueya Sugihara [sueyas]
  19. * Created.
  20. *
  21. ***************************************************************************/
  22. BOOL bInitialDither(
  23. PDEVOBJ pdevobj)
  24. {
  25. PCURRENTSTATUS lpnp;
  26. lpnp = (PCURRENTSTATUS)MINIDEV_DATA(pdevobj);
  27. // Already created the NewTable[][][] by dither.exe.
  28. if( lpnp->iTextQuality != CMDID_TEXTQUALITY_GRAY ){
  29. int B_LOW;
  30. int B_R;
  31. int UCR;
  32. int YUCR;
  33. int B_GEN;
  34. int i;
  35. // FLOATOBJ f1,f2;
  36. float f1,f2;
  37. // initialize.
  38. if( lpnp->iTextQuality == CMDID_TEXTQUALITY_PHOTO ){
  39. B_LOW = 0;
  40. B_R = 70;
  41. UCR = 50;
  42. YUCR = 4;
  43. B_GEN = 2;
  44. }else{
  45. B_LOW = 0;
  46. B_R = 100;
  47. UCR = 60;
  48. YUCR = 4;
  49. B_GEN = 3;
  50. }
  51. // Create KuroTBL[] to get black from YMC.
  52. for( i=0; i< 256; i++){
  53. if( i < B_LOW )
  54. lpnp->KuroTBL[i] = 0;
  55. else{
  56. int k;
  57. FLOATOBJ_SetLong(&f1, (i - B_LOW));
  58. FLOATOBJ_DivLong(&f1, (255 - B_LOW));
  59. f2 = f1;
  60. for(k=0; k<(B_GEN - 1); k++){
  61. FLOATOBJ_Mul(&f1, &f2);
  62. }
  63. FLOATOBJ_MulLong(&f1, 255);
  64. FLOATOBJ_MulLong(&f1, B_R);
  65. FLOATOBJ_DivLong(&f1, 100);
  66. FLOATOBJ_AddFloat(&f1,(FLOAT)0.5);
  67. lpnp->KuroTBL[i] = (unsigned char)FLOATOBJ_GetLong(&f1);
  68. }
  69. }
  70. // Create UcrTBL[] to reduce extracting black density from YMC
  71. for( i=0; i< 256; i++){
  72. if( i < B_LOW )
  73. lpnp->UcrTBL[i] = 0;
  74. else{
  75. FLOATOBJ_SetLong(&f1, (i - B_LOW));
  76. FLOATOBJ_MulLong(&f1, UCR);
  77. FLOATOBJ_DivLong(&f1, 100);
  78. lpnp->UcrTBL[i] = (unsigned char)FLOATOBJ_GetLong(&f1);
  79. }
  80. }
  81. lpnp->YellowUcr = (unsigned char)((unsigned int)(100 - YUCR) * 255 / 100);
  82. }
  83. return TRUE;
  84. }
  85. /*************************** Function Header *******************************
  86. * bInitialColorConvert
  87. *
  88. * Pre-processing of color conversion process.
  89. *
  90. * HISTORY:
  91. * 24 Jun 1996 -by- Sueya Sugihara [sueyas]
  92. * Created.
  93. *
  94. ***************************************************************************/
  95. BOOL bInitialColorConvert(
  96. PDEVOBJ pdevobj)
  97. {
  98. PCURRENTSTATUS lpnp;
  99. int i;
  100. BYTE *RedHosei;
  101. BYTE *GreenHosei;
  102. BYTE *BlueHosei;
  103. lpnp = (PCURRENTSTATUS)MINIDEV_DATA(pdevobj);
  104. // Color definitions.
  105. lpnp->RGB_Rx = 6400; // X value of Red 100% on monitor
  106. lpnp->RGB_Ry = 3300; // Y value of Red 100% on monitor
  107. lpnp->RGB_Gx = 2900; // X value of Green 100% on monitor
  108. lpnp->RGB_Gy = 6000; // Y value of Green 100% on monitor
  109. lpnp->RGB_Bx = 1500; // X value of Blue 100% on monitor
  110. lpnp->RGB_By = 600; // Y value of Blue 100% on monitor
  111. lpnp->RGB_Wx = 3127; // X value of White 100% on monitor
  112. lpnp->RGB_Wy = 3290; // Y value of White 100% on monitor
  113. lpnp->CMY_Cx = 1726; // X value of Cyan 100% on ribbon
  114. lpnp->CMY_Cy = 2248; // Y value of Cyan 100% on ribbon
  115. lpnp->CMY_Mx = 3923; // X value of Magenta 100% on ribbon
  116. lpnp->CMY_My = 2295; // Y value of Magenta 100% on ribbon
  117. lpnp->CMY_Yx = 4600; // X value of Yellow 100% on ribbon
  118. lpnp->CMY_Yy = 4600; // Y value of Yellow 100% on ribbon
  119. lpnp->CMY_Rx = 6000; // X value of Red (MY) 100% on ribbon
  120. lpnp->CMY_Ry = 3200; // Y value of Red (MY) 100% on ribbon
  121. lpnp->CMY_Gx = 2362; // X value of Green (CY) 100% on ribbon
  122. lpnp->CMY_Gy = 5024; // Y value of Green (CY) 100% on ribbon
  123. lpnp->CMY_Bx = 2121; // X value of Blue (CM) 100% on ribbon
  124. lpnp->CMY_By = 1552; // Y value of Blue (CM) 100% on ribbon
  125. lpnp->CMY_Wx = 3148; // X value of White on paper
  126. lpnp->CMY_Wy = 3317; // Y value of White on paper
  127. lpnp->RedAdj = 0; // Param for density adjust
  128. lpnp->RedStart = 0; // Position of start for density adjust
  129. lpnp->GreenAdj = 400; // Param for density adjust
  130. lpnp->GreenStart = 50; // Position of start for density adjust
  131. lpnp->BlueAdj = 0; // Param for density adjust
  132. lpnp->BlueStart = 0; // Position of start for density adjust
  133. // Calculation of density adjustment table.
  134. RedHosei = lpnp->RedHosei;
  135. GreenHosei = lpnp->GreenHosei;
  136. BlueHosei = lpnp->BlueHosei;
  137. for(i = 0; i < 256; i ++){
  138. RedHosei[i] = GreenHosei[i] = BlueHosei[i] = 0;
  139. }
  140. if( lpnp->RedAdj != 0 ){
  141. for(i = lpnp->RedStart; i < 255; i++)
  142. RedHosei[i] = (unsigned char)((255 - i) * (i - lpnp->RedStart) / lpnp->RedAdj);
  143. }
  144. if( lpnp->GreenAdj != 0 ){
  145. for(i = lpnp->GreenStart; i < 255; i++)
  146. GreenHosei[i] = (unsigned char)((255 - i) * (i - lpnp->GreenStart) / lpnp->GreenAdj);
  147. }
  148. if( lpnp->BlueAdj != 0 ){
  149. for(i = lpnp->BlueStart; i < 255; i++)
  150. BlueHosei[i] = (unsigned char)((255 - i) * (i - lpnp->BlueStart) / lpnp->BlueAdj);
  151. }
  152. // Calculation of color definition data.
  153. lpnp->RGB_Rx -= lpnp->RGB_Wx; lpnp->RGB_Ry -= lpnp->RGB_Wy;
  154. lpnp->RGB_Gx -= lpnp->RGB_Wx; lpnp->RGB_Gy -= lpnp->RGB_Wy;
  155. lpnp->RGB_Bx -= lpnp->RGB_Wx; lpnp->RGB_By -= lpnp->RGB_Wy;
  156. lpnp->RGB_Cx = ( lpnp->RGB_Gx - lpnp->RGB_Bx ) / 2 + lpnp->RGB_Bx;
  157. lpnp->RGB_Cy = ( lpnp->RGB_Gy - lpnp->RGB_By ) / 2 + lpnp->RGB_By;
  158. lpnp->RGB_Mx = ( lpnp->RGB_Rx - lpnp->RGB_Bx ) / 2 + lpnp->RGB_Bx;
  159. lpnp->RGB_My = ( lpnp->RGB_Ry - lpnp->RGB_By ) / 2 + lpnp->RGB_By;
  160. lpnp->RGB_Yx = ( lpnp->RGB_Rx - lpnp->RGB_Gx ) / 2 + lpnp->RGB_Gx;
  161. lpnp->RGB_Yy = ( lpnp->RGB_Ry - lpnp->RGB_Gy ) / 2 + lpnp->RGB_Gy;
  162. lpnp->CMY_Cx -= lpnp->CMY_Wx; lpnp->CMY_Cy -= lpnp->CMY_Wy;
  163. lpnp->CMY_Mx -= lpnp->CMY_Wx; lpnp->CMY_My -= lpnp->CMY_Wy;
  164. lpnp->CMY_Yx -= lpnp->CMY_Wx; lpnp->CMY_Yy -= lpnp->CMY_Wy;
  165. lpnp->CMY_Rx -= lpnp->CMY_Wx; lpnp->CMY_Ry -= lpnp->CMY_Wy;
  166. lpnp->CMY_Gx -= lpnp->CMY_Wx; lpnp->CMY_Gy -= lpnp->CMY_Wy;
  167. lpnp->CMY_Bx -= lpnp->CMY_Wx; lpnp->CMY_By -= lpnp->CMY_Wy;
  168. // Calculation of data for color dimension judgement
  169. lpnp->CMY_Cd = Calc_degree( lpnp->CMY_Cx, lpnp->CMY_Cy );
  170. lpnp->CMY_Md = Calc_degree( lpnp->CMY_Mx, lpnp->CMY_My );
  171. lpnp->CMY_Yd = Calc_degree( lpnp->CMY_Yx, lpnp->CMY_Yy );
  172. lpnp->CMY_Rd = Calc_degree( lpnp->CMY_Rx, lpnp->CMY_Ry );
  173. lpnp->CMY_Gd = Calc_degree( lpnp->CMY_Gx, lpnp->CMY_Gy );
  174. lpnp->CMY_Bd = Calc_degree( lpnp->CMY_Bx, lpnp->CMY_By );
  175. return TRUE;
  176. }
  177. int Calc_degree( int x, int y)
  178. {
  179. register int val;
  180. if( x == 0 ){
  181. if( y == 0 )
  182. val = 0;
  183. else if( y > 0 )
  184. val = 30000;
  185. else
  186. val = -30000;
  187. }else{
  188. val = y / x;
  189. if( val > 300 )
  190. val = 30000;
  191. else if( val < -300 )
  192. val = -30000;
  193. else
  194. val = (y * 100) / x;
  195. }
  196. return val;
  197. }
  198. // bOHPConvert() - No longer used.
  199. /*************************** Function Header *******************************
  200. * bPhotoConvert
  201. *
  202. * Convert RGB to CMYK for photo graphics.
  203. *
  204. *
  205. * HISTORY:
  206. * 24 Jun 1996 -by- Sueya Sugihara [sueyas]
  207. * Created.
  208. *
  209. ***************************************************************************/
  210. BOOL bPhotoConvert(
  211. PDEVOBJ pdevobj,
  212. BYTE bRed,
  213. BYTE bGreen,
  214. BYTE bBlue,
  215. BYTE *ppy,
  216. BYTE *ppm,
  217. BYTE *ppc,
  218. BYTE *ppk)
  219. {
  220. int k, w, pk, r, g, b;
  221. int Est_x, Est_y;
  222. int p1, p2;
  223. int deg, area;
  224. register int val_a, val_b, val_c, val_d;
  225. register int val1, val2;
  226. BYTE hosei;
  227. int py, pm, pc;
  228. int wx, wy;
  229. PCURRENTSTATUS lpnp;
  230. lpnp = (PCURRENTSTATUS)MINIDEV_DATA(pdevobj);
  231. k = max( bRed, bGreen );
  232. k = max( k, bBlue );
  233. // Set black element
  234. pk = 255 - k;
  235. w = min( bRed, bGreen );
  236. w = min( w, bBlue );
  237. // Cut white element from each color
  238. r = bRed - w;
  239. g = bGreen - w;
  240. b = bBlue - w;
  241. // Get estimation for Est_x and Est_y
  242. if( r == 0 ){ // G->C->B
  243. if(( g == 0 ) && ( b == 0 )){ // no color
  244. Est_x = 0;
  245. Est_y = 0;
  246. }
  247. else if( g >= b ){ // G->C dimension
  248. p1 = (lpnp->RGB_Gx * g) / 255;
  249. p2 = (lpnp->RGB_Cx * g) / 255;
  250. Est_x = ((p2 - p1) * b) / g + p1;
  251. p1 = (lpnp->RGB_Gy * g) / 255;
  252. p2 = (lpnp->RGB_Cy * g) / 255;
  253. Est_y = ((p2 - p1) * b) / g + p1;
  254. }
  255. else { // B->C dimension
  256. p1 = (lpnp->RGB_Bx * b) / 255;
  257. p2 = (lpnp->RGB_Cx * b) / 255;
  258. Est_x = ((p2 - p1) * g) / b + p1;
  259. p1 = (lpnp->RGB_By * b) / 255;
  260. p2 = (lpnp->RGB_Cy * b) / 255;
  261. Est_y = ((p2 - p1) * g) / b + p1;
  262. }
  263. }
  264. else if( g == 0 ){ // B->M->R
  265. if( b >= r ){ // B->M dimension
  266. p1 = (lpnp->RGB_Bx * b) / 255;
  267. p2 = (lpnp->RGB_Mx * b) / 255;
  268. Est_x = ((p2 - p1) * r) / b + p1;
  269. p1 = (lpnp->RGB_By * b) / 255;
  270. p2 = (lpnp->RGB_My * b) / 255;
  271. Est_y = ((p2 - p1) * r) / b + p1;
  272. }
  273. else{ // R->M dimension
  274. p1 = (lpnp->RGB_Rx * r) / 255;
  275. p2 = (lpnp->RGB_Mx * r) / 255;
  276. Est_x = ((p2 - p1) * b) / r + p1;
  277. p1 = (lpnp->RGB_Ry * r) / 255;
  278. p2 = (lpnp->RGB_My * r) / 255;
  279. Est_y = ((p2 - p1) * b) / r + p1;
  280. }
  281. }
  282. else{ // G->Y->R
  283. if( g >= r ){ // G->Y dimension
  284. p1 = (lpnp->RGB_Gx * g) / 255;
  285. p2 = (lpnp->RGB_Yx * g) / 255;
  286. Est_x = ((p2 - p1) * r) / g + p1;
  287. p1 = (lpnp->RGB_Gy * g) / 255;
  288. p2 = (lpnp->RGB_Yy * g) / 255;
  289. Est_y = ((p2 - p1) * r) / g + p1;
  290. }
  291. else{ // R->Y dimension
  292. p1 = (lpnp->RGB_Rx * r) / 255;
  293. p2 = (lpnp->RGB_Yx * r) / 255;
  294. Est_x = ((p2 - p1) * g) / r + p1;
  295. p1 = (lpnp->RGB_Ry * r) / 255;
  296. p2 = (lpnp->RGB_Yy * r) / 255;
  297. Est_y = ((p2 - p1) * g) / r + p1;
  298. }
  299. }
  300. // Convert origin of Est_x and Est_y to paper color
  301. wx = lpnp->RGB_Wx ? lpnp->RGB_Wx : 1;
  302. wy = lpnp->RGB_Wy ? lpnp->RGB_Wy : 1;
  303. Est_x += lpnp->RGB_Wx;
  304. Est_y += lpnp->RGB_Wy;
  305. Est_x = Est_x * lpnp->CMY_Wx / wx;
  306. Est_y = Est_y * lpnp->CMY_Wy / wy;
  307. Est_x -= lpnp->CMY_Wx;
  308. Est_y -= lpnp->CMY_Wy;
  309. pc = pm = py = 0;
  310. if( !((Est_x == 0) && (Est_y == 0)) ){
  311. // Get deg on CMY color dimension from Est_x and Est_y
  312. if( Est_x == 0 ){
  313. if( Est_y > 0 )
  314. deg = 30000;
  315. else
  316. deg = -30000;
  317. }
  318. else{
  319. deg = Est_y / Est_x;
  320. if( deg > 300 )
  321. deg = 30000;
  322. else if( deg < -300 )
  323. deg = -30000;
  324. else
  325. deg = ( Est_y * 100 ) / Est_x;
  326. }
  327. if( Est_x >= 0 ){
  328. if( deg <= lpnp->CMY_Md ) // M->B dimension
  329. area = 1;
  330. else if( deg <= lpnp->CMY_Rd ) // M->R dimension
  331. area = 2;
  332. else if( deg <= lpnp->CMY_Yd ) // Y->R dimension
  333. area = 3;
  334. else // Y->G dimension
  335. area = 4;
  336. }
  337. else{
  338. if( deg <= lpnp->CMY_Gd ) // Y->G dimension
  339. area = 4;
  340. else if( deg <= lpnp->CMY_Cd ) // C->G dimension
  341. area = 5;
  342. else if( deg <= lpnp->CMY_Bd ) // C->B dimension
  343. area = 6;
  344. else // M->B dimension
  345. area = 1;
  346. }
  347. switch ( area ){
  348. case 1: // M->B dimension
  349. val_a = lpnp->CMY_Bx - lpnp->CMY_Mx;
  350. val_b = lpnp->CMY_By - lpnp->CMY_My;
  351. val_c = lpnp->CMY_Mx;
  352. val_d = lpnp->CMY_My;
  353. val1 = val_b * val_c - val_a * val_d;
  354. val2 = ( val_b * Est_x - val_a * Est_y ) * 255;
  355. val1 = val1 ? val1 : 1;
  356. pm = val2 / val1;
  357. if( pm < 0 )
  358. pm = 0;
  359. val1 = val_a * val_d - val_b * val_c;
  360. val2 = ( val_d * Est_x - val_c * Est_y ) * 255;
  361. val1 = val1 ? val1 : 1;
  362. pc = val2 / val1;
  363. if( pc < 0 )
  364. pc = 0;
  365. if( pc > 255 )
  366. pc = 255;
  367. hosei = lpnp->BlueHosei[pc];
  368. pc += hosei;
  369. pm += hosei;
  370. if( pc > 255 )
  371. pc = 255;
  372. if( pm > 255 )
  373. pm = 255;
  374. break;
  375. case 2: // M->R dimension
  376. val_a = lpnp->CMY_Rx - lpnp->CMY_Mx;
  377. val_b = lpnp->CMY_Ry - lpnp->CMY_My;
  378. val_c = lpnp->CMY_Mx;
  379. val_d = lpnp->CMY_My;
  380. val1 = val_b * val_c - val_a * val_d;
  381. val2 = ( val_b * Est_x - val_a * Est_y ) * 255;
  382. val1 = val1 ? val1 : 1;
  383. pm = val2 / val1;
  384. if( pm < 0 )
  385. pm = 0;
  386. val1 = val_a * val_d - val_b * val_c;
  387. val2 = ( val_d * Est_x - val_c * Est_y ) * 255;
  388. val1 = val1 ? val1 : 1;
  389. py = val2 / val1;
  390. if( py < 0 )
  391. py = 0;
  392. if( py > 255 )
  393. py = 255;
  394. hosei = lpnp->RedHosei[py];
  395. py += hosei;
  396. pm += hosei;
  397. if( pm > 255 )
  398. pm = 255;
  399. if( py > 255 )
  400. py = 255;
  401. break;
  402. case 3: // Y->R dimension
  403. val_a = lpnp->CMY_Rx - lpnp->CMY_Yx;
  404. val_b = lpnp->CMY_Ry - lpnp->CMY_Yy;
  405. val_c = lpnp->CMY_Yx;
  406. val_d = lpnp->CMY_Yy;
  407. val1 = val_b * val_c - val_a * val_d;
  408. val2 = ( val_b * Est_x - val_a * Est_y ) * 255;
  409. val1 = val1 ? val1 : 1;
  410. py = val2 / val1;
  411. if( py < 0 )
  412. py = 0;
  413. val1 = val_a * val_d - val_b * val_c;
  414. val2 = ( val_d * Est_x - val_c * Est_y ) * 255;
  415. val1 = val1 ? val1 : 1;
  416. pm = val2 / val1;
  417. if( pm < 0 )
  418. pm = 0;
  419. if( pm > 255 )
  420. pm = 255;
  421. hosei = lpnp->RedHosei[pm];
  422. py += hosei;
  423. pm += hosei;
  424. if( pm > 255 )
  425. pm = 255;
  426. if( py > 255 )
  427. py = 255;
  428. break;
  429. case 4: // Y->G dimension
  430. val_a = lpnp->CMY_Gx - lpnp->CMY_Yx;
  431. val_b = lpnp->CMY_Gy - lpnp->CMY_Yy;
  432. val_c = lpnp->CMY_Yx;
  433. val_d = lpnp->CMY_Yy;
  434. val1 = val_b * val_c - val_a * val_d;
  435. val2 = ( val_b * Est_x - val_a * Est_y ) * 255;
  436. val1 = val1 ? val1 : 1;
  437. py = val2 / val1;
  438. if( py < 0 )
  439. py = 0;
  440. val1 = val_a * val_d - val_b * val_c;
  441. val2 = ( val_d * Est_x - val_c * Est_y ) * 255;
  442. val1 = val1 ? val1 : 1;
  443. pc = val2 / val1;
  444. if( pc < 0 )
  445. pc = 0;
  446. if( pc > 255 )
  447. pc = 255;
  448. hosei = lpnp->GreenHosei[pc];
  449. py += hosei;
  450. pc += hosei;
  451. if( pc > 255 )
  452. pc = 255;
  453. if( py > 255 )
  454. py = 255;
  455. break;
  456. case 5: // C->G dimension
  457. val_a = lpnp->CMY_Gx - lpnp->CMY_Cx;
  458. val_b = lpnp->CMY_Gy - lpnp->CMY_Cy;
  459. val_c = lpnp->CMY_Cx;
  460. val_d = lpnp->CMY_Cy;
  461. val1 = val_b * val_c - val_a * val_d;
  462. val2 = ( val_b * Est_x - val_a * Est_y ) * 255;
  463. val1 = val1 ? val1 : 1;
  464. pc = val2 / val1;
  465. if( pc < 0 )
  466. pc = 0;
  467. val1 = val_a * val_d - val_b * val_c;
  468. val2 = ( val_d * Est_x - val_c * Est_y ) * 255;
  469. val1 = val1 ? val1 : 1;
  470. py = val2 / val1;
  471. if( py < 0 )
  472. py = 0;
  473. if( py > 255 )
  474. py = 255;
  475. // Dwnsity adjustment for green
  476. hosei = lpnp->GreenHosei[py];
  477. py += hosei;
  478. pc += hosei;
  479. if( pc > 255 )
  480. pc = 255;
  481. if( py > 255 )
  482. py = 255;
  483. break;
  484. case 6: // C->B dimension
  485. val_a = lpnp->CMY_Bx - lpnp->CMY_Cx;
  486. val_b = lpnp->CMY_By - lpnp->CMY_Cy;
  487. val_c = lpnp->CMY_Cx;
  488. val_d = lpnp->CMY_Cy;
  489. val1 = val_b * val_c - val_a * val_d;
  490. val2 = ( val_b * Est_x - val_a * Est_y ) * 255;
  491. val1 = val1 ? val1 : 1;
  492. pc = val2 / val1;
  493. if( pc < 0 )
  494. pc = 0;
  495. val1 = val_a * val_d - val_b * val_c;
  496. val2 = ( val_d * Est_x - val_c * Est_y ) * 255;
  497. val1 = val1 ? val1 : 1;
  498. pm = val2 / val1;
  499. if( pm < 0 )
  500. pm = 0;
  501. if( pm > 255 )
  502. pm = 255;
  503. hosei = lpnp->BlueHosei[pm];
  504. pc += hosei;
  505. pm += hosei;
  506. if( pc > 255 )
  507. pc = 255;
  508. if( pm > 255 )
  509. pm = 255;
  510. } // switch area
  511. }
  512. // Add pk to color
  513. k = pc;
  514. if( k < pm )
  515. k = pm;
  516. if( k < py )
  517. k = py;
  518. r = ( pk + k > 255) ? 255 - k : pk;
  519. pk -= r;
  520. pc += r;
  521. pm += r;
  522. py += r;
  523. // Extract K and adjust to other color for its extracting value
  524. if (bPlaneSendOrderCMYK(lpnp)) {
  525. int min_p;
  526. BYTE ucr_sub, ucr_div;
  527. min_p = min( py, pm );
  528. min_p = min( min_p, pc );
  529. #ifdef BLACK_RIBBON_HACK
  530. if( min_p == 255 ){
  531. pk = 255;
  532. pc = pm = py = 0;
  533. }
  534. else{
  535. #endif // BLACK_RIBBOM_HACK
  536. pk += lpnp->KuroTBL[min_p];
  537. pk = ( pk > 255 ) ? 255 : pk;
  538. ucr_sub = lpnp->UcrTBL[min_p];
  539. ucr_div = 255 - ucr_sub;
  540. ucr_div = ucr_div ? ucr_div : 1;
  541. py = (BYTE)((UINT)(py - ucr_sub) * lpnp->YellowUcr / ucr_div);
  542. pm = (BYTE)((UINT)(pm - ucr_sub) * 255 / ucr_div);
  543. pc = (BYTE)((UINT)(pc - ucr_sub) * 255 / ucr_div);
  544. #ifdef BLACK_RIBBON_HACK
  545. }
  546. #endif // BLACK_RIBBON_HACK
  547. }
  548. py = 255 - py;
  549. pm = 255 - pm;
  550. pc = 255 - pc;
  551. pk = 255 - pk;
  552. *ppy = (BYTE)py;
  553. *ppm = (BYTE)pm;
  554. *ppc = (BYTE)pc;
  555. *ppk = (BYTE)pk;
  556. return TRUE;
  557. }
  558. /*************************** Function Header *******************************
  559. * bBusinessConvert
  560. *
  561. * Convert RGB to CMYK for business graphics.
  562. *
  563. *
  564. * HISTORY:
  565. * 24 Jun 1996 -by- Sueya Sugihara [sueyas]
  566. * Created.
  567. *
  568. ***************************************************************************/
  569. BOOL bBusinessConvert(
  570. PDEVOBJ pdevobj,
  571. BYTE bRed,
  572. BYTE bGreen,
  573. BYTE bBlue,
  574. BYTE *ppy,
  575. BYTE *ppm,
  576. BYTE *ppc,
  577. BYTE *ppk)
  578. {
  579. int py, pm, pc, pk;
  580. int min_p;
  581. BYTE ucr_sub, ucr_div;
  582. PCURRENTSTATUS lpnp;
  583. lpnp = (PCURRENTSTATUS)MINIDEV_DATA(pdevobj);
  584. // Simple convert RGB to CMY
  585. py = 255 - bBlue;
  586. pm = 255 - bGreen;
  587. pc = 255 - bRed;
  588. pk = 0;
  589. // Extract K and adjust to other color for its extracting value
  590. // Extract pk from py, pm and pc by using followings, and erase black element.
  591. // When this media is 3 plane type, we do not extract black.
  592. if (bPlaneSendOrderCMYK(lpnp)) {
  593. min_p = min( py, pm );
  594. min_p = min( min_p, pc );
  595. #ifdef BLACK_RIBBON_HACK
  596. if( min_p == 255 ){
  597. pk = 255;
  598. pc = pm = py = 0;
  599. }
  600. else{
  601. #endif // BLACK_RIBBON_HACK
  602. pk = lpnp->KuroTBL[min_p];
  603. ucr_sub = lpnp->UcrTBL[min_p];
  604. ucr_div = 255 - ucr_sub;
  605. ucr_div = ucr_div ? ucr_div : 1;
  606. py = (BYTE)((UINT)(py - ucr_sub) * lpnp->YellowUcr / ucr_div);
  607. pm = (BYTE)((UINT)(pm - ucr_sub) * 255 / ucr_div);
  608. pc = (BYTE)((UINT)(pc - ucr_sub) * 255 / ucr_div);
  609. #ifdef BLACK_RIBBON_HACK
  610. }
  611. #endif // BLACK_RIBBON_HACK
  612. }
  613. py = 255 - py;
  614. pm = 255 - pm;
  615. pc = 255 - pc;
  616. pk = 255 - pk;
  617. *ppy = (BYTE)py;
  618. *ppm = (BYTE)pm;
  619. *ppc = (BYTE)pc;
  620. *ppk = (BYTE)pk;
  621. return TRUE;
  622. }
  623. /*************************** Function Header *******************************
  624. * bCharacterConvert
  625. *
  626. * Convert RGB to CMYK for character graphics.
  627. *
  628. *
  629. * HISTORY:
  630. * 24 Jun 1996 -by- Sueya Sugihara [sueyas]
  631. * Created.
  632. *
  633. ***************************************************************************/
  634. BOOL bCharacterConvert(
  635. PDEVOBJ pdevobj,
  636. BYTE bRed,
  637. BYTE bGreen,
  638. BYTE bBlue,
  639. BYTE *ppy,
  640. BYTE *ppm,
  641. BYTE *ppc,
  642. BYTE *ppk)
  643. {
  644. int py, pm, pc, pk;
  645. int min_p;
  646. BYTE ucr_sub, ucr_div;
  647. PCURRENTSTATUS lpnp;
  648. lpnp = (PCURRENTSTATUS)MINIDEV_DATA(pdevobj);
  649. // Simple convert RGB to CMY
  650. py = 255 - bBlue;
  651. pm = 255 - bGreen;
  652. pc = 255 - bRed;
  653. pk = 0;
  654. // Extract K and adjust to other color for its extracting value
  655. // Extract pk from py, pm and pc by using followings, and erase black element.
  656. // When this media is 3 plane type, we do not extract black.
  657. if (bPlaneSendOrderCMYK(lpnp)) {
  658. min_p = min( py, pm );
  659. min_p = min( min_p, pc );
  660. if( min_p == 255 ){
  661. pk = 255;
  662. pc = pm = py = 0;
  663. }
  664. else{
  665. pk = lpnp->KuroTBL[min_p];
  666. ucr_sub = lpnp->UcrTBL[min_p];
  667. ucr_div = 255 - ucr_sub;
  668. ucr_div = ucr_div ? ucr_div : 1;
  669. py = (BYTE)((UINT)(py - ucr_sub) * lpnp->YellowUcr / ucr_div);
  670. pm = (BYTE)((UINT)(pm - ucr_sub) * 255 / ucr_div);
  671. pc = (BYTE)((UINT)(pc - ucr_sub) * 255 / ucr_div);
  672. }
  673. }
  674. py = 255 - py;
  675. pm = 255 - pm;
  676. pc = 255 - pc;
  677. pk = 255 - pk;
  678. *ppy = (BYTE)py;
  679. *ppm = (BYTE)pm;
  680. *ppc = (BYTE)pc;
  681. *ppk = (BYTE)pk;
  682. return TRUE;
  683. }
  684. /*************************** Function Header *******************************
  685. * bMonoConvert
  686. *
  687. * Convert RGB to Grayscale.
  688. *
  689. *
  690. * HISTORY:
  691. * 24 Jun 1996 -by- Sueya Sugihara [sueyas]
  692. * Created.
  693. *
  694. ***************************************************************************/
  695. BOOL bMonoConvert(
  696. PDEVOBJ pdevobj,
  697. BYTE bRed,
  698. BYTE bGreen,
  699. BYTE bBlue,
  700. BYTE *ppk)
  701. {
  702. int mono;
  703. mono = ( 30 * bRed + 59 * bGreen + 11 * bBlue ) / 100;
  704. *ppk = 0xff - (BYTE)( mono & 0xff );
  705. return TRUE;
  706. }
  707. /*************************** Function Header *******************************
  708. * cVDColorDither
  709. *
  710. * VD Color Dither processing
  711. *
  712. *
  713. * HISTORY:
  714. * 11 Jan 1999 -by- Yoshitaka Oku [yoshitao]
  715. * Created.
  716. *
  717. * BYTE Color : Plane Color <Yellow, Cyan, Magenta, Black>
  718. * BYTE c : oliginal tone of the pixel
  719. * int x : X position of the pixel
  720. * int y : Y position of the pixel
  721. *
  722. ***************************************************************************/
  723. cVDColorDither(
  724. BYTE Color,
  725. BYTE c,
  726. int x,
  727. int y)
  728. {
  729. int m, n;
  730. short Base;
  731. BYTE Tone;
  732. BYTE C_Thresh, Thresh;
  733. short AdjustedColor;
  734. BYTE TempTone;
  735. BYTE BaseTone;
  736. switch (Color) {
  737. case Yellow:
  738. Base = 112;
  739. m = n = 12;
  740. break;
  741. case Cyan:
  742. case Magenta:
  743. Base = 208;
  744. m = n = 40;
  745. break;
  746. case Black:
  747. Base = 96;
  748. m = n = 24;
  749. break;
  750. default:
  751. Color = Black;
  752. Base = 96;
  753. m = n = 24;
  754. break;
  755. }
  756. Tone = 0; /* Clear Tone value */
  757. c = VD_ColorAdjustTable[Color][c]; /* Convert orignal color */
  758. if (c != 0) {
  759. C_Thresh = (VD_DitherTable[Color][y % m][x % n]);
  760. if ( C_Thresh < 16 )
  761. Thresh = 1;
  762. else {
  763. C_Thresh -= 16;
  764. Thresh = (C_Thresh >> 2) + 1;
  765. }
  766. AdjustedColor = VD_ExpandValueTable[Color][c] - 1;
  767. if ( AdjustedColor < Base )
  768. TempTone = ( AdjustedColor >> 4 ) + 1;
  769. else {
  770. AdjustedColor -= Base;
  771. TempTone = ( AdjustedColor >> 2 ) + ( Base >> 4 ) + 1;
  772. }
  773. if (TempTone >= 232) TempTone = 232-1;
  774. BaseTone = VD_ToneOptimaizeTable[Color][TempTone].base;
  775. if ( BaseTone > Thresh ) {
  776. Tone = 15;
  777. } else {
  778. if ( BaseTone == Thresh ) {
  779. if ( BaseTone == 1 ) {
  780. if (( AdjustedColor & 0x0f ) >= C_Thresh )
  781. Tone = VD_ToneOptimaizeTable[Color][(( AdjustedColor >> 4) & 0x0f )+ 1 ].offset;
  782. else
  783. Tone = VD_ToneOptimaizeTable[Color][( AdjustedColor >> 4) & 0x0f ].offset ;
  784. } else {
  785. if ((AdjustedColor & 0x03) >= (C_Thresh & 0x03))
  786. Tone = VD_ToneOptimaizeTable[Color][TempTone].offset;
  787. else {
  788. if (TempTone < 1) TempTone = 1;
  789. if (VD_ToneOptimaizeTable[Color][TempTone -1].base == BaseTone)
  790. Tone = VD_ToneOptimaizeTable[Color][TempTone -1].offset;
  791. }
  792. }
  793. }
  794. }
  795. }
  796. return (Tone);
  797. }
  798. /*************************** Function Header *******************************
  799. * bDitherProcess
  800. *
  801. * Dither processing
  802. *
  803. *
  804. * HISTORY:
  805. * 24 Jun 1996 -by- Sueya Sugihara [sueyas]
  806. * Created.
  807. *
  808. ***************************************************************************/
  809. BOOL bDitherProcess(
  810. PDEVOBJ pdevobj,
  811. int x,
  812. BYTE py,
  813. BYTE pm,
  814. BYTE pc,
  815. BYTE pk,
  816. BYTE *pby,
  817. BYTE *pbm,
  818. BYTE *pbc,
  819. BYTE *pbk)
  820. {
  821. PCURRENTSTATUS lpnp;
  822. BYTE rm;
  823. lpnp = (PCURRENTSTATUS)MINIDEV_DATA(pdevobj);
  824. if( lpnp->iDither == DITHER_VD ){
  825. // Yellow
  826. *pby = (BYTE)cVDColorDither(Yellow, (BYTE)(255 - py), x, lpnp->y);
  827. // Magenta
  828. *pbm = (BYTE)cVDColorDither(Magenta, (BYTE)(255 - pm), x, lpnp->y);
  829. // Cyan
  830. *pbc = (BYTE)cVDColorDither(Cyan, (BYTE)(255 - pc), x, lpnp->y);
  831. // Black
  832. *pbk = (BYTE)cVDColorDither(Black, (BYTE)(255 - pk), x, lpnp->y);
  833. }else if( lpnp->iDither == DITHER_DYE ){
  834. rm = DYE_NewTable[lpnp->y % DYE_MaxY][x % DYE_MaxX];
  835. // Yellow
  836. *pby = ( (255 - py) / kToneLevel ) + ( ( ( (255 - py) % kToneLevel ) > rm ) ? 1 : 0 );
  837. // Magenta
  838. *pbm = ( (255 - pm) / kToneLevel ) + ( ( ( (255 - pm) % kToneLevel ) > rm ) ? 1 : 0 );
  839. // Cyan
  840. *pbc = ( (255 - pc) / kToneLevel ) + ( ( ( (255 - pc) % kToneLevel ) > rm ) ? 1 : 0 );
  841. // Black
  842. *pbk = 0;
  843. }else if( lpnp->iDither == DITHER_HIGH ){
  844. // Yellow
  845. rm = H_NewTable[Yellow][lpnp->y % H_MaxY[Yellow]][x % H_MaxX[Yellow]];
  846. *pby = ( py <= rm ) ? 1 : 0;
  847. // Magenta
  848. rm = H_NewTable[Magenta][lpnp->y % H_MaxY[Magenta]][x % H_MaxX[Magenta]];
  849. *pbm = ( pm <= rm ) ? 1 : 0;
  850. // Cyan
  851. rm = H_NewTable[Cyan][lpnp->y % H_MaxY[Cyan]][x % H_MaxX[Cyan]];
  852. *pbc = ( pc <= rm ) ? 1 : 0;
  853. // Black
  854. rm = H_NewTable[Black][lpnp->y % H_MaxY[Black]][x % H_MaxX[Black]];
  855. if( lpnp->iTextQuality == CMDID_TEXTQUALITY_PHOTO )
  856. *pbk = ( pk < rm ) ? 1 : 0;
  857. else
  858. *pbk = ( pk <= rm ) ? 1 : 0;
  859. }else if( lpnp->iDither == DITHER_LOW ){
  860. // Yellow
  861. rm = L_NewTable[Yellow][lpnp->y % L_MaxY[Yellow]][x % L_MaxX[Yellow]];
  862. *pby = ( py <= rm ) ? 1 : 0;
  863. // Magenta
  864. rm = L_NewTable[Magenta][lpnp->y % L_MaxY[Magenta]][x % L_MaxX[Magenta]];
  865. *pbm = ( pm <= rm ) ? 1 : 0;
  866. // Cyan
  867. rm = L_NewTable[Cyan][lpnp->y % L_MaxY[Cyan]][x % L_MaxX[Cyan]];
  868. *pbc = ( pc <= rm ) ? 1 : 0;
  869. // Black
  870. rm = L_NewTable[Black][lpnp->y % L_MaxY[Black]][x % L_MaxX[Black]];
  871. if( lpnp->iTextQuality == CMDID_TEXTQUALITY_PHOTO )
  872. *pbk = ( pk < rm ) ? 1 : 0;
  873. else
  874. *pbk = ( pk <= rm ) ? 1 : 0;
  875. }else{ // DITHER_HIGH_DIV2
  876. // Yellow
  877. rm = H_NewTable[Yellow][(lpnp->y/2) % H_MaxY[Yellow]][(x/2) % H_MaxX[Yellow]];
  878. *pby = ( py <= rm ) ? 1 : 0;
  879. // Magenta
  880. rm = H_NewTable[Magenta][(lpnp->y/2) % H_MaxY[Magenta]][(x/2) % H_MaxX[Magenta]];
  881. *pbm = ( pm <= rm ) ? 1 : 0;
  882. // Cyan
  883. rm = H_NewTable[Cyan][(lpnp->y/2) % H_MaxY[Cyan]][(x/2) % H_MaxX[Cyan]];
  884. *pbc = ( pc <= rm ) ? 1 : 0;
  885. // Black
  886. rm = H_NewTable[Black][(lpnp->y/2) % H_MaxY[Black]][(x/2) % H_MaxX[Black]];
  887. if( lpnp->iTextQuality == CMDID_TEXTQUALITY_PHOTO )
  888. *pbk = ( pk < rm ) ? 1 : 0;
  889. else
  890. *pbk = ( pk <= rm ) ? 1 : 0;
  891. }
  892. return TRUE;
  893. }