compress.go raw

   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  }
  59