forked from google/tiff
/
image.go
102 lines (88 loc) · 2.64 KB
/
image.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package image
import (
"fmt"
"image"
"io"
"github.com/google/tiff"
"github.com/google/tiff/bigtiff"
"github.com/google/tiff/tiff85"
)
type Decoder interface {
Image() (image.Image, error)
Config() (image.Config, error)
}
type TIFFHandler interface {
Decoder(tiff.TIFF) (Decoder, error)
CanHandle(tiff.TIFF) bool
}
type IFDHandler interface {
Decoder(tiff.IFD, tiff.BReader) (Decoder, error)
CanHandle(tiff.IFD) bool
}
func validateTIFF(t tiff.TIFF) error {
if len(t.IFDs()) == 0 {
return fmt.Errorf("tiff/image: no IFDs present in tiff to process")
}
if t.IFDs()[0] == nil {
return fmt.Errorf("tiff/image: IFD 0 is nil")
}
if t.IFDs()[0].NumEntries() == 0 || len(t.IFDs()[0].Fields()) == 0 {
return fmt.Errorf("tiff/image: no entries found in IFD 0")
}
return nil
}
func getDecoder(t tiff.TIFF) (dec Decoder, err error) {
if err = validateTIFF(t); err != nil {
return
}
// Look for alternates that can handle the whole tiff.
if handlr := findAlternateTIFFHandler(t); handlr != nil {
return handlr.Decoder(t)
}
// Look for alternates that can handle specific IFDs.
for _, ifd := range t.IFDs() {
if handlr := findAlternateIFDHandler(ifd); handlr != nil {
return handlr.Decoder(ifd, t.R())
}
}
// If no alternates are found... do our own thing as best we can, which
// means baseline support only.
ifd0 := t.IFDs()[0]
if !new(BaselineHandler).CanHandle(ifd0) {
return nil, fmt.Errorf("tiff/image: no handlers available for this tiff")
}
return new(BaselineHandler).Decoder(ifd0, t.R())
}
func Decode(r io.Reader) (img image.Image, err error) {
var dec Decoder
var t tiff.TIFF
if t, err = tiff.Parse(tiff.NewReadAtReadSeeker(r), nil, nil); err != nil {
return
}
if dec, err = getDecoder(t); err != nil {
return
}
return dec.Image()
}
func DecodeConfig(r io.Reader) (cfg image.Config, err error) {
var dec Decoder
var t tiff.TIFF
if t, err = tiff.Parse(tiff.NewReadAtReadSeeker(r), nil, nil); err != nil {
return
}
if dec, err = getDecoder(t); err != nil {
return
}
return dec.Config()
}
func init() {
image.RegisterFormat("tiff", tiff.MagicBigEndian, Decode, DecodeConfig)
image.RegisterFormat("tiff", tiff.MagicLitEndian, Decode, DecodeConfig)
image.RegisterFormat("bigtiff", bigtiff.MagicBigEndian, Decode, DecodeConfig)
image.RegisterFormat("bigtiff", bigtiff.MagicLitEndian, Decode, DecodeConfig)
image.RegisterFormat("tiff85", tiff85.MagicBigEndian, Decode, DecodeConfig)
image.RegisterFormat("tiff85", tiff85.MagicLitEndian, Decode, DecodeConfig)
}