...
Source file src/compress/lzw/reader.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package lzw
17
18
19
20
21 import (
22 "bufio"
23 "errors"
24 "fmt"
25 "io"
26 )
27
28
29 type Order int
30
31 const (
32
33 LSB Order = iota
34
35
36 MSB
37 )
38
39 const (
40 maxWidth = 12
41 decoderInvalidCode = 0xffff
42 flushBuffer = 1 << maxWidth
43 )
44
45
46
47 type decoder struct {
48 r io.ByteReader
49 bits uint32
50 nBits uint
51 width uint
52 read func(*decoder) (uint16, error)
53 litWidth int
54 err error
55
56
57
58
59
60
61
62
63
64
65
66
67
68 clear, eof, hi, overflow, last uint16
69
70
71
72
73
74
75 suffix [1 << maxWidth]uint8
76 prefix [1 << maxWidth]uint16
77
78
79
80
81
82
83
84
85 output [2 * 1 << maxWidth]byte
86 o int
87 toRead []byte
88 }
89
90
91 func (d *decoder) readLSB() (uint16, error) {
92 for d.nBits < d.width {
93 x, err := d.r.ReadByte()
94 if err != nil {
95 return 0, err
96 }
97 d.bits |= uint32(x) << d.nBits
98 d.nBits += 8
99 }
100 code := uint16(d.bits & (1<<d.width - 1))
101 d.bits >>= d.width
102 d.nBits -= d.width
103 return code, nil
104 }
105
106
107 func (d *decoder) readMSB() (uint16, error) {
108 for d.nBits < d.width {
109 x, err := d.r.ReadByte()
110 if err != nil {
111 return 0, err
112 }
113 d.bits |= uint32(x) << (24 - d.nBits)
114 d.nBits += 8
115 }
116 code := uint16(d.bits >> (32 - d.width))
117 d.bits <<= d.width
118 d.nBits -= d.width
119 return code, nil
120 }
121
122 func (d *decoder) Read(b []byte) (int, error) {
123 for {
124 if len(d.toRead) > 0 {
125 n := copy(b, d.toRead)
126 d.toRead = d.toRead[n:]
127 return n, nil
128 }
129 if d.err != nil {
130 return 0, d.err
131 }
132 d.decode()
133 }
134 }
135
136
137
138
139 func (d *decoder) decode() {
140
141 loop:
142 for {
143 code, err := d.read(d)
144 if err != nil {
145 if err == io.EOF {
146 err = io.ErrUnexpectedEOF
147 }
148 d.err = err
149 break
150 }
151 switch {
152 case code < d.clear:
153
154 d.output[d.o] = uint8(code)
155 d.o++
156 if d.last != decoderInvalidCode {
157
158 d.suffix[d.hi] = uint8(code)
159 d.prefix[d.hi] = d.last
160 }
161 case code == d.clear:
162 d.width = 1 + uint(d.litWidth)
163 d.hi = d.eof
164 d.overflow = 1 << d.width
165 d.last = decoderInvalidCode
166 continue
167 case code == d.eof:
168 d.err = io.EOF
169 break loop
170 case code <= d.hi:
171 c, i := code, len(d.output)-1
172 if code == d.hi && d.last != decoderInvalidCode {
173
174
175
176 c = d.last
177 for c >= d.clear {
178 c = d.prefix[c]
179 }
180 d.output[i] = uint8(c)
181 i--
182 c = d.last
183 }
184
185 for c >= d.clear {
186 d.output[i] = d.suffix[c]
187 i--
188 c = d.prefix[c]
189 }
190 d.output[i] = uint8(c)
191 d.o += copy(d.output[d.o:], d.output[i:])
192 if d.last != decoderInvalidCode {
193
194 d.suffix[d.hi] = uint8(c)
195 d.prefix[d.hi] = d.last
196 }
197 default:
198 d.err = errors.New("lzw: invalid code")
199 break loop
200 }
201 d.last, d.hi = code, d.hi+1
202 if d.hi >= d.overflow {
203 if d.width == maxWidth {
204 d.last = decoderInvalidCode
205
206
207
208 d.hi--
209 } else {
210 d.width++
211 d.overflow <<= 1
212 }
213 }
214 if d.o >= flushBuffer {
215 break
216 }
217 }
218
219 d.toRead = d.output[:d.o]
220 d.o = 0
221 }
222
223 var errClosed = errors.New("lzw: reader/writer is closed")
224
225 func (d *decoder) Close() error {
226 d.err = errClosed
227 return nil
228 }
229
230
231
232
233
234
235
236
237
238
239 func NewReader(r io.Reader, order Order, litWidth int) io.ReadCloser {
240 d := new(decoder)
241 switch order {
242 case LSB:
243 d.read = (*decoder).readLSB
244 case MSB:
245 d.read = (*decoder).readMSB
246 default:
247 d.err = errors.New("lzw: unknown order")
248 return d
249 }
250 if litWidth < 2 || 8 < litWidth {
251 d.err = fmt.Errorf("lzw: litWidth %d out of range", litWidth)
252 return d
253 }
254 if br, ok := r.(io.ByteReader); ok {
255 d.r = br
256 } else {
257 d.r = bufio.NewReader(r)
258 }
259 d.litWidth = litWidth
260 d.width = 1 + uint(litWidth)
261 d.clear = uint16(1) << uint(litWidth)
262 d.eof, d.hi = d.clear+1, d.clear+1
263 d.overflow = uint16(1) << d.width
264 d.last = decoderInvalidCode
265
266 return d
267 }
268
View as plain text