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.

447 lines
9.9 KiB

  1. /* File: C:\WACKER\xfer\cmprs2.c (Created: 20-Jan-1994)
  2. * created from HAWIN source file
  3. * cmprs2.c -- Routines to implement data decompression
  4. *
  5. * Copyright 1989,1994 by Hilgraeve Inc. -- Monroe, MI
  6. * All rights reserved
  7. *
  8. * $Revision: 1 $
  9. * $Date: 10/05/98 1:16p $
  10. */
  11. #include <windows.h>
  12. #include <tdll\stdtyp.h>
  13. #if !defined(BYTE)
  14. #define BYTE unsigned char
  15. #endif
  16. #include "cmprs.h"
  17. #include "cmprs.hh"
  18. #if SHOW
  19. // #include <stdio.h>
  20. #endif
  21. /* * * * * * * * * * * * * *
  22. * Decompression routines *
  23. * * * * * * * * * * * * * */
  24. typedef struct s_dcmp_node DCMP_NODE;
  25. struct s_dcmp_node
  26. {
  27. DCMP_NODE *pstLinkBack;
  28. DCMP_NODE *pstLinkFwd;
  29. BYTE ucChar;
  30. };
  31. #define NODE_CAST DCMP_NODE *
  32. DCMP_NODE *pstDcmpTbl; // pointer to lookup table
  33. DCMP_NODE *pstCode = NULL; // used to scan table for output
  34. int (**ppfDcmpPutfunc)(void *, int); /* ptr. to ptr. to function used
  35. by calling func */
  36. int (*pfDcmpPutChar)(void *, int); /* ptr. to function used
  37. internally to get data */
  38. void *pPsave;
  39. DCMP_NODE *pstTblLimit = NULL; /* pointer to table beyond 1st 256 nodes */
  40. DCMP_NODE *pstExtraNode = NULL; /* pointer to additional node used in spec. case */
  41. int fDcmpError; /* set TRUE if illegal code is received */
  42. int fStartFresh = FALSE;
  43. unsigned int usCodeMask; /* mask to isolate varible sized codes */
  44. unsigned int usOldCode; /* last code received */
  45. int mcFirstChar; /* final character of pattern readout, actually,
  46. the FIRST character of pattern (characters
  47. are read out in reverse order */
  48. // #pragma optimize("lgea",on)
  49. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  50. * FUNCTION: decompress_start
  51. *
  52. * DESCRIPTION:
  53. *
  54. *
  55. * ARGUMENTS:
  56. *
  57. *
  58. * RETURNS:
  59. *
  60. */
  61. int decompress_start(int (**put_func)(void *, int),
  62. void *pP,
  63. int fPauses)
  64. {
  65. unsigned int usCount;
  66. DCMP_NODE *pstTmp;
  67. if (!compress_enable())
  68. return(FALSE);
  69. pPsave = pP;
  70. fFlushable = fPauses;
  71. // Due to the use of based pointers, we must use compress_tblspace + 1
  72. // in the following code. Otherwise, node 0 (which could have an offset
  73. // of 0 looks like a NULL pointer.
  74. // pstDcmpTbl = (DCMP_NODE *)(OFFSETOF(compress_tblspace) + 1);
  75. pstDcmpTbl = (DCMP_NODE *)(compress_tblspace);
  76. pstCode = NULL;
  77. pstExtraNode = (NODE_CAST)&pstDcmpTbl[MAXNODES]; /* last node */
  78. pstExtraNode->pstLinkFwd = NULL;
  79. pstTblLimit = (NODE_CAST)&pstDcmpTbl[256];
  80. for (usCount = 0, pstTmp = pstDcmpTbl; usCount < 256; ++usCount)
  81. {
  82. pstTmp->ucChar = (BYTE)usCount;
  83. ++pstTmp;
  84. }
  85. ulHoldReg = 0;
  86. sBitsLeft = 0;
  87. sCodeBits = 9;
  88. usMaxCode = 512;
  89. usCodeMask = (1 << sCodeBits) - 1;
  90. usFreeCode = FIRSTFREE;
  91. fDcmpError = FALSE;
  92. fStartFresh = FALSE;
  93. ppfDcmpPutfunc = put_func;
  94. pfDcmpPutChar = *ppfDcmpPutfunc;
  95. *ppfDcmpPutfunc = dcmp_putc;
  96. usxCmprsStatus = COMPRESS_ACTIVE;
  97. #if SHOW
  98. printf("D decompress_start, sCodeBits=%d\n",
  99. sCodeBits);
  100. #endif
  101. return(TRUE);
  102. }
  103. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  104. * FUNCTION: decompress_error
  105. *
  106. * DESCRIPTION:
  107. *
  108. *
  109. * ARGUMENTS:
  110. *
  111. *
  112. * RETURNS:
  113. *
  114. */
  115. int decompress_error(void)
  116. {
  117. return(fDcmpError);
  118. }
  119. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  120. * FUNCTION: dcmp_start
  121. *
  122. * DESCRIPTION:
  123. *
  124. *
  125. * ARGUMENTS:
  126. *
  127. *
  128. * RETURNS:
  129. *
  130. */
  131. int dcmp_start(void *pX, int mcStartChar)
  132. {
  133. unsigned int usCode;
  134. ulHoldReg |= ((unsigned long)mcStartChar << sBitsLeft);
  135. sBitsLeft += 8;
  136. #if SHOW
  137. printf("D %02X %08lX,%2d dcmp_start\n", mcStartChar,
  138. ulHoldReg, sBitsLeft);
  139. #endif
  140. if (sBitsLeft >= sCodeBits)
  141. {
  142. usCode = (unsigned int)ulHoldReg & usCodeMask;
  143. ulHoldReg >>= sCodeBits;
  144. sBitsLeft -= sCodeBits;
  145. #if SHOW
  146. printf("D >> %03X %08lX,%2d sCodeBits=%d dcmp_start\n",
  147. usCode, ulHoldReg, sBitsLeft, sCodeBits);
  148. #endif
  149. /* Table has just been cleared, code must be in range of 0 - 255 */
  150. if (!IN_RANGE((INT)usCode, 0, 255))
  151. {
  152. #if SHOW
  153. printf("D >> %03X ERROR: out of range\n",
  154. usCode);
  155. #endif
  156. return(dcmp_abort());
  157. }
  158. else
  159. {
  160. #if SHOW
  161. printf("D %02X dcmp_start\n", usCode);
  162. #endif
  163. mcStartChar = (*pfDcmpPutChar)(pPsave, mcFirstChar =
  164. (INT)(usOldCode = usCode));
  165. *ppfDcmpPutfunc = dcmp_putc;
  166. }
  167. }
  168. return(mcStartChar);
  169. }
  170. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  171. * FUNCTION: dcmp_putc
  172. *
  173. * DESCRIPTION:
  174. *
  175. *
  176. * ARGUMENTS:
  177. *
  178. *
  179. * RETURNS:
  180. *
  181. */
  182. int dcmp_putc(void *pX, int mcInput)
  183. {
  184. unsigned int usCode;
  185. unsigned int usInCode;
  186. int mcPutResult;
  187. DCMP_NODE *pstTmp;
  188. ulHoldReg |= ((unsigned long)mcInput << sBitsLeft);
  189. sBitsLeft += 8;
  190. #if SHOW
  191. printf("D %02X %08lX,%2d\n", mcInput, ulHoldReg, sBitsLeft);
  192. #endif
  193. if (sBitsLeft >= sCodeBits)
  194. {
  195. usCode = (unsigned int)ulHoldReg & usCodeMask;
  196. ulHoldReg >>= sCodeBits;
  197. sBitsLeft -= sCodeBits;
  198. #if SHOW
  199. printf("D >> %03X %08lX,%2d sCodeBits=%d\n",
  200. usCode, ulHoldReg, sBitsLeft, sCodeBits);
  201. #endif
  202. if (usCode == STOPCODE)
  203. {
  204. if (!fFlushable)
  205. decompress_stop();
  206. else
  207. {
  208. // Pause in the data, leave lookup table intact but start
  209. // receiving a fresh stream.
  210. sBitsLeft = 0;
  211. ulHoldReg = 0L;
  212. fStartFresh = TRUE;
  213. #if SHOW
  214. printf("D %08lX,%2d setting fFreshStart\n",
  215. ulHoldReg, sBitsLeft);
  216. #endif
  217. }
  218. }
  219. else if (usCode == CLEARCODE)
  220. {
  221. sCodeBits = 9;
  222. usMaxCode = 512;
  223. usCodeMask = (1 << sCodeBits) - 1;
  224. usFreeCode = FIRSTFREE;
  225. *ppfDcmpPutfunc = dcmp_start;
  226. #if SHOW
  227. printf("D CLEARCODE, sCodeBits=%d\n",
  228. sCodeBits);
  229. #endif
  230. }
  231. else if (usCode > (unsigned int)usFreeCode)
  232. {
  233. #if SHOW
  234. printf("D ERROR: usCode > usFreeCode of %03X\n",
  235. usFreeCode);
  236. #endif
  237. return(dcmp_abort());
  238. }
  239. else
  240. {
  241. pstCode = (NODE_CAST)&pstDcmpTbl[usInCode = usCode];
  242. if (usCode == usFreeCode) /* spec. case k<w>k<w>k */
  243. {
  244. pstCode = (NODE_CAST)&pstDcmpTbl[usCode = usOldCode];
  245. pstExtraNode->ucChar = (BYTE)mcFirstChar;
  246. pstCode->pstLinkFwd = pstExtraNode;
  247. #if SHOW
  248. printf("D Special case: k<w>k<w>k\n");
  249. #endif
  250. }
  251. else
  252. pstCode->pstLinkFwd = NULL;
  253. while(pstCode > pstTblLimit)
  254. {
  255. pstCode->pstLinkBack->pstLinkFwd = pstCode;
  256. pstCode = pstCode->pstLinkBack;
  257. }
  258. mcFirstChar = pstCode->ucChar;
  259. if (!fStartFresh)
  260. {
  261. #if SHOW
  262. printf("D D Added %03X = %03X + %02X\n",
  263. usFreeCode, usOldCode, mcFirstChar);
  264. #endif
  265. if (usFreeCode < MAXNODES)
  266. {
  267. pstTmp = (NODE_CAST)&pstDcmpTbl[usFreeCode++];
  268. pstTmp->ucChar = (BYTE)mcFirstChar;
  269. pstTmp->pstLinkBack = (NODE_CAST)&pstDcmpTbl[usOldCode];
  270. }
  271. }
  272. fStartFresh = FALSE;
  273. usOldCode = usInCode;
  274. if (usFreeCode >= usMaxCode && sCodeBits < MAXCODEBITS)
  275. {
  276. ++sCodeBits;
  277. usCodeMask = (1 << sCodeBits) - 1;
  278. usMaxCode *= 2;
  279. #if SHOW
  280. printf("D D New sCodeBits = %d\n",
  281. sCodeBits);
  282. #endif
  283. }
  284. while (pstCode != NULL)
  285. {
  286. #if SHOW
  287. printf("D %02X ", pstCode->ucChar);
  288. #endif
  289. if ((mcPutResult = (*pfDcmpPutChar)(pPsave, pstCode->ucChar)) < 0)
  290. {
  291. if (mcPutResult == DCMP_UNFINISHED)
  292. {
  293. #if SHOW
  294. printf("Interrupted");
  295. #endif
  296. pstCode = pstCode->pstLinkFwd; // to pick up later
  297. mcInput = DCMP_UNFINISHED;
  298. break;
  299. }
  300. else
  301. {
  302. #if SHOW
  303. printf("ERROR: putc returned -1");
  304. #endif
  305. pstCode = NULL;
  306. mcInput = ERROR;
  307. break;
  308. }
  309. }
  310. #if SHOW
  311. printf("\n");
  312. #endif
  313. pstCode = pstCode->pstLinkFwd;
  314. }
  315. }
  316. }
  317. return(mcInput);
  318. }
  319. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  320. * FUNCTION: decompress_continue
  321. *
  322. * DESCRIPTION:
  323. * Needed for compression in remote control. Picks up expansion of an
  324. * output string after it has been interrupted.
  325. *
  326. * ARGUMENTS:
  327. *
  328. *
  329. * RETURNS:
  330. *
  331. */
  332. int decompress_continue(void)
  333. {
  334. int mcPutResult;
  335. int mcRetCode;
  336. // Deliver an initial unfinished code so routines downstream can pick
  337. // up midstream if necessary
  338. if ((*pfDcmpPutChar)(pPsave, DCMP_UNFINISHED) == DCMP_UNFINISHED)
  339. return DCMP_UNFINISHED;
  340. // Now continue delivering any remaining expansion codes unless
  341. // interrupted again
  342. while (pstCode != NULL)
  343. {
  344. if ((mcPutResult = (*pfDcmpPutChar)(pPsave, pstCode->ucChar)) < 0)
  345. {
  346. if (mcPutResult == DCMP_UNFINISHED)
  347. {
  348. pstCode = pstCode->pstLinkFwd; // to pick up later
  349. mcRetCode = DCMP_UNFINISHED;
  350. break;
  351. }
  352. else
  353. {
  354. pstCode = NULL;
  355. mcRetCode = ERROR;
  356. break;
  357. }
  358. }
  359. pstCode = pstCode->pstLinkFwd;
  360. }
  361. return mcRetCode;
  362. }
  363. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  364. * FUNCTION: dcmp_abort
  365. *
  366. * DESCRIPTION:
  367. *
  368. *
  369. * ARGUMENTS:
  370. *
  371. *
  372. * RETURNS:
  373. *
  374. */
  375. int dcmp_abort(void)
  376. {
  377. /* print error message or whatever */
  378. fDcmpError = TRUE;
  379. decompress_stop();
  380. return(ERROR);
  381. }
  382. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  383. * FUNCTION: decompress_stop
  384. *
  385. * DESCRIPTION:
  386. *
  387. *
  388. * ARGUMENTS:
  389. *
  390. *
  391. * RETURNS:
  392. *
  393. */
  394. void decompress_stop(void)
  395. {
  396. #if SHOW
  397. printf("D Decompress_stop\n");
  398. #endif
  399. if (ppfDcmpPutfunc != NULL)
  400. {
  401. *ppfDcmpPutfunc = pfDcmpPutChar;
  402. ppfDcmpPutfunc = NULL;
  403. }
  404. usxCmprsStatus = COMPRESS_IDLE;
  405. }
  406. /* end of cmprs2.c */