Subversion Repositories pentevo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
969 dimkam 1
// this is not a code to be separately compiled!
2
// instead, it is included in mhmt-depack.c several times and depends on existing at include moment #define's to generate some compiling code
3
//
4
//                   // example defines:
5
//#define DPK_CHECK  // check input stream for consistency
6
//#define DPK_DEPACK // do depacking
7
//#define DPK_REPERR // report errors via printf
8
{
9
        ULONG check;
10
        ULONG byte,bits,bitlen;
11
        LONG disp;
12
        ULONG length;
13
 
14
        ULONG stop;
15
 
16
 
17
        ULONG success = 1;
18
 
19
 
20
 
21
 
22
 
23
        // rewind input stream
24
        //
25
        check = depack_getbyte(DEPACK_GETBYTE_REWIND);
26
#ifdef DPK_CHECK
27
        if( 0xFFFFFFFF == check )
28
        {
29
 #ifdef DPK_REPERR
30
                printf("mhmt-depack-megalz.c:{} - Can't rewind input stream!\n");
31
 #endif
32
                return 0;
33
        }
34
#endif
35
 
36
 
37
        // first byte of input stream goes to the output unchanged
38
        //
39
        byte = depack_getbyte(DEPACK_GETBYTE_NEXT);
40
#ifdef DPK_CHECK
41
        if( 0xFFFFFFFF == byte )
42
        {
43
NO_BYTE:
44
 #ifdef DPK_REPERR
45
                printf("mhmt-depack-megalz.c:{} - Can't get byte from input stream!\n");
46
 #endif
47
                return 0;
48
        }
49
#endif
50
 
51
#ifdef DPK_DEPACK
52
        success = success && depack_outbyte( (UBYTE)(0x00FF&byte), DEPACK_OUTBYTE_ADD );
53
#endif
54
 
55
 
56
#ifdef DPK_CHECK
57
 #ifdef DPK_REPERR
58
 #endif
59
#endif
60
        // next is byte to the bitstream
61
        //
62
        check = depack_getbits(8,DEPACK_GETBITS_FORCE);
63
#ifdef DPK_CHECK
64
        if( 0xFFFFFFFF == check )
65
        {
66
NO_BITS:
67
 #ifdef DPK_REPERR
68
                printf("mhmt-depack-megalz.c:{} - Can't get bits from input stream!\n");
69
 #endif
70
                return 0;
71
        }
72
#endif
73
 
74
 
75
 
76
        // now normal depacking loop
77
        //
78
        stop = 0;
79
        while( (!stop) && success )
80
        {
81
                bits = depack_getbits(1,DEPACK_GETBITS_NEXT);
82
#ifdef DPK_CHECK
83
                if( 0xFFFFFFFF == bits ) goto NO_BITS;
84
#endif
85
 
86
                if( 1&bits ) // %1<byte>
87
                {
88
                        byte = depack_getbyte(DEPACK_GETBYTE_NEXT);
89
#ifdef DPK_CHECK
90
                        if( 0xFFFFFFFF == byte ) goto NO_BYTE;
91
#endif
92
 
93
#ifdef DPK_DEPACK
94
                        success = success && depack_outbyte( (UBYTE)(0x00FF&byte), DEPACK_OUTBYTE_ADD );
95
#endif
96
                }
97
                else // %0xx
98
                {
99
                        bits = depack_getbits(2,DEPACK_GETBITS_NEXT);
100
#ifdef DPK_CHECK
101
                        if( 0xFFFFFFFF == bits ) goto NO_BITS;
102
#endif
103
 
104
                        switch( 0x03 & bits )
105
                        {
106
                        case 0x00: // %000xxx
107
 
108
                                bits = depack_getbits(3,DEPACK_GETBITS_NEXT);
109
#ifdef DPK_CHECK
110
                                if( 0xFFFFFFFF == bits ) goto NO_BITS;
111
#endif
112
 
113
                                disp = (-8) | (bits&0x07); // FFFFFFF8..FFFFFFFF (-8..-1)
114
#ifdef DPK_CHECK
115
                                if( (ULONG)(-disp) > wrk.maxwin )
116
                                {
117
WRONG_DISP:
118
 #ifdef DPK_REPERR
119
                                        printf("mhmt-depack-megalz.c:{} - Wrong lookback displacement of %d, greater than maxwin\n",(-disp) );
120
 #endif
121
                                        return 0;
122
                                }
123
#endif
124
 
125
#ifdef DPK_DEPACK
126
                                success = success && depack_repeat(disp,1);
127
#endif
128
                                break;
129
 
130
 
131
                        case 0x01: // %001
132
 
133
                                byte = depack_getbyte(DEPACK_GETBYTE_NEXT);
134
#ifdef DPK_CHECK
135
                                if( 0xFFFFFFFF == byte ) goto NO_BYTE;
136
#endif
137
 
138
                                disp = (-256) | (0x00FF&byte); // -1..-256
139
#ifdef DPK_CHECK
140
                                if( (ULONG)(-disp) > wrk.maxwin ) goto WRONG_DISP;
141
#endif
142
 
143
#ifdef DPK_DEPACK
144
                                success = success && depack_repeat(disp,2);
145
#endif
146
                                break;
147
 
148
 
149
                        case 0x02: // %010
150
 
151
                                length = 3;
152
FAR_DISP:
153
                                bits = depack_getbits(1,DEPACK_GETBITS_NEXT);
154
#ifdef DPK_CHECK
155
                                if( 0xFFFFFFFF == bits ) goto NO_BITS;
156
#endif
157
                                if( !(1&bits) ) // -1..-256
158
                                {
159
                                        byte = depack_getbyte(DEPACK_GETBYTE_NEXT);
160
#ifdef DPK_CHECK
161
                                        if( 0xFFFFFFFF == byte ) goto NO_BYTE;
162
#endif
163
                                        disp = (-256) | (0x00FF&byte); // -1..-256
164
#ifdef DPK_CHECK
165
                                        if( (ULONG)(-disp) > wrk.maxwin ) goto WRONG_DISP;
166
#endif
167
 
168
#ifdef DPK_DEPACK
169
                                        success = success && depack_repeat(disp,length);
170
#endif
171
                                }
172
                                else // -257..-4352
173
                                {
174
                                        bits = depack_getbits(4,DEPACK_GETBITS_NEXT);
175
#ifdef DPK_CHECK
176
                                        if( 0xFFFFFFFF == bits ) goto NO_BITS;
177
#endif
178
                                        byte = depack_getbyte(DEPACK_GETBYTE_NEXT);
179
#ifdef DPK_CHECK
180
                                        if( 0xFFFFFFFF == byte ) goto NO_BYTE;
181
#endif
182
                                        disp = ( ((-16)|(15&bits)) - 1 )*0x100 + byte;
183
#ifdef DPK_CHECK
184
                                        if( (ULONG)(-disp) > wrk.maxwin ) goto WRONG_DISP;
185
#endif
186
 
187
#ifdef DPK_DEPACK
188
                                        success = success && depack_repeat(disp,length);
189
#endif
190
                                }
191
 
192
                                break;
193
 
194
 
195
                        case 0x03: // %011 - variable length
196
 
197
                                bitlen = 0;
198
                                do
199
                                {
200
                                        bits = depack_getbits(1,DEPACK_GETBITS_NEXT);
201
#ifdef DPK_CHECK
202
                                        if( 0xFFFFFFFF == bits ) goto NO_BITS;
203
#endif
204
                                        bitlen++;
205
 
206
                                } while ( !(1&bits) );
207
 
208
                                if( bitlen==9 ) // happy final! WARNING: does not check whether there is remaining of input stream left unused!
209
                                {
210
                                        stop = 1;
211
                                        break; // exit switch(){}
212
                                }
213
#ifdef DPK_CHECK
214
                                if( bitlen>7 )
215
                                {
216
 #ifdef DPK_REPERR
217
                                        printf("mhmt-depack-megalz.c:{} - Wrong LZ code\n");
218
 #endif
219
                                        return 0;
220
                                }
221
#endif
222
                                bits = depack_getbits(bitlen,DEPACK_GETBITS_NEXT);
223
#ifdef DPK_CHECK
224
                                if( 0xFFFFFFFF == bits ) goto NO_BITS;
225
#endif
226
                                length = 2 + (1<<bitlen) + ( bits & ((1<<bitlen)-1) );
227
#ifdef DPK_CHECK
228
                                if( length>255 )
229
                                {
230
 #ifdef DPK_REPERR
231
                                        printf("mhmt-depack-megalz.c:{} - Wrong LZ code\n");
232
 #endif
233
                                        return 0;
234
                                }
235
#endif
236
                                goto FAR_DISP;
237
 
238
                                break;
239
                        }
240
                }
241
 
242
        }
243
 
244
        return success;
245
}