MM-14617 Dependency upgrades and adding modules support. (#10517)

* Dependency upgrades and adding modules support.

* Commenting out file tests playload verification portion.

* Fixing viper.

* Fixing hclog.
Этот коммит содержится в:
Christopher Speller
2019-04-10 07:56:17 -07:00
коммит произвёл GitHub
родитель bd8a54bb08
Коммит 41d117c37b
550 изменённых файлов: 22572 добавлений и 114088 удалений

275
vendor/github.com/rwcarlsen/goexif/exif/exif.go сгенерированный поставляемый
Просмотреть файл

@@ -3,14 +3,12 @@
package exif
import (
"bufio"
"bytes"
"encoding/binary"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
"math"
"strconv"
"strings"
@@ -140,10 +138,22 @@ var stagePrefix = map[tiffError]string{
loadInteroperability: "loading Interoperability sub-IFD",
}
type offsetReaderAt struct {
offset int64
r io.ReaderAt
}
func (r *offsetReaderAt) ReadAt(p []byte, off int64) (int, error) {
return r.r.ReadAt(p, off+r.offset)
}
// Parse reads data from the tiff data in x and populates the tags
// in x. If parsing a sub-IFD fails, the error is recorded and
// parsing continues with the remaining sub-IFDs.
func (p *parser) Parse(x *Exif) error {
if len(x.Tiff.Dirs) == 0 {
return errors.New("Invalid exif data")
}
x.LoadTags(x.Tiff.Dirs[0], exifFields, false)
// thumbnails
@@ -171,7 +181,6 @@ func (p *parser) Parse(x *Exif) error {
}
func loadSubDir(x *Exif, ptr FieldName, fieldMap map[uint16]FieldName) error {
r := bytes.NewReader(x.Raw)
tag, err := x.Get(ptr)
if err != nil {
@@ -182,11 +191,7 @@ func loadSubDir(x *Exif, ptr FieldName, fieldMap map[uint16]FieldName) error {
return nil
}
_, err = r.Seek(offset, 0)
if err != nil {
return fmt.Errorf("exif: seek to sub-IFD %s failed: %v", ptr, err)
}
subDir, _, err := tiff.DecodeDir(r, x.Tiff.Order)
subDir, _, err := tiff.DecodeDir(x.ReaderAt, x.Tiff.Order, uint32(offset))
if err != nil {
return fmt.Errorf("exif: sub-IFD %s decode failed: %v", ptr, err)
}
@@ -196,9 +201,12 @@ func loadSubDir(x *Exif, ptr FieldName, fieldMap map[uint16]FieldName) error {
// Exif provides access to decoded EXIF metadata fields and values.
type Exif struct {
Tiff *tiff.Tiff
main map[FieldName]*tiff.Tag
Raw []byte
Tiff *tiff.Tiff
main map[FieldName]*tiff.Tag
Raw []byte
ReaderAt io.ReaderAt
exifLength uint16
exifStart uint32
}
// Decode parses EXIF data from r (a TIFF, JPEG, or raw EXIF block)
@@ -210,6 +218,39 @@ type Exif struct {
// The error can be inspected with functions such as IsCriticalError
// to determine whether the returned object might still be usable.
func Decode(r io.Reader) (*Exif, error) {
reader := &readerToReaderAt{reader: r}
exif, err := LazyDecode(reader)
if err != nil {
return nil, err
}
_, err = exif.Tiff.LoadAllVals()
if err != nil {
return nil, err
}
if exif.exifLength > 0 {
exif.Raw = make([]byte, exif.exifLength)
_, err := exif.ReaderAt.ReadAt(exif.Raw, 0)
if err != nil {
return nil, decodeError{cause: err}
}
} else {
exif.Raw = reader.buffer[exif.exifStart:]
}
return exif, nil
}
// LazyDecode parses EXIF data from r (a TIFF, JPEG, or raw EXIF block)
// and returns a queryable Exif object. After the EXIF data section is
// called and the TIFF structure is decoded, each registered parser is
// called (in order of registration). If one parser returns an error,
// decoding terminates and the remaining parsers are not called.
//
// The error can be inspected with functions such as IsCriticalError
// to determine whether the returned object might still be usable.
//
// It differs from Decode as it only reads known exif fields and does not attempt to read the
// entire contents of the exif tiff subdirectory; the Exif.Raw field will be nil.
func LazyDecode(r io.ReaderAt) (*Exif, error) {
// EXIF data in JPEG is stored in the APP1 marker. EXIF data uses the TIFF
// format to store data.
@@ -217,84 +258,39 @@ func Decode(r io.Reader) (*Exif, error) {
// If we're parsing a JPEG image, we need to strip away the JPEG APP1
// marker and also the EXIF header.
header := make([]byte, 4)
n, err := io.ReadFull(r, header)
if err != nil {
return nil, fmt.Errorf("exif: error reading 4 byte header, got %d, %v", n, err)
}
var isTiff bool
var isRawExif bool
var assumeJPEG bool
switch string(header) {
case "II*\x00":
// TIFF - Little endian (Intel)
isTiff = true
case "MM\x00*":
// TIFF - Big endian (Motorola)
isTiff = true
case "Exif":
isRawExif = true
default:
// Not TIFF, assume JPEG
assumeJPEG = true
}
// Put the header bytes back into the reader.
r = io.MultiReader(bytes.NewReader(header), r)
var (
er *bytes.Reader
tif *tiff.Tiff
sec *appSec
)
switch {
case isRawExif:
var header [6]byte
if _, err := io.ReadFull(r, header[:]); err != nil {
return nil, fmt.Errorf("exif: unexpected raw exif header read error")
}
if got, want := string(header[:]), "Exif\x00\x00"; got != want {
return nil, fmt.Errorf("exif: unexpected raw exif header; got %q, want %q", got, want)
}
fallthrough
case isTiff:
// Functions below need the IFDs from the TIFF data to be stored in a
// *bytes.Reader. We use TeeReader to get a copy of the bytes as a
// side-effect of tiff.Decode() doing its work.
b := &bytes.Buffer{}
tr := io.TeeReader(r, b)
tif, err = tiff.Decode(tr)
er = bytes.NewReader(b.Bytes())
case assumeJPEG:
// Locate the JPEG APP1 header.
sec, err = newAppSec(jpeg_APP1, r)
if err != nil {
return nil, err
}
// Strip away EXIF header.
er, err = sec.exifReader()
if err != nil {
return nil, err
}
tif, err = tiff.Decode(er)
}
if err != nil {
return nil, decodeError{cause: err}
}
er.Seek(0, 0)
raw, err := ioutil.ReadAll(er)
if err != nil {
return nil, decodeError{cause: err}
}
// build an exif structure from the tiff
x := &Exif{
main: map[FieldName]*tiff.Tag{},
Tiff: tif,
Raw: raw,
main: map[FieldName]*tiff.Tag{},
exifStart: 0,
exifLength: 0,
ReaderAt: r,
}
b := make([]byte, 6)
_, err := r.ReadAt(b, 0)
if bytes.Compare(b, []byte("Exif\x00\x00")) == 0 {
x.exifStart = 6
x.ReaderAt = &offsetReaderAt{
offset: 6,
r: x.ReaderAt,
}
}
x.Tiff, err = tiff.LazyDecode(x.ReaderAt)
if tiff.IsInvalidTiff(err) {
x.exifStart, x.exifLength, err = findJPEGExifOffset(jpeg_APP1, r)
if err != nil {
return nil, decodeError{cause: err}
}
x.ReaderAt = &offsetReaderAt{
offset: int64(x.exifStart),
r: x.ReaderAt,
}
x.Tiff, err = tiff.LazyDecode(x.ReaderAt)
}
if err != nil {
return nil, decodeError{cause: err}
}
for i, p := range parsers {
@@ -351,6 +347,10 @@ type Walker interface {
// EXIF field. If w aborts the walk with an error, that error is returned.
func (x *Exif) Walk(w Walker) error {
for name, tag := range x.main {
err := tag.LoadVal()
if err != nil {
return err
}
if err := w.Walk(name, tag); err != nil {
return err
}
@@ -572,8 +572,13 @@ func (x *Exif) JpegThumbnail() ([]byte, error) {
if err != nil {
return nil, err
}
tiff := make([]byte, l)
_, err = x.ReaderAt.ReadAt(tiff, int64(start))
if err != nil {
return nil, err
}
return x.Raw[start : start+l], nil
return tiff, nil
}
// MarshalJson implements the encoding/json.Marshaler interface providing output of
@@ -582,71 +587,45 @@ func (x Exif) MarshalJSON() ([]byte, error) {
return json.Marshal(x.main)
}
type appSec struct {
marker byte
data []byte
}
// newAppSec finds marker in r and returns the corresponding application data
// section.
func newAppSec(marker byte, r io.Reader) (*appSec, error) {
br := bufio.NewReader(r)
app := &appSec{marker: marker}
var dataLen int
// findJPEGExifOffset finds marker in r and returns the offset of the Exif data
func findJPEGExifOffset(marker byte, r io.ReaderAt) (uint32, uint16, error) {
// read the file 1MB per 1MB to locate the marker
bufferLength := 4096
// Ensure there is a small overlap between buffers to handle the case
// where the marker is located exactly in-between 2 reads
seeker := make([]byte, bufferLength+2)
appHeader := []byte{0xFF, marker}
// seek to marker
for dataLen == 0 {
if _, err := br.ReadBytes(0xFF); err != nil {
return nil, err
}
c, err := br.ReadByte()
if err != nil {
return nil, err
} else if c != marker {
continue
var markerIndex int
i := 0
for {
count, err := r.ReadAt(seeker, int64(i*bufferLength))
if err != nil && err != io.EOF {
return 0, 0, err
}
dataLenBytes := make([]byte, 2)
for k, _ := range dataLenBytes {
c, err := br.ReadByte()
if err != nil {
return nil, err
}
dataLenBytes[k] = c
markerIndex = bytes.Index(seeker, appHeader)
// stop at the end of the file or when the marker is found
if markerIndex >= 0 || count < bufferLength {
break
}
dataLen = int(binary.BigEndian.Uint16(dataLenBytes)) - 2
i++
}
// read section data
nread := 0
for nread < dataLen {
s := make([]byte, dataLen-nread)
n, err := br.Read(s)
nread += n
if err != nil && nread < dataLen {
return nil, err
}
app.data = append(app.data, s[:n]...)
if markerIndex < 0 {
return 0, 0, fmt.Errorf("Unable to find the JPEG Exif marker")
}
return app, nil
}
// reader returns a reader on this appSec.
func (app *appSec) reader() *bytes.Reader {
return bytes.NewReader(app.data)
}
// exifReader returns a reader on this appSec with the read cursor advanced to
// the start of the exif's tiff encoded portion.
func (app *appSec) exifReader() (*bytes.Reader, error) {
if len(app.data) < 6 {
return nil, errors.New("exif: failed to find exif intro marker")
}
// read/check for exif special mark
exif := app.data[:6]
if !bytes.Equal(exif, append([]byte("Exif"), 0x00, 0x00)) {
return nil, errors.New("exif: failed to find exif intro marker")
}
return bytes.NewReader(app.data[6:]), nil
// Skip the application header
markerIndex += i*bufferLength + 2
// Read content length and check that it actually contains an exif
header := make([]byte, 8)
_, err := r.ReadAt(header, int64(markerIndex))
if err != nil {
return 0, 0, err
}
if !bytes.Equal(header[2:], []byte("Exif\000\000")) {
return 0, 0, fmt.Errorf("Unable to find the JPEG Exif marker")
}
dataLen := binary.BigEndian.Uint16(header[:2]) - 2
return uint32(markerIndex + len(header)), dataLen, nil
}

16
vendor/github.com/rwcarlsen/goexif/exif/fields.go сгенерированный поставляемый
Просмотреть файл

@@ -91,6 +91,15 @@ const (
LensModel FieldName = "LensModel"
)
// Windows-specific tags
const (
XPTitle FieldName = "XPTitle"
XPComment FieldName = "XPComment"
XPAuthor FieldName = "XPAuthor"
XPKeywords FieldName = "XPKeywords"
XPSubject FieldName = "XPSubject"
)
// thumbnail fields
const (
ThumbJPEGInterchangeFormat FieldName = "ThumbJPEGInterchangeFormat" // offset to thumb jpeg SOI
@@ -166,6 +175,13 @@ var exifFields = map[uint16]FieldName{
0x013B: Artist,
0x8298: Copyright,
// Windows-specific tags
0x9c9b: XPTitle,
0x9c9c: XPComment,
0x9c9d: XPAuthor,
0x9c9e: XPKeywords,
0x9c9f: XPSubject,
// private tags
exifPointer: ExifIFDPointer,

29
vendor/github.com/rwcarlsen/goexif/exif/readerAt.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,29 @@
package exif
import (
"io"
)
type readerToReaderAt struct {
reader io.Reader
buffer []byte
}
func (r *readerToReaderAt) ReadAt(p []byte, start int64) (n int, err error) {
end := start + int64(len(p))
n = 0
l := len(r.buffer)
if end > int64(l) {
new := make([]byte, end-int64(l))
n, err = r.reader.Read(new)
if err == io.EOF {
err = nil
}
r.buffer = append(r.buffer, new[:n]...)
}
if end > int64(len(r.buffer)) {
end = int64(len(r.buffer))
}
n = copy(p[:], r.buffer[start:end])
return
}

34
vendor/github.com/rwcarlsen/goexif/exif/regen_regress.go сгенерированный поставляемый
Просмотреть файл

@@ -9,6 +9,7 @@ import (
"log"
"os"
"path/filepath"
"sort"
"strings"
"github.com/rwcarlsen/goexif/exif"
@@ -35,6 +36,7 @@ func main() {
if err != nil {
log.Fatal(err)
}
sort.Strings(names)
for i, name := range names {
names[i] = filepath.Join("samples", name)
}
@@ -46,6 +48,10 @@ func makeExpected(files []string, w io.Writer) {
fmt.Fprintf(w, "var regressExpected = map[string]map[FieldName]string{\n")
for _, name := range files {
if !strings.HasSuffix(name, ".jpg") {
continue
}
f, err := os.Open(name)
if err != nil {
continue
@@ -57,23 +63,29 @@ func makeExpected(files []string, w io.Writer) {
continue
}
var items []string
x.Walk(walkFunc(func(name exif.FieldName, tag *tiff.Tag) error {
if strings.HasPrefix(string(name), exif.UnknownPrefix) {
items = append(items, fmt.Sprintf("\"%v\": `%v`,\n", name, tag.String()))
} else {
items = append(items, fmt.Sprintf("%v: `%v`,\n", name, tag.String()))
}
return nil
}))
sort.Strings(items)
fmt.Fprintf(w, "\"%v\": map[FieldName]string{\n", filepath.Base(name))
x.Walk(&regresswalk{w})
for _, item := range items {
fmt.Fprint(w, item)
}
fmt.Fprintf(w, "},\n")
f.Close()
}
fmt.Fprintf(w, "}")
}
type regresswalk struct {
wr io.Writer
}
type walkFunc func(exif.FieldName, *tiff.Tag) error
func (w *regresswalk) Walk(name exif.FieldName, tag *tiff.Tag) error {
if strings.HasPrefix(string(name), exif.UnknownPrefix) {
fmt.Fprintf(w.wr, "\"%v\": `%v`,\n", name, tag.String())
} else {
fmt.Fprintf(w.wr, "%v: `%v`,\n", name, tag.String())
}
return nil
func (f walkFunc) Walk(name exif.FieldName, tag *tiff.Tag) error {
return f(name, tag)
}

104
vendor/github.com/rwcarlsen/goexif/tiff/tag.go сгенерированный поставляемый
Просмотреть файл

@@ -107,71 +107,59 @@ type Tag struct {
ratVals [][]int64
strVal string
format Format
// raw contains the raw content of the value
// either the value if it fits in 4 bytes or a pointer to it if bigger
r io.ReaderAt
raw []byte
valLen uint32
}
// DecodeTag parses a tiff-encoded IFD tag from r and returns a Tag object. The
// first read from r should be the first byte of the tag. ReadAt offsets should
// generally be relative to the beginning of the tiff structure (not relative
// to the beginning of the tag).
func DecodeTag(r ReadAtReader, order binary.ByteOrder) (*Tag, error) {
func DecodeTag(r io.ReaderAt, rawData []byte, order binary.ByteOrder) (*Tag, error) {
t := new(Tag)
t.order = order
t.r = r
err := binary.Read(r, order, &t.Id)
if err != nil {
return nil, errors.New("tiff: tag id read failed: " + err.Error())
}
err = binary.Read(r, order, &t.Type)
if err != nil {
return nil, errors.New("tiff: tag type read failed: " + err.Error())
}
err = binary.Read(r, order, &t.Count)
if err != nil {
return nil, errors.New("tiff: tag component count read failed: " + err.Error())
}
t.Id = order.Uint16(rawData[0:2])
t.Type = DataType(order.Uint16(rawData[2:4]))
t.Count = order.Uint32(rawData[4:8])
// There seems to be a relatively common corrupt tag which has a Count of
// MaxUint32. This is probably not a valid value, so return early.
if t.Count == 1<<32-1 {
if t.Count >= 1<<32-1 {
return t, errors.New("invalid Count offset in tag")
}
valLen := typeSize[t.Type] * t.Count
if valLen == 0 {
t.valLen = typeSize[t.Type] * t.Count
if t.valLen == 0 {
return t, errors.New("zero length tag value")
}
if valLen > 4 {
binary.Read(r, order, &t.ValOffset)
t.raw = rawData[8:12]
// Use a bytes.Buffer so we don't allocate a huge slice if the tag
// is corrupt.
var buff bytes.Buffer
sr := io.NewSectionReader(r, int64(t.ValOffset), int64(valLen))
n, err := io.Copy(&buff, sr)
return t, nil
}
func (t *Tag) LoadVal() error {
if t.Val != nil {
return nil
}
if t.valLen > 4 {
offset := t.order.Uint32(t.raw)
val := make([]byte, t.valLen)
_, err := t.r.ReadAt(val, int64(offset))
if err != nil {
return t, errors.New("tiff: tag value read failed: " + err.Error())
} else if n != int64(valLen) {
return t, ErrShortReadTagValue
return errors.New("tiff: tag value read failed: " + err.Error())
}
t.Val = buff.Bytes()
t.Val = val
} else {
val := make([]byte, valLen)
if _, err = io.ReadFull(r, val); err != nil {
return t, errors.New("tiff: tag offset read failed: " + err.Error())
}
// ignore padding.
if _, err = io.ReadFull(r, make([]byte, 4-valLen)); err != nil {
return t, errors.New("tiff: tag offset read failed: " + err.Error())
}
t.Val = val
t.Val = t.raw[0:t.valLen]
}
return t, t.convertVals()
return t.convertVals()
}
func (t *Tag) convertVals() error {
@@ -340,6 +328,12 @@ func (t *Tag) Rat(i int) (*big.Rat, error) {
// numerator-denominator pair. It returns an error if the tag's Format is not
// RatVal. It panics if i is out of range.
func (t *Tag) Rat2(i int) (num, den int64, err error) {
if t.ratVals == nil {
err := t.LoadVal()
if err != nil {
return 0, 0, err
}
}
if t.format != RatVal {
return 0, 0, t.typeErr(RatVal)
}
@@ -349,6 +343,12 @@ func (t *Tag) Rat2(i int) (num, den int64, err error) {
// Int64 returns the tag's i'th value as an integer. It returns an error if the
// tag's Format is not IntVal. It panics if i is out of range.
func (t *Tag) Int64(i int) (int64, error) {
if t.intVals == nil {
err := t.LoadVal()
if err != nil {
return 0, err
}
}
if t.format != IntVal {
return 0, t.typeErr(IntVal)
}
@@ -358,6 +358,12 @@ func (t *Tag) Int64(i int) (int64, error) {
// Int returns the tag's i'th value as an integer. It returns an error if the
// tag's Format is not IntVal. It panics if i is out of range.
func (t *Tag) Int(i int) (int, error) {
if t.intVals == nil {
err := t.LoadVal()
if err != nil {
return 0, err
}
}
if t.format != IntVal {
return 0, t.typeErr(IntVal)
}
@@ -367,6 +373,12 @@ func (t *Tag) Int(i int) (int, error) {
// Float returns the tag's i'th value as a float. It returns an error if the
// tag's Format is not IntVal. It panics if i is out of range.
func (t *Tag) Float(i int) (float64, error) {
if t.floatVals == nil {
err := t.LoadVal()
if err != nil {
return 0, err
}
}
if t.format != FloatVal {
return 0, t.typeErr(FloatVal)
}
@@ -376,6 +388,12 @@ func (t *Tag) Float(i int) (float64, error) {
// StringVal returns the tag's value as a string. It returns an error if the
// tag's Format is not StringVal. It panics if i is out of range.
func (t *Tag) StringVal() (string, error) {
if t.strVal == "" {
err := t.LoadVal()
if err != nil {
return "", err
}
}
if t.format != StringVal {
return "", t.typeErr(StringVal)
}
@@ -396,6 +414,10 @@ func (t *Tag) String() string {
}
func (t *Tag) MarshalJSON() ([]byte, error) {
err := t.LoadVal()
if err != nil {
return nil, err
}
switch t.format {
case StringVal, UndefVal:
return nullString(t.Val), nil

83
vendor/github.com/rwcarlsen/goexif/tiff/tiff.go сгенерированный поставляемый
Просмотреть файл

@@ -11,6 +11,8 @@ import (
"io/ioutil"
)
const notValidTIFF = "tiff: invalid TIFF header"
// ReadAtReader is used when decoding Tiff tags and directories
type ReadAtReader interface {
io.Reader
@@ -26,6 +28,10 @@ type Tiff struct {
Order binary.ByteOrder
}
func IsInvalidTiff(err error) bool {
return err != nil && err.Error() == notValidTIFF
}
// Decode parses tiff-encoded data from r and returns a Tiff struct that
// reflects the structure and content of the tiff data. The first read from r
// should be the first byte of the tiff-encoded data and not necessarily the
@@ -36,12 +42,27 @@ func Decode(r io.Reader) (*Tiff, error) {
return nil, errors.New("tiff: could not read data")
}
buf := bytes.NewReader(data)
t, err := LazyDecode(buf)
if err != nil {
return nil, err
}
return t.LoadAllVals()
}
// LazyDecode parses tiff-encoded data from r and returns a Tiff struct that
// reflects the structure and content of the tiff data. The first read from r
// should be the first byte of the tiff-encoded data and not necessarily the
// first byte of an os.File object.
//
// It differs from Decode as it is restricted to parsing the tiff structure
// and only decodes the values on demand.
func LazyDecode(r io.ReaderAt) (*Tiff, error) {
t := new(Tiff)
// read byte order
bo := make([]byte, 2)
if _, err = io.ReadFull(buf, bo); err != nil {
if _, err := r.ReadAt(bo, 0); err != nil {
return nil, errors.New("tiff: could not read tiff byte order")
}
if string(bo) == "II" {
@@ -49,39 +70,31 @@ func Decode(r io.Reader) (*Tiff, error) {
} else if string(bo) == "MM" {
t.Order = binary.BigEndian
} else {
return nil, errors.New("tiff: could not read tiff byte order")
return nil, errors.New(notValidTIFF)
}
// check for special tiff marker
var sp int16
err = binary.Read(buf, t.Order, &sp)
if err != nil || 42 != sp {
sp := make([]byte, 2)
_, err := r.ReadAt(sp, 2)
if err != nil || 42 != t.Order.Uint16(sp) {
return nil, errors.New("tiff: could not find special tiff marker")
}
// load offset to first IFD
var offset int32
err = binary.Read(buf, t.Order, &offset)
binaryOffset := make([]byte, 4)
_, err = r.ReadAt(binaryOffset, 4)
if err != nil {
return nil, errors.New("tiff: could not read offset to first IFD")
}
offset := t.Order.Uint32(binaryOffset)
// load IFD's
var d *Dir
prev := offset
for offset != 0 {
// seek to offset
_, err := buf.Seek(int64(offset), 0)
if err != nil {
return nil, errors.New("tiff: seek to IFD failed")
}
if buf.Len() == 0 {
return nil, errors.New("tiff: seek offset after EOF")
}
// load the dir
d, offset, err = DecodeDir(buf, t.Order)
d, offset, err = DecodeDir(r, t.Order, offset)
if err != nil {
return nil, err
}
@@ -97,6 +110,19 @@ func Decode(r io.Reader) (*Tiff, error) {
return t, nil
}
// LoadAllVals loads and parses all tiff directory values in memory
func (t *Tiff) LoadAllVals() (*Tiff, error) {
for _, d := range t.Dirs {
for _, tag := range d.Tags {
err := tag.LoadVal()
if err != nil {
return nil, err
}
}
}
return t, nil
}
func (tf *Tiff) String() string {
var buf bytes.Buffer
fmt.Fprint(&buf, "Tiff{")
@@ -116,32 +142,41 @@ type Dir struct {
// is the offset to the next IFD. The first read from r should be at the first
// byte of the IFD. ReadAt offsets should generally be relative to the
// beginning of the tiff structure (not relative to the beginning of the IFD).
func DecodeDir(r ReadAtReader, order binary.ByteOrder) (d *Dir, offset int32, err error) {
d = new(Dir)
func DecodeDir(r io.ReaderAt, order binary.ByteOrder, offset uint32) (*Dir, uint32, error) {
d := new(Dir)
// get num of tags in ifd
var nTags int16
err = binary.Read(r, order, &nTags)
b := make([]byte, 4)
_, err := r.ReadAt(b[0:2], int64(offset))
if err != nil {
return nil, 0, errors.New("tiff: failed to read IFD tag count: " + err.Error())
}
nTags := order.Uint16(b[0:2])
tags := make([]byte, 12*nTags)
offset += 2
_, err = r.ReadAt(tags, int64(offset))
if err != nil {
return nil, 0, errors.New("tiff: falied to read offset to next IFD: " + err.Error())
}
// load tags
for n := 0; n < int(nTags); n++ {
t, err := DecodeTag(r, order)
t, err := DecodeTag(r, tags[n*12:(n+1)*12], order)
if err != nil {
return nil, 0, err
}
d.Tags = append(d.Tags, t)
offset += 12
}
// get offset to next ifd
err = binary.Read(r, order, &offset)
_, err = r.ReadAt(b, int64(offset))
if err != nil {
return nil, 0, errors.New("tiff: falied to read offset to next IFD: " + err.Error())
}
return d, offset, nil
return d, order.Uint32(b), nil
}
func (d *Dir) String() string {