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}