From b4ee62151dd8faae12a0bff2d6f13be8c5824e64 Mon Sep 17 00:00:00 2001 From: "Stephen McQuay (smcquay)" Date: Mon, 28 Nov 2016 22:28:05 -0800 Subject: [PATCH] vendor exif --- vendor/github.com/rwcarlsen/goexif/LICENSE | 24 + .../rwcarlsen/goexif/exif/README.md | 4 + .../github.com/rwcarlsen/goexif/exif/exif.go | 619 ++++++++++++++++++ .../rwcarlsen/goexif/exif/fields.go | 293 +++++++++ .../rwcarlsen/goexif/exif/regen_regress.go | 79 +++ .../rwcarlsen/goexif/exif/sample1.jpg | Bin 0 -> 80603 bytes .../rwcarlsen/goexif/tiff/sample1.tif | Bin 0 -> 18382 bytes .../github.com/rwcarlsen/goexif/tiff/tag.go | 438 +++++++++++++ .../github.com/rwcarlsen/goexif/tiff/tiff.go | 153 +++++ vendor/vendor.json | 19 + 10 files changed, 1629 insertions(+) create mode 100644 vendor/github.com/rwcarlsen/goexif/LICENSE create mode 100644 vendor/github.com/rwcarlsen/goexif/exif/README.md create mode 100644 vendor/github.com/rwcarlsen/goexif/exif/exif.go create mode 100644 vendor/github.com/rwcarlsen/goexif/exif/fields.go create mode 100644 vendor/github.com/rwcarlsen/goexif/exif/regen_regress.go create mode 100644 vendor/github.com/rwcarlsen/goexif/exif/sample1.jpg create mode 100644 vendor/github.com/rwcarlsen/goexif/tiff/sample1.tif create mode 100644 vendor/github.com/rwcarlsen/goexif/tiff/tag.go create mode 100644 vendor/github.com/rwcarlsen/goexif/tiff/tiff.go create mode 100644 vendor/vendor.json diff --git a/vendor/github.com/rwcarlsen/goexif/LICENSE b/vendor/github.com/rwcarlsen/goexif/LICENSE new file mode 100644 index 0000000..aa62504 --- /dev/null +++ b/vendor/github.com/rwcarlsen/goexif/LICENSE @@ -0,0 +1,24 @@ + +Copyright (c) 2012, Robert Carlsen & Contributors +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/rwcarlsen/goexif/exif/README.md b/vendor/github.com/rwcarlsen/goexif/exif/README.md new file mode 100644 index 0000000..b3bf5fa --- /dev/null +++ b/vendor/github.com/rwcarlsen/goexif/exif/README.md @@ -0,0 +1,4 @@ + +To regenerate the regression test data, run `go generate` inside the exif +package directory and commit the changes to *regress_expected_test.go*. + diff --git a/vendor/github.com/rwcarlsen/goexif/exif/exif.go b/vendor/github.com/rwcarlsen/goexif/exif/exif.go new file mode 100644 index 0000000..b420729 --- /dev/null +++ b/vendor/github.com/rwcarlsen/goexif/exif/exif.go @@ -0,0 +1,619 @@ +// Package exif implements decoding of EXIF data as defined in the EXIF 2.2 +// specification (http://www.exif.org/Exif2-2.PDF). +package exif + +import ( + "bufio" + "bytes" + "encoding/binary" + "encoding/json" + "errors" + "fmt" + "io" + "io/ioutil" + "math" + "strconv" + "strings" + "time" + + "github.com/rwcarlsen/goexif/tiff" +) + +const ( + jpeg_APP1 = 0xE1 + + exifPointer = 0x8769 + gpsPointer = 0x8825 + interopPointer = 0xA005 +) + +// A decodeError is returned when the image cannot be decoded as a tiff image. +type decodeError struct { + cause error +} + +func (de decodeError) Error() string { + return fmt.Sprintf("exif: decode failed (%v) ", de.cause.Error()) +} + +// IsShortReadTagValueError identifies a ErrShortReadTagValue error. +func IsShortReadTagValueError(err error) bool { + de, ok := err.(decodeError) + if ok { + return de.cause == tiff.ErrShortReadTagValue + } + return false +} + +// A TagNotPresentError is returned when the requested field is not +// present in the EXIF. +type TagNotPresentError FieldName + +func (tag TagNotPresentError) Error() string { + return fmt.Sprintf("exif: tag %q is not present", string(tag)) +} + +func IsTagNotPresentError(err error) bool { + _, ok := err.(TagNotPresentError) + return ok +} + +// Parser allows the registration of custom parsing and field loading +// in the Decode function. +type Parser interface { + // Parse should read data from x and insert parsed fields into x via + // LoadTags. + Parse(x *Exif) error +} + +var parsers []Parser + +func init() { + RegisterParsers(&parser{}) +} + +// RegisterParsers registers one or more parsers to be automatically called +// when decoding EXIF data via the Decode function. +func RegisterParsers(ps ...Parser) { + parsers = append(parsers, ps...) +} + +type parser struct{} + +type tiffErrors map[tiffError]string + +func (te tiffErrors) Error() string { + var allErrors []string + for k, v := range te { + allErrors = append(allErrors, fmt.Sprintf("%s: %v\n", stagePrefix[k], v)) + } + return strings.Join(allErrors, "\n") +} + +// IsCriticalError, given the error returned by Decode, reports whether the +// returned *Exif may contain usable information. +func IsCriticalError(err error) bool { + _, ok := err.(tiffErrors) + return !ok +} + +// IsExifError reports whether the error happened while decoding the EXIF +// sub-IFD. +func IsExifError(err error) bool { + if te, ok := err.(tiffErrors); ok { + _, isExif := te[loadExif] + return isExif + } + return false +} + +// IsGPSError reports whether the error happened while decoding the GPS sub-IFD. +func IsGPSError(err error) bool { + if te, ok := err.(tiffErrors); ok { + _, isGPS := te[loadExif] + return isGPS + } + return false +} + +// IsInteroperabilityError reports whether the error happened while decoding the +// Interoperability sub-IFD. +func IsInteroperabilityError(err error) bool { + if te, ok := err.(tiffErrors); ok { + _, isInterop := te[loadInteroperability] + return isInterop + } + return false +} + +type tiffError int + +const ( + loadExif tiffError = iota + loadGPS + loadInteroperability +) + +var stagePrefix = map[tiffError]string{ + loadExif: "loading EXIF sub-IFD", + loadGPS: "loading GPS sub-IFD", + loadInteroperability: "loading Interoperability sub-IFD", +} + +// 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 { + x.LoadTags(x.Tiff.Dirs[0], exifFields, false) + + // thumbnails + if len(x.Tiff.Dirs) >= 2 { + x.LoadTags(x.Tiff.Dirs[1], thumbnailFields, false) + } + + te := make(tiffErrors) + + // recurse into exif, gps, and interop sub-IFDs + if err := loadSubDir(x, ExifIFDPointer, exifFields); err != nil { + te[loadExif] = err.Error() + } + if err := loadSubDir(x, GPSInfoIFDPointer, gpsFields); err != nil { + te[loadGPS] = err.Error() + } + + if err := loadSubDir(x, InteroperabilityIFDPointer, interopFields); err != nil { + te[loadInteroperability] = err.Error() + } + if len(te) > 0 { + return te + } + return nil +} + +func loadSubDir(x *Exif, ptr FieldName, fieldMap map[uint16]FieldName) error { + r := bytes.NewReader(x.Raw) + + tag, err := x.Get(ptr) + if err != nil { + return nil + } + offset, err := tag.Int64(0) + if err != nil { + 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) + if err != nil { + return fmt.Errorf("exif: sub-IFD %s decode failed: %v", ptr, err) + } + x.LoadTags(subDir, fieldMap, false) + return nil +} + +// Exif provides access to decoded EXIF metadata fields and values. +type Exif struct { + Tiff *tiff.Tiff + main map[FieldName]*tiff.Tag + Raw []byte +} + +// Decode parses EXIF-encoded data from r and returns a queryable Exif +// object. After the exif data section is called and the tiff structure +// 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. +func Decode(r io.Reader) (*Exif, error) { + // EXIF data in JPEG is stored in the APP1 marker. EXIF data uses the TIFF + // format to store data. + // If we're parsing a TIFF image, we don't need to strip away any data. + // 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 := r.Read(header) + if err != nil { + return nil, err + } + if n < len(header) { + return nil, errors.New("exif: short read on header") + } + + var isTiff bool + switch string(header) { + case "II*\x00": + // TIFF - Little endian (Intel) + isTiff = true + case "MM\x00*": + // TIFF - Big endian (Motorola) + isTiff = true + default: + // Not TIFF, assume JPEG + } + + // Put the header bytes back into the reader. + r = io.MultiReader(bytes.NewReader(header), r) + var ( + er *bytes.Reader + tif *tiff.Tiff + ) + + if 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()) + } else { + // Locate the JPEG APP1 header. + var sec *appSec + 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, + } + + for i, p := range parsers { + if err := p.Parse(x); err != nil { + if _, ok := err.(tiffErrors); ok { + return x, err + } + // This should never happen, as Parse always returns a tiffError + // for now, but that could change. + return x, fmt.Errorf("exif: parser %v failed (%v)", i, err) + } + } + + return x, nil +} + +// LoadTags loads tags into the available fields from the tiff Directory +// using the given tagid-fieldname mapping. Used to load makernote and +// other meta-data. If showMissing is true, tags in d that are not in the +// fieldMap will be loaded with the FieldName UnknownPrefix followed by the +// tag ID (in hex format). +func (x *Exif) LoadTags(d *tiff.Dir, fieldMap map[uint16]FieldName, showMissing bool) { + for _, tag := range d.Tags { + name := fieldMap[tag.Id] + if name == "" { + if !showMissing { + continue + } + name = FieldName(fmt.Sprintf("%v%x", UnknownPrefix, tag.Id)) + } + x.main[name] = tag + } +} + +// Get retrieves the EXIF tag for the given field name. +// +// If the tag is not known or not present, an error is returned. If the +// tag name is known, the error will be a TagNotPresentError. +func (x *Exif) Get(name FieldName) (*tiff.Tag, error) { + if tg, ok := x.main[name]; ok { + return tg, nil + } + return nil, TagNotPresentError(name) +} + +// Walker is the interface used to traverse all fields of an Exif object. +type Walker interface { + // Walk is called for each non-nil EXIF field. Returning a non-nil + // error aborts the walk/traversal. + Walk(name FieldName, tag *tiff.Tag) error +} + +// Walk calls the Walk method of w with the name and tag for every non-nil +// 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 { + if err := w.Walk(name, tag); err != nil { + return err + } + } + return nil +} + +// DateTime returns the EXIF's "DateTimeOriginal" field, which +// is the creation time of the photo. If not found, it tries +// the "DateTime" (which is meant as the modtime) instead. +// The error will be TagNotPresentErr if none of those tags +// were found, or a generic error if the tag value was +// not a string, or the error returned by time.Parse. +// +// If the EXIF lacks timezone information or GPS time, the returned +// time's Location will be time.Local. +func (x *Exif) DateTime() (time.Time, error) { + var dt time.Time + tag, err := x.Get(DateTimeOriginal) + if err != nil { + tag, err = x.Get(DateTime) + if err != nil { + return dt, err + } + } + if tag.Format() != tiff.StringVal { + return dt, errors.New("DateTime[Original] not in string format") + } + exifTimeLayout := "2006:01:02 15:04:05" + dateStr := strings.TrimRight(string(tag.Val), "\x00") + // TODO(bradfitz,mpl): look for timezone offset, GPS time, etc. + // For now, just always return the time.Local timezone. + return time.ParseInLocation(exifTimeLayout, dateStr, time.Local) +} + +func ratFloat(num, dem int64) float64 { + return float64(num) / float64(dem) +} + +// Tries to parse a Geo degrees value from a string as it was found in some +// EXIF data. +// Supported formats so far: +// - "52,00000,50,00000,34,01180" ==> 52 deg 50'34.0118" +// Probably due to locale the comma is used as decimal mark as well as the +// separator of three floats (degrees, minutes, seconds) +// http://en.wikipedia.org/wiki/Decimal_mark#Hindu.E2.80.93Arabic_numeral_system +// - "52.0,50.0,34.01180" ==> 52deg50'34.0118" +// - "52,50,34.01180" ==> 52deg50'34.0118" +func parseTagDegreesString(s string) (float64, error) { + const unparsableErrorFmt = "Unknown coordinate format: %s" + isSplitRune := func(c rune) bool { + return c == ',' || c == ';' + } + parts := strings.FieldsFunc(s, isSplitRune) + var degrees, minutes, seconds float64 + var err error + switch len(parts) { + case 6: + degrees, err = strconv.ParseFloat(parts[0]+"."+parts[1], 64) + if err != nil { + return 0.0, fmt.Errorf(unparsableErrorFmt, s) + } + minutes, err = strconv.ParseFloat(parts[2]+"."+parts[3], 64) + if err != nil { + return 0.0, fmt.Errorf(unparsableErrorFmt, s) + } + minutes = math.Copysign(minutes, degrees) + seconds, err = strconv.ParseFloat(parts[4]+"."+parts[5], 64) + if err != nil { + return 0.0, fmt.Errorf(unparsableErrorFmt, s) + } + seconds = math.Copysign(seconds, degrees) + case 3: + degrees, err = strconv.ParseFloat(parts[0], 64) + if err != nil { + return 0.0, fmt.Errorf(unparsableErrorFmt, s) + } + minutes, err = strconv.ParseFloat(parts[1], 64) + if err != nil { + return 0.0, fmt.Errorf(unparsableErrorFmt, s) + } + minutes = math.Copysign(minutes, degrees) + seconds, err = strconv.ParseFloat(parts[2], 64) + if err != nil { + return 0.0, fmt.Errorf(unparsableErrorFmt, s) + } + seconds = math.Copysign(seconds, degrees) + default: + return 0.0, fmt.Errorf(unparsableErrorFmt, s) + } + return degrees + minutes/60.0 + seconds/3600.0, nil +} + +func parse3Rat2(tag *tiff.Tag) ([3]float64, error) { + v := [3]float64{} + for i := range v { + num, den, err := tag.Rat2(i) + if err != nil { + return v, err + } + v[i] = ratFloat(num, den) + if tag.Count < uint32(i+2) { + break + } + } + return v, nil +} + +func tagDegrees(tag *tiff.Tag) (float64, error) { + switch tag.Format() { + case tiff.RatVal: + // The usual case, according to the Exif spec + // (http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf, + // sec 4.6.6, p. 52 et seq.) + v, err := parse3Rat2(tag) + if err != nil { + return 0.0, err + } + return v[0] + v[1]/60 + v[2]/3600.0, nil + case tiff.StringVal: + // Encountered this weird case with a panorama picture taken with a HTC phone + s, err := tag.StringVal() + if err != nil { + return 0.0, err + } + return parseTagDegreesString(s) + default: + // don't know how to parse value, give up + return 0.0, fmt.Errorf("Malformed EXIF Tag Degrees") + } +} + +// LatLong returns the latitude and longitude of the photo and +// whether it was present. +func (x *Exif) LatLong() (lat, long float64, err error) { + // All calls of x.Get might return an TagNotPresentError + longTag, err := x.Get(FieldName("GPSLongitude")) + if err != nil { + return + } + ewTag, err := x.Get(FieldName("GPSLongitudeRef")) + if err != nil { + return + } + latTag, err := x.Get(FieldName("GPSLatitude")) + if err != nil { + return + } + nsTag, err := x.Get(FieldName("GPSLatitudeRef")) + if err != nil { + return + } + if long, err = tagDegrees(longTag); err != nil { + return 0, 0, fmt.Errorf("Cannot parse longitude: %v", err) + } + if lat, err = tagDegrees(latTag); err != nil { + return 0, 0, fmt.Errorf("Cannot parse latitude: %v", err) + } + ew, err := ewTag.StringVal() + if err == nil && ew == "W" { + long *= -1.0 + } else if err != nil { + return 0, 0, fmt.Errorf("Cannot parse longitude: %v", err) + } + ns, err := nsTag.StringVal() + if err == nil && ns == "S" { + lat *= -1.0 + } else if err != nil { + return 0, 0, fmt.Errorf("Cannot parse longitude: %v", err) + } + return lat, long, nil +} + +// String returns a pretty text representation of the decoded exif data. +func (x *Exif) String() string { + var buf bytes.Buffer + for name, tag := range x.main { + fmt.Fprintf(&buf, "%s: %s\n", name, tag) + } + return buf.String() +} + +// JpegThumbnail returns the jpeg thumbnail if it exists. If it doesn't exist, +// TagNotPresentError will be returned +func (x *Exif) JpegThumbnail() ([]byte, error) { + offset, err := x.Get(ThumbJPEGInterchangeFormat) + if err != nil { + return nil, err + } + start, err := offset.Int(0) + if err != nil { + return nil, err + } + + length, err := x.Get(ThumbJPEGInterchangeFormatLength) + if err != nil { + return nil, err + } + l, err := length.Int(0) + if err != nil { + return nil, err + } + + return x.Raw[start : start+l], nil +} + +// MarshalJson implements the encoding/json.Marshaler interface providing output of +// all EXIF fields present (names and values). +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 + + // 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 + } + + dataLenBytes := make([]byte, 2) + for k,_ := range dataLenBytes { + c, err := br.ReadByte() + if err != nil { + return nil, err + } + dataLenBytes[k] = c + } + dataLen = int(binary.BigEndian.Uint16(dataLenBytes)) - 2 + } + + // 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]...) + } + 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 +} diff --git a/vendor/github.com/rwcarlsen/goexif/exif/fields.go b/vendor/github.com/rwcarlsen/goexif/exif/fields.go new file mode 100644 index 0000000..0388d23 --- /dev/null +++ b/vendor/github.com/rwcarlsen/goexif/exif/fields.go @@ -0,0 +1,293 @@ +package exif + +type FieldName string + +// UnknownPrefix is used as the first part of field names for decoded tags for +// which there is no known/supported EXIF field. +const UnknownPrefix = "UnknownTag_" + +// Primary EXIF fields +const ( + ImageWidth FieldName = "ImageWidth" + ImageLength = "ImageLength" // Image height called Length by EXIF spec + BitsPerSample = "BitsPerSample" + Compression = "Compression" + PhotometricInterpretation = "PhotometricInterpretation" + Orientation = "Orientation" + SamplesPerPixel = "SamplesPerPixel" + PlanarConfiguration = "PlanarConfiguration" + YCbCrSubSampling = "YCbCrSubSampling" + YCbCrPositioning = "YCbCrPositioning" + XResolution = "XResolution" + YResolution = "YResolution" + ResolutionUnit = "ResolutionUnit" + DateTime = "DateTime" + ImageDescription = "ImageDescription" + Make = "Make" + Model = "Model" + Software = "Software" + Artist = "Artist" + Copyright = "Copyright" + ExifIFDPointer = "ExifIFDPointer" + GPSInfoIFDPointer = "GPSInfoIFDPointer" + InteroperabilityIFDPointer = "InteroperabilityIFDPointer" + ExifVersion = "ExifVersion" + FlashpixVersion = "FlashpixVersion" + ColorSpace = "ColorSpace" + ComponentsConfiguration = "ComponentsConfiguration" + CompressedBitsPerPixel = "CompressedBitsPerPixel" + PixelXDimension = "PixelXDimension" + PixelYDimension = "PixelYDimension" + MakerNote = "MakerNote" + UserComment = "UserComment" + RelatedSoundFile = "RelatedSoundFile" + DateTimeOriginal = "DateTimeOriginal" + DateTimeDigitized = "DateTimeDigitized" + SubSecTime = "SubSecTime" + SubSecTimeOriginal = "SubSecTimeOriginal" + SubSecTimeDigitized = "SubSecTimeDigitized" + ImageUniqueID = "ImageUniqueID" + ExposureTime = "ExposureTime" + FNumber = "FNumber" + ExposureProgram = "ExposureProgram" + SpectralSensitivity = "SpectralSensitivity" + ISOSpeedRatings = "ISOSpeedRatings" + OECF = "OECF" + ShutterSpeedValue = "ShutterSpeedValue" + ApertureValue = "ApertureValue" + BrightnessValue = "BrightnessValue" + ExposureBiasValue = "ExposureBiasValue" + MaxApertureValue = "MaxApertureValue" + SubjectDistance = "SubjectDistance" + MeteringMode = "MeteringMode" + LightSource = "LightSource" + Flash = "Flash" + FocalLength = "FocalLength" + SubjectArea = "SubjectArea" + FlashEnergy = "FlashEnergy" + SpatialFrequencyResponse = "SpatialFrequencyResponse" + FocalPlaneXResolution = "FocalPlaneXResolution" + FocalPlaneYResolution = "FocalPlaneYResolution" + FocalPlaneResolutionUnit = "FocalPlaneResolutionUnit" + SubjectLocation = "SubjectLocation" + ExposureIndex = "ExposureIndex" + SensingMethod = "SensingMethod" + FileSource = "FileSource" + SceneType = "SceneType" + CFAPattern = "CFAPattern" + CustomRendered = "CustomRendered" + ExposureMode = "ExposureMode" + WhiteBalance = "WhiteBalance" + DigitalZoomRatio = "DigitalZoomRatio" + FocalLengthIn35mmFilm = "FocalLengthIn35mmFilm" + SceneCaptureType = "SceneCaptureType" + GainControl = "GainControl" + Contrast = "Contrast" + Saturation = "Saturation" + Sharpness = "Sharpness" + DeviceSettingDescription = "DeviceSettingDescription" + SubjectDistanceRange = "SubjectDistanceRange" + LensMake = "LensMake" + LensModel = "LensModel" +) + +// thumbnail fields +const ( + ThumbJPEGInterchangeFormat = "ThumbJPEGInterchangeFormat" // offset to thumb jpeg SOI + ThumbJPEGInterchangeFormatLength = "ThumbJPEGInterchangeFormatLength" // byte length of thumb +) + +// GPS fields +const ( + GPSVersionID FieldName = "GPSVersionID" + GPSLatitudeRef = "GPSLatitudeRef" + GPSLatitude = "GPSLatitude" + GPSLongitudeRef = "GPSLongitudeRef" + GPSLongitude = "GPSLongitude" + GPSAltitudeRef = "GPSAltitudeRef" + GPSAltitude = "GPSAltitude" + GPSTimeStamp = "GPSTimeStamp" + GPSSatelites = "GPSSatelites" + GPSStatus = "GPSStatus" + GPSMeasureMode = "GPSMeasureMode" + GPSDOP = "GPSDOP" + GPSSpeedRef = "GPSSpeedRef" + GPSSpeed = "GPSSpeed" + GPSTrackRef = "GPSTrackRef" + GPSTrack = "GPSTrack" + GPSImgDirectionRef = "GPSImgDirectionRef" + GPSImgDirection = "GPSImgDirection" + GPSMapDatum = "GPSMapDatum" + GPSDestLatitudeRef = "GPSDestLatitudeRef" + GPSDestLatitude = "GPSDestLatitude" + GPSDestLongitudeRef = "GPSDestLongitudeRef" + GPSDestLongitude = "GPSDestLongitude" + GPSDestBearingRef = "GPSDestBearingRef" + GPSDestBearing = "GPSDestBearing" + GPSDestDistanceRef = "GPSDestDistanceRef" + GPSDestDistance = "GPSDestDistance" + GPSProcessingMethod = "GPSProcessingMethod" + GPSAreaInformation = "GPSAreaInformation" + GPSDateStamp = "GPSDateStamp" + GPSDifferential = "GPSDifferential" +) + +// interoperability fields +const ( + InteroperabilityIndex FieldName = "InteroperabilityIndex" +) + +var exifFields = map[uint16]FieldName{ + ///////////////////////////////////// + ////////// IFD 0 //////////////////// + ///////////////////////////////////// + + // image data structure for the thumbnail + 0x0100: ImageWidth, + 0x0101: ImageLength, + 0x0102: BitsPerSample, + 0x0103: Compression, + 0x0106: PhotometricInterpretation, + 0x0112: Orientation, + 0x0115: SamplesPerPixel, + 0x011C: PlanarConfiguration, + 0x0212: YCbCrSubSampling, + 0x0213: YCbCrPositioning, + 0x011A: XResolution, + 0x011B: YResolution, + 0x0128: ResolutionUnit, + + // Other tags + 0x0132: DateTime, + 0x010E: ImageDescription, + 0x010F: Make, + 0x0110: Model, + 0x0131: Software, + 0x013B: Artist, + 0x8298: Copyright, + + // private tags + exifPointer: ExifIFDPointer, + + ///////////////////////////////////// + ////////// Exif sub IFD ///////////// + ///////////////////////////////////// + + gpsPointer: GPSInfoIFDPointer, + interopPointer: InteroperabilityIFDPointer, + + 0x9000: ExifVersion, + 0xA000: FlashpixVersion, + + 0xA001: ColorSpace, + + 0x9101: ComponentsConfiguration, + 0x9102: CompressedBitsPerPixel, + 0xA002: PixelXDimension, + 0xA003: PixelYDimension, + + 0x927C: MakerNote, + 0x9286: UserComment, + + 0xA004: RelatedSoundFile, + 0x9003: DateTimeOriginal, + 0x9004: DateTimeDigitized, + 0x9290: SubSecTime, + 0x9291: SubSecTimeOriginal, + 0x9292: SubSecTimeDigitized, + + 0xA420: ImageUniqueID, + + // picture conditions + 0x829A: ExposureTime, + 0x829D: FNumber, + 0x8822: ExposureProgram, + 0x8824: SpectralSensitivity, + 0x8827: ISOSpeedRatings, + 0x8828: OECF, + 0x9201: ShutterSpeedValue, + 0x9202: ApertureValue, + 0x9203: BrightnessValue, + 0x9204: ExposureBiasValue, + 0x9205: MaxApertureValue, + 0x9206: SubjectDistance, + 0x9207: MeteringMode, + 0x9208: LightSource, + 0x9209: Flash, + 0x920A: FocalLength, + 0x9214: SubjectArea, + 0xA20B: FlashEnergy, + 0xA20C: SpatialFrequencyResponse, + 0xA20E: FocalPlaneXResolution, + 0xA20F: FocalPlaneYResolution, + 0xA210: FocalPlaneResolutionUnit, + 0xA214: SubjectLocation, + 0xA215: ExposureIndex, + 0xA217: SensingMethod, + 0xA300: FileSource, + 0xA301: SceneType, + 0xA302: CFAPattern, + 0xA401: CustomRendered, + 0xA402: ExposureMode, + 0xA403: WhiteBalance, + 0xA404: DigitalZoomRatio, + 0xA405: FocalLengthIn35mmFilm, + 0xA406: SceneCaptureType, + 0xA407: GainControl, + 0xA408: Contrast, + 0xA409: Saturation, + 0xA40A: Sharpness, + 0xA40B: DeviceSettingDescription, + 0xA40C: SubjectDistanceRange, + 0xA433: LensMake, + 0xA434: LensModel, +} + +var gpsFields = map[uint16]FieldName{ + ///////////////////////////////////// + //// GPS sub-IFD //////////////////// + ///////////////////////////////////// + 0x0: GPSVersionID, + 0x1: GPSLatitudeRef, + 0x2: GPSLatitude, + 0x3: GPSLongitudeRef, + 0x4: GPSLongitude, + 0x5: GPSAltitudeRef, + 0x6: GPSAltitude, + 0x7: GPSTimeStamp, + 0x8: GPSSatelites, + 0x9: GPSStatus, + 0xA: GPSMeasureMode, + 0xB: GPSDOP, + 0xC: GPSSpeedRef, + 0xD: GPSSpeed, + 0xE: GPSTrackRef, + 0xF: GPSTrack, + 0x10: GPSImgDirectionRef, + 0x11: GPSImgDirection, + 0x12: GPSMapDatum, + 0x13: GPSDestLatitudeRef, + 0x14: GPSDestLatitude, + 0x15: GPSDestLongitudeRef, + 0x16: GPSDestLongitude, + 0x17: GPSDestBearingRef, + 0x18: GPSDestBearing, + 0x19: GPSDestDistanceRef, + 0x1A: GPSDestDistance, + 0x1B: GPSProcessingMethod, + 0x1C: GPSAreaInformation, + 0x1D: GPSDateStamp, + 0x1E: GPSDifferential, +} + +var interopFields = map[uint16]FieldName{ + ///////////////////////////////////// + //// Interoperability sub-IFD /////// + ///////////////////////////////////// + 0x1: InteroperabilityIndex, +} + +var thumbnailFields = map[uint16]FieldName{ + 0x0201: ThumbJPEGInterchangeFormat, + 0x0202: ThumbJPEGInterchangeFormatLength, +} diff --git a/vendor/github.com/rwcarlsen/goexif/exif/regen_regress.go b/vendor/github.com/rwcarlsen/goexif/exif/regen_regress.go new file mode 100644 index 0000000..17bac52 --- /dev/null +++ b/vendor/github.com/rwcarlsen/goexif/exif/regen_regress.go @@ -0,0 +1,79 @@ +// +build ignore + +package main + +import ( + "flag" + "fmt" + "io" + "log" + "os" + "path/filepath" + "strings" + + "github.com/rwcarlsen/goexif/exif" + "github.com/rwcarlsen/goexif/tiff" +) + +func main() { + flag.Parse() + fname := flag.Arg(0) + + dst, err := os.Create(fname) + if err != nil { + log.Fatal(err) + } + defer dst.Close() + + dir, err := os.Open("samples") + if err != nil { + log.Fatal(err) + } + defer dir.Close() + + names, err := dir.Readdirnames(0) + if err != nil { + log.Fatal(err) + } + for i, name := range names { + names[i] = filepath.Join("samples", name) + } + makeExpected(names, dst) +} + +func makeExpected(files []string, w io.Writer) { + fmt.Fprintf(w, "package exif\n\n") + fmt.Fprintf(w, "var regressExpected = map[string]map[FieldName]string{\n") + + for _, name := range files { + f, err := os.Open(name) + if err != nil { + continue + } + + x, err := exif.Decode(f) + if err != nil { + f.Close() + continue + } + + fmt.Fprintf(w, "\"%v\": map[FieldName]string{\n", filepath.Base(name)) + x.Walk(®resswalk{w}) + fmt.Fprintf(w, "},\n") + f.Close() + } + fmt.Fprintf(w, "}") +} + +type regresswalk struct { + wr io.Writer +} + +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 +} diff --git a/vendor/github.com/rwcarlsen/goexif/exif/sample1.jpg b/vendor/github.com/rwcarlsen/goexif/exif/sample1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..87bcf8e33a54e6a6608c7d789175395f2b223b5a GIT binary patch literal 80603 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.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 literal 0 HcmV?d00001 diff --git a/vendor/github.com/rwcarlsen/goexif/tiff/sample1.tif b/vendor/github.com/rwcarlsen/goexif/tiff/sample1.tif new file mode 100644 index 0000000000000000000000000000000000000000..fe51399c542954e5cd837eb50626c5cd02991ebb GIT binary patch literal 18382 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 literal 0 HcmV?d00001 diff --git a/vendor/github.com/rwcarlsen/goexif/tiff/tag.go b/vendor/github.com/rwcarlsen/goexif/tiff/tag.go new file mode 100644 index 0000000..66b68e3 --- /dev/null +++ b/vendor/github.com/rwcarlsen/goexif/tiff/tag.go @@ -0,0 +1,438 @@ +package tiff + +import ( + "bytes" + "encoding/binary" + "errors" + "fmt" + "io" + "math/big" + "strings" + "unicode" + "unicode/utf8" +) + +// Format specifies the Go type equivalent used to represent the basic +// tiff data types. +type Format int + +const ( + IntVal Format = iota + FloatVal + RatVal + StringVal + UndefVal + OtherVal +) + +var ErrShortReadTagValue = errors.New("tiff: short read of tag value") + +var formatNames = map[Format]string{ + IntVal: "int", + FloatVal: "float", + RatVal: "rational", + StringVal: "string", + UndefVal: "undefined", + OtherVal: "other", +} + +// DataType represents the basic tiff tag data types. +type DataType uint16 + +const ( + DTByte DataType = 1 + DTAscii = 2 + DTShort = 3 + DTLong = 4 + DTRational = 5 + DTSByte = 6 + DTUndefined = 7 + DTSShort = 8 + DTSLong = 9 + DTSRational = 10 + DTFloat = 11 + DTDouble = 12 +) + +var typeNames = map[DataType]string{ + DTByte: "byte", + DTAscii: "ascii", + DTShort: "short", + DTLong: "long", + DTRational: "rational", + DTSByte: "signed byte", + DTUndefined: "undefined", + DTSShort: "signed short", + DTSLong: "signed long", + DTSRational: "signed rational", + DTFloat: "float", + DTDouble: "double", +} + +// typeSize specifies the size in bytes of each type. +var typeSize = map[DataType]uint32{ + DTByte: 1, + DTAscii: 1, + DTShort: 2, + DTLong: 4, + DTRational: 8, + DTSByte: 1, + DTUndefined: 1, + DTSShort: 2, + DTSLong: 4, + DTSRational: 8, + DTFloat: 4, + DTDouble: 8, +} + +// Tag reflects the parsed content of a tiff IFD tag. +type Tag struct { + // Id is the 2-byte tiff tag identifier. + Id uint16 + // Type is an integer (1 through 12) indicating the tag value's data type. + Type DataType + // Count is the number of type Type stored in the tag's value (i.e. the + // tag's value is an array of type Type and length Count). + Count uint32 + // Val holds the bytes that represent the tag's value. + Val []byte + // ValOffset holds byte offset of the tag value w.r.t. the beginning of the + // reader it was decoded from. Zero if the tag value fit inside the offset + // field. + ValOffset uint32 + + order binary.ByteOrder + intVals []int64 + floatVals []float64 + ratVals [][]int64 + strVal string + format Format +} + +// 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) { + t := new(Tag) + t.order = order + + 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()) + } + + // 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 { + return t, errors.New("invalid Count offset in tag") + } + + valLen := typeSize[t.Type] * t.Count + if valLen == 0 { + return t, errors.New("zero length tag value") + } + + if valLen > 4 { + binary.Read(r, order, &t.ValOffset) + + // 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) + if err != nil { + return t, errors.New("tiff: tag value read failed: " + err.Error()) + } else if n != int64(valLen) { + return t, ErrShortReadTagValue + } + t.Val = buff.Bytes() + + } 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 + } + + return t, t.convertVals() +} + +func (t *Tag) convertVals() error { + r := bytes.NewReader(t.Val) + + switch t.Type { + case DTAscii: + if len(t.Val) > 0 { + t.strVal = string(t.Val[:len(t.Val)-1]) // ignore the last byte (NULL). + } + case DTByte: + var v uint8 + t.intVals = make([]int64, int(t.Count)) + for i := range t.intVals { + err := binary.Read(r, t.order, &v) + if err != nil { + return err + } + t.intVals[i] = int64(v) + } + case DTShort: + var v uint16 + t.intVals = make([]int64, int(t.Count)) + for i := range t.intVals { + err := binary.Read(r, t.order, &v) + if err != nil { + return err + } + t.intVals[i] = int64(v) + } + case DTLong: + var v uint32 + t.intVals = make([]int64, int(t.Count)) + for i := range t.intVals { + err := binary.Read(r, t.order, &v) + if err != nil { + return err + } + t.intVals[i] = int64(v) + } + case DTSByte: + var v int8 + t.intVals = make([]int64, int(t.Count)) + for i := range t.intVals { + err := binary.Read(r, t.order, &v) + if err != nil { + return err + } + t.intVals[i] = int64(v) + } + case DTSShort: + var v int16 + t.intVals = make([]int64, int(t.Count)) + for i := range t.intVals { + err := binary.Read(r, t.order, &v) + if err != nil { + return err + } + t.intVals[i] = int64(v) + } + case DTSLong: + var v int32 + t.intVals = make([]int64, int(t.Count)) + for i := range t.intVals { + err := binary.Read(r, t.order, &v) + if err != nil { + return err + } + t.intVals[i] = int64(v) + } + case DTRational: + t.ratVals = make([][]int64, int(t.Count)) + for i := range t.ratVals { + var n, d uint32 + err := binary.Read(r, t.order, &n) + if err != nil { + return err + } + err = binary.Read(r, t.order, &d) + if err != nil { + return err + } + t.ratVals[i] = []int64{int64(n), int64(d)} + } + case DTSRational: + t.ratVals = make([][]int64, int(t.Count)) + for i := range t.ratVals { + var n, d int32 + err := binary.Read(r, t.order, &n) + if err != nil { + return err + } + err = binary.Read(r, t.order, &d) + if err != nil { + return err + } + t.ratVals[i] = []int64{int64(n), int64(d)} + } + case DTFloat: // float32 + t.floatVals = make([]float64, int(t.Count)) + for i := range t.floatVals { + var v float32 + err := binary.Read(r, t.order, &v) + if err != nil { + return err + } + t.floatVals[i] = float64(v) + } + case DTDouble: + t.floatVals = make([]float64, int(t.Count)) + for i := range t.floatVals { + var u float64 + err := binary.Read(r, t.order, &u) + if err != nil { + return err + } + t.floatVals[i] = u + } + } + + switch t.Type { + case DTByte, DTShort, DTLong, DTSByte, DTSShort, DTSLong: + t.format = IntVal + case DTRational, DTSRational: + t.format = RatVal + case DTFloat, DTDouble: + t.format = FloatVal + case DTAscii: + t.format = StringVal + case DTUndefined: + t.format = UndefVal + default: + t.format = OtherVal + } + + return nil +} + +// Format returns a value indicating which method can be called to retrieve the +// tag's value properly typed (e.g. integer, rational, etc.). +func (t *Tag) Format() Format { return t.format } + +func (t *Tag) typeErr(to Format) error { + return &wrongFmtErr{typeNames[t.Type], formatNames[to]} +} + +// Rat returns the tag's i'th value as a rational number. It returns a nil and +// an error if this tag's Format is not RatVal. It panics for zero deminators +// or if i is out of range. +func (t *Tag) Rat(i int) (*big.Rat, error) { + n, d, err := t.Rat2(i) + if err != nil { + return nil, err + } + return big.NewRat(n, d), nil +} + +// Rat2 returns the tag's i'th value as a rational number represented by a +// 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.format != RatVal { + return 0, 0, t.typeErr(RatVal) + } + return t.ratVals[i][0], t.ratVals[i][1], nil +} + +// 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.format != IntVal { + return 0, t.typeErr(IntVal) + } + return t.intVals[i], nil +} + +// 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.format != IntVal { + return 0, t.typeErr(IntVal) + } + return int(t.intVals[i]), nil +} + +// 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.format != FloatVal { + return 0, t.typeErr(FloatVal) + } + return t.floatVals[i], nil +} + +// 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.format != StringVal { + return "", t.typeErr(StringVal) + } + return t.strVal, nil +} + +// String returns a nicely formatted version of the tag. +func (t *Tag) String() string { + data, err := t.MarshalJSON() + if err != nil { + return "ERROR: " + err.Error() + } + + if t.Count == 1 { + return strings.Trim(fmt.Sprintf("%s", data), "[]") + } + return fmt.Sprintf("%s", data) +} + +func (t *Tag) MarshalJSON() ([]byte, error) { + switch t.format { + case StringVal, UndefVal: + return nullString(t.Val), nil + case OtherVal: + return []byte(fmt.Sprintf("unknown tag type '%v'", t.Type)), nil + } + + rv := []string{} + for i := 0; i < int(t.Count); i++ { + switch t.format { + case RatVal: + n, d, _ := t.Rat2(i) + rv = append(rv, fmt.Sprintf(`"%v/%v"`, n, d)) + case FloatVal: + v, _ := t.Float(i) + rv = append(rv, fmt.Sprintf("%v", v)) + case IntVal: + v, _ := t.Int(i) + rv = append(rv, fmt.Sprintf("%v", v)) + } + } + return []byte(fmt.Sprintf(`[%s]`, strings.Join(rv, ","))), nil +} + +func nullString(in []byte) []byte { + rv := bytes.Buffer{} + rv.WriteByte('"') + for _, b := range in { + if unicode.IsPrint(rune(b)) { + rv.WriteByte(b) + } + } + rv.WriteByte('"') + rvb := rv.Bytes() + if utf8.Valid(rvb) { + return rvb + } + return []byte(`""`) +} + +type wrongFmtErr struct { + From, To string +} + +func (e *wrongFmtErr) Error() string { + return fmt.Sprintf("cannot convert tag type '%v' into '%v'", e.From, e.To) +} diff --git a/vendor/github.com/rwcarlsen/goexif/tiff/tiff.go b/vendor/github.com/rwcarlsen/goexif/tiff/tiff.go new file mode 100644 index 0000000..771e918 --- /dev/null +++ b/vendor/github.com/rwcarlsen/goexif/tiff/tiff.go @@ -0,0 +1,153 @@ +// Package tiff implements TIFF decoding as defined in TIFF 6.0 specification at +// http://partners.adobe.com/public/developer/en/tiff/TIFF6.pdf +package tiff + +import ( + "bytes" + "encoding/binary" + "errors" + "fmt" + "io" + "io/ioutil" +) + +// ReadAtReader is used when decoding Tiff tags and directories +type ReadAtReader interface { + io.Reader + io.ReaderAt +} + +// Tiff provides access to a decoded tiff data structure. +type Tiff struct { + // Dirs is an ordered slice of the tiff's Image File Directories (IFDs). + // The IFD at index 0 is IFD0. + Dirs []*Dir + // The tiff's byte-encoding (i.e. big/little endian). + Order binary.ByteOrder +} + +// 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 +// first byte of an os.File object. +func Decode(r io.Reader) (*Tiff, error) { + data, err := ioutil.ReadAll(r) + if err != nil { + return nil, errors.New("tiff: could not read data") + } + buf := bytes.NewReader(data) + + t := new(Tiff) + + // read byte order + bo := make([]byte, 2) + if _, err = io.ReadFull(buf, bo); err != nil { + return nil, errors.New("tiff: could not read tiff byte order") + } + if string(bo) == "II" { + t.Order = binary.LittleEndian + } else if string(bo) == "MM" { + t.Order = binary.BigEndian + } else { + return nil, errors.New("tiff: could not read tiff byte order") + } + + // check for special tiff marker + var sp int16 + err = binary.Read(buf, t.Order, &sp) + if err != nil || 42 != 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) + if err != nil { + return nil, errors.New("tiff: could not read offset to first IFD") + } + + // 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) + if err != nil { + return nil, err + } + + if offset == prev { + return nil, errors.New("tiff: recursive IFD") + } + prev = offset + + t.Dirs = append(t.Dirs, d) + } + + return t, nil +} + +func (tf *Tiff) String() string { + var buf bytes.Buffer + fmt.Fprint(&buf, "Tiff{") + for _, d := range tf.Dirs { + fmt.Fprintf(&buf, "%s, ", d.String()) + } + fmt.Fprintf(&buf, "}") + return buf.String() +} + +// Dir provides access to the parsed content of a tiff Image File Directory (IFD). +type Dir struct { + Tags []*Tag +} + +// DecodeDir parses a tiff-encoded IFD from r and returns a Dir object. offset +// 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) + + // get num of tags in ifd + var nTags int16 + err = binary.Read(r, order, &nTags) + if err != nil { + return nil, 0, errors.New("tiff: failed to read IFD tag count: " + err.Error()) + } + + // load tags + for n := 0; n < int(nTags); n++ { + t, err := DecodeTag(r, order) + if err != nil { + return nil, 0, err + } + d.Tags = append(d.Tags, t) + } + + // get offset to next ifd + err = binary.Read(r, order, &offset) + if err != nil { + return nil, 0, errors.New("tiff: falied to read offset to next IFD: " + err.Error()) + } + + return d, offset, nil +} + +func (d *Dir) String() string { + s := "Dir{" + for _, t := range d.Tags { + s += t.String() + ", " + } + return s + "}" +} diff --git a/vendor/vendor.json b/vendor/vendor.json new file mode 100644 index 0000000..51da265 --- /dev/null +++ b/vendor/vendor.json @@ -0,0 +1,19 @@ +{ + "comment": "", + "ignore": "test", + "package": [ + { + "checksumSHA1": "Q68FxXX04PtPDIG7C1RlSDhx/ko=", + "path": "github.com/rwcarlsen/goexif/exif", + "revision": "709fab3d192d7c62f86043caff1e7e3fb0f42bd8", + "revisionTime": "2015-05-20T14:06:47Z" + }, + { + "checksumSHA1": "0+tTLlssYWyGuq+vQs4IiPIXJW4=", + "path": "github.com/rwcarlsen/goexif/tiff", + "revision": "709fab3d192d7c62f86043caff1e7e3fb0f42bd8", + "revisionTime": "2015-05-20T14:06:47Z" + } + ], + "rootPath": "mcquay.me/arrange" +}