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.

400 lines
9.7 KiB

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