compress.go

 1// Copyright 2011 The Go Authors. All rights reserved.
 2// Use of this source code is governed by a BSD-style
 3// license that can be found in the LICENSE file.
 4
 5package tiff
 6
 7import (
 8	"bufio"
 9	"io"
10)
11
12type byteReader interface {
13	io.Reader
14	io.ByteReader
15}
16
17// unpackBits decodes the PackBits-compressed data in src and returns the
18// uncompressed data.
19//
20// The PackBits compression format is described in section 9 (p. 42)
21// of the TIFF spec.
22func unpackBits(r io.Reader) ([]byte, error) {
23	buf := make([]byte, 128)
24	dst := make([]byte, 0, 1024)
25	br, ok := r.(byteReader)
26	if !ok {
27		br = bufio.NewReader(r)
28	}
29
30	for {
31		b, err := br.ReadByte()
32		if err != nil {
33			if err == io.EOF {
34				return dst, nil
35			}
36			return nil, err
37		}
38		code := int(int8(b))
39		switch {
40		case code >= 0:
41			n, err := io.ReadFull(br, buf[:code+1])
42			if err != nil {
43				return nil, err
44			}
45			dst = append(dst, buf[:n]...)
46		case code == -128:
47			// No-op.
48		default:
49			if b, err = br.ReadByte(); err != nil {
50				return nil, err
51			}
52			for j := 0; j < 1-code; j++ {
53				buf[j] = b
54			}
55			dst = append(dst, buf[:1-code]...)
56		}
57	}
58}