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