tiff/lzw: sync with the stdlib compress/lzw.

As noted at the top of reader.go, this package is a fork of the standard
library's LZW package, due to an "off by one" in the TIFF format. Grep
for "NOTE" in the Go code for more details.

This commit picks up an upstream change:
https://go-review.googlesource.com/14410 "tidy up some flush calls"

Picking up the more recent change:
https://go-review.googlesource.com/42032 "fix hi code overflow"
will be a follow-up commit, separate from this straightforward commit,
since it has a non-trivial interaction with that off by one.

Change-Id: Iaf795d11590b3e3e0891e3ea3f04b696de4243c9
Reviewed-on: https://go-review.googlesource.com/42191
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Nigel Tao 2017-04-30 16:25:07 +10:00
parent 3210c0296b
commit d442804300

View File

@ -147,6 +147,7 @@ func (d *decoder) Read(b []byte) (int, error) {
// litWidth is the width in bits of literal codes. // litWidth is the width in bits of literal codes.
func (d *decoder) decode() { func (d *decoder) decode() {
// Loop over the code stream, converting codes into decompressed bytes. // Loop over the code stream, converting codes into decompressed bytes.
loop:
for { for {
code, err := d.read(d) code, err := d.read(d)
if err != nil { if err != nil {
@ -154,8 +155,7 @@ func (d *decoder) decode() {
err = io.ErrUnexpectedEOF err = io.ErrUnexpectedEOF
} }
d.err = err d.err = err
d.flush() break
return
} }
switch { switch {
case code < d.clear: case code < d.clear:
@ -174,9 +174,8 @@ func (d *decoder) decode() {
d.last = decoderInvalidCode d.last = decoderInvalidCode
continue continue
case code == d.eof: case code == d.eof:
d.flush()
d.err = io.EOF d.err = io.EOF
return break loop
case code <= d.hi: case code <= d.hi:
c, i := code, len(d.output)-1 c, i := code, len(d.output)-1
if code == d.hi { if code == d.hi {
@ -206,8 +205,7 @@ func (d *decoder) decode() {
} }
default: default:
d.err = errors.New("lzw: invalid code") d.err = errors.New("lzw: invalid code")
d.flush() break loop
return
} }
d.last, d.hi = code, d.hi+1 d.last, d.hi = code, d.hi+1
if d.hi+1 >= d.overflow { // NOTE: the "+1" is where TIFF's LZW differs from the standard algorithm. if d.hi+1 >= d.overflow { // NOTE: the "+1" is where TIFF's LZW differs from the standard algorithm.
@ -219,13 +217,10 @@ func (d *decoder) decode() {
} }
} }
if d.o >= flushBuffer { if d.o >= flushBuffer {
d.flush() break
return
} }
} }
} // Flush pending output.
func (d *decoder) flush() {
d.toRead = d.output[:d.o] d.toRead = d.output[:d.o]
d.o = 0 d.o = 0
} }