Source code of Windows XP (NT5)
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
11 KiB

  1. /* ------------------------------------------------------------------------ */
  2. /* */
  3. /* Copyright (c) Microsoft Corporation, 2000-2001. All rights reserved. */
  4. /* Copyright (c) Andrew Kadatch, 1991-2001. All rights reserved. */
  5. /* */
  6. /* Microsoft Confidential -- do not redistribute. */
  7. /* */
  8. /* ------------------------------------------------------------------------ */
  9. #include "xprs.h"
  10. #define ALLOCATE_ON_STACK 1
  11. #define MAGIC_DECODE 0x35DEC0DE
  12. typedef struct
  13. {
  14. struct
  15. {
  16. uchar *end, *beg, *careful, *stop, *last;
  17. } dst;
  18. struct
  19. {
  20. const uchar *end, *beg, *careful, *end_1, *end_tag, *end_bitmask2, *last;
  21. }
  22. src;
  23. int result;
  24. int eof;
  25. int magic;
  26. #if CODING & (CODING_HUFF_LEN | CODING_HUFF_PTR | CODING_HUFF_ALL)
  27. uint16 table[(1 << DECODE_BITS) + (HUFF_SIZE << 1)];
  28. #endif
  29. } decode_info;
  30. #if CODING == CODING_BY_BIT
  31. static int bit_to_len_initialized = 0;
  32. static uchar bit_to_len1[1 << (9 - MIN_MATCH)];
  33. static uchar bit_to_len2[1 << (9 - MIN_MATCH)];
  34. static void bit_to_len_init (void)
  35. {
  36. int i, k;
  37. if (bit_to_len_initialized) return;
  38. bit_to_len1[0] = 0;
  39. bit_to_len2[0] = 9 - MIN_MATCH;
  40. for (k = 1, i = 1 << (8 - MIN_MATCH); i != 0; i >>= 1, ++k)
  41. {
  42. memset (bit_to_len1 + i, k, i);
  43. memset (bit_to_len2 + i, k - 1, i);
  44. }
  45. bit_to_len_initialized = 1;
  46. }
  47. #endif
  48. #if CODING & (CODING_HUFF_LEN | CODING_HUFF_PTR | CODING_HUFF_ALL)
  49. static int huffman_decode_create (uint16 *table, const uchar *length)
  50. {
  51. xint i, j, k, last, freq[16], sum[16];
  52. /* calculate number of codewords */
  53. memset (freq, 0, sizeof (freq));
  54. i = HUFF_SIZE >> 1;
  55. do
  56. {
  57. k = length[--i];
  58. ++freq[k & 0xf];
  59. ++freq[k >> 4];
  60. }
  61. while (i != 0);
  62. /* handle special case(s) -- 0 and 1 symbols in alphabet */
  63. if (freq[0] == HUFF_SIZE)
  64. goto ok;
  65. if (freq[0] == HUFF_SIZE - 1)
  66. goto bad;
  67. #if 0
  68. {
  69. if (freq[1] != 1)
  70. goto bad;
  71. i = -1; do ++i; while (length[i] == 0);
  72. k = i << 1;
  73. if (length[i] != 1) ++k;
  74. i = 1 << DECODE_BITS;
  75. do
  76. *table++ = (uint16) k;
  77. while (--i > 0);
  78. goto ok;
  79. }
  80. #endif
  81. /* save frequences */
  82. memcpy (sum, freq, sizeof (sum));
  83. /* check code correctness */
  84. k = 0;
  85. i = 15;
  86. do
  87. {
  88. if ((k += freq[i]) & 1)
  89. goto bad;
  90. k >>= 1;
  91. }
  92. while (--i != 0);
  93. if (k != 1)
  94. goto bad;
  95. /* sort symbols */
  96. k = 0;
  97. for (i = 1; i < 16; ++i)
  98. freq[i] = (k += freq[i]);
  99. last = freq[15]; /* preserve number of symbols in alphabet */
  100. i = HUFF_SIZE << 4;
  101. do
  102. {
  103. i -= 1 << 4;
  104. k = length[i >> 5] >> 4;
  105. if (k != 0)
  106. table[--freq[k]] = (uint16) (k | i);
  107. i -= 1 << 4;
  108. k = length[i >> 5] & 0xf;
  109. if (k != 0)
  110. table[--freq[k]] = (uint16) (k | i);
  111. }
  112. while (i != 0);
  113. /* now create decoding table */
  114. k = i = (1 << DECODE_BITS) + (HUFF_SIZE << 1);
  115. {
  116. xint n;
  117. for (n = 15; n > DECODE_BITS; --n)
  118. {
  119. j = i;
  120. while (k > j)
  121. table[--i] = (uint16) ((k -= 2) | 0x8000);
  122. for (k = sum[n]; --k >= 0;)
  123. table[--i] = table[--last];
  124. k = j;
  125. }
  126. }
  127. j = i;
  128. i = 1 << DECODE_BITS;
  129. while (k > j)
  130. table[--i] = (uint16) ((k -= 2) | 0x8000);
  131. while (last > 0)
  132. {
  133. k = table[--last];
  134. j = i - ((1 << DECODE_BITS) >> (k & 15));
  135. do
  136. table[--i] = (uint16) k;
  137. while (i != j);
  138. }
  139. assert ((i | last) == 0);
  140. ok:
  141. return (1);
  142. bad:
  143. return (0);
  144. }
  145. #endif /* CODING */
  146. #if DEBUG
  147. #define RET_OK do {printf ("OK @ %d\n", __LINE__); goto ret_ok;} while (0)
  148. #define RET_ERR do {printf ("ERR @ %d\n", __LINE__); goto ret_err;} while (0)
  149. #else
  150. #define RET_OK goto ret_ok
  151. #define RET_ERR goto ret_err
  152. #endif
  153. #define GET_UINT16(x,p) x = *(__unaligned uint16 *)(p); p += 2
  154. #define COPY_8_BYTES(dst,src) \
  155. dst[0] = src[0]; dst[1] = src[1]; dst[2] = src[2]; dst[3] = src[3]; \
  156. dst[4] = src[4]; dst[5] = src[5]; dst[6] = src[6]; dst[7] = src[7]
  157. /* do not use "memcpy" -- it does not work properly if "dst" and "src" are close (overlap) */
  158. #define COPY_BLOCK_SLOW(dst,src,len) \
  159. if (len > 8) do \
  160. { \
  161. COPY_8_BYTES (dst, src); \
  162. len -= 8; dst += 8; src += 8; \
  163. } \
  164. while (len > 8); \
  165. do \
  166. *dst++ = *src++, --len; \
  167. while (len)
  168. #ifndef i386
  169. #define COPY_BLOCK_FAST_8(dst,src) \
  170. COPY_8_BYTES (dst, src)
  171. #else
  172. #if 0
  173. #define COPY_BLOCK_FAST_8(dst,src) \
  174. ((__unaligned uint32 *) dst)[0] = ((__unaligned uint32 *) src)[0]; \
  175. ((__unaligned uint32 *) dst)[1] = ((__unaligned uint32 *) src)[1]
  176. #else
  177. #define COPY_BLOCK_FAST_8(dst,src) \
  178. ((__unaligned __int64 *) dst)[0] = ((__unaligned __int64 *) src)[0]
  179. #endif
  180. #endif /* i386 */
  181. #define BIORD(bits) \
  182. (Mask >> (sizeof (Mask) * 8 - (bits)))
  183. #define CONCAT2(x,y) x##y
  184. #define CONCAT(x,y) CONCAT2(x,y)
  185. #define bits_t signed char
  186. #define BIORD_MORE0(bits) \
  187. if ((Bits = (bits_t) (Bits - (bits))) < 0) \
  188. { \
  189. CAREFUL_ERR_IF (src >= info->src.end_1); \
  190. Mask += ((ubitmask4) *(__unaligned ubitmask2 *)src) << (-Bits); \
  191. src += sizeof (ubitmask2); \
  192. Bits += (bits_t) (sizeof (ubitmask2) * 8); \
  193. }
  194. #define BIORD_MORE(bits) \
  195. Mask <<= (bits_t)(bits); \
  196. BIORD_MORE0 (bits)
  197. #define BIORD_WORD(result,bits) \
  198. result = 1 << (bits); \
  199. if (bits) \
  200. { \
  201. result += BIORD (bits); \
  202. BIORD_MORE (bits); \
  203. }
  204. #define BIORD_DECODE(result,table) { \
  205. bits_t __bits; \
  206. result = ((int16 *)(table))[BIORD (DECODE_BITS)]; \
  207. if (result < 0) \
  208. { \
  209. Mask <<= DECODE_BITS; \
  210. do \
  211. { \
  212. result &= 0x7fff; \
  213. if ((bitmask4) Mask < 0) ++result; \
  214. result = ((int16 *)(table))[result]; \
  215. Mask <<= 1; \
  216. } \
  217. while (result < 0); \
  218. __bits = (bits_t)(result & 15); \
  219. } \
  220. else \
  221. { \
  222. __bits = (bits_t)(result & 15); \
  223. Mask <<= __bits; \
  224. } \
  225. result >>= 4; \
  226. Bits = (bits_t) (Bits - __bits); \
  227. } \
  228. if (Bits < 0) \
  229. { \
  230. CAREFUL_ERR_IF (src >= info->src.end_1); \
  231. if (CODING == CODING_HUFF_ALL) \
  232. {CAREFUL_IF (src >= info->src.careful, rdmore);} \
  233. Mask += ((ubitmask4) *(__unaligned ubitmask2 *)src) << (-Bits); \
  234. src += sizeof (ubitmask2); \
  235. Bits += (bits_t) (sizeof (ubitmask2) * 8); \
  236. }
  237. #ifdef _MSC_VER
  238. #ifdef _M_IX86
  239. #pragma optimize ("aw", off)
  240. #else
  241. #pragma optimize ("w", off)
  242. #endif /* _M_IX86 */
  243. #endif /* _MSC_VER */
  244. #define CAREFUL 0
  245. #include "xdecode.i"
  246. #define CAREFUL 1
  247. #include "xdecode.i"
  248. #ifdef _MSC_VER
  249. #ifdef _M_IX86
  250. #pragma optimize ("aw", on)
  251. #else
  252. #pragma optimize ("w", on)
  253. #endif /* _M_IX86 */
  254. #endif
  255. int XPRESS_CALL XpressDecode
  256. (
  257. XpressDecodeStream stream,
  258. void *orig, int orig_size, int decode_size,
  259. const void *comp, int comp_size
  260. )
  261. {
  262. decode_info *info;
  263. const uchar *src;
  264. #if ALLOCATE_ON_STACK
  265. decode_info stack_info;
  266. info = &stack_info;
  267. info->src.beg = (void *) stream;
  268. #else
  269. if (stream == 0 || (info = (decode_info *) stream)->magic != MAGIC_DECODE)
  270. return (-1);
  271. #endif
  272. if (comp_size == orig_size)
  273. return (decode_size);
  274. if (orig_size < comp_size
  275. || comp_size < 0
  276. || orig_size <= MIN_SIZE
  277. || comp_size < MIN_SIZE
  278. )
  279. return (-1);
  280. if (orig_size > BUFF_SIZE || decode_size <= 0)
  281. return (decode_size);
  282. src = comp;
  283. info->dst.beg = orig;
  284. info->dst.end = (uchar *) orig + orig_size;
  285. info->dst.stop = (uchar *) orig + decode_size;
  286. info->src.end = src + comp_size;
  287. info->src.end_1 = info->src.end - 1;
  288. info->src.end_tag = info->src.end - (sizeof (tag_t) - 1);
  289. info->src.end_bitmask2 = info->src.end - (sizeof (bitmask2) - 1);
  290. // check bounds when we read new mask (at most 8 * sizeof (tag_t)) pointers
  291. // we may write at most 8 bytes without checks
  292. #define RESERVE_DST ((8 * 8 + 2) * sizeof (tag_t))
  293. info->dst.careful = info->dst.beg;
  294. if (info->dst.stop - info->dst.beg > RESERVE_DST)
  295. info->dst.careful = info->dst.stop - RESERVE_DST;
  296. // we may read at most 7 bytes
  297. #define RESERVE_SRC ((7 * 8 + 2) * sizeof (tag_t))
  298. info->src.careful = info->src.beg;
  299. if (info->src.end - info->src.beg > RESERVE_SRC)
  300. info->src.careful = info->src.end - RESERVE_SRC;
  301. #if CODING & (CODING_HUFF_LEN | CODING_HUFF_PTR | CODING_HUFF_ALL)
  302. if (!huffman_decode_create (info->table, src))
  303. return (-1);
  304. src += HUFF_SIZE >> 1;
  305. #endif
  306. #if CODING == CODING_BY_BIT
  307. bit_to_len_init ();
  308. #endif
  309. info->src.beg = src;
  310. info->result = 0;
  311. info->eof = 0;
  312. do_decode (info);
  313. if (!info->result || info->dst.last > info->dst.stop || info->src.last > info->src.end
  314. || (info->dst.stop == info->dst.end && !info->eof)
  315. )
  316. return (-1);
  317. return (decode_size);
  318. }
  319. XpressDecodeStream
  320. XPRESS_CALL
  321. XpressDecodeCreate
  322. (
  323. void *context, // user-defined context info (will be passed to AllocFn)
  324. XpressAllocFn *AllocFn // memory allocation callback
  325. )
  326. {
  327. #if ALLOCATE_ON_STACK
  328. #ifdef _M_IX86
  329. return ((XpressDecodeStream) 1);
  330. #else
  331. return ((XpressDecodeStream) (__int64) 1);
  332. #endif
  333. #else
  334. decode_info *info;
  335. if (AllocFn == 0 || (info = AllocFn (context, sizeof (*info))) == 0)
  336. return (0);
  337. info->magic = MAGIC_DECODE;
  338. return ((XpressDecodeStream) info);
  339. #endif
  340. }
  341. void
  342. XPRESS_CALL
  343. XpressDecodeClose
  344. (
  345. XpressDecodeStream stream, // encoder's workspace
  346. void *context, // user-defined context info (will be passed to FreeFn)
  347. XpressFreeFn *FreeFn // callback that releases the memory
  348. )
  349. {
  350. #if ALLOCATE_ON_STACK
  351. /* do nothing */
  352. #else
  353. if (FreeFn != 0 && stream != 0 && ((decode_info *) stream)->magic == MAGIC_DECODE)
  354. {
  355. ((decode_info *) stream)->magic = 0;
  356. FreeFn (context, stream);
  357. }
  358. #endif
  359. }