git.lucas.co / go_mono
git clone https://git.lucas.co/go_mono.git

tiff/compress.go (1.1K)

 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 
 5 package tiff
 6 
 7 import (
 8 	"bufio"
 9 	"io"
10 )
11 
12 type 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.
22 func 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 }