root/trunk/contrib/extractor/libmpq/huffman.cpp @ 2

Revision 2, 32.4 kB (checked in by yumileroy, 17 years ago)

[svn] * Proper SVN structure

Original author: Neo2003
Date: 2008-10-02 16:23:55-05:00

Line 
1/*
2 *  huffman.c -- functions do decompress files in MPQ files which
3 *               uses a modified huffman version.
4 *
5 *  Copyright (C) 2003 Maik Broemme <mbroemme@plusserver.de>
6 *
7 *  Differences between C++ and C version:
8 *
9 *    - Removed the object oriented stuff.
10 *    - Replaced the goto things with some better C code.
11 *
12 *  This source was adepted from the C++ version of huffman.cpp included
13 *  in stormlib. The C++ version belongs to the following authors,
14 *
15 *  Ladislav Zezula <ladik.zezula.net>
16 *  ShadowFlare <BlakFlare@hotmail.com>
17 *
18 *  This program is free software; you can redistribute it and/or modify
19 *  it under the terms of the GNU General Public License as published by
20 *  the Free Software Foundation; either version 2 of the License, or
21 *  (at your option) any later version.
22 *
23 *  This program is distributed in the hope that it will be useful,
24 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
25 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26 *  GNU General Public License for more details.
27 *
28 *  You should have received a copy of the GNU General Public License
29 *  along with this program; if not, write to the Free Software
30 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 */
32#include <stdlib.h>
33#include <string.h>
34
35#include "mpq.h"
36#include "huffman.h"
37
38unsigned char table1502A630[] = {
39
40        /* Data for compression type 0x00 */
41        0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
42        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
43        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
44        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
45        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
47        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
48        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
49        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
50        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
51        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
52        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
53        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
54        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
55        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
56        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
57        0x00, 0x00,
58
59        /* Data for compression type 0x01 */
60        0x54, 0x16, 0x16, 0x0D, 0x0C, 0x08, 0x06, 0x05, 0x06, 0x05, 0x06, 0x03, 0x04, 0x04, 0x03, 0x05,
61        0x0E, 0x0B, 0x14, 0x13, 0x13, 0x09, 0x0B, 0x06, 0x05, 0x04, 0x03, 0x02, 0x03, 0x02, 0x02, 0x02,
62        0x0D, 0x07, 0x09, 0x06, 0x06, 0x04, 0x03, 0x02, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02,
63        0x09, 0x06, 0x04, 0x04, 0x04, 0x04, 0x03, 0x02, 0x03, 0x02, 0x02, 0x02, 0x02, 0x03, 0x02, 0x04,
64        0x08, 0x03, 0x04, 0x07, 0x09, 0x05, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x03, 0x02, 0x02,
65        0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02,
66        0x06, 0x0A, 0x08, 0x08, 0x06, 0x07, 0x04, 0x03, 0x04, 0x04, 0x02, 0x02, 0x04, 0x02, 0x03, 0x03,
67        0x04, 0x03, 0x07, 0x07, 0x09, 0x06, 0x04, 0x03, 0x03, 0x02, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02,
68        0x0A, 0x02, 0x02, 0x03, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x06, 0x03, 0x05, 0x02, 0x03,
69        0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x03, 0x01, 0x01, 0x01,
70        0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x04, 0x04, 0x04, 0x07, 0x09, 0x08, 0x0C, 0x02,
71        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x03,
72        0x04, 0x01, 0x02, 0x04, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01,
73        0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
74        0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
75        0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x06, 0x4B,
76        0x00, 0x00,
77
78        /* Data for compression type 0x02 */
79        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x27, 0x00, 0x00, 0x23, 0x00, 0x00,
80        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
81        0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x06, 0x0E, 0x10, 0x04,
82        0x06, 0x08, 0x05, 0x04, 0x04, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03, 0x01, 0x01, 0x02, 0x01, 0x01,
83        0x01, 0x04, 0x02, 0x04, 0x02, 0x02, 0x02, 0x01, 0x01, 0x04, 0x01, 0x01, 0x02, 0x03, 0x03, 0x02,
84        0x03, 0x01, 0x03, 0x06, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x01, 0x01,
85        0x01, 0x29, 0x07, 0x16, 0x12, 0x40, 0x0A, 0x0A, 0x11, 0x25, 0x01, 0x03, 0x17, 0x10, 0x26, 0x2A,
86        0x10, 0x01, 0x23, 0x23, 0x2F, 0x10, 0x06, 0x07, 0x02, 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
87        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
88        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
89        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
90        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
91        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
92        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
93        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
94        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
95        0x00, 0x00,
96
97        /* Data for compression type 0x03 */
98        0xFF, 0x0B, 0x07, 0x05, 0x0B, 0x02, 0x02, 0x02, 0x06, 0x02, 0x02, 0x01, 0x04, 0x02, 0x01, 0x03,
99        0x09, 0x01, 0x01, 0x01, 0x03, 0x04, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01,
100        0x05, 0x01, 0x01, 0x01, 0x0D, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
101        0x02, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01,
102        0x0A, 0x04, 0x02, 0x01, 0x06, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01,
103        0x05, 0x02, 0x03, 0x04, 0x03, 0x03, 0x03, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x03, 0x03,
104        0x01, 0x03, 0x01, 0x01, 0x02, 0x05, 0x01, 0x01, 0x04, 0x03, 0x05, 0x01, 0x03, 0x01, 0x03, 0x03,
105        0x02, 0x01, 0x04, 0x03, 0x0A, 0x06, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
106        0x02, 0x02, 0x01, 0x0A, 0x02, 0x05, 0x01, 0x01, 0x02, 0x07, 0x02, 0x17, 0x01, 0x05, 0x01, 0x01,
107        0x0E, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
108        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
109        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
110        0x06, 0x02, 0x01, 0x04, 0x05, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01,
111        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
112        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x07, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01,
113        0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x11,
114        0x00, 0x00,
115
116        /* Data for compression type 0x04 */
117        0xFF, 0xFB, 0x98, 0x9A, 0x84, 0x85, 0x63, 0x64, 0x3E, 0x3E, 0x22, 0x22, 0x13, 0x13, 0x18, 0x17,
118        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
119        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
120        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
121        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
122        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
123        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
124        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
125        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
126        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
127        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
128        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
129        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
130        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
131        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
132        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
133        0x00, 0x00,
134
135        /* Data for compression type 0x05 */
136        0xFF, 0xF1, 0x9D, 0x9E, 0x9A, 0x9B, 0x9A, 0x97, 0x93, 0x93, 0x8C, 0x8E, 0x86, 0x88, 0x80, 0x82,
137        0x7C, 0x7C, 0x72, 0x73, 0x69, 0x6B, 0x5F, 0x60, 0x55, 0x56, 0x4A, 0x4B, 0x40, 0x41, 0x37, 0x37,
138        0x2F, 0x2F, 0x27, 0x27, 0x21, 0x21, 0x1B, 0x1C, 0x17, 0x17, 0x13, 0x13, 0x10, 0x10, 0x0D, 0x0D,
139        0x0B, 0x0B, 0x09, 0x09, 0x08, 0x08, 0x07, 0x07, 0x06, 0x05, 0x05, 0x04, 0x04, 0x04, 0x19, 0x18,
140        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
141        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
142        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
143        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
144        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
145        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
146        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
147        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
148        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
149        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
150        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
151        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
152        0x00, 0x00,
153
154        /* Data for compression type 0x06 */
155        0xC3, 0xCB, 0xF5, 0x41, 0xFF, 0x7B, 0xF7, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
156        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
157        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
158        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
159        0xBF, 0xCC, 0xF2, 0x40, 0xFD, 0x7C, 0xF7, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
160        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
161        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
162        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
163        0x7A, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
164        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
165        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
166        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
167        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
168        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
169        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
170        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
171        0x00, 0x00,
172
173        /* Data for compression type 0x07 */
174        0xC3, 0xD9, 0xEF, 0x3D, 0xF9, 0x7C, 0xE9, 0x1E, 0xFD, 0xAB, 0xF1, 0x2C, 0xFC, 0x5B, 0xFE, 0x17,
175        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
176        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
177        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
178        0xBD, 0xD9, 0xEC, 0x3D, 0xF5, 0x7D, 0xE8, 0x1D, 0xFB, 0xAE, 0xF0, 0x2C, 0xFB, 0x5C, 0xFF, 0x18,
179        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
180        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
181        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
182        0x70, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
183        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
184        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
185        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
186        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
187        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
188        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
189        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
190        0x00, 0x00,
191
192        /* Data for compression type 0x08 */
193        0xBA, 0xC5, 0xDA, 0x33, 0xE3, 0x6D, 0xD8, 0x18, 0xE5, 0x94, 0xDA, 0x23, 0xDF, 0x4A, 0xD1, 0x10,
194        0xEE, 0xAF, 0xE4, 0x2C, 0xEA, 0x5A, 0xDE, 0x15, 0xF4, 0x87, 0xE9, 0x21, 0xF6, 0x43, 0xFC, 0x12,
195        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
196        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
197        0xB0, 0xC7, 0xD8, 0x33, 0xE3, 0x6B, 0xD6, 0x18, 0xE7, 0x95, 0xD8, 0x23, 0xDB, 0x49, 0xD0, 0x11,
198        0xE9, 0xB2, 0xE2, 0x2B, 0xE8, 0x5C, 0xDD, 0x15, 0xF1, 0x87, 0xE7, 0x20, 0xF7, 0x44, 0xFF, 0x13,
199        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
200        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
201        0x5F, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
202        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
203        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
204        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
205        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
206        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
207        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
208        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
209        0x00, 0x00
210};
211
212/* Gets previous Huffman tree item (?) */
213struct huffman_tree_item *libmpq_huff_get_prev_item(struct huffman_tree_item *hi, long value) {
214        if (PTR_INT(hi->prev) < 0) {
215                return PTR_NOT(hi->prev);
216        }
217        if (value < 0) {
218                value = hi - hi->next->prev;
219        }
220        return hi->prev + value;
221}
222
223/* 1500BC90 */
224static void libmpq_huff_remove_item(struct huffman_tree_item *hi) {
225        struct huffman_tree_item *temp;                 /* EDX */
226
227        if (hi->next != NULL) {
228                temp = hi->prev;
229                if (PTR_INT(temp) <= 0) {
230                        temp = PTR_NOT(temp);
231                } else {
232                        temp += (hi - hi->next->prev);
233                }
234                temp->next          = hi->next;
235                hi->next->prev      = hi->prev;
236                hi->next = hi->prev = NULL;
237        }
238}
239
240static void libmpq_huff_insert_item(struct huffman_tree_item **p_item, struct huffman_tree_item *item, unsigned long where, struct huffman_tree_item *item2) {
241        struct huffman_tree_item *next = item->next;    /* EDI - next to the first item */
242        struct huffman_tree_item *prev = item->prev;    /* ESI - prev to the first item */
243        struct huffman_tree_item *prev2;                /* Pointer to previous item */
244        long next2;                                     /* Pointer to the next item */
245
246        /* The same code like in mpq_huff_remove_item(); */
247        if (next != 0) {                                /* If the first item already has next one */
248                if (PTR_INT(prev) < 0) {
249                        prev = PTR_NOT(prev);
250                } else {
251                        prev += (item - next->prev);
252                }
253
254                /*
255                 * 150083C1
256                 * Remove the item from the tree
257                 */
258                prev->next = next;
259                next->prev = prev;
260
261                /* Invalidate 'prev' and 'next' pointer */
262                item->next = 0;
263                item->prev = 0;
264        }
265
266        if (item2 == NULL) {                            /* EDX - If the second item is not entered, */
267                item2 = PTR_PTR(&p_item[1]);            /* take the first tree item */
268        }
269
270        switch (where) {
271                case SWITCH_ITEMS:                      /* Switch the two items */
272                        item->next  = item2->next;      /* item2->next (Pointer to pointer to first) */
273                        item->prev  = item2->next->prev;
274                        item2->next->prev = item;
275                        item2->next = item;             /* Set the first item */
276                        return;
277                case INSERT_ITEM:                       /* Insert as the last item */
278                        item->next = item2;             /* Set next item (or pointer to pointer to first item) */
279                        item->prev = item2->prev;       /* Set prev item (or last item in the tree) */
280                        next2 = PTR_INT(p_item[0]);     /* Usually NULL */
281                        prev2 = item2->prev;            /* Prev item to the second (or last tree item) */
282                        if (PTR_INT(prev2) < 0) {
283                                prev2 = PTR_NOT(prev);
284                                prev2->next = item;
285                                item2->prev = item;     /* Next after last item */
286                                return;
287                        }
288                        if (next2 < 0) {
289                                next2 = item2 - item2->next->prev;
290                        }
291                        prev2 += next2;
292                        prev2->next = item;
293                        item2->prev = item;             /* Set the next/last item */
294                        return;
295                default:
296                        return;
297        }
298}
299
300/* Builds Huffman tree. Called with the first 8 bits loaded from input stream. */
301static void libmpq_huff_build_tree(struct huffman_tree *ht, unsigned int cmp_type) {
302        unsigned long max_byte;                         /* [ESP+10] - The greatest character found in table */
303        unsigned char *byte_array;                      /* [ESP+1C] - Pointer to unsigned char in table1502A630 */
304        unsigned long i;                                /* egcs in linux doesn't like multiple for loops without an explicit i */
305        unsigned int found;                             /* Thats needed to replace the goto stuff from original source :) */
306        struct huffman_tree_item **p_item;              /* [ESP+14] - Pointer to Huffman tree item pointer array */
307        struct huffman_tree_item *child1;
308
309        /* Loop while pointer has a negative value. */
310        while (PTR_INT(ht->last) > 0) {                 /* ESI - Last entry */
311                struct huffman_tree_item *temp;         /* EAX */
312       
313                if (ht->last->next != NULL) {           /* ESI->next */
314                        libmpq_huff_remove_item(ht->last);
315                }
316                ht->item3058   = PTR_PTR(&ht->item3054);/* [EDI+4] */
317                ht->last->prev = ht->item3058;          /* EAX */
318                temp           = libmpq_huff_get_prev_item(PTR_PTR(&ht->item3054), PTR_INT(&ht->item3050));
319                temp->next     = ht->last;
320                ht->item3054   = ht->last;
321        }
322
323        /* Clear all pointers in huffman tree item array. */
324        memset(ht->items306C, 0, sizeof(ht->items306C));
325
326        max_byte = 0;                                   /* Greatest character found init to zero. */
327        p_item = (struct huffman_tree_item **)&ht->items306C;   /* Pointer to current entry in huffman tree item pointer array */
328
329        /* Ensure we have low 8 bits only */
330        cmp_type   &= 0xFF;
331        byte_array  = table1502A630 + cmp_type * 258;   /* EDI also */
332
333        for (i = 0; i < 0x100; i++, p_item++) {
334                struct huffman_tree_item *item = ht->item3058;  /* Item to be created */
335                struct huffman_tree_item *p_item3 = ht->item3058;
336                unsigned char one_byte = byte_array[i];
337
338                /* Skip all the bytes which are zero. */
339                if (byte_array[i] == 0) {
340                        continue;
341                }
342
343                /* If not valid pointer, take the first available item in the array. */
344                if (PTR_INT(item) <= 0) {
345                        item = &ht->items0008[ht->items++];
346                }
347
348                /* Insert this item as the top of the tree. */
349                libmpq_huff_insert_item(&ht->item305C, item, SWITCH_ITEMS, NULL);
350
351                item->parent    = NULL;                 /* Invalidate child and parent */
352                item->child     = NULL;
353                *p_item         = item;                 /* Store pointer into pointer array */
354
355                item->dcmp_byte  = i;                   /* Store counter */
356                item->byte_value = one_byte;            /* Store byte value */
357                if (one_byte >= max_byte) {
358                        max_byte = one_byte;
359                        continue;
360                }
361
362                /* Find the first item which has byte value greater than current one byte */
363                found = 0;
364                if (PTR_INT((p_item3 = ht->last)) > 0) {/* EDI - Pointer to the last item */
365
366                        /* 15006AF7 */
367                        if (p_item3 != NULL) {
368                                do {                    /* 15006AFB */
369                                        if (p_item3->byte_value >= one_byte) {
370                                                found = 1;
371                                                break;
372                                        }
373                                        p_item3 = p_item3->prev;
374                                } while (PTR_INT(p_item3) > 0);
375                        }
376                }
377
378                if (found == 0) {
379                        p_item3 = NULL;
380                }
381
382                /* 15006B09 */
383                if (item->next != NULL) {
384                        libmpq_huff_remove_item(item);
385                }
386
387                /* 15006B15 */
388                if (p_item3 == NULL) {
389                        p_item3 = PTR_PTR(&ht->first);
390                }
391
392                /* 15006B1F */
393                item->next = p_item3->next;
394                item->prev = p_item3->next->prev;
395                p_item3->next->prev = item;
396                p_item3->next = item;
397        }
398
399        /* 15006B4A */
400        for (; i < 0x102; i++) {
401                struct huffman_tree_item **p_item2 = &ht->items306C[i]; /* EDI */
402
403                /* 15006B59  */
404                struct huffman_tree_item *item2 = ht->item3058; /* ESI */
405                if (PTR_INT(item2) <= 0) {
406                        item2 = &ht->items0008[ht->items++];
407                }
408                libmpq_huff_insert_item(&ht->item305C, item2, INSERT_ITEM, NULL);
409
410                /* 15006B89 */
411                item2->dcmp_byte  = i;
412                item2->byte_value = 1;
413                item2->parent     = NULL;
414                item2->child      = NULL;
415                *p_item2++        = item2;
416        }
417
418        /* 15006BAA */
419        if (PTR_INT((child1 = ht->last)) > 0) {         /* EDI - last item (first child to item */
420                struct huffman_tree_item *child2;       /* EBP */
421                struct huffman_tree_item *item;         /* ESI */
422
423                /* 15006BB8 */
424                while (PTR_INT((child2 = child1->prev)) > 0) {
425                        if (PTR_INT((item = ht->item3058)) <= 0) {
426                                item = &ht->items0008[ht->items++];
427                        }
428                        /* 15006BE3 */
429                        libmpq_huff_insert_item(&ht->item305C, item, SWITCH_ITEMS, NULL);
430
431                        /* 15006BF3 */
432                        item->parent = NULL;
433                        item->child  = NULL;
434
435                        /*
436                         * EDX = child2->byte_value + child1->byte_value;
437                         * EAX = child1->byte_value;
438                         * ECX = max_byte;              The greatest character (0xFF usually)
439                         */
440                        item->byte_value = child1->byte_value + child2->byte_value;     /* 0x02 */
441                        item->child      = child1;      /* Prev item in the */
442                        child1->parent   = item;
443                        child2->parent   = item;
444
445                        /* EAX = item->byte_value; */
446                        if (item->byte_value >= max_byte) {
447                                max_byte = item->byte_value;
448                        } else {
449                                struct huffman_tree_item *p_item2 = child2->prev;       /* EDI */
450                                found = 0;
451                                if (PTR_INT(p_item2) > 0) {
452
453                                        /* 15006C2D */
454                                        do {
455                                                if (p_item2->byte_value >= item->byte_value) {
456                                                        found = 1;
457                                                        break;
458                                                }
459                                                p_item2 = p_item2->prev;
460                                        } while (PTR_INT(p_item2) > 0);
461                                }
462                                if (found == 0) {
463                                        p_item2 = NULL;
464                                }
465                                if (item->next != 0) {
466                                        struct huffman_tree_item *temp4 = libmpq_huff_get_prev_item(item, -1);
467                                        temp4->next      = item->next;  /* The first item changed */
468                                        item->next->prev = item->prev;  /* First->prev changed to negative value */
469                                        item->next = NULL;
470                                        item->prev = NULL;
471                                }
472
473                                /* 15006C62 */
474                                if (p_item2 == NULL) {
475                                        p_item2 = PTR_PTR(&ht->first);
476                                }
477                                item->next = p_item2->next;             /* Set item with 0x100 byte value */
478                                item->prev = p_item2->next->prev;       /* Set item with 0x17 byte value */
479                                p_item2->next->prev = item;             /* Changed prev of item with */
480                                p_item2->next = item;
481                        }
482
483                        /* 15006C7B */
484                        if (PTR_INT((child1 = child2->prev)) <= 0) {
485                                break;
486                        }
487                }
488        }
489
490        /* 15006C88 */
491        ht->offs0004 = 1;
492}
493
494/* Gets the whole byte from the input stream. */
495static unsigned long libmpq_huff_get_8bits(struct huffman_input_stream *is) {
496        unsigned long one_byte;
497
498        if (is->bits <= 8) {
499                is->bit_buf |= *(unsigned short *)is->in_buf << is->bits;
500                is->in_buf  += sizeof(unsigned short);
501                is->bits    += 16;
502        }
503
504        one_byte      = (is->bit_buf & 0xFF);
505        is->bit_buf >>= 8;
506        is->bits     -= 8;
507
508        return one_byte;
509}
510
511/* Gets 7 bits from the stream. */
512static unsigned long libmpq_huff_get_7bits(struct huffman_input_stream *is) {
513        if (is->bits <= 7) {
514                is->bit_buf |= *(unsigned short *)is->in_buf << is->bits;
515                is->in_buf  += sizeof(unsigned short);
516                is->bits    += 16;
517        }
518
519        /* Get 7 bits from input stream. */
520        return (is->bit_buf & 0x7F);
521}
522
523/* Gets one bit from input stream. */
524unsigned long libmpq_huff_get_bit(struct huffman_input_stream *is) {
525        unsigned long bit = (is->bit_buf & 1);
526
527        is->bit_buf >>= 1;
528        if (--is->bits == 0) {
529                is->bit_buf  = *(unsigned long *)is->in_buf;
530                is->in_buf  += sizeof(unsigned long);
531                is->bits     = 32;
532        }
533        return bit;
534}
535
536static struct huffman_tree_item *libmpq_huff_call1500E740(struct huffman_tree *ht, unsigned int value) {
537        struct huffman_tree_item *p_item1 = ht->item3058;       /* EDX */
538        struct huffman_tree_item *p_item2;                      /* EAX */
539        struct huffman_tree_item *p_next;
540        struct huffman_tree_item *p_prev;
541        struct huffman_tree_item **pp_item;
542
543        if (PTR_INT(p_item1) <= 0 || (p_item2 = p_item1) == NULL) {
544                if((p_item2 = &ht->items0008[ht->items++]) != NULL) {
545                        p_item1 = p_item2;
546                } else {
547                        p_item1 = ht->first;
548                }
549        } else {
550                p_item1 = p_item2;
551        }
552
553        p_next = p_item1->next;
554        if (p_next != NULL) {
555                p_prev = p_item1->prev;
556                if (PTR_INT(p_prev) <= 0) {
557                        p_prev = PTR_NOT(p_prev);
558                } else {
559                        p_prev += (p_item1 - p_item1->next->prev);
560                }
561
562                p_prev->next = p_next;
563                p_next->prev = p_prev;
564                p_item1->next = NULL;
565                p_item1->prev = NULL;
566        }
567        pp_item = &ht->first;                           /* ESI */
568        if (value > 1) {
569
570                /* ECX = ht->first->next; */
571                p_item1->next = *pp_item;
572                p_item1->prev = (*pp_item)->prev;
573
574                (*pp_item)->prev = p_item2;
575                *pp_item = p_item1;
576
577                p_item2->parent = NULL;
578                p_item2->child  = NULL;
579        } else {
580                p_item1->next = (struct huffman_tree_item *)pp_item;
581                p_item1->prev = pp_item[1];
582                /* EDI = ht->item305C; */
583                p_prev = pp_item[1];                    /* ECX */
584                if (p_prev <= 0) {
585                        p_prev = PTR_NOT(p_prev);
586                        p_prev->next = p_item1;
587                        p_prev->prev = p_item2;
588
589                        p_item2->parent = NULL;
590                        p_item2->child  = NULL;
591                } else {
592                        if (PTR_INT(ht->item305C) < 0) {
593                                p_prev += (struct huffman_tree_item *)pp_item - (*pp_item)->prev;
594                        } else {
595                                p_prev += PTR_INT(ht->item305C);
596                        }
597
598                        p_prev->next    = p_item1;
599                        pp_item[1]      = p_item2;
600                        p_item2->parent = NULL;
601                        p_item2->child  = NULL;
602                }
603        }
604        return p_item2;
605}
606
607static void libmpq_huff_call1500E820(struct huffman_tree *ht, struct huffman_tree_item *p_item) {
608        struct huffman_tree_item *p_item1;              /* EDI */
609        struct huffman_tree_item *p_item2 = NULL;       /* EAX */
610        struct huffman_tree_item *p_item3;              /* EDX */
611        struct huffman_tree_item *p_prev;               /* EBX */
612
613        for (; p_item != NULL; p_item = p_item->parent) {
614                p_item->byte_value++;
615
616                for (p_item1 = p_item; ; p_item1 = p_prev) {
617                        p_prev = p_item1->prev;
618                        if (PTR_INT(p_prev) <= 0) {
619                                p_prev = NULL;
620                                break;
621                        }
622                        if (p_prev->byte_value >= p_item->byte_value) {
623                                break;
624                        }
625                }
626
627                if (p_item1 == p_item) {
628                        continue;
629                }
630
631                if (p_item1->next != NULL) {
632                        p_item2 = libmpq_huff_get_prev_item(p_item1, -1);
633                        p_item2->next = p_item1->next;
634                        p_item1->next->prev = p_item1->prev;
635                        p_item1->next = NULL;
636                        p_item1->prev = NULL;
637                }
638                p_item2 = p_item->next;
639                p_item1->next = p_item2;
640                p_item1->prev = p_item2->prev;
641                p_item2->prev = p_item1;
642                p_item->next = p_item1;
643                if ((p_item2 = p_item1) != NULL) {
644                        p_item2 = libmpq_huff_get_prev_item(p_item, -1);
645                        p_item2->next = p_item->next;
646                        p_item->next->prev = p_item->prev;
647                        p_item->next = NULL;
648                        p_item->prev = NULL;
649                }
650
651                if (p_prev == NULL) {
652                        p_prev = PTR_PTR(&ht->first);
653                }
654                p_item2       = p_prev->next;
655                p_item->next  = p_item2;
656                p_item->prev  = p_item2->prev;
657                p_item2->prev = p_item;
658                p_prev->next  = p_item;
659
660                p_item3 = p_item1->parent->child;
661                p_item2 = p_item->parent;
662                if (p_item2->child == p_item) {
663                        p_item2->child = p_item1;
664                }
665
666                if (p_item3 == p_item1) {
667                        p_item1->parent->child = p_item;
668                }
669
670                p_item2 = p_item->parent;
671                p_item->parent  = p_item1->parent;
672                p_item1->parent = p_item2;
673                ht->offs0004++;
674        }
675}
676
677int libmpq_huff_do_decompress(struct huffman_tree *ht, struct huffman_input_stream *is, unsigned char *out_buf, unsigned int out_length) {
678        unsigned int n8bits;                            /* 8 bits loaded from input stream */
679        unsigned int n7bits;                            /* 7 bits loaded from input stream */
680        unsigned int found;                             /* Thats needed to replace the goto stuff from original source :) */
681        unsigned int dcmp_byte = 0;
682        unsigned long bit_count;
683        struct huffman_decompress *qd;
684        unsigned int has_qd;                            /* Can we use quick decompression? */
685        struct huffman_tree_item *p_item1;
686        struct huffman_tree_item *p_item2;
687        unsigned char *out_pos = out_buf;
688
689        /* Test the output length. Must not be non zero. */
690        if (out_length == 0) {
691                return 0;
692        }
693
694        /* Get the compression type from the input stream. */
695        n8bits = libmpq_huff_get_8bits(is);
696
697        /* Build the Huffman tree */
698        libmpq_huff_build_tree(ht, n8bits);
699        ht->cmp0 = (n8bits == 0) ? TRUE : FALSE;
700
701        for(;;) {
702                n7bits = libmpq_huff_get_7bits(is);     /* Get 7 bits from input stream */
703
704                /*
705                 * Try to use quick decompression. Check huffman_decompress array for corresponding item.
706                 * If found, use the result byte instead.
707                 */
708                qd = &ht->qd3474[n7bits];
709
710                /* If there is a quick-pass possible (ebx) */
711                has_qd = (qd->offs00 >= ht->offs0004) ? TRUE : FALSE;
712
713                /* If we can use quick decompress, use it. */
714                if (has_qd) {
715                        found = 0;
716                        if (qd->bits > 7) {
717                                is->bit_buf >>= 7;
718                                is->bits -= 7;
719                                p_item1 = qd->p_item;
720                                found = 1;
721                        }
722                        if (found == 0) {
723                                is->bit_buf >>= qd->bits;
724                                is->bits     -= qd->bits;
725                                dcmp_byte     = qd->dcmp_byte;
726                        }
727                } else {
728                        found = 1;
729                        p_item1 = ht->first->next->prev;
730                        if (PTR_INT(p_item1) <= 0) {
731                                p_item1 = NULL;
732                        }
733                }
734
735                if (found == 1) {
736                        bit_count = 0;
737                        p_item2 = NULL;
738                        do {
739                                p_item1 = p_item1->child;       /* Move down by one level */
740                                if (libmpq_huff_get_bit(is)) {  /* If current bit is set, move to previous */
741                                        p_item1 = p_item1->prev;
742                                }
743                                if (++bit_count == 7) {         /* If we are at 7th bit, save current huffman tree item. */
744                                        p_item2 = p_item1;
745                                }
746                        } while (p_item1->child != NULL);       /* Walk until tree has no deeper level */
747
748                        if (has_qd == FALSE) {
749                                if (bit_count > 7) {
750                                        qd->offs00 = ht->offs0004;
751                                        qd->bits   = bit_count;
752                                        qd->p_item = p_item2;
753                                } else {
754                                        unsigned long index = n7bits & (0xFFFFFFFF >> (32 - bit_count));
755                                        unsigned long add   = (1 << bit_count);
756
757                                        for (qd = &ht->qd3474[index]; index <= 0x7F; index += add, qd += add) {
758                                                qd->offs00    = ht->offs0004;
759                                                qd->bits      = bit_count;
760                                                qd->dcmp_byte = p_item1->dcmp_byte;
761                                        }
762                                }
763                        }
764                        dcmp_byte = p_item1->dcmp_byte;
765                }
766
767                if (dcmp_byte == 0x101) {               /* Huffman tree needs to be modified */
768                        n8bits  = libmpq_huff_get_8bits(is);
769                        p_item1 = (ht->last <= 0) ? NULL : ht->last;
770
771                        p_item2 = libmpq_huff_call1500E740(ht, 1);
772                        p_item2->parent     = p_item1;
773                        p_item2->dcmp_byte  = p_item1->dcmp_byte;
774                        p_item2->byte_value = p_item1->byte_value;
775                        ht->items306C[p_item2->dcmp_byte] = p_item2;
776
777                        p_item2 = libmpq_huff_call1500E740(ht, 1);
778                        p_item2->parent     = p_item1;
779                        p_item2->dcmp_byte  = n8bits;
780                        p_item2->byte_value = 0;
781                        ht->items306C[p_item2->dcmp_byte] = p_item2;
782
783                        p_item1->child = p_item2;
784                        libmpq_huff_call1500E820(ht, p_item2);
785                        if (ht->cmp0 == 0) {
786                                libmpq_huff_call1500E820(ht, ht->items306C[n8bits]);
787                        }
788                        dcmp_byte = n8bits;
789                }
790
791                if (dcmp_byte == 0x100) {
792                        break;
793                }
794
795                *out_pos++ = (unsigned char)dcmp_byte;
796                if (--out_length == 0) {
797                        break;
798                }
799                if (ht->cmp0) {
800                        libmpq_huff_call1500E820(ht, ht->items306C[dcmp_byte]);
801                }
802        }
803        return (out_pos - out_buf);
804}
805
806int libmpq_huff_init_tree(struct huffman_tree *ht, struct huffman_tree_item *hi, unsigned int cmp) {
807        int count;
808
809        /* Clear links for all the items in the tree */
810        for (hi = ht->items0008, count = 0x203; count != 0; hi++, count--) {
811                hi->next = hi->prev = NULL;
812        }
813
814        ht->item3050 = NULL;
815        ht->item3054 = PTR_PTR(&ht->item3054);
816        ht->item3058 = PTR_NOT(ht->item3054);
817
818        ht->item305C = NULL;
819        ht->first    = PTR_PTR(&ht->first);
820        ht->last     = PTR_NOT(ht->first);
821
822        ht->offs0004 = 1;
823        ht->items    = 0;
824
825        /* Clear all huffman_decompress items. Do this only if preparing for decompression */
826        if (cmp == LIBMPQ_HUFF_DECOMPRESS) {
827                for (count = 0; count < sizeof(ht->qd3474) / sizeof(struct huffman_decompress); count++) {
828                        ht->qd3474[count].offs00 = 0;
829                }
830        }
831
832    return 0;
833}
Note: See TracBrowser for help on using the browser.