2021-02-09 20:17:06 +01:00
|
|
|
package exif
|
|
|
|
|
|
|
|
import (
|
|
|
|
"path"
|
|
|
|
"reflect"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"io/ioutil"
|
|
|
|
|
2021-02-10 01:00:02 +01:00
|
|
|
"github.com/dsoprea/go-logging"
|
2021-02-09 20:17:06 +01:00
|
|
|
|
2021-02-10 01:00:02 +01:00
|
|
|
"github.com/dsoprea/go-exif/v2/common"
|
2021-02-09 20:17:06 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
testExifData []byte
|
|
|
|
)
|
|
|
|
|
|
|
|
func getExifSimpleTestIb() *IfdBuilder {
|
|
|
|
defer func() {
|
|
|
|
if state := recover(); state != nil {
|
|
|
|
err := log.Wrap(state.(error))
|
|
|
|
log.Panic(err)
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
im := NewIfdMapping()
|
|
|
|
|
|
|
|
err := LoadStandardIfds(im)
|
|
|
|
log.PanicIf(err)
|
|
|
|
|
|
|
|
ti := NewTagIndex()
|
|
|
|
ib := NewIfdBuilder(im, ti, exifcommon.IfdStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
|
|
|
|
|
|
|
|
err = ib.AddStandard(0x000b, "asciivalue")
|
|
|
|
log.PanicIf(err)
|
|
|
|
|
|
|
|
err = ib.AddStandard(0x00ff, []uint16{0x1122})
|
|
|
|
log.PanicIf(err)
|
|
|
|
|
|
|
|
err = ib.AddStandard(0x0100, []uint32{0x33445566})
|
|
|
|
log.PanicIf(err)
|
|
|
|
|
|
|
|
err = ib.AddStandard(0x013e, []exifcommon.Rational{{Numerator: 0x11112222, Denominator: 0x33334444}})
|
|
|
|
log.PanicIf(err)
|
|
|
|
|
|
|
|
return ib
|
|
|
|
}
|
|
|
|
|
|
|
|
func getExifSimpleTestIbBytes() []byte {
|
|
|
|
defer func() {
|
|
|
|
if state := recover(); state != nil {
|
|
|
|
err := log.Wrap(state.(error))
|
|
|
|
log.Panic(err)
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
im := NewIfdMapping()
|
|
|
|
|
|
|
|
err := LoadStandardIfds(im)
|
|
|
|
log.PanicIf(err)
|
|
|
|
|
|
|
|
ti := NewTagIndex()
|
|
|
|
ib := NewIfdBuilder(im, ti, exifcommon.IfdStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
|
|
|
|
|
|
|
|
err = ib.AddStandard(0x000b, "asciivalue")
|
|
|
|
log.PanicIf(err)
|
|
|
|
|
|
|
|
err = ib.AddStandard(0x00ff, []uint16{0x1122})
|
|
|
|
log.PanicIf(err)
|
|
|
|
|
|
|
|
err = ib.AddStandard(0x0100, []uint32{0x33445566})
|
|
|
|
log.PanicIf(err)
|
|
|
|
|
|
|
|
err = ib.AddStandard(0x013e, []exifcommon.Rational{{Numerator: 0x11112222, Denominator: 0x33334444}})
|
|
|
|
log.PanicIf(err)
|
|
|
|
|
|
|
|
ibe := NewIfdByteEncoder()
|
|
|
|
|
|
|
|
exifData, err := ibe.EncodeToExif(ib)
|
|
|
|
log.PanicIf(err)
|
|
|
|
|
|
|
|
return exifData
|
|
|
|
}
|
|
|
|
|
|
|
|
func validateExifSimpleTestIb(exifData []byte, t *testing.T) {
|
|
|
|
defer func() {
|
|
|
|
if state := recover(); state != nil {
|
|
|
|
err := log.Wrap(state.(error))
|
|
|
|
log.Panic(err)
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
im := NewIfdMapping()
|
|
|
|
|
|
|
|
err := LoadStandardIfds(im)
|
|
|
|
log.PanicIf(err)
|
|
|
|
|
|
|
|
ti := NewTagIndex()
|
|
|
|
|
|
|
|
eh, index, err := Collect(im, ti, exifData)
|
|
|
|
log.PanicIf(err)
|
|
|
|
|
|
|
|
if eh.ByteOrder != exifcommon.TestDefaultByteOrder {
|
|
|
|
t.Fatalf("EXIF byte-order is not correct: %v", eh.ByteOrder)
|
|
|
|
} else if eh.FirstIfdOffset != ExifDefaultFirstIfdOffset {
|
|
|
|
t.Fatalf("EXIF first IFD-offset not correct: (0x%02x)", eh.FirstIfdOffset)
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(index.Ifds) != 1 {
|
|
|
|
t.Fatalf("There wasn't exactly one IFD decoded: (%d)", len(index.Ifds))
|
|
|
|
}
|
|
|
|
|
|
|
|
ifd := index.RootIfd
|
|
|
|
|
|
|
|
if ifd.ByteOrder != exifcommon.TestDefaultByteOrder {
|
|
|
|
t.Fatalf("IFD byte-order not correct.")
|
|
|
|
} else if ifd.ifdIdentity.UnindexedString() != exifcommon.IfdStandardIfdIdentity.UnindexedString() {
|
|
|
|
t.Fatalf("IFD name not correct.")
|
|
|
|
} else if ifd.ifdIdentity.Index() != 0 {
|
|
|
|
t.Fatalf("IFD index not zero: (%d)", ifd.ifdIdentity.Index())
|
|
|
|
} else if ifd.Offset != uint32(0x0008) {
|
|
|
|
t.Fatalf("IFD offset not correct.")
|
|
|
|
} else if len(ifd.Entries) != 4 {
|
|
|
|
t.Fatalf("IFD number of entries not correct: (%d)", len(ifd.Entries))
|
|
|
|
} else if ifd.NextIfdOffset != uint32(0) {
|
|
|
|
t.Fatalf("Next-IFD offset is non-zero.")
|
|
|
|
} else if ifd.NextIfd != nil {
|
|
|
|
t.Fatalf("Next-IFD pointer is non-nil.")
|
|
|
|
}
|
|
|
|
|
|
|
|
// Verify the values by using the actual, original types (this is awesome).
|
|
|
|
|
|
|
|
expected := []struct {
|
|
|
|
tagId uint16
|
|
|
|
value interface{}
|
|
|
|
}{
|
|
|
|
{tagId: 0x000b, value: "asciivalue"},
|
|
|
|
{tagId: 0x00ff, value: []uint16{0x1122}},
|
|
|
|
{tagId: 0x0100, value: []uint32{0x33445566}},
|
|
|
|
{tagId: 0x013e, value: []exifcommon.Rational{{Numerator: 0x11112222, Denominator: 0x33334444}}},
|
|
|
|
}
|
|
|
|
|
|
|
|
for i, ite := range ifd.Entries {
|
|
|
|
if ite.TagId() != expected[i].tagId {
|
|
|
|
t.Fatalf("Tag-ID for entry (%d) not correct: (0x%02x) != (0x%02x)", i, ite.TagId(), expected[i].tagId)
|
|
|
|
}
|
|
|
|
|
|
|
|
value, err := ite.Value()
|
|
|
|
log.PanicIf(err)
|
|
|
|
|
|
|
|
if reflect.DeepEqual(value, expected[i].value) != true {
|
|
|
|
t.Fatalf("Value for entry (%d) not correct: [%v] != [%v]", i, value, expected[i].value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func getTestImageFilepath() string {
|
|
|
|
assetsPath := exifcommon.GetTestAssetsPath()
|
|
|
|
testImageFilepath := path.Join(assetsPath, "NDM_8901.jpg")
|
|
|
|
return testImageFilepath
|
|
|
|
}
|
|
|
|
|
|
|
|
func getTestExifData() []byte {
|
|
|
|
if testExifData == nil {
|
|
|
|
assetsPath := exifcommon.GetTestAssetsPath()
|
|
|
|
filepath := path.Join(assetsPath, "NDM_8901.jpg.exif")
|
|
|
|
|
|
|
|
var err error
|
|
|
|
|
|
|
|
testExifData, err = ioutil.ReadFile(filepath)
|
|
|
|
log.PanicIf(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return testExifData
|
|
|
|
}
|
|
|
|
|
|
|
|
func getTestGpsImageFilepath() string {
|
|
|
|
assetsPath := exifcommon.GetTestAssetsPath()
|
|
|
|
testGpsImageFilepath := path.Join(assetsPath, "gps.jpg")
|
|
|
|
return testGpsImageFilepath
|
|
|
|
}
|