Skip to content

Commit

Permalink
Renamed IFD constants to be Tiff specific.
Browse files Browse the repository at this point in the history
- TagIndex now takes a IfdMapping and validates the IFDs in adds.
- Changed from creating IFD-mapping and loading with standard config to
  a single step using the alternative constructor.
  • Loading branch information
ml-bnr committed Aug 3, 2018
1 parent 8112863 commit 32b3793
Show file tree
Hide file tree
Showing 15 changed files with 434 additions and 585 deletions.
4 changes: 2 additions & 2 deletions exif-read-tool/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func main() {
// Run the parse.

im := exif.NewIfdMappingWithStandard()
ti := exif.NewTagIndex()
ti := exif.NewTagIndex(im)

entries := make([]IfdEntry, 0)
visitor := func(fqIfdPath string, ifdIndex int, tagId uint16, tagType exif.TagType, valueContext exif.ValueContext) (err error) {
Expand Down Expand Up @@ -134,7 +134,7 @@ func main() {
return nil
}

_, err = exif.Visit(exif.IfdStandard, im, ti, rawExif, visitor)
_, err = exif.Visit(exif.TiffIfdStandard, im, ti, rawExif, visitor)
log.PanicIf(err)

if printAsJsonArg == true {
Expand Down
57 changes: 26 additions & 31 deletions exif_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ func TestVisit(t *testing.T) {
}
}()

ti := NewTagIndex()
im := NewIfdMappingWithStandard()
ti := NewTagIndex(im)

// Open the file.

Expand Down Expand Up @@ -54,8 +55,6 @@ func TestVisit(t *testing.T) {

// Run the parse.

im := NewIfdMappingWithStandard()

tags := make([]string, 0)

visitor := func(fqIfdPath string, ifdIndex int, tagId uint16, tagType TagType, valueContext ValueContext) (err error) {
Expand Down Expand Up @@ -100,7 +99,7 @@ func TestVisit(t *testing.T) {
return nil
}

_, err = Visit(IfdStandard, im, ti, data[foundAt:], visitor)
_, err = Visit(TiffIfdStandard, im, ti, data[foundAt:], visitor)
log.PanicIf(err)

expected := []string{
Expand Down Expand Up @@ -226,12 +225,8 @@ func TestCollect(t *testing.T) {
rawExif, err := SearchFileAndExtractExif(filepath)
log.PanicIf(err)

im := NewIfdMapping()

err = LoadStandardIfds(im)
log.PanicIf(err)

ti := NewTagIndex()
im := NewIfdMappingWithStandard()
ti := NewTagIndex(im)

_, index, err := Collect(im, ti, rawExif)
log.PanicIf(err)
Expand Down Expand Up @@ -265,52 +260,52 @@ func TestCollect(t *testing.T) {
t.Fatalf("Root IFD chain not terminated correctly (2).")
}

if rootIfd.IfdPath != IfdPathStandard {
if rootIfd.IfdPath != TiffIfdPathStandard {
t.Fatalf("Root IFD is not labeled correctly: [%s]", rootIfd.IfdPath)
} else if rootIfd.NextIfd.IfdPath != IfdPathStandard {
} else if rootIfd.NextIfd.IfdPath != TiffIfdPathStandard {
t.Fatalf("Root IFD sibling is not labeled correctly: [%s]", rootIfd.IfdPath)
} else if rootIfd.Children[0].IfdPath != IfdPathStandardExif {
} else if rootIfd.Children[0].IfdPath != TiffIfdPathStandardExif {
t.Fatalf("Root IFD child (0) is not labeled correctly: [%s]", rootIfd.Children[0].IfdPath)
} else if rootIfd.Children[1].IfdPath != IfdPathStandardGps {
} else if rootIfd.Children[1].IfdPath != TiffIfdPathStandardGps {
t.Fatalf("Root IFD child (1) is not labeled correctly: [%s]", rootIfd.Children[1].IfdPath)
} else if rootIfd.Children[0].Children[0].IfdPath != IfdPathStandardExifIop {
} else if rootIfd.Children[0].Children[0].IfdPath != TiffIfdPathStandardExifIop {
t.Fatalf("Exif IFD child is not an IOP IFD: [%s]", rootIfd.Children[0].Children[0].IfdPath)
}

if lookup[IfdPathStandard][0].IfdPath != IfdPathStandard {
if lookup[TiffIfdPathStandard][0].IfdPath != TiffIfdPathStandard {
t.Fatalf("Lookup for standard IFD not correct.")
} else if lookup[IfdPathStandard][1].IfdPath != IfdPathStandard {
} else if lookup[TiffIfdPathStandard][1].IfdPath != TiffIfdPathStandard {
t.Fatalf("Lookup for standard IFD not correct.")
}

if lookup[IfdPathStandardExif][0].IfdPath != IfdPathStandardExif {
if lookup[TiffIfdPathStandardExif][0].IfdPath != TiffIfdPathStandardExif {
t.Fatalf("Lookup for EXIF IFD not correct.")
}

if lookup[IfdPathStandardGps][0].IfdPath != IfdPathStandardGps {
if lookup[TiffIfdPathStandardGps][0].IfdPath != TiffIfdPathStandardGps {
t.Fatalf("Lookup for GPS IFD not correct.")
}

if lookup[IfdPathStandardExifIop][0].IfdPath != IfdPathStandardExifIop {
if lookup[TiffIfdPathStandardExifIop][0].IfdPath != TiffIfdPathStandardExifIop {
t.Fatalf("Lookup for IOP IFD not correct.")
}

foundExif := 0
foundGps := 0
for _, ite := range lookup[IfdPathStandard][0].Entries {
if ite.ChildIfdPath == IfdPathStandardExif {
for _, ite := range lookup[TiffIfdPathStandard][0].Entries {
if ite.ChildIfdPath == TiffIfdPathStandardExif {
foundExif++

if ite.TagId != IfdExifId {
t.Fatalf("EXIF IFD tag-ID mismatch: (0x%04x) != (0x%04x)", ite.TagId, IfdExifId)
if ite.TagId != TiffIfdExifId {
t.Fatalf("EXIF IFD tag-ID mismatch: (0x%04x) != (0x%04x)", ite.TagId, TiffIfdExifId)
}
}

if ite.ChildIfdPath == IfdPathStandardGps {
if ite.ChildIfdPath == TiffIfdPathStandardGps {
foundGps++

if ite.TagId != IfdGpsId {
t.Fatalf("GPS IFD tag-ID mismatch: (0x%04x) != (0x%04x)", ite.TagId, IfdGpsId)
if ite.TagId != TiffIfdGpsId {
t.Fatalf("GPS IFD tag-ID mismatch: (0x%04x) != (0x%04x)", ite.TagId, TiffIfdGpsId)
}
}
}
Expand All @@ -322,12 +317,12 @@ func TestCollect(t *testing.T) {
}

foundIop := 0
for _, ite := range lookup[IfdPathStandardExif][0].Entries {
if ite.ChildIfdPath == IfdPathStandardExifIop {
for _, ite := range lookup[TiffIfdPathStandardExif][0].Entries {
if ite.ChildIfdPath == TiffIfdPathStandardExifIop {
foundIop++

if ite.TagId != IfdIopId {
t.Fatalf("IOP IFD tag-ID mismatch: (0x%04x) != (0x%04x)", ite.TagId, IfdIopId)
if ite.TagId != TiffIfdIopId {
t.Fatalf("IOP IFD tag-ID mismatch: (0x%04x) != (0x%04x)", ite.TagId, TiffIfdIopId)
}
}
}
Expand Down
73 changes: 22 additions & 51 deletions ifd.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,34 +8,6 @@ import (
"github.com/dsoprea/go-logging"
)

const (
// IFD names. The paths that we referred to the IFDs with are comprised of
// these.

IfdStandard = "IFD"
IfdExif = "Exif"
IfdGps = "GPSInfo"
IfdIop = "Iop"

// Tag IDs for child IFDs.

IfdExifId = 0x8769
IfdGpsId = 0x8825
IfdIopId = 0xA005

// Just a placeholder.

IfdRootId = 0x0000

// The paths of the standard IFDs expressed in the standard IFD-mappings
// and as the group-names in the tag data.

IfdPathStandard = "IFD"
IfdPathStandardExif = "IFD/Exif"
IfdPathStandardExifIop = "IFD/Exif/Iop"
IfdPathStandardGps = "IFD/GPSInfo"
)

var (
ifdLogger = log.NewLogger("exif.ifd")
)
Expand Down Expand Up @@ -289,11 +261,17 @@ func (im *IfdMapping) StripPathPhraseIndices(pathPhrase string) (strippedPathPhr
return strippedPathPhrase, nil
}

type IfdDefinition struct {
ParentPlacement []uint16
TagId uint16
Name string
}

// Add puts the given IFD at the given position of the tree. The position of the
// tree is referred to as the placement and is represented by a set of tag-IDs,
// where the leftmost is the root tag and the tags going to the right are
// progressive descendants.
func (im *IfdMapping) Add(parentPlacement []uint16, tagId uint16, name string) (err error) {
func (im *IfdMapping) Add(id IfdDefinition) (err error) {
defer func() {
if state := recover(); state != nil {
err = log.Wrap(state.(error))
Expand All @@ -302,37 +280,37 @@ func (im *IfdMapping) Add(parentPlacement []uint16, tagId uint16, name string) (

// TODO(dustin): !! It would be nicer to provide a list of names in the placement rather than tag-IDs.

ptr, err := im.Get(parentPlacement)
ptr, err := im.Get(id.ParentPlacement)
log.PanicIf(err)

path := make([]string, len(parentPlacement)+1)
if len(parentPlacement) > 0 {
path := make([]string, len(id.ParentPlacement)+1)
if len(id.ParentPlacement) > 0 {
copy(path, ptr.Path)
}

path[len(path)-1] = name
path[len(path)-1] = id.Name

placement := make([]uint16, len(parentPlacement)+1)
placement := make([]uint16, len(id.ParentPlacement)+1)
if len(placement) > 0 {
copy(placement, ptr.Placement)
}

placement[len(placement)-1] = tagId
placement[len(placement)-1] = id.TagId

childIfd := &MappedIfd{
ParentTagId: ptr.TagId,
Path: path,
Placement: placement,
Name: name,
TagId: tagId,
Name: id.Name,
TagId: id.TagId,
Children: make(map[uint16]*MappedIfd),
}

if _, found := ptr.Children[tagId]; found == true {
log.Panicf("child IFD with tag-ID (%04x) already registered under IFD [%s] with tag-ID (%04x)", tagId, ptr.Name, ptr.TagId)
if _, found := ptr.Children[id.TagId]; found == true {
log.Panicf("child IFD with tag-ID (%04x) already registered under IFD [%s] with tag-ID (%04x)", id.TagId, ptr.Name, ptr.TagId)
}

ptr.Children[tagId] = childIfd
ptr.Children[id.TagId] = childIfd

return nil
}
Expand Down Expand Up @@ -391,17 +369,10 @@ func LoadStandardIfds(im *IfdMapping) (err error) {
}
}()

err = im.Add([]uint16{}, IfdRootId, IfdStandard)
log.PanicIf(err)

err = im.Add([]uint16{IfdRootId}, IfdExifId, IfdExif)
log.PanicIf(err)

err = im.Add([]uint16{IfdRootId, IfdExifId}, IfdIopId, IfdIop)
log.PanicIf(err)

err = im.Add([]uint16{IfdRootId}, IfdGpsId, IfdGps)
log.PanicIf(err)
for _, id := range TiffIfds {
err := im.Add(id)
log.PanicIf(err)
}

return nil
}
4 changes: 2 additions & 2 deletions ifd_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ func NewIfdBuilderWithExistingIfd(ifd *Ifd) (ib *IfdBuilder) {
var ifdTagId uint16

// There is no tag-ID for the root IFD. It will never be a child IFD.
if ifdPath != IfdPathStandard {
if ifdPath != TiffIfdPathStandard {
mi, err := ifd.ifdMapping.GetWithPath(ifdPath)
log.PanicIf(err)

Expand Down Expand Up @@ -496,7 +496,7 @@ func (ib *IfdBuilder) SetThumbnail(data []byte) (err error) {
}
}()

if ib.ifdPath != IfdPathStandard {
if ib.ifdPath != TiffIfdPathStandard {
log.Panicf("thumbnails can only go into a root Ifd (and only the second one)")
}

Expand Down
Loading

0 comments on commit 32b3793

Please sign in to comment.