@@ -6,164 +6,100 @@ namespace ICSharpCode.SharpZipLib.Zip.Compression
6
6
class InflaterDynHeader
7
7
{
8
8
#region Constants
9
- const int LNUM = 0 ;
10
- const int DNUM = 1 ;
11
- const int BLNUM = 2 ;
12
- const int BLLENS = 3 ;
13
- const int LENS = 4 ;
14
- const int REPS = 5 ;
15
-
16
- static readonly int [ ] repMin = { 3 , 3 , 11 } ;
17
- static readonly int [ ] repBits = { 2 , 3 , 7 } ;
18
9
19
10
static readonly int [ ] BL_ORDER =
20
11
{ 16 , 17 , 18 , 0 , 8 , 7 , 9 , 6 , 10 , 5 , 11 , 4 , 12 , 3 , 13 , 2 , 14 , 1 , 15 } ;
21
12
#endregion
22
13
23
14
public bool Decode ( StreamManipulator input )
24
15
{
25
- decode_loop :
26
- for ( ; ; ) {
27
- switch ( mode ) {
28
- case LNUM :
29
- lnum = input . PeekBits ( 5 ) ;
30
- if ( lnum < 0 ) {
31
- return false ;
32
- }
33
- lnum += 257 ;
34
- input . DropBits ( 5 ) ;
35
- // System.err.println("LNUM: "+lnum);
36
- mode = DNUM ;
37
- goto case DNUM ; // fall through
38
- case DNUM :
39
- dnum = input . PeekBits ( 5 ) ;
40
- if ( dnum < 0 ) {
41
- return false ;
42
- }
43
- dnum ++ ;
44
- input . DropBits ( 5 ) ;
45
- // System.err.println("DNUM: "+dnum);
46
- num = lnum + dnum ;
47
- litdistLens = new byte [ num ] ;
48
- mode = BLNUM ;
49
- goto case BLNUM ; // fall through
50
- case BLNUM :
51
- blnum = input . PeekBits ( 4 ) ;
52
- if ( blnum < 0 ) {
53
- return false ;
54
- }
55
- blnum += 4 ;
56
- input . DropBits ( 4 ) ;
57
- blLens = new byte [ 19 ] ;
58
- ptr = 0 ;
59
- // System.err.println("BLNUM: "+blnum);
60
- mode = BLLENS ;
61
- goto case BLLENS ; // fall through
62
- case BLLENS :
63
- while ( ptr < blnum ) {
64
- int len = input . PeekBits ( 3 ) ;
65
- if ( len < 0 ) {
66
- return false ;
67
- }
68
- input . DropBits ( 3 ) ;
69
- // System.err.println("blLens["+BL_ORDER[ptr]+"]: "+len);
70
- blLens [ BL_ORDER [ ptr ] ] = ( byte ) len ;
71
- ptr ++ ;
16
+ try
17
+ {
18
+ lnum = input . GrabBits ( 5 ) + 257 ;
19
+ dnum = input . GrabBits ( 5 ) + 1 ;
20
+ blnum = input . GrabBits ( 4 ) + 4 ;
21
+ num = lnum + dnum ;
22
+
23
+ lengths = new byte [ 19 ] ;
24
+
25
+ for ( int i = 0 ; i < blnum ; i ++ )
26
+ {
27
+ lengths [ BL_ORDER [ i ] ] = ( byte ) input . GrabBits ( 3 , true ) ;
28
+ }
29
+ blTree = new InflaterHuffmanTree ( lengths ) ;
30
+ lengths = new byte [ num ] ;
31
+
32
+ int index = 0 ;
33
+ while ( index < lnum + dnum )
34
+ {
35
+ byte len ;
36
+
37
+ int symbol = blTree . GetSymbol ( input ) ;
38
+ if ( symbol < 0 )
39
+ return false ;
40
+ if ( symbol < 16 )
41
+ lengths [ index ++ ] = ( byte ) symbol ;
42
+ else
43
+ {
44
+ len = 0 ;
45
+ if ( symbol == 16 )
46
+ {
47
+ if ( index == 0 )
48
+ return false ; // No last length!
49
+ len = lengths [ index - 1 ] ;
50
+ symbol = input . GrabBits ( 2 , true ) + 3 ;
72
51
}
73
- blTree = new InflaterHuffmanTree ( blLens ) ;
74
- blLens = null ;
75
- ptr = 0 ;
76
- mode = LENS ;
77
- goto case LENS ; // fall through
78
- case LENS : {
79
- int symbol ;
80
- while ( ( ( symbol = blTree . GetSymbol ( input ) ) & ~ 15 ) == 0 ) {
81
- /* Normal case: symbol in [0..15] */
82
-
83
- // System.err.println("litdistLens["+ptr+"]: "+symbol);
84
- litdistLens [ ptr ++ ] = lastLen = ( byte ) symbol ;
85
-
86
- if ( ptr == num ) {
87
- /* Finished */
88
- return true ;
89
- }
90
- }
91
-
92
- /* need more input ? */
93
- if ( symbol < 0 ) {
94
- return false ;
95
- }
96
-
97
- /* otherwise repeat code */
98
- if ( symbol >= 17 ) {
99
- /* repeat zero */
100
- // System.err.println("repeating zero");
101
- lastLen = 0 ;
102
- } else {
103
- if ( ptr == 0 ) {
104
- throw new SharpZipBaseException ( ) ;
105
- }
106
- }
107
- repSymbol = symbol - 16 ;
52
+ else if ( symbol == 17 )
53
+ {
54
+ // repeat zero 3..10 times
55
+ symbol = input . GrabBits ( 3 , true ) + 3 ;
108
56
}
109
- mode = REPS ;
110
- goto case REPS ; // fall through
111
- case REPS : {
112
- int bits = repBits [ repSymbol ] ;
113
- int count = input . PeekBits ( bits ) ;
114
- if ( count < 0 ) {
115
- return false ;
116
- }
117
- input . DropBits ( bits ) ;
118
- count += repMin [ repSymbol ] ;
119
- // System.err.println("litdistLens repeated: "+count);
120
-
121
- if ( ptr + count > num ) {
122
- throw new SharpZipBaseException ( ) ;
123
- }
124
- while ( count -- > 0 ) {
125
- litdistLens [ ptr ++ ] = lastLen ;
126
- }
127
-
128
- if ( ptr == num ) {
129
- /* Finished */
130
- return true ;
131
- }
57
+ else
58
+ {
59
+ // (symbol == 18), repeat zero 11..138 times
60
+ symbol = input . GrabBits ( 7 , true ) + 11 ;
132
61
}
133
- mode = LENS ;
134
- goto decode_loop ;
62
+
63
+ if ( index + symbol > lnum + dnum )
64
+ return false ; // too many lengths!
65
+
66
+ // repeat last or zero symbol times
67
+ while ( symbol -- > 0 )
68
+ lengths [ index ++ ] = len ;
69
+ }
135
70
}
71
+
72
+ if ( lengths [ 256 ] == 0 )
73
+ return false ; // No end-of-block code!
74
+
75
+ return true ;
76
+ }
77
+ catch ( Exception x )
78
+ {
79
+ return false ;
136
80
}
137
81
}
138
82
139
83
public InflaterHuffmanTree BuildLitLenTree ( )
140
84
{
141
85
byte [ ] litlenLens = new byte [ lnum ] ;
142
- Array . Copy ( litdistLens , 0 , litlenLens , 0 , lnum ) ;
86
+ Array . Copy ( lengths , 0 , litlenLens , 0 , lnum ) ;
143
87
return new InflaterHuffmanTree ( litlenLens ) ;
144
88
}
145
89
146
90
public InflaterHuffmanTree BuildDistTree ( )
147
91
{
148
92
byte [ ] distLens = new byte [ dnum ] ;
149
- Array . Copy ( litdistLens , lnum , distLens , 0 , dnum ) ;
93
+ Array . Copy ( lengths , lnum , distLens , 0 , dnum ) ;
150
94
return new InflaterHuffmanTree ( distLens ) ;
151
95
}
152
96
153
97
#region Instance Fields
154
- byte [ ] blLens ;
155
- byte [ ] litdistLens ;
98
+ byte [ ] lengths ;
156
99
157
100
InflaterHuffmanTree blTree ;
158
101
159
- /// <summary>
160
- /// The current decode mode
161
- /// </summary>
162
- int mode ;
163
102
int lnum , dnum , blnum , num ;
164
- int repSymbol ;
165
- byte lastLen ;
166
- int ptr ;
167
103
#endregion
168
104
169
105
}
0 commit comments