exif.go (17308B)
1 // Package exif implements decoding of EXIF data as defined in the EXIF 2.2 2 // specification (http://www.exif.org/Exif2-2.PDF). 3 package exif 4 5 import ( 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 22 const ( 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. 31 type decodeError struct { 32 cause error 33 } 34 35 func (de decodeError) Error() string { 36 return fmt.Sprintf("exif: decode failed (%v) ", de.cause.Error()) 37 } 38 39 // IsShortReadTagValueError identifies a ErrShortReadTagValue error. 40 func 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. 50 type TagNotPresentError FieldName 51 52 func (tag TagNotPresentError) Error() string { 53 return fmt.Sprintf("exif: tag %q is not present", string(tag)) 54 } 55 56 func 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. 63 type 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 69 var parsers []Parser 70 71 func 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. 77 func RegisterParsers(ps ...Parser) { 78 parsers = append(parsers, ps...) 79 } 80 81 type parser struct{} 82 83 type tiffErrors map[tiffError]string 84 85 func (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. 95 func 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. 102 func 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. 111 func 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. 121 func IsInteroperabilityError(err error) bool { 122 if te, ok := err.(tiffErrors); ok { 123 _, isInterop := te[loadInteroperability] 124 return isInterop 125 } 126 return false 127 } 128 129 type tiffError int 130 131 const ( 132 loadExif tiffError = iota 133 loadGPS 134 loadInteroperability 135 ) 136 137 var 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. 146 func (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 176 func 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. 201 type 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. 215 func 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). 322 func (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. 339 func (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. 347 type 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. 355 func (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. 373 func (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 395 func (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 411 func 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" 424 func 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 469 func 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 484 func 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. 510 func (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. 550 func (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 560 func (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). 584 func (x Exif) MarshalJSON() ([]byte, error) { 585 return json.Marshal(x.main) 586 } 587 588 type appSec struct { 589 marker byte 590 data []byte 591 } 592 593 // newAppSec finds marker in r and returns the corresponding application data 594 // section. 595 func 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. 638 func (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. 644 func (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 }