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.

494 lines
12 KiB

  1. //-----------------------------------------------------------------------------
  2. // FILE NAME : FUMH.C
  3. // FUNCTION : MH Compress and MH2 Compress
  4. // AUTHER : 1996.08.08 FPL)Y.YUTANI
  5. // NOTE : for Windows NT V4.0
  6. // MODIFY : Reduce data size Oct.31,1996 H.Ishida
  7. // MODIFY : for NT.50 MiniDriver Sep.3,1997 H.Ishida(FPL)
  8. //-----------------------------------------------------------------------------
  9. // COPYRIGHT(C) FUJITSU LIMITED 1996-1997
  10. #include <minidrv.h>
  11. #include "fuxl.h"
  12. #include "fumhdef.h"
  13. const
  14. CODETABLE
  15. WhiteMakeUpTable[] =
  16. {
  17. { 0xd800, 5 },
  18. { 0x9000, 5 },
  19. { 0x5c00, 6 },
  20. { 0x6e00, 7 },
  21. { 0x3600, 8 },
  22. { 0x3700, 8 },
  23. { 0x6400, 8 },
  24. { 0x6500, 8 },
  25. { 0x6800, 8 },
  26. { 0x6700, 8 },
  27. { 0x6600, 9 },
  28. { 0x6680, 9 },
  29. { 0x6900, 9 },
  30. { 0x6980, 9 },
  31. { 0x6a00, 9 },
  32. { 0x6a80, 9 },
  33. { 0x6b00, 9 },
  34. { 0x6b80, 9 },
  35. { 0x6c00, 9 },
  36. { 0x6c80, 9 },
  37. { 0x6d00, 9 },
  38. { 0x6d80, 9 },
  39. { 0x4c00, 9 },
  40. { 0x4c80, 9 },
  41. { 0x4d00, 9 },
  42. { 0x6000, 6 },
  43. { 0x4d80, 9 },
  44. { 0x0100, 11 },
  45. { 0x0180, 11 },
  46. { 0x01a0, 11 },
  47. { 0x0120, 12 },
  48. { 0x0130, 12 },
  49. { 0x0140, 12 },
  50. { 0x0150, 12 },
  51. { 0x0160, 12 },
  52. { 0x0170, 12 },
  53. { 0x01c0, 12 },
  54. { 0x01d0, 12 },
  55. { 0x01e0, 12 },
  56. { 0x01f0, 12 },
  57. { 0x3500, 8 },
  58. { 0x1c00, 6 },
  59. { 0x7000, 4 },
  60. { 0x8000, 4 },
  61. { 0xb000, 4 },
  62. { 0xc000, 4 },
  63. { 0xe000, 4 },
  64. { 0xf000, 4 },
  65. { 0x9800, 5 },
  66. { 0xa000, 5 },
  67. { 0x3800, 5 },
  68. { 0x4000, 5 },
  69. { 0x2000, 6 },
  70. { 0x0c00, 6 },
  71. { 0xd000, 6 },
  72. { 0xd400, 6 },
  73. { 0xa800, 6 },
  74. { 0xac00, 6 },
  75. { 0x4e00, 7 },
  76. { 0x1800, 7 },
  77. { 0x1000, 7 },
  78. { 0x2e00, 7 },
  79. { 0x0600, 7 },
  80. { 0x0800, 7 },
  81. };
  82. const
  83. CODETABLE
  84. WhiteTerminateTable[] =
  85. {
  86. { 0x3500, 8 },
  87. { 0x1c00, 6 },
  88. { 0x7000, 4 },
  89. { 0x8000, 4 },
  90. { 0xb000, 4 },
  91. { 0xc000, 4 },
  92. { 0xe000, 4 },
  93. { 0xf000, 4 },
  94. { 0x9800, 5 },
  95. { 0xa000, 5 },
  96. { 0x3800, 5 },
  97. { 0x4000, 5 },
  98. { 0x2000, 6 },
  99. { 0x0c00, 6 },
  100. { 0xd000, 6 },
  101. { 0xd400, 6 },
  102. { 0xa800, 6 },
  103. { 0xac00, 6 },
  104. { 0x4e00, 7 },
  105. { 0x1800, 7 },
  106. { 0x1000, 7 },
  107. { 0x2e00, 7 },
  108. { 0x0600, 7 },
  109. { 0x0800, 7 },
  110. { 0x5000, 7 },
  111. { 0x5600, 7 },
  112. { 0x2600, 7 },
  113. { 0x4800, 7 },
  114. { 0x3000, 7 },
  115. { 0x0200, 8 },
  116. { 0x0300, 8 },
  117. { 0x1a00, 8 },
  118. { 0x1b00, 8 },
  119. { 0x1200, 8 },
  120. { 0x1300, 8 },
  121. { 0x1400, 8 },
  122. { 0x1500, 8 },
  123. { 0x1600, 8 },
  124. { 0x1700, 8 },
  125. { 0x2800, 8 },
  126. { 0x2900, 8 },
  127. { 0x2a00, 8 },
  128. { 0x2b00, 8 },
  129. { 0x2c00, 8 },
  130. { 0x2d00, 8 },
  131. { 0x0400, 8 },
  132. { 0x0500, 8 },
  133. { 0x0a00, 8 },
  134. { 0x0b00, 8 },
  135. { 0x5200, 8 },
  136. { 0x5300, 8 },
  137. { 0x5400, 8 },
  138. { 0x5500, 8 },
  139. { 0x2400, 8 },
  140. { 0x2500, 8 },
  141. { 0x5800, 8 },
  142. { 0x5900, 8 },
  143. { 0x5a00, 8 },
  144. { 0x5b00, 8 },
  145. { 0x4a00, 8 },
  146. { 0x4b00, 8 },
  147. { 0x3200, 8 },
  148. { 0x3300, 8 },
  149. { 0x3400, 8 },
  150. };
  151. const
  152. CODETABLE
  153. BlackMakeUpTable[] =
  154. {
  155. { 0x03c0, 10 },
  156. { 0x0c80, 12 },
  157. { 0x0c90, 12 },
  158. { 0x05b0, 12 },
  159. { 0x0330, 12 },
  160. { 0x0340, 12 },
  161. { 0x0350, 12 },
  162. { 0x0360, 13 },
  163. { 0x0368, 13 },
  164. { 0x0250, 13 },
  165. { 0x0258, 13 },
  166. { 0x0260, 13 },
  167. { 0x0268, 13 },
  168. { 0x0390, 13 },
  169. { 0x0398, 13 },
  170. { 0x03a0, 13 },
  171. { 0x03a8, 13 },
  172. { 0x03b0, 13 },
  173. { 0x03b8, 13 },
  174. { 0x0290, 13 },
  175. { 0x0298, 13 },
  176. { 0x02a0, 13 },
  177. { 0x02a8, 13 },
  178. { 0x02d0, 13 },
  179. { 0x02d8, 13 },
  180. { 0x0320, 13 },
  181. { 0x0328, 13 },
  182. { 0x0100, 11 },
  183. { 0x0180, 11 },
  184. { 0x01a0, 11 },
  185. { 0x0120, 12 },
  186. { 0x0130, 12 },
  187. { 0x0140, 12 },
  188. { 0x0150, 12 },
  189. { 0x0160, 12 },
  190. { 0x0170, 12 },
  191. { 0x01c0, 12 },
  192. { 0x01d0, 12 },
  193. { 0x01e0, 12 },
  194. { 0x01f0, 12 },
  195. { 0x0dc0, 10 },
  196. { 0x4000, 3 },
  197. { 0xc000, 2 },
  198. { 0x8000, 2 },
  199. { 0x6000, 3 },
  200. { 0x3000, 4 },
  201. { 0x2000, 4 },
  202. { 0x1800, 5 },
  203. { 0x1400, 6 },
  204. { 0x1000, 6 },
  205. { 0x0800, 7 },
  206. { 0x0a00, 7 },
  207. { 0x0e00, 7 },
  208. { 0x0400, 8 },
  209. { 0x0700, 8 },
  210. { 0x0c00, 9 },
  211. { 0x05c0, 10 },
  212. { 0x0600, 10 },
  213. { 0x0200, 10 },
  214. { 0x0ce0, 11 },
  215. { 0x0d00, 11 },
  216. { 0x0d80, 11 },
  217. { 0x06e0, 11 },
  218. { 0x0500, 11 },
  219. };
  220. const
  221. CODETABLE
  222. BlackTerminateTable[] =
  223. {
  224. { 0x0dc0, 10 },
  225. { 0x4000, 3 },
  226. { 0xc000, 2 },
  227. { 0x8000, 2 },
  228. { 0x6000, 3 },
  229. { 0x3000, 4 },
  230. { 0x2000, 4 },
  231. { 0x1800, 5 },
  232. { 0x1400, 6 },
  233. { 0x1000, 6 },
  234. { 0x0800, 7 },
  235. { 0x0a00, 7 },
  236. { 0x0e00, 7 },
  237. { 0x0400, 8 },
  238. { 0x0700, 8 },
  239. { 0x0c00, 9 },
  240. { 0x05c0, 10 },
  241. { 0x0600, 10 },
  242. { 0x0200, 10 },
  243. { 0x0ce0, 11 },
  244. { 0x0d00, 11 },
  245. { 0x0d80, 11 },
  246. { 0x06e0, 11 },
  247. { 0x0500, 11 },
  248. { 0x02e0, 11 },
  249. { 0x0300, 11 },
  250. { 0x0ca0, 12 },
  251. { 0x0cb0, 12 },
  252. { 0x0cc0, 12 },
  253. { 0x0cd0, 12 },
  254. { 0x0680, 12 },
  255. { 0x0690, 12 },
  256. { 0x06a0, 12 },
  257. { 0x06b0, 12 },
  258. { 0x0d20, 12 },
  259. { 0x0d30, 12 },
  260. { 0x0d40, 12 },
  261. { 0x0d50, 12 },
  262. { 0x0d60, 12 },
  263. { 0x0d70, 12 },
  264. { 0x06c0, 12 },
  265. { 0x06d0, 12 },
  266. { 0x0da0, 12 },
  267. { 0x0db0, 12 },
  268. { 0x0540, 12 },
  269. { 0x0550, 12 },
  270. { 0x0560, 12 },
  271. { 0x0570, 12 },
  272. { 0x0640, 12 },
  273. { 0x0650, 12 },
  274. { 0x0520, 12 },
  275. { 0x0530, 12 },
  276. { 0x0240, 12 },
  277. { 0x0370, 12 },
  278. { 0x0380, 12 },
  279. { 0x0270, 12 },
  280. { 0x0280, 12 },
  281. { 0x0580, 12 },
  282. { 0x0590, 12 },
  283. { 0x02b0, 12 },
  284. { 0x02c0, 12 },
  285. { 0x05a0, 12 },
  286. { 0x0660, 12 },
  287. { 0x0670, 12 },
  288. };
  289. //-----------------------------------------------------------------------------
  290. // DWORD FjCountBits
  291. // BYTE *pTmp Pointer of sources area
  292. // DWORD cBitstmp Now bit number from top of sources area
  293. // DWORD cBitsMax Last bits number in this line
  294. // BOOL hWhite color flag
  295. // TRUE : counting white bits
  296. // FALSE : counting black bits
  297. // Return code : Join same color bits number
  298. //-----------------------------------------------------------------------------
  299. DWORD FjCountBits( BYTE *pTmp, DWORD cBitsTmp, DWORD cBitsMax, BOOL bWhite )
  300. {
  301. DWORD cBits, k;
  302. pTmp += (cBitsTmp / 8);
  303. k = cBitsTmp % 8;
  304. for (cBits = 0; cBits < cBitsMax; cBits++) {
  305. if (((*pTmp & (1 << (7 - k))) == 0) != bWhite)
  306. break;
  307. k++;
  308. if (k == 8) {
  309. k = 0;
  310. pTmp++;
  311. }
  312. }
  313. return cBits;
  314. }
  315. //-----------------------------------------------------------------------------
  316. // VOID FjBitsCopy
  317. // BYTE *pTmp Pointer of destinaition area
  318. // DWORD cBitsTmp Bit number from top of destination area
  319. // DWORD dwCode Copy code
  320. // INT cCopyBits Copy size(bit)
  321. //-----------------------------------------------------------------------------
  322. VOID FjBitsCopy( BYTE *pTmp, DWORD cBitsTmp, DWORD dwCode, INT cCopyBits )
  323. {
  324. INT k, cBits;
  325. DWORD dwMask, dwTmp;
  326. pTmp += (cBitsTmp / 8);
  327. k = cBitsTmp % 8;
  328. cBits = cCopyBits + k;
  329. dwTmp = (DWORD)*pTmp << 16;
  330. dwTmp &= 0xff000000L >> k;
  331. dwTmp |= dwCode << (8 - k);
  332. if( cBits <= 8 ) {
  333. *pTmp = (BYTE)(dwTmp >> 16);
  334. } else if( cBits <= 16 ) {
  335. *pTmp = (BYTE)(dwTmp >> 16);
  336. *(pTmp + 1) = (BYTE)(dwTmp >> 8);
  337. } else {
  338. *pTmp = (BYTE)(dwTmp >> 16);
  339. *(pTmp + 1) = (BYTE)(dwTmp >> 8);
  340. *(pTmp + 2) = (BYTE)dwTmp;
  341. }
  342. }
  343. //-----------------------------------------------------------------------------
  344. // DWORD MhCompress
  345. // BYTE *pDest Pointer of destinaition area
  346. // DWORD cDestN Size of destination area(byte)
  347. // BYTE *pSrc Pointer of sources area
  348. // DWORD cSrcN Size of sources area(byte)
  349. // DWORD cSrcX Sources image x width
  350. // DWORD cSrcY Sources image y height
  351. // Return code : Writing size to destination area
  352. //-----------------------------------------------------------------------------
  353. DWORD MhCompress( BYTE *pDest, DWORD cDestN, BYTE *pSrc, DWORD cSrcN, DWORD cSrcX, DWORD cSrcY )
  354. {
  355. DWORD cBitsSrc, cBitsSrcMax;
  356. DWORD cBitsDest, cBitsDestMax, cBitsDestMark;
  357. DWORD cBitsRun;
  358. DWORD dwCode, cBits;
  359. DWORD i;
  360. PATNINFO ptnInfo;
  361. cBitsDest = 0;
  362. cBitsSrc = 0;
  363. cBitsDestMax = cDestN * 8;
  364. for (i = 0; i < cSrcY; i++) {
  365. // Set initial color
  366. ptnInfo.dwNextColor = NEXT_COLOR_WHITE;
  367. // Top EOL
  368. if (cBitsDest + CBITS_EOL_CODE > cBitsDestMax)
  369. return 0;
  370. FjBitsCopy(pDest, cBitsDest, EOL_CODE, CBITS_EOL_CODE);
  371. cBitsDest += CBITS_EOL_CODE;
  372. // vvv Oct.31,1996 H.Ishida
  373. cBitsDestMark = cBitsDest;
  374. // ^^^ Oct.31,1996 H.Ishida
  375. // Encode
  376. cBitsSrcMax = cBitsSrc + (cSrcX * 8);
  377. // Compress one line image
  378. while ( cBitsSrc < cBitsSrcMax ) {
  379. // Next run is white
  380. if( ptnInfo.dwNextColor == NEXT_COLOR_WHITE ) {
  381. // Count white bits
  382. cBitsRun = FjCountBits(pSrc, cBitsSrc, (cBitsSrcMax - cBitsSrc), TRUE);
  383. cBitsSrc += cBitsRun;
  384. // vvv Oct.31,1996 H.Ishida
  385. // reduce data size
  386. if(cBitsSrc >= cBitsSrcMax){
  387. if(cBitsDest > cBitsDestMark)
  388. break;
  389. cBitsRun = 2; // Whole white line is convert to white 2 dots:Minimun MH data.
  390. }
  391. // ^^^ Oct.31,1996 H.Ishida
  392. // Careful, white run length over maximam
  393. while( cBitsRun > RUNLENGTH_MAX ) {
  394. dwCode = WhiteMakeUpTable[MAKEUP_TABLE_MAX - 1].wCode;
  395. cBits = WhiteMakeUpTable[MAKEUP_TABLE_MAX - 1].cBits;
  396. if (cBitsDest + cBits > cBitsDestMax)
  397. return 0;
  398. FjBitsCopy(pDest, cBitsDest, dwCode, cBits);
  399. cBitsDest += cBits;
  400. cBitsRun -= RUNLENGTH_MAX;
  401. }
  402. if (cBitsRun >= 64) {
  403. dwCode = WhiteMakeUpTable[(cBitsRun / TERMINATE_MAX) - 1].wCode;
  404. cBits = WhiteMakeUpTable[(cBitsRun / TERMINATE_MAX) - 1].cBits;
  405. if (cBitsDest + cBits > cBitsDestMax)
  406. return 0;
  407. FjBitsCopy(pDest, cBitsDest, dwCode, cBits);
  408. cBitsDest += cBits;
  409. }
  410. dwCode = WhiteTerminateTable[cBitsRun % TERMINATE_MAX].wCode;
  411. cBits = WhiteTerminateTable[cBitsRun % TERMINATE_MAX].cBits;
  412. if (cBitsDest + cBits > cBitsDestMax)
  413. return 0;
  414. FjBitsCopy(pDest, cBitsDest, dwCode, cBits);
  415. cBitsDest += cBits;
  416. ptnInfo.dwNextColor = NEXT_COLOR_BLACK;
  417. } else {
  418. // Black bits
  419. cBitsRun = FjCountBits(pSrc, cBitsSrc, (cBitsSrcMax - cBitsSrc), FALSE);
  420. cBitsSrc += cBitsRun;
  421. // Careful, black run length over maximam
  422. while( cBitsRun > RUNLENGTH_MAX ) {
  423. dwCode = BlackMakeUpTable[MAKEUP_TABLE_MAX - 1].wCode;
  424. cBits = BlackMakeUpTable[MAKEUP_TABLE_MAX - 1].cBits;
  425. if (cBitsDest + cBits > cBitsDestMax)
  426. return 0;
  427. FjBitsCopy(pDest, cBitsDest, dwCode, cBits);
  428. cBitsDest += cBits;
  429. cBitsRun -= RUNLENGTH_MAX;
  430. }
  431. if (cBitsRun >= 64) {
  432. dwCode = BlackMakeUpTable[(cBitsRun / TERMINATE_MAX) - 1].wCode;
  433. cBits = BlackMakeUpTable[(cBitsRun / TERMINATE_MAX) - 1].cBits;
  434. if (cBitsDest + cBits > cBitsDestMax)
  435. return 0;
  436. FjBitsCopy(pDest, cBitsDest, dwCode, cBits);
  437. cBitsDest += cBits;
  438. }
  439. dwCode = BlackTerminateTable[cBitsRun % TERMINATE_MAX].wCode;
  440. cBits = BlackTerminateTable[cBitsRun % TERMINATE_MAX].cBits;
  441. if (cBitsDest + cBits > cBitsDestMax)
  442. return 0;
  443. FjBitsCopy(pDest, cBitsDest, dwCode, cBits);
  444. cBitsDest += cBits;
  445. ptnInfo.dwNextColor = NEXT_COLOR_WHITE;
  446. }
  447. }
  448. // End of one raster
  449. }
  450. // Last EOL.
  451. if (cBitsDest + CBITS_EOL_CODE > cBitsDestMax)
  452. return 0;
  453. FjBitsCopy(pDest, cBitsDest, EOL_CODE, CBITS_EOL_CODE);
  454. cBitsDest += CBITS_EOL_CODE;
  455. // Pad with 0 until byte boundary
  456. if ((cBits = (8 - (cBitsDest % 8)) % 8) != 0) {
  457. if (cBitsDest + cBits > cBitsDestMax)
  458. return 0;
  459. FjBitsCopy(pDest, cBitsDest, FILL_CODE, cBits);
  460. cBitsDest += cBits;
  461. }
  462. return cBitsDest / 8;
  463. }
  464. // end of FUMH.c