go-exif/ifd_test.go
Dustin Oprea 9068786204 Rewired to use IFD-path strings instead of IfdIdentities.
- These are absolute representations of where an IFD is positioned with
  respect to the other IFDs. There is a more-specific, "fully-qualified"
  form of the IFD-path that allows you to express indices in order to
  refer to specific siblings.

- Eliminates issues with IFDs at different levels potentially having the
  same name (if that's what is required with a certain dataset/
  datasource).

- There is a specific IFD registry that controls the heirarchy of IFDs
  that we recognize and the tags associated with the child IFDs. This
  allows custom hierarchies replacing even the TIFF specification for
  which are expected in an image (so we can read other types of images
  or any potential IFD hierarchy, even non-image ones).

- IFD and IB instances embed the IFD-path and FQ IFD-path that they were
  found or built for.
2018-08-01 08:35:21 -04:00

265 lines
5.4 KiB
Go

package exif
import (
"fmt"
"reflect"
"sort"
"testing"
"github.com/dsoprea/go-logging"
)
func TestIfdMapping_Add(t *testing.T) {
im := NewIfdMapping()
err := im.Add([]uint16{}, 0x1111, "ifd0")
log.PanicIf(err)
err = im.Add([]uint16{0x1111}, 0x4444, "ifd00")
log.PanicIf(err)
err = im.Add([]uint16{0x1111, 0x4444}, 0x5555, "ifd000")
log.PanicIf(err)
err = im.Add([]uint16{}, 0x2222, "ifd1")
log.PanicIf(err)
err = im.Add([]uint16{}, 0x3333, "ifd2")
log.PanicIf(err)
lineages, err := im.DumpLineages()
log.PanicIf(err)
sort.Strings(lineages)
expected := []string{
"ifd0",
"ifd0/ifd00",
"ifd0/ifd00/ifd000",
"ifd1",
"ifd2",
}
if reflect.DeepEqual(lineages, expected) != true {
fmt.Printf("Actual:\n")
fmt.Printf("\n")
for i, line := range lineages {
fmt.Printf("(%d) %s\n", i, line)
}
fmt.Printf("\n")
fmt.Printf("Expected:\n")
fmt.Printf("\n")
for i, line := range expected {
fmt.Printf("(%d) %s\n", i, line)
}
t.Fatalf("IFD-mapping dump not correct.")
}
}
func TestIfdMapping_LoadStandardIfds(t *testing.T) {
im := NewIfdMapping()
err := LoadStandardIfds(im)
log.PanicIf(err)
lineages, err := im.DumpLineages()
log.PanicIf(err)
sort.Strings(lineages)
expected := []string{
"IFD",
"IFD/Exif",
"IFD/Exif/Iop",
"IFD/GPSInfo",
}
if reflect.DeepEqual(lineages, expected) != true {
fmt.Printf("Actual:\n")
fmt.Printf("\n")
for i, line := range lineages {
fmt.Printf("(%d) %s\n", i, line)
}
fmt.Printf("\n")
fmt.Printf("Expected:\n")
fmt.Printf("\n")
for i, line := range expected {
fmt.Printf("(%d) %s\n", i, line)
}
t.Fatalf("IFD-mapping dump not correct.")
}
}
func TestIfdMapping_Get(t *testing.T) {
im := NewIfdMapping()
err := LoadStandardIfds(im)
log.PanicIf(err)
mi, err := im.Get([]uint16{IfdRootId, IfdExifId, IfdIopId})
log.PanicIf(err)
if mi.ParentTagId != IfdExifId {
t.Fatalf("Parent tag-ID not correct")
} else if mi.TagId != IfdIopId {
t.Fatalf("Tag-ID not correct")
} else if mi.Name != "Iop" {
t.Fatalf("name not correct")
} else if mi.PathPhrase() != "IFD/Exif/Iop" {
t.Fatalf("path not correct")
}
}
func TestIfdMapping_GetWithPath(t *testing.T) {
im := NewIfdMapping()
err := LoadStandardIfds(im)
log.PanicIf(err)
mi, err := im.GetWithPath("IFD/Exif/Iop")
log.PanicIf(err)
if mi.ParentTagId != IfdExifId {
t.Fatalf("Parent tag-ID not correct")
} else if mi.TagId != IfdIopId {
t.Fatalf("Tag-ID not correct")
} else if mi.Name != "Iop" {
t.Fatalf("name not correct")
} else if mi.PathPhrase() != "IFD/Exif/Iop" {
t.Fatalf("path not correct")
}
}
func TestIfdMapping_ResolvePath__Regular(t *testing.T) {
im := NewIfdMapping()
err := LoadStandardIfds(im)
log.PanicIf(err)
lineage, err := im.ResolvePath("IFD/Exif/Iop")
log.PanicIf(err)
expected := []IfdTagIdAndIndex{
IfdTagIdAndIndex{Name: "IFD", TagId: 0, Index: 0},
IfdTagIdAndIndex{Name: "Exif", TagId: 0x8769, Index: 0},
IfdTagIdAndIndex{Name: "Iop", TagId: 0xa005, Index: 0},
}
if reflect.DeepEqual(lineage, expected) != true {
t.Fatalf("Lineage not correct.")
}
}
func TestIfdMapping_ResolvePath__WithIndices(t *testing.T) {
im := NewIfdMapping()
err := LoadStandardIfds(im)
log.PanicIf(err)
lineage, err := im.ResolvePath("IFD/Exif1/Iop")
log.PanicIf(err)
expected := []IfdTagIdAndIndex{
IfdTagIdAndIndex{Name: "IFD", TagId: 0, Index: 0},
IfdTagIdAndIndex{Name: "Exif", TagId: 0x8769, Index: 1},
IfdTagIdAndIndex{Name: "Iop", TagId: 0xa005, Index: 0},
}
if reflect.DeepEqual(lineage, expected) != true {
t.Fatalf("Lineage not correct.")
}
}
func TestIfdMapping_ResolvePath__Miss(t *testing.T) {
im := NewIfdMapping()
err := LoadStandardIfds(im)
log.PanicIf(err)
_, err = im.ResolvePath("IFD/Exif/Invalid")
if err == nil {
t.Fatalf("Expected failure for invalid IFD path.")
} else if err.Error() != "ifd child with name [Invalid] not registered: [IFD/Exif/Invalid]" {
log.Panic(err)
}
}
func TestIfdMapping_FqPathPhraseFromLineage(t *testing.T) {
lineage := []IfdTagIdAndIndex{
IfdTagIdAndIndex{Name: "IFD", Index: 0},
IfdTagIdAndIndex{Name: "Exif", Index: 1},
IfdTagIdAndIndex{Name: "Iop", Index: 0},
}
im := NewIfdMapping()
fqPathPhrase := im.FqPathPhraseFromLineage(lineage)
if fqPathPhrase != "IFD/Exif1/Iop" {
t.Fatalf("path-phrase not correct: [%s]", fqPathPhrase)
}
}
func TestIfdMapping_PathPhraseFromLineage(t *testing.T) {
lineage := []IfdTagIdAndIndex{
IfdTagIdAndIndex{Name: "IFD", Index: 0},
IfdTagIdAndIndex{Name: "Exif", Index: 1},
IfdTagIdAndIndex{Name: "Iop", Index: 0},
}
im := NewIfdMapping()
fqPathPhrase := im.PathPhraseFromLineage(lineage)
if fqPathPhrase != "IFD/Exif/Iop" {
t.Fatalf("path-phrase not correct: [%s]", fqPathPhrase)
}
}
func TestIfdMapping_NewIfdMappingWithStandard(t *testing.T) {
imWith := NewIfdMappingWithStandard()
imWithout := NewIfdMapping()
err := LoadStandardIfds(imWithout)
outputWith, err := imWith.DumpLineages()
log.PanicIf(err)
sort.Strings(outputWith)
outputWithout, err := imWithout.DumpLineages()
log.PanicIf(err)
sort.Strings(outputWithout)
if reflect.DeepEqual(outputWith, outputWithout) != true {
fmt.Printf("WITH:\n")
fmt.Printf("\n")
for _, line := range outputWith {
fmt.Printf("%s\n", line)
}
fmt.Printf("\n")
fmt.Printf("WITHOUT:\n")
fmt.Printf("\n")
for _, line := range outputWithout {
fmt.Printf("%s\n", line)
}
fmt.Printf("\n")
t.Fatalf("Standard IFDs not loaded correctly.")
}
}