Repository: go
Issue: x/image/tiff: CCITT reader EOF error for tiff image
Labels: NeedsInvestigation

<!--
Please answer these questions before submitting your issue. Thanks!
For questions please use one of our forums: https://github.com/golang/go/wiki/Questions
-->

### What version of Go are you using (`go version`)?

<pre>
$ go version
go version go1.14.4 linux/amd64
</pre>

### Does this issue reproduce with the latest release?

With last `master` branch.

### What operating system and processor architecture are you using (`go env`)?

<details><summary><code>go env</code> Output</summary><br><pre>
$ go env
GO111MODULE="on"
GOARCH="amd64"
GOBIN="/home/x/go/bin"
GOCACHE="/home/x/.cache/go-build"
GOENV="/home/x/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/x/go"
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/lib/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build670162663=/tmp/go-build -gno-record-gcc-switches"
</pre></details>

### What did you do?

Tiff file used to get an error [debug_26428.zip](https://github.com/golang/go/files/4803989/debug_26428.zip) (compressed with zip, extract it for usage). Length of tiff file is: `26428` bytes.

I've created test cases that can be used for `tiff` and `ccitt` package. Because it is called with `tiff.Decode()`, but error is in `ccitt.decodeEOL()`.

#### tiff 

Copy extracted tiff to [root testdata](https://github.com/golang/image/tree/master/testdata) and copy this test case to [`tiff.reader_test.go`](https://github.com/golang/image/blob/master/tiff/reader_test.go)

```go
func TestTiffDecodeOfCCITTEndOfLine(t *testing.T) {
	b, err := ioutil.ReadFile("../testdata/debug_26428.tiff")
	if err != nil {
		t.Fatalf("Read File: %v", err)
	}
	if _, err = Decode(bytes.NewReader(b)); err != nil {
		t.Errorf("Shouldn't error, but got err: %v", err)
	}
}
```

Output:

```
--- FAIL: TestTiffDecodeOfCCITTEndOfLine (0.02s)
    reader_test.go:68: Shouldn't error, but got err: ccitt: missing End-of-Line
```


#### ccitt

Copy extracted tiff to [`ccitt` testdata](https://github.com/golang/image/tree/master/ccitt/testdata) and copy this test to [`ccitt.reader_test.go`](https://github.com/golang/image/blob/master/ccitt/reader_test.go)

Data taken from actual debugging for this file, when called with `tiff.Decode()`.

```go
func TestReadEndOfLineError(t *testing.T) {
	f, err := os.Open("testdata/debug_26428.tiff")
	if err != nil {
		t.Fatalf("Open: %v", err)
	}
	defer f.Close()
	const width, height = 2481, 3508
	opts := &Options{
		Align:  false,
		Invert: true,
	}
	offset := 160
	n := 26268
	if _, err := ioutil.ReadAll(NewReader(io.NewSectionReader(f, int64(offset), int64(n)), MSB, Group4, width, height, opts)); err != nil {
		t.Fatalf("Shouldn't error but got error: %v", err)
	}
}
```

Output:

```
--- FAIL: TestReadEndOfLineError (0.03s)
    reader_test.go:411: Shouldn't error but got error: ccitt: missing End-of-Line
```



### What works for this case

I'm not even remotely expert on specs for TIFF and ccitt, but I've changed last return from `return errMissingEOL` to  `return nil` and I'm getting correct image and everything works fine and tried in many files (mostly all scanned textual with images, and all B/W) and I've see no problems with this fix/hack.

```go
// decodeEOL decodes the 12-bit EOL code 0000_0000_0001.
func decodeEOL(b *bitReader) error {
	nBitsRead, bitsRead := uint32(0), uint64(0)
	for {
		bit, err := b.nextBit()
		if err != nil {
			if err == io.EOF {
				err = errMissingEOL
			}
			return err
		}
		bitsRead |= bit << (63 - nBitsRead)
		nBitsRead++

		if nBitsRead < 12 {
			if bit&1 == 0 {
				continue
			}
		} else if bit&1 != 0 {
			return nil
		}

		// Unread the bits we've read, then return errMissingEOL.
		b.bits = (b.bits >> nBitsRead) | bitsRead
		b.nBits += nBitsRead

                // Changing from errMissingEOL to nil works for this case
		// return errMissingEOL
               return nil
	}
}
```

### Request

Can anybody see in TIFF provided, run this tests, maybe do better "fix".  Because with this applied `ccitt` test `TestRead` fails with output:

```
--- FAIL: TestRead (0.00s)
    reader_test.go:437: AutoDetectHeight produced different output.
```

Thanks