index,camtool: try and cope better with broken exif

http://camlistore.org/issue/493

Change-Id: I40aebd67252cf82a3a5a143af6c258d7ed2aecda
This commit is contained in:
mpl 2014-10-29 02:01:14 +01:00
parent f97cf5b587
commit fda1399e9c
3 changed files with 31 additions and 4 deletions

View File

@ -32,9 +32,18 @@ func showEXIF(file string) {
defer f.Close()
ex, err := exif.Decode(f)
if err != nil {
log.Fatalf("exif.Decode: %v", err)
if exif.IsCriticalError(err) {
log.Fatalf("exif.Decode, critical error: %v", err)
}
log.Printf("exif.Decode, warning: %v", err)
}
fmt.Printf("%v\n", ex)
if exif.IsExifError(err) {
// the error happened while decoding the EXIF sub-IFD, so as DateTime is
// part of it, we have to assume (until there's a better "decode effort"
// strategy in goexif) that it's not usable.
return
}
fmt.Printf("exif.Decode = %#v\n", ex)
ct, err := ex.DateTime()
fmt.Printf("exif.DateTime = %v, %v\n", ct, err)
}

View File

@ -410,6 +410,7 @@ func (ix *Index) populateFile(fetcher blob.Fetcher, b *schema.Blob, mm *mutation
log.Printf("filename %q exif = %v, %v", b.FileName(), ft, err)
}
// TODO(mpl): find (generate?) more broken EXIF images to experiment with.
err = indexEXIF(wholeRef, bytes.NewReader(imageBuf.Bytes), mm)
if err == io.EOF {
var fr *schema.FileReader
@ -472,9 +473,14 @@ func (f exifWalkFunc) Walk(name exif.FieldName, tag *tiff.Tag) error { return f(
var errEXIFPanic = errors.New("EXIF library panicked while walking fields")
func indexEXIF(wholeRef blob.Ref, reader io.Reader, mm *mutationMap) (err error) {
var tiffErr error
ex, err := exif.Decode(reader)
if err != nil {
return
tiffErr = err
if exif.IsCriticalError(err) {
return
}
log.Printf("Non critical TIFF decoding error: %v", err)
}
defer func() {
// The EXIF library panics if you access a field past
@ -549,6 +555,10 @@ func indexEXIF(wholeRef blob.Ref, reader io.Reader, mm *mutationMap) (err error)
return
}
if exif.IsGPSError(tiffErr) {
log.Printf("Invalid EXIF GPS data: %v", tiffErr)
return nil
}
if lat, long, err := ex.LatLong(); err == nil {
mm.Set(keyEXIFGPS.Key(wholeRef), keyEXIFGPS.Val(fmt.Sprint(lat), fmt.Sprint(long)))
} else if !exif.IsTagNotPresentError(err) {

View File

@ -958,9 +958,13 @@ func FileTime(f io.ReaderAt) (time.Time, error) {
size = 256 << 10 // enough to get the EXIF
}
r := io.NewSectionReader(f, 0, size)
var tiffErr error
ex, err := exif.Decode(r)
if err != nil {
return defaultTime()
tiffErr = err
if exif.IsCriticalError(err) || exif.IsExifError(err) {
return defaultTime()
}
}
ct, err = ex.DateTime()
if err != nil {
@ -969,6 +973,10 @@ func FileTime(f io.ReaderAt) (time.Time, error) {
// If the EXIF file only had local timezone, but it did have
// GPS, then lookup the timezone and correct the time.
if ct.Location() == time.Local {
if exif.IsGPSError(tiffErr) {
log.Printf("Invalid EXIF GPS data: %v", tiffErr)
return ct, nil
}
if lat, long, err := ex.LatLong(); err == nil {
if loc := lookupLocation(latlong.LookupZoneName(lat, long)); loc != nil {
if t, err := exifDateTimeInLocation(ex, loc); err == nil {