1// Package exif implements decoding of EXIF data as defined in the EXIF 2.2
2// specification (http://www.exif.org/Exif2-2.PDF).
3package exif
4
5import (
6	"bufio"
7	"bytes"
8	"encoding/binary"
9	"encoding/json"
10	"errors"
11	"fmt"
12	"io"
13	"io/ioutil"
14	"math"
15	"strconv"
16	"strings"
17	"time"
18
19	"github.com/rwcarlsen/goexif/tiff"
20)
21
22const (
23	jpeg_APP1 = 0xE1
24
25	exifPointer    = 0x8769
26	gpsPointer     = 0x8825
27	interopPointer = 0xA005
28)
29
30// A decodeError is returned when the image cannot be decoded as a tiff image.
31type decodeError struct {
32	cause error
33}
34
35func (de decodeError) Error() string {
36	return fmt.Sprintf("exif: decode failed (%v) ", de.cause.Error())
37}
38
39// IsShortReadTagValueError identifies a ErrShortReadTagValue error.
40func IsShortReadTagValueError(err error) bool {
41	de, ok := err.(decodeError)
42	if ok {
43		return de.cause == tiff.ErrShortReadTagValue
44	}
45	return false
46}
47
48// A TagNotPresentError is returned when the requested field is not
49// present in the EXIF.
50type TagNotPresentError FieldName
51
52func (tag TagNotPresentError) Error() string {
53	return fmt.Sprintf("exif: tag %q is not present", string(tag))
54}
55
56func IsTagNotPresentError(err error) bool {
57	_, ok := err.(TagNotPresentError)
58	return ok
59}
60
61// Parser allows the registration of custom parsing and field loading
62// in the Decode function.
63type Parser interface {
64	// Parse should read data from x and insert parsed fields into x via
65	// LoadTags.
66	Parse(x *Exif) error
67}
68
69var parsers []Parser
70
71func init() {
72	RegisterParsers(&parser{})
73}
74
75// RegisterParsers registers one or more parsers to be automatically called
76// when decoding EXIF data via the Decode function.
77func RegisterParsers(ps ...Parser) {
78	parsers = append(parsers, ps...)
79}
80
81type parser struct{}
82
83type tiffErrors map[tiffError]string
84
85func (te tiffErrors) Error() string {
86	var allErrors []string
87	for k, v := range te {
88		allErrors = append(allErrors, fmt.Sprintf("%s: %v\n", stagePrefix[k], v))
89	}
90	return strings.Join(allErrors, "\n")
91}
92
93// IsCriticalError, given the error returned by Decode, reports whether the
94// returned *Exif may contain usable information.
95func IsCriticalError(err error) bool {
96	_, ok := err.(tiffErrors)
97	return !ok
98}
99
100// IsExifError reports whether the error happened while decoding the EXIF
101// sub-IFD.
102func IsExifError(err error) bool {
103	if te, ok := err.(tiffErrors); ok {
104		_, isExif := te[loadExif]
105		return isExif
106	}
107	return false
108}
109
110// IsGPSError reports whether the error happened while decoding the GPS sub-IFD.
111func IsGPSError(err error) bool {
112	if te, ok := err.(tiffErrors); ok {
113		_, isGPS := te[loadExif]
114		return isGPS
115	}
116	return false
117}
118
119// IsInteroperabilityError reports whether the error happened while decoding the
120// Interoperability sub-IFD.
121func IsInteroperabilityError(err error) bool {
122	if te, ok := err.(tiffErrors); ok {
123		_, isInterop := te[loadInteroperability]
124		return isInterop
125	}
126	return false
127}
128
129type tiffError int
130
131const (
132	loadExif tiffError = iota
133	loadGPS
134	loadInteroperability
135)
136
137var stagePrefix = map[tiffError]string{
138	loadExif:             "loading EXIF sub-IFD",
139	loadGPS:              "loading GPS sub-IFD",
140	loadInteroperability: "loading Interoperability sub-IFD",
141}
142
143// Parse reads data from the tiff data in x and populates the tags
144// in x. If parsing a sub-IFD fails, the error is recorded and
145// parsing continues with the remaining sub-IFDs.
146func (p *parser) Parse(x *Exif) error {
147	if len(x.Tiff.Dirs) == 0 {
148		return errors.New("Invalid exif data")
149	}
150	x.LoadTags(x.Tiff.Dirs[0], exifFields, false)
151
152	// thumbnails
153	if len(x.Tiff.Dirs) >= 2 {
154		x.LoadTags(x.Tiff.Dirs[1], thumbnailFields, false)
155	}
156
157	te := make(tiffErrors)
158
159	// recurse into exif, gps, and interop sub-IFDs
160	if err := loadSubDir(x, ExifIFDPointer, exifFields); err != nil {
161		te[loadExif] = err.Error()
162	}
163	if err := loadSubDir(x, GPSInfoIFDPointer, gpsFields); err != nil {
164		te[loadGPS] = err.Error()
165	}
166
167	if err := loadSubDir(x, InteroperabilityIFDPointer, interopFields); err != nil {
168		te[loadInteroperability] = err.Error()
169	}
170	if len(te) > 0 {
171		return te
172	}
173	return nil
174}
175
176func loadSubDir(x *Exif, ptr FieldName, fieldMap map[uint16]FieldName) error {
177	r := bytes.NewReader(x.Raw)
178
179	tag, err := x.Get(ptr)
180	if err != nil {
181		return nil
182	}
183	offset, err := tag.Int64(0)
184	if err != nil {
185		return nil
186	}
187
188	_, err = r.Seek(offset, 0)
189	if err != nil {
190		return fmt.Errorf("exif: seek to sub-IFD %s failed: %v", ptr, err)
191	}
192	subDir, _, err := tiff.DecodeDir(r, x.Tiff.Order)
193	if err != nil {
194		return fmt.Errorf("exif: sub-IFD %s decode failed: %v", ptr, err)
195	}
196	x.LoadTags(subDir, fieldMap, false)
197	return nil
198}
199
200// Exif provides access to decoded EXIF metadata fields and values.
201type Exif struct {
202	Tiff *tiff.Tiff
203	main map[FieldName]*tiff.Tag
204	Raw  []byte
205}
206
207// Decode parses EXIF data from r (a TIFF, JPEG, or raw EXIF block)
208// and returns a queryable Exif object. After the EXIF data section is
209// called and the TIFF structure is decoded, each registered parser is
210// called (in order of registration). If one parser returns an error,
211// decoding terminates and the remaining parsers are not called.
212//
213// The error can be inspected with functions such as IsCriticalError
214// to determine whether the returned object might still be usable.
215func Decode(r io.Reader) (*Exif, error) {
216
217	// EXIF data in JPEG is stored in the APP1 marker. EXIF data uses the TIFF
218	// format to store data.
219	// If we're parsing a TIFF image, we don't need to strip away any data.
220	// If we're parsing a JPEG image, we need to strip away the JPEG APP1
221	// marker and also the EXIF header.
222
223	header := make([]byte, 4)
224	n, err := io.ReadFull(r, header)
225	if err != nil {
226		return nil, fmt.Errorf("exif: error reading 4 byte header, got %d, %v", n, err)
227	}
228
229	var isTiff bool
230	var isRawExif bool
231	var assumeJPEG bool
232	switch string(header) {
233	case "II*\x00":
234		// TIFF - Little endian (Intel)
235		isTiff = true
236	case "MM\x00*":
237		// TIFF - Big endian (Motorola)
238		isTiff = true
239	case "Exif":
240		isRawExif = true
241	default:
242		// Not TIFF, assume JPEG
243		assumeJPEG = true
244	}
245
246	// Put the header bytes back into the reader.
247	r = io.MultiReader(bytes.NewReader(header), r)
248	var (
249		er  *bytes.Reader
250		tif *tiff.Tiff
251		sec *appSec
252	)
253
254	switch {
255	case isRawExif:
256		var header [6]byte
257		if _, err := io.ReadFull(r, header[:]); err != nil {
258			return nil, fmt.Errorf("exif: unexpected raw exif header read error")
259		}
260		if got, want := string(header[:]), "Exif\x00\x00"; got != want {
261			return nil, fmt.Errorf("exif: unexpected raw exif header; got %q, want %q", got, want)
262		}
263		fallthrough
264	case isTiff:
265		// Functions below need the IFDs from the TIFF data to be stored in a
266		// *bytes.Reader.  We use TeeReader to get a copy of the bytes as a
267		// side-effect of tiff.Decode() doing its work.
268		b := &bytes.Buffer{}
269		tr := io.TeeReader(r, b)
270		tif, err = tiff.Decode(tr)
271		er = bytes.NewReader(b.Bytes())
272	case assumeJPEG:
273		// Locate the JPEG APP1 header.
274		sec, err = newAppSec(jpeg_APP1, r)
275		if err != nil {
276			return nil, err
277		}
278		// Strip away EXIF header.
279		er, err = sec.exifReader()
280		if err != nil {
281			return nil, err
282		}
283		tif, err = tiff.Decode(er)
284	}
285
286	if err != nil {
287		return nil, decodeError{cause: err}
288	}
289
290	er.Seek(0, 0)
291	raw, err := ioutil.ReadAll(er)
292	if err != nil {
293		return nil, decodeError{cause: err}
294	}
295
296	// build an exif structure from the tiff
297	x := &Exif{
298		main: map[FieldName]*tiff.Tag{},
299		Tiff: tif,
300		Raw:  raw,
301	}
302
303	for i, p := range parsers {
304		if err := p.Parse(x); err != nil {
305			if _, ok := err.(tiffErrors); ok {
306				return x, err
307			}
308			// This should never happen, as Parse always returns a tiffError
309			// for now, but that could change.
310			return x, fmt.Errorf("exif: parser %v failed (%v)", i, err)
311		}
312	}
313
314	return x, nil
315}
316
317// LoadTags loads tags into the available fields from the tiff Directory
318// using the given tagid-fieldname mapping.  Used to load makernote and
319// other meta-data.  If showMissing is true, tags in d that are not in the
320// fieldMap will be loaded with the FieldName UnknownPrefix followed by the
321// tag ID (in hex format).
322func (x *Exif) LoadTags(d *tiff.Dir, fieldMap map[uint16]FieldName, showMissing bool) {
323	for _, tag := range d.Tags {
324		name := fieldMap[tag.Id]
325		if name == "" {
326			if !showMissing {
327				continue
328			}
329			name = FieldName(fmt.Sprintf("%v%x", UnknownPrefix, tag.Id))
330		}
331		x.main[name] = tag
332	}
333}
334
335// Get retrieves the EXIF tag for the given field name.
336//
337// If the tag is not known or not present, an error is returned. If the
338// tag name is known, the error will be a TagNotPresentError.
339func (x *Exif) Get(name FieldName) (*tiff.Tag, error) {
340	if tg, ok := x.main[name]; ok {
341		return tg, nil
342	}
343	return nil, TagNotPresentError(name)
344}
345
346// Walker is the interface used to traverse all fields of an Exif object.
347type Walker interface {
348	// Walk is called for each non-nil EXIF field. Returning a non-nil
349	// error aborts the walk/traversal.
350	Walk(name FieldName, tag *tiff.Tag) error
351}
352
353// Walk calls the Walk method of w with the name and tag for every non-nil
354// EXIF field.  If w aborts the walk with an error, that error is returned.
355func (x *Exif) Walk(w Walker) error {
356	for name, tag := range x.main {
357		if err := w.Walk(name, tag); err != nil {
358			return err
359		}
360	}
361	return nil
362}
363
364// DateTime returns the EXIF's "DateTimeOriginal" field, which
365// is the creation time of the photo. If not found, it tries
366// the "DateTime" (which is meant as the modtime) instead.
367// The error will be TagNotPresentErr if none of those tags
368// were found, or a generic error if the tag value was
369// not a string, or the error returned by time.Parse.
370//
371// If the EXIF lacks timezone information or GPS time, the returned
372// time's Location will be time.Local.
373func (x *Exif) DateTime() (time.Time, error) {
374	var dt time.Time
375	tag, err := x.Get(DateTimeOriginal)
376	if err != nil {
377		tag, err = x.Get(DateTime)
378		if err != nil {
379			return dt, err
380		}
381	}
382	if tag.Format() != tiff.StringVal {
383		return dt, errors.New("DateTime[Original] not in string format")
384	}
385	exifTimeLayout := "2006:01:02 15:04:05"
386	dateStr := strings.TrimRight(string(tag.Val), "\x00")
387	// TODO(bradfitz,mpl): look for timezone offset, GPS time, etc.
388	timeZone := time.Local
389	if tz, _ := x.TimeZone(); tz != nil {
390		timeZone = tz
391	}
392	return time.ParseInLocation(exifTimeLayout, dateStr, timeZone)
393}
394
395func (x *Exif) TimeZone() (*time.Location, error) {
396	// TODO: parse more timezone fields (e.g. Nikon WorldTime).
397	timeInfo, err := x.Get("Canon.TimeInfo")
398	if err != nil {
399		return nil, err
400	}
401	if timeInfo.Count < 2 {
402		return nil, errors.New("Canon.TimeInfo does not contain timezone")
403	}
404	offsetMinutes, err := timeInfo.Int(1)
405	if err != nil {
406		return nil, err
407	}
408	return time.FixedZone("", offsetMinutes*60), nil
409}
410
411func ratFloat(num, dem int64) float64 {
412	return float64(num) / float64(dem)
413}
414
415// Tries to parse a Geo degrees value from a string as it was found in some
416// EXIF data.
417// Supported formats so far:
418// - "52,00000,50,00000,34,01180" ==> 52 deg 50'34.0118"
419//   Probably due to locale the comma is used as decimal mark as well as the
420//   separator of three floats (degrees, minutes, seconds)
421//   http://en.wikipedia.org/wiki/Decimal_mark#Hindu.E2.80.93Arabic_numeral_system
422// - "52.0,50.0,34.01180" ==> 52deg50'34.0118"
423// - "52,50,34.01180"     ==> 52deg50'34.0118"
424func parseTagDegreesString(s string) (float64, error) {
425	const unparsableErrorFmt = "Unknown coordinate format: %s"
426	isSplitRune := func(c rune) bool {
427		return c == ',' || c == ';'
428	}
429	parts := strings.FieldsFunc(s, isSplitRune)
430	var degrees, minutes, seconds float64
431	var err error
432	switch len(parts) {
433	case 6:
434		degrees, err = strconv.ParseFloat(parts[0]+"."+parts[1], 64)
435		if err != nil {
436			return 0.0, fmt.Errorf(unparsableErrorFmt, s)
437		}
438		minutes, err = strconv.ParseFloat(parts[2]+"."+parts[3], 64)
439		if err != nil {
440			return 0.0, fmt.Errorf(unparsableErrorFmt, s)
441		}
442		minutes = math.Copysign(minutes, degrees)
443		seconds, err = strconv.ParseFloat(parts[4]+"."+parts[5], 64)
444		if err != nil {
445			return 0.0, fmt.Errorf(unparsableErrorFmt, s)
446		}
447		seconds = math.Copysign(seconds, degrees)
448	case 3:
449		degrees, err = strconv.ParseFloat(parts[0], 64)
450		if err != nil {
451			return 0.0, fmt.Errorf(unparsableErrorFmt, s)
452		}
453		minutes, err = strconv.ParseFloat(parts[1], 64)
454		if err != nil {
455			return 0.0, fmt.Errorf(unparsableErrorFmt, s)
456		}
457		minutes = math.Copysign(minutes, degrees)
458		seconds, err = strconv.ParseFloat(parts[2], 64)
459		if err != nil {
460			return 0.0, fmt.Errorf(unparsableErrorFmt, s)
461		}
462		seconds = math.Copysign(seconds, degrees)
463	default:
464		return 0.0, fmt.Errorf(unparsableErrorFmt, s)
465	}
466	return degrees + minutes/60.0 + seconds/3600.0, nil
467}
468
469func parse3Rat2(tag *tiff.Tag) ([3]float64, error) {
470	v := [3]float64{}
471	for i := range v {
472		num, den, err := tag.Rat2(i)
473		if err != nil {
474			return v, err
475		}
476		v[i] = ratFloat(num, den)
477		if tag.Count < uint32(i+2) {
478			break
479		}
480	}
481	return v, nil
482}
483
484func tagDegrees(tag *tiff.Tag) (float64, error) {
485	switch tag.Format() {
486	case tiff.RatVal:
487		// The usual case, according to the Exif spec
488		// (http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf,
489		// sec 4.6.6, p. 52 et seq.)
490		v, err := parse3Rat2(tag)
491		if err != nil {
492			return 0.0, err
493		}
494		return v[0] + v[1]/60 + v[2]/3600.0, nil
495	case tiff.StringVal:
496		// Encountered this weird case with a panorama picture taken with a HTC phone
497		s, err := tag.StringVal()
498		if err != nil {
499			return 0.0, err
500		}
501		return parseTagDegreesString(s)
502	default:
503		// don't know how to parse value, give up
504		return 0.0, fmt.Errorf("Malformed EXIF Tag Degrees")
505	}
506}
507
508// LatLong returns the latitude and longitude of the photo and
509// whether it was present.
510func (x *Exif) LatLong() (lat, long float64, err error) {
511	// All calls of x.Get might return an TagNotPresentError
512	longTag, err := x.Get(FieldName("GPSLongitude"))
513	if err != nil {
514		return
515	}
516	ewTag, err := x.Get(FieldName("GPSLongitudeRef"))
517	if err != nil {
518		return
519	}
520	latTag, err := x.Get(FieldName("GPSLatitude"))
521	if err != nil {
522		return
523	}
524	nsTag, err := x.Get(FieldName("GPSLatitudeRef"))
525	if err != nil {
526		return
527	}
528	if long, err = tagDegrees(longTag); err != nil {
529		return 0, 0, fmt.Errorf("Cannot parse longitude: %v", err)
530	}
531	if lat, err = tagDegrees(latTag); err != nil {
532		return 0, 0, fmt.Errorf("Cannot parse latitude: %v", err)
533	}
534	ew, err := ewTag.StringVal()
535	if err == nil && ew == "W" {
536		long *= -1.0
537	} else if err != nil {
538		return 0, 0, fmt.Errorf("Cannot parse longitude: %v", err)
539	}
540	ns, err := nsTag.StringVal()
541	if err == nil && ns == "S" {
542		lat *= -1.0
543	} else if err != nil {
544		return 0, 0, fmt.Errorf("Cannot parse longitude: %v", err)
545	}
546	return lat, long, nil
547}
548
549// String returns a pretty text representation of the decoded exif data.
550func (x *Exif) String() string {
551	var buf bytes.Buffer
552	for name, tag := range x.main {
553		fmt.Fprintf(&buf, "%s: %s\n", name, tag)
554	}
555	return buf.String()
556}
557
558// JpegThumbnail returns the jpeg thumbnail if it exists. If it doesn't exist,
559// TagNotPresentError will be returned
560func (x *Exif) JpegThumbnail() ([]byte, error) {
561	offset, err := x.Get(ThumbJPEGInterchangeFormat)
562	if err != nil {
563		return nil, err
564	}
565	start, err := offset.Int(0)
566	if err != nil {
567		return nil, err
568	}
569
570	length, err := x.Get(ThumbJPEGInterchangeFormatLength)
571	if err != nil {
572		return nil, err
573	}
574	l, err := length.Int(0)
575	if err != nil {
576		return nil, err
577	}
578
579	return x.Raw[start : start+l], nil
580}
581
582// MarshalJson implements the encoding/json.Marshaler interface providing output of
583// all EXIF fields present (names and values).
584func (x Exif) MarshalJSON() ([]byte, error) {
585	return json.Marshal(x.main)
586}
587
588type appSec struct {
589	marker byte
590	data   []byte
591}
592
593// newAppSec finds marker in r and returns the corresponding application data
594// section.
595func newAppSec(marker byte, r io.Reader) (*appSec, error) {
596	br := bufio.NewReader(r)
597	app := &appSec{marker: marker}
598	var dataLen int
599
600	// seek to marker
601	for dataLen == 0 {
602		if _, err := br.ReadBytes(0xFF); err != nil {
603			return nil, err
604		}
605		c, err := br.ReadByte()
606		if err != nil {
607			return nil, err
608		} else if c != marker {
609			continue
610		}
611
612		dataLenBytes := make([]byte, 2)
613		for k, _ := range dataLenBytes {
614			c, err := br.ReadByte()
615			if err != nil {
616				return nil, err
617			}
618			dataLenBytes[k] = c
619		}
620		dataLen = int(binary.BigEndian.Uint16(dataLenBytes)) - 2
621	}
622
623	// read section data
624	nread := 0
625	for nread < dataLen {
626		s := make([]byte, dataLen-nread)
627		n, err := br.Read(s)
628		nread += n
629		if err != nil && nread < dataLen {
630			return nil, err
631		}
632		app.data = append(app.data, s[:n]...)
633	}
634	return app, nil
635}
636
637// reader returns a reader on this appSec.
638func (app *appSec) reader() *bytes.Reader {
639	return bytes.NewReader(app.data)
640}
641
642// exifReader returns a reader on this appSec with the read cursor advanced to
643// the start of the exif's tiff encoded portion.
644func (app *appSec) exifReader() (*bytes.Reader, error) {
645	if len(app.data) < 6 {
646		return nil, errors.New("exif: failed to find exif intro marker")
647	}
648
649	// read/check for exif special mark
650	exif := app.data[:6]
651	if !bytes.Equal(exif, append([]byte("Exif"), 0x00, 0x00)) {
652		return nil, errors.New("exif: failed to find exif intro marker")
653	}
654	return bytes.NewReader(app.data[6:]), nil
655}
656