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