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.

422 lines
8.5 KiB

  1. /*==============================================================================
  2. This source file contains routines for chaingon decompression of glyphs.
  3. 29-Dec-93 RajeevD Integrated into unified resource executor.
  4. ==============================================================================*/
  5. #include <ifaxos.h>
  6. #include <memory.h>
  7. #include "resexec.h"
  8. #include "constant.h"
  9. #include "jtypes.h" // type definition used in cartridge
  10. #include "jres.h" // cartridge resource data type definition
  11. #include "hretype.h" // define data structure used by hre.c and rpgen.c
  12. #define CEIL32(val) (((val) + 31) & ~31)
  13. #define RUN_FLAG ((short) 0x8000)
  14. // Bit Stream Object
  15. typedef class FAR BITIO
  16. {
  17. private:
  18. UINT uBit;
  19. public:
  20. LPBYTE lpb;
  21. BITIO (LPBYTE lpbInit) {lpb = lpbInit, uBit = 0;}
  22. BITIO () {uBit = 0;}
  23. short Read2 (void);
  24. short Read4 (void);
  25. short Read6 (void);
  26. short Read8 (void);
  27. WORD Read8U (void);
  28. short Read16 (void);
  29. WORD ReadU (void);
  30. short DecodeDelta (void);
  31. }
  32. FAR *LPBITIO;
  33. //==============================================================================
  34. short BITIO::Read2 (void)
  35. {
  36. short s;
  37. // Mask and shift 2-bit field.
  38. s = (*lpb >> (6 - uBit)) & 0x03;
  39. // Advance stream pointer.
  40. uBit += 2;
  41. if (uBit == 8)
  42. {lpb++; uBit = 0;}
  43. #ifndef BITIO_NOSIGNEXT
  44. if (s >= 2)
  45. s -= 4; // Sign extend into short.
  46. #endif
  47. return s;
  48. }
  49. //========================================================================
  50. short BITIO::Read4 (void)
  51. {
  52. LPBYTE lpbVal;
  53. short s;
  54. if (uBit == 6)
  55. {
  56. lpbVal = (LPBYTE) &s;
  57. lpbVal[1] = *lpb++;
  58. lpbVal[0] = *lpb;
  59. s >>= 6;
  60. s &= 0x000F;
  61. uBit = 2;
  62. }
  63. else
  64. {
  65. s = (*lpb >> (4 - uBit)) & 0x0F;
  66. uBit += 4;
  67. if (uBit == 8)
  68. { lpb++; uBit = 0; }
  69. }
  70. #ifndef BITIO_NOSIGNEXT
  71. if (s >= 8)
  72. s -= 16; // Sign extend into short.
  73. #endif
  74. return s;
  75. }
  76. //========================================================================
  77. short BITIO::Read6 (void)
  78. {
  79. LPBYTE lpbVal;
  80. short s;
  81. switch (uBit/2)
  82. {
  83. case 0:
  84. s = (short) (*lpb >> 2);
  85. uBit = 6;
  86. break;
  87. case 1:
  88. s = (short) *lpb++;
  89. uBit = 0;
  90. break;
  91. case 2:
  92. lpbVal = (LPBYTE) &s;
  93. lpbVal[1] = *lpb++;
  94. lpbVal[0] = *lpb;
  95. s >>= 6;
  96. uBit = 2;
  97. break;
  98. case 3:
  99. lpbVal = (BYTE *) &s;
  100. lpbVal[1] = *lpb++;
  101. lpbVal[0] = *lpb;
  102. s >>= 4;
  103. uBit = 4;
  104. break;
  105. }
  106. s &= 0x003F;
  107. #ifndef BITIO_NOSIGNEXT
  108. if (s >= 32)
  109. s -= 64; // Sign extend into short.
  110. #endif
  111. return s;
  112. }
  113. //========================================================================
  114. short BITIO::Read8 (void)
  115. {
  116. short s;
  117. LPBYTE lpbVal;
  118. if (uBit == 0)
  119. s = (short) *lpb++;
  120. else
  121. {
  122. lpbVal = (LPBYTE) &s;
  123. lpbVal[1] = *lpb++;
  124. lpbVal[0] = *lpb;
  125. s >>= (8 - uBit);
  126. s &= 0x00FF;
  127. }
  128. #ifndef BITIO_NOSIGNEXT
  129. if (s >= 128)
  130. s -= 256; // Sign extend into short.
  131. #endif
  132. return s;
  133. }
  134. //========================================================================
  135. WORD BITIO::Read8U (void)
  136. {
  137. short s;
  138. LPBYTE lpbVal;
  139. if (uBit == 0)
  140. s = (short) *lpb++;
  141. else
  142. {
  143. lpbVal = (LPBYTE) &s;
  144. lpbVal[1] = *lpb++;
  145. lpbVal[0] = *lpb;
  146. s >>= (8 - uBit);
  147. s &= 0x00FF;
  148. }
  149. return s;
  150. }
  151. //========================================================================
  152. short BITIO::Read16 (void)
  153. {
  154. short s;
  155. LPBYTE lpbVal = (LPBYTE) &s;
  156. lpbVal[1] = *lpb++;
  157. lpbVal[0] = *lpb++;
  158. switch (uBit/2)
  159. {
  160. case 0:
  161. break;
  162. case 1:
  163. s <<= 2;
  164. s |= (*lpb >> 6) & 0x03;
  165. break;
  166. case 2:
  167. s <<= 4;
  168. s |= (*lpb >> 4) & 0x0F;
  169. break;
  170. case 3:
  171. s <<= 6;
  172. s |= (*lpb >> 2) & 0x3F;
  173. break;
  174. }
  175. return s;
  176. }
  177. //==============================================================================
  178. WORD BITIO::ReadU (void)
  179. {
  180. WORD w = Read8U();
  181. if (w == 0xFF)
  182. w = Read16();
  183. return w;
  184. }
  185. /*==============================================================================
  186. This utility procedure uses an OR operation to fill runs in a scan buffer.
  187. ==============================================================================*/
  188. LPBYTE FillRun // Returns next scan line
  189. (
  190. LPBYTE lpbLine, // first output scan line
  191. UINT cbLine, // width of a scan line
  192. UINT xLeft, // left column, inclusive
  193. UINT xRight, // right column, exclusive
  194. UINT cLines = 1 // number of scan lines
  195. )
  196. {
  197. const static WORD wFill[16] =
  198. {
  199. 0xFFFF, 0xFF7F, 0xFF3F, 0xFF1F,
  200. 0xFF0F, 0xFF07, 0xFF03, 0xFF01,
  201. 0xFF00, 0x7F00, 0x3F00, 0x1F00,
  202. 0x0F00, 0x0700, 0x0300, 0x0100,
  203. };
  204. UINT iwLeft, iwRight;
  205. WORD wLeft, wRight; // masks
  206. LPWORD lpwLine = (LPWORD) lpbLine;
  207. UINT cwLine = cbLine / 2;
  208. iwLeft = xLeft / 16;
  209. iwRight = xRight / 16;
  210. wLeft = wFill [xLeft & 15];
  211. wRight = ~wFill [xRight & 15];
  212. if (iwLeft == iwRight)
  213. {
  214. while (cLines--)
  215. {
  216. // Run is within a single WORD.
  217. lpwLine[iwLeft] |= wLeft & wRight;
  218. lpwLine += cwLine;
  219. }
  220. }
  221. else
  222. {
  223. UINT cbMiddle = 2 * (iwRight - iwLeft - 1);
  224. while (cLines--)
  225. {
  226. // Run spans more than one WORD.
  227. lpwLine[iwLeft] |= wLeft;
  228. _fmemset (lpwLine + iwLeft + 1, 0xFF, cbMiddle);
  229. if (wRight) // Don't access beyond output!
  230. lpwLine[iwRight] |= wRight;
  231. lpwLine += cwLine;
  232. }
  233. }
  234. return (LPBYTE) lpwLine;
  235. }
  236. //==============================================================================
  237. UINT // unpacked size
  238. UnpackGlyph
  239. (
  240. LPBYTE lpbIn, // packed glyph
  241. LPBYTE lpbOut // output buffer
  242. )
  243. {
  244. BITIO bitio (lpbIn); // input bit stream
  245. LPWORD lpwOut; // alias for lpbOut
  246. WORD xExt, yExt; // glyph dimensions
  247. UINT cbLine; // scan line width
  248. // Decode glyph header.
  249. xExt = bitio.ReadU();
  250. yExt = bitio.ReadU();
  251. cbLine = CEIL32(xExt) / 8;
  252. // Write glyph dimensions.
  253. lpwOut = (LPWORD) lpbOut;
  254. *lpwOut++ = yExt;
  255. *lpwOut++ = xExt;
  256. lpbOut = (LPBYTE) lpwOut;
  257. // Clear output buffer.
  258. _fmemset (lpbOut, 0x00, cbLine * yExt);
  259. // Unpack each chain.
  260. while (1)
  261. {
  262. LPBYTE lpbScan; // output buffer
  263. UINT yTop; // top of chaingon
  264. UINT xLeft, xRight; // left and right bound
  265. short dxLeft, dxRight; // left and right delta
  266. UINT cLine, cRun; // line counters
  267. // Decode chain header.
  268. xRight = bitio.ReadU();
  269. if (!xRight) // termination
  270. goto done;
  271. cLine = bitio.ReadU();
  272. xLeft = bitio.ReadU();
  273. yTop = bitio.ReadU();
  274. lpbScan = lpbOut + yTop * cbLine;
  275. xRight += xLeft;
  276. // Fill first row.
  277. lpbScan = FillRun (lpbScan, cbLine, xLeft, xRight);
  278. cLine--;
  279. // Fill remaining rows.
  280. while (cLine)
  281. {
  282. dxLeft = bitio.DecodeDelta ();
  283. if (dxLeft == RUN_FLAG)
  284. {
  285. // Decode run of repeated lines.
  286. cRun = (bitio.Read4() & 0xF) + 3;
  287. lpbScan = FillRun (lpbScan, cbLine, xLeft, xRight, cRun);
  288. cLine -= cRun;
  289. }
  290. else
  291. {
  292. // Adjust by deltas.
  293. dxRight = bitio.DecodeDelta();
  294. xLeft += dxLeft;
  295. xRight += dxRight;
  296. lpbScan = FillRun (lpbScan, cbLine, xLeft, xRight);
  297. cLine--;
  298. }
  299. } // while (cLine--)
  300. } // while (1)
  301. done:
  302. return 2 * sizeof(WORD) + yExt * cbLine;
  303. }
  304. //==============================================================================
  305. void WINAPI UnpackGlyphSet (LPVOID lpIn, LPVOID lpOut)
  306. {
  307. LPJG_GS_HDR lpSetIn = (LPJG_GS_HDR) lpIn;
  308. LPJG_GS_HDR lpSetOut = (LPJG_GS_HDR) lpOut;
  309. LPBYTE lpbOut;
  310. WORD iGlyph;
  311. // Copy header.
  312. _fmemcpy (lpSetOut, lpSetIn, sizeof(JG_RES_HDR) + sizeof(WORD));
  313. // Create pointer to end of offset tables.
  314. lpbOut = ((LPBYTE) lpSetOut) + lpSetIn->ausOffset[0];
  315. // Unpack the glyphs.
  316. for (iGlyph=0; iGlyph<lpSetIn->usGlyphs; iGlyph++)
  317. {
  318. lpSetOut->ausOffset[iGlyph] = (USHORT)(lpbOut - (LPBYTE) lpSetOut);
  319. lpbOut += UnpackGlyph
  320. ((LPBYTE) lpSetIn + lpSetIn->ausOffset[iGlyph], lpbOut);
  321. }
  322. }
  323. //==============================================================================
  324. short // Returns delta (or RUN_FLAG)
  325. BITIO::DecodeDelta (void)
  326. {
  327. short s;
  328. s = Read2();
  329. if (s != -2) // Trap -1, 0, +1.
  330. return s;
  331. s = Read4(); // Get 4-bit prefix.
  332. switch (s)
  333. {
  334. case 0: // run of zeros
  335. return RUN_FLAG;
  336. case 1: // 6-bit literal
  337. s = Read6();
  338. return (s >= 0? s + 8 : s - 7);
  339. case -1: // 8-bit literal
  340. s = Read8();
  341. return (s >= 0? s + 40 : s - 39);
  342. case -8: // 16-bit literal
  343. return Read16();
  344. default: // 4-bit literal
  345. return s;
  346. }
  347. }