ifd.go: Add type system for IFD IDs, names, and paths

This allows us to pass around individual tokens that we can use to
generate IDs, names, and qualified and non-qualified IFD paths, rather
than [necessarily] having to pass or store them individually.

The previous global variables were strings. Now they are IfdIdentity structs
and have been renamed to be more accurate (in general, as well as for this).
The previous variables have been kept but are now just assigned to the newer
variables. This is backwards-compatibility that will be removed in the future.
dustin/master
Dustin Oprea 2020-05-19 21:25:09 -04:00
parent 40de7cc624
commit 08ac8466dd
29 changed files with 637 additions and 484 deletions

View File

@ -1,29 +1,223 @@
package exifcommon package exifcommon
const ( import (
// IFD names. The paths that we referred to the IFDs with are comprised of "fmt"
// these. "strings"
IfdStandard = "IFD" "github.com/dsoprea/go-logging"
IfdExif = "Exif" )
IfdGps = "GPSInfo"
IfdIop = "Iop" // IfdTag describes a single IFD tag and its parent (if any).
type IfdTag struct {
// Tag IDs for child IFDs. parentIfdTag *IfdTag
tagId uint16
IfdExifId = 0x8769 name string
IfdGpsId = 0x8825 }
IfdIopId = 0xA005
func NewIfdTag(parentIfdTag *IfdTag, tagId uint16, name string) IfdTag {
// Just a placeholder. return IfdTag{
parentIfdTag: parentIfdTag,
IfdRootId = 0x0000 tagId: tagId,
name: name,
// The paths of the standard IFDs expressed in the standard IFD-mappings }
// and as the group-names in the tag data. }
IfdPathStandard = "IFD" // ParentIfd returns the IfdTag of this IFD's parent.
IfdPathStandardExif = "IFD/Exif" func (it IfdTag) ParentIfd() *IfdTag {
IfdPathStandardExifIop = "IFD/Exif/Iop" return it.parentIfdTag
IfdPathStandardGps = "IFD/GPSInfo" }
// TagId returns the tag-ID of this IFD.
func (it IfdTag) TagId() uint16 {
return it.tagId
}
// Name returns the simple name of this IFD.
func (it IfdTag) Name() string {
return it.name
}
// String returns a descriptive string.
func (it IfdTag) String() string {
parentIfdPhrase := ""
if it.parentIfdTag != nil {
parentIfdPhrase = fmt.Sprintf(" PARENT=(0x%04x)[%s]", it.parentIfdTag.tagId, it.parentIfdTag.name)
}
return fmt.Sprintf("IfdTag<TAG-ID=(0x%04x) NAME=[%s]%s>", it.tagId, it.name, parentIfdPhrase)
}
var (
// rootStandardIfd is the standard root IFD.
rootStandardIfd = NewIfdTag(nil, 0x0000, "IFD") // IFD
// exifStandardIfd is the standard "Exif" IFD.
exifStandardIfd = NewIfdTag(&rootStandardIfd, 0x8769, "Exif") // IFD/Exif
// iopStandardIfd is the standard "Iop" IFD.
iopStandardIfd = NewIfdTag(&exifStandardIfd, 0xA005, "Iop") // IFD/Exif/Iop
// gpsInfoStandardIfd is the standard "GPS" IFD.
gpsInfoStandardIfd = NewIfdTag(&rootStandardIfd, 0x8825, "GPSInfo") // IFD/GPSInfo
)
// IfdIdentityPart represents one component in an IFD path.
type IfdIdentityPart struct {
Name string
Index int
}
// String returns a fully-qualified IFD path.
func (iip IfdIdentityPart) String() string {
if iip.Index > 0 {
return fmt.Sprintf("%s%d", iip.Name, iip.Index)
} else {
return iip.Name
}
}
// UnindexedString returned a non-fully-qualified IFD path.
func (iip IfdIdentityPart) UnindexedString() string {
return iip.Name
}
// IfdIdentity represents a single IFD path and provides access to various
// information and representations.
//
// Only global instances can be used for equality checks.
type IfdIdentity struct {
ifdTag IfdTag
parts []IfdIdentityPart
ifdPath string
fqIfdPath string
}
// NewIfdIdentity returns a new IfdIdentity struct.
func NewIfdIdentity(ifdTag IfdTag, parts ...IfdIdentityPart) (ii *IfdIdentity) {
ii = &IfdIdentity{
ifdTag: ifdTag,
parts: parts,
}
ii.ifdPath = ii.getIfdPath()
ii.fqIfdPath = ii.getFqIfdPath()
return ii
}
func (ii *IfdIdentity) getFqIfdPath() string {
partPhrases := make([]string, len(ii.parts))
for i, iip := range ii.parts {
partPhrases[i] = iip.String()
}
return strings.Join(partPhrases, "/")
}
func (ii *IfdIdentity) getIfdPath() string {
partPhrases := make([]string, len(ii.parts))
for i, iip := range ii.parts {
partPhrases[i] = iip.UnindexedString()
}
return strings.Join(partPhrases, "/")
}
// String returns a fully-qualified IFD path.
func (ii *IfdIdentity) String() string {
return ii.fqIfdPath
}
// UnindexedString returns a non-fully-qualified IFD path.
func (ii *IfdIdentity) UnindexedString() string {
return ii.ifdPath
}
// IfdTag returns the tag struct behind this IFD.
func (ii *IfdIdentity) IfdTag() IfdTag {
return ii.ifdTag
}
// TagId returns the tag-ID of the IFD.
func (ii *IfdIdentity) TagId() uint16 {
return ii.ifdTag.TagId()
}
// LeafPathPart returns the last right-most path-part, which represents the
// current IFD.
func (ii *IfdIdentity) LeafPathPart() IfdIdentityPart {
return ii.parts[len(ii.parts)-1]
}
// Name returns the simple name of this IFD.
func (ii *IfdIdentity) Name() string {
return ii.LeafPathPart().Name
}
// Index returns the index of this IFD (more then one IFD under a parent IFD
// will be numbered [0..n]).
func (ii *IfdIdentity) Index() int {
return ii.LeafPathPart().Index
}
// Equals returns true if the two IfdIdentity instances are effectively
// identical.
//
// Since there's no way to get a specific fully-qualified IFD path without a
// certain slice of parts and all other fields are also derived from this,
// checking that the fully-qualified IFD path is equals is sufficient.
func (ii *IfdIdentity) Equals(ii2 *IfdIdentity) bool {
return ii.String() == ii2.String()
}
// NewChild creates an IfdIdentity for an IFD that is a child of the current
// IFD.
func (ii *IfdIdentity) NewChild(childIfdTag IfdTag, index int) (iiChild *IfdIdentity) {
if *childIfdTag.parentIfdTag != ii.ifdTag {
log.Panicf("can not add child; we are not the parent:\nUS=%v\nCHILD=%v", ii.ifdTag, childIfdTag)
}
childPart := IfdIdentityPart{childIfdTag.name, index}
childParts := append(ii.parts, childPart)
iiChild = NewIfdIdentity(childIfdTag, childParts...)
return iiChild
}
// NewSibling creates an IfdIdentity for an IFD that is a sibling to the current
// one.
func (ii *IfdIdentity) NewSibling(index int) (iiSibling *IfdIdentity) {
parts := make([]IfdIdentityPart, len(ii.parts))
copy(parts, ii.parts)
parts[len(parts)-1].Index = index
iiSibling = NewIfdIdentity(ii.ifdTag, parts...)
return iiSibling
}
var (
// IfdStandardIfdIdentity represents the IFD path for IFD0.
IfdStandardIfdIdentity = NewIfdIdentity(rootStandardIfd, IfdIdentityPart{"IFD", 0})
// IfdExifStandardIfdIdentity represents the IFD path for IFD0/Exif0.
IfdExifStandardIfdIdentity = IfdStandardIfdIdentity.NewChild(exifStandardIfd, 0)
// IfdExifIopStandardIfdIdentity represents the IFD path for IFD0/Exif0/Iop0.
IfdExifIopStandardIfdIdentity = IfdExifStandardIfdIdentity.NewChild(iopStandardIfd, 0)
// IfdGPSInfoStandardIfdIdentity represents the IFD path for IFD0/GPSInfo0.
IfdGpsInfoStandardIfdIdentity = IfdStandardIfdIdentity.NewChild(gpsInfoStandardIfd, 0)
// Ifd1StandardIfdIdentity represents the IFD path for IFD1.
Ifd1StandardIfdIdentity = NewIfdIdentity(rootStandardIfd, IfdIdentityPart{"IFD", 1})
)
var (
// DEPRECATION(dustin): These are for backwards-compatibility. These used to be strings but are now IfdIdentity structs and the newer "StandardIfdIdentity" symbols above should be used instead. These will be removed in the next release.
IfdPathStandard = IfdStandardIfdIdentity
IfdPathStandardExif = IfdExifStandardIfdIdentity
IfdPathStandardExifIop = IfdExifIopStandardIfdIdentity
IfdPathStandardGps = IfdGpsInfoStandardIfdIdentity
) )

View File

@ -12,6 +12,8 @@ import (
"io/ioutil" "io/ioutil"
"github.com/dsoprea/go-logging" "github.com/dsoprea/go-logging"
"github.com/dsoprea/go-exif/v2/common"
) )
const ( const (
@ -190,7 +192,7 @@ func ParseExifHeader(data []byte) (eh ExifHeader, err error) {
} }
// Visit recursively invokes a callback for every tag. // Visit recursively invokes a callback for every tag.
func Visit(rootIfdName string, ifdMapping *IfdMapping, tagIndex *TagIndex, exifData []byte, visitor TagVisitorFn) (eh ExifHeader, furthestOffset uint32, err error) { func Visit(rootIfdIdentity *exifcommon.IfdIdentity, ifdMapping *IfdMapping, tagIndex *TagIndex, exifData []byte, visitor TagVisitorFn) (eh ExifHeader, furthestOffset uint32, err error) {
defer func() { defer func() {
if state := recover(); state != nil { if state := recover(); state != nil {
err = log.Wrap(state.(error)) err = log.Wrap(state.(error))
@ -202,7 +204,7 @@ func Visit(rootIfdName string, ifdMapping *IfdMapping, tagIndex *TagIndex, exifD
ie := NewIfdEnumerate(ifdMapping, tagIndex, exifData, eh.ByteOrder) ie := NewIfdEnumerate(ifdMapping, tagIndex, exifData, eh.ByteOrder)
err = ie.Scan(rootIfdName, eh.FirstIfdOffset, visitor) err = ie.Scan(rootIfdIdentity, eh.FirstIfdOffset, visitor)
log.PanicIf(err) log.PanicIf(err)
furthestOffset = ie.FurthestOffset() furthestOffset = ie.FurthestOffset()

View File

@ -96,7 +96,7 @@ func TestVisit(t *testing.T) {
return nil return nil
} }
_, furthestOffset, err := Visit(exifcommon.IfdStandard, im, ti, data[foundAt:], visitor) _, furthestOffset, err := Visit(exifcommon.IfdStandardIfdIdentity, im, ti, data[foundAt:], visitor)
log.PanicIf(err) log.PanicIf(err)
if furthestOffset != 32935 { if furthestOffset != 32935 {
@ -310,52 +310,52 @@ func TestCollect(t *testing.T) {
t.Fatalf("Root IFD chain not terminated correctly (2).") t.Fatalf("Root IFD chain not terminated correctly (2).")
} }
if rootIfd.IfdPath != exifcommon.IfdPathStandard { if rootIfd.ifdIdentity.UnindexedString() != exifcommon.IfdStandardIfdIdentity.UnindexedString() {
t.Fatalf("Root IFD is not labeled correctly: [%s]", rootIfd.IfdPath) t.Fatalf("Root IFD is not labeled correctly: [%s]", rootIfd.ifdIdentity.UnindexedString())
} else if rootIfd.NextIfd.IfdPath != exifcommon.IfdPathStandard { } else if rootIfd.NextIfd.ifdIdentity.UnindexedString() != exifcommon.IfdStandardIfdIdentity.UnindexedString() {
t.Fatalf("Root IFD sibling is not labeled correctly: [%s]", rootIfd.IfdPath) t.Fatalf("Root IFD sibling is not labeled correctly: [%s]", rootIfd.ifdIdentity.UnindexedString())
} else if rootIfd.Children[0].IfdPath != exifcommon.IfdPathStandardExif { } else if rootIfd.Children[0].ifdIdentity.UnindexedString() != exifcommon.IfdExifStandardIfdIdentity.UnindexedString() {
t.Fatalf("Root IFD child (0) is not labeled correctly: [%s]", rootIfd.Children[0].IfdPath) t.Fatalf("Root IFD child (0) is not labeled correctly: [%s]", rootIfd.Children[0].ifdIdentity.UnindexedString())
} else if rootIfd.Children[1].IfdPath != exifcommon.IfdPathStandardGps { } else if rootIfd.Children[1].ifdIdentity.UnindexedString() != exifcommon.IfdGpsInfoStandardIfdIdentity.UnindexedString() {
t.Fatalf("Root IFD child (1) is not labeled correctly: [%s]", rootIfd.Children[1].IfdPath) t.Fatalf("Root IFD child (1) is not labeled correctly: [%s]", rootIfd.Children[1].ifdIdentity.UnindexedString())
} else if rootIfd.Children[0].Children[0].IfdPath != exifcommon.IfdPathStandardExifIop { } else if rootIfd.Children[0].Children[0].ifdIdentity.UnindexedString() != exifcommon.IfdExifIopStandardIfdIdentity.UnindexedString() {
t.Fatalf("Exif IFD child is not an IOP IFD: [%s]", rootIfd.Children[0].Children[0].IfdPath) t.Fatalf("Exif IFD child is not an IOP IFD: [%s]", rootIfd.Children[0].Children[0].ifdIdentity.UnindexedString())
} }
if lookup[exifcommon.IfdPathStandard].IfdPath != exifcommon.IfdPathStandard { if lookup[exifcommon.IfdStandardIfdIdentity.UnindexedString()].ifdIdentity.UnindexedString() != exifcommon.IfdStandardIfdIdentity.UnindexedString() {
t.Fatalf("Lookup for standard IFD not correct.") t.Fatalf("Lookup for standard IFD not correct.")
} else if lookup[exifcommon.IfdPathStandard+"1"].IfdPath != exifcommon.IfdPathStandard { } else if lookup[exifcommon.IfdStandardIfdIdentity.UnindexedString()+"1"].ifdIdentity.UnindexedString() != exifcommon.IfdStandardIfdIdentity.UnindexedString() {
t.Fatalf("Lookup for standard IFD not correct.") t.Fatalf("Lookup for standard IFD not correct.")
} }
if lookup[exifcommon.IfdPathStandardExif].IfdPath != exifcommon.IfdPathStandardExif { if lookup[exifcommon.IfdExifStandardIfdIdentity.UnindexedString()].ifdIdentity.UnindexedString() != exifcommon.IfdExifStandardIfdIdentity.UnindexedString() {
t.Fatalf("Lookup for EXIF IFD not correct.") t.Fatalf("Lookup for EXIF IFD not correct.")
} }
if lookup[exifcommon.IfdPathStandardGps].IfdPath != exifcommon.IfdPathStandardGps { if lookup[exifcommon.IfdGpsInfoStandardIfdIdentity.UnindexedString()].ifdIdentity.UnindexedString() != exifcommon.IfdGpsInfoStandardIfdIdentity.UnindexedString() {
t.Fatalf("Lookup for GPS IFD not correct.") t.Fatalf("Lookup for GPS IFD not correct.")
} }
if lookup[exifcommon.IfdPathStandardExifIop].IfdPath != exifcommon.IfdPathStandardExifIop { if lookup[exifcommon.IfdExifIopStandardIfdIdentity.UnindexedString()].ifdIdentity.UnindexedString() != exifcommon.IfdExifIopStandardIfdIdentity.UnindexedString() {
t.Fatalf("Lookup for IOP IFD not correct.") t.Fatalf("Lookup for IOP IFD not correct.")
} }
foundExif := 0 foundExif := 0
foundGps := 0 foundGps := 0
for _, ite := range lookup[exifcommon.IfdPathStandard].Entries { for _, ite := range lookup[exifcommon.IfdStandardIfdIdentity.UnindexedString()].Entries {
if ite.ChildIfdPath() == exifcommon.IfdPathStandardExif { if ite.ChildIfdPath() == exifcommon.IfdExifStandardIfdIdentity.UnindexedString() {
foundExif++ foundExif++
if ite.TagId() != exifcommon.IfdExifId { if ite.TagId() != exifcommon.IfdExifStandardIfdIdentity.TagId() {
t.Fatalf("EXIF IFD tag-ID mismatch: (0x%04x) != (0x%04x)", ite.TagId(), exifcommon.IfdExifId) t.Fatalf("EXIF IFD tag-ID mismatch: (0x%04x) != (0x%04x)", ite.TagId(), exifcommon.IfdExifStandardIfdIdentity.TagId())
} }
} }
if ite.ChildIfdPath() == exifcommon.IfdPathStandardGps { if ite.ChildIfdPath() == exifcommon.IfdGpsInfoStandardIfdIdentity.UnindexedString() {
foundGps++ foundGps++
if ite.TagId() != exifcommon.IfdGpsId { if ite.TagId() != exifcommon.IfdGpsInfoStandardIfdIdentity.TagId() {
t.Fatalf("GPS IFD tag-ID mismatch: (0x%04x) != (0x%04x)", ite.TagId(), exifcommon.IfdGpsId) t.Fatalf("GPS IFD tag-ID mismatch: (0x%04x) != (0x%04x)", ite.TagId(), exifcommon.IfdGpsInfoStandardIfdIdentity.TagId())
} }
} }
} }
@ -367,12 +367,12 @@ func TestCollect(t *testing.T) {
} }
foundIop := 0 foundIop := 0
for _, ite := range lookup[exifcommon.IfdPathStandardExif].Entries { for _, ite := range lookup[exifcommon.IfdExifStandardIfdIdentity.UnindexedString()].Entries {
if ite.ChildIfdPath() == exifcommon.IfdPathStandardExifIop { if ite.ChildIfdPath() == exifcommon.IfdExifIopStandardIfdIdentity.UnindexedString() {
foundIop++ foundIop++
if ite.TagId() != exifcommon.IfdIopId { if ite.TagId() != exifcommon.IfdExifIopStandardIfdIdentity.TagId() {
t.Fatalf("IOP IFD tag-ID mismatch: (0x%04x) != (0x%04x)", ite.TagId(), exifcommon.IfdIopId) t.Fatalf("IOP IFD tag-ID mismatch: (0x%04x) != (0x%04x)", ite.TagId(), exifcommon.IfdExifIopStandardIfdIdentity.TagId())
} }
} }
} }

View File

@ -375,16 +375,28 @@ func LoadStandardIfds(im *IfdMapping) (err error) {
} }
}() }()
err = im.Add([]uint16{}, exifcommon.IfdRootId, exifcommon.IfdStandard) err = im.Add(
[]uint16{},
exifcommon.IfdStandardIfdIdentity.TagId(), exifcommon.IfdStandardIfdIdentity.Name())
log.PanicIf(err) log.PanicIf(err)
err = im.Add([]uint16{exifcommon.IfdRootId}, exifcommon.IfdExifId, exifcommon.IfdExif) err = im.Add(
[]uint16{exifcommon.IfdStandardIfdIdentity.TagId()},
exifcommon.IfdExifStandardIfdIdentity.TagId(), exifcommon.IfdExifStandardIfdIdentity.Name())
log.PanicIf(err) log.PanicIf(err)
err = im.Add([]uint16{exifcommon.IfdRootId, exifcommon.IfdExifId}, exifcommon.IfdIopId, exifcommon.IfdIop) err = im.Add(
[]uint16{exifcommon.IfdStandardIfdIdentity.TagId(), exifcommon.IfdExifStandardIfdIdentity.TagId()},
exifcommon.IfdExifIopStandardIfdIdentity.TagId(), exifcommon.IfdExifIopStandardIfdIdentity.Name())
log.PanicIf(err) log.PanicIf(err)
err = im.Add([]uint16{exifcommon.IfdRootId}, exifcommon.IfdGpsId, exifcommon.IfdGps) err = im.Add(
[]uint16{exifcommon.IfdStandardIfdIdentity.TagId()},
exifcommon.IfdGpsInfoStandardIfdIdentity.TagId(), exifcommon.IfdGpsInfoStandardIfdIdentity.Name())
log.PanicIf(err) log.PanicIf(err)
return nil return nil

View File

@ -218,18 +218,7 @@ func NewStandardBuilderTag(ifdPath string, it *IndexedTag, byteOrder binary.Byte
} }
type IfdBuilder struct { type IfdBuilder struct {
// ifdName is the name of the IFD represented by this instance. ifdIdentity *exifcommon.IfdIdentity
name string
// ifdPath is the path of the IFD represented by this instance.
ifdPath string
// fqIfdPath is the fully-qualified path of the IFD represented by this
// instance.
fqIfdPath string
// ifdTagId will be non-zero if we're a child IFD.
ifdTagId uint16
byteOrder binary.ByteOrder byteOrder binary.ByteOrder
@ -253,32 +242,9 @@ type IfdBuilder struct {
tagIndex *TagIndex tagIndex *TagIndex
} }
func NewIfdBuilder(ifdMapping *IfdMapping, tagIndex *TagIndex, fqIfdPath string, byteOrder binary.ByteOrder) (ib *IfdBuilder) { func NewIfdBuilder(ifdMapping *IfdMapping, tagIndex *TagIndex, ii *exifcommon.IfdIdentity, byteOrder binary.ByteOrder) (ib *IfdBuilder) {
ifdPath, err := ifdMapping.StripPathPhraseIndices(fqIfdPath)
log.PanicIf(err)
var ifdTagId uint16
mi, err := ifdMapping.GetWithPath(ifdPath)
if err == nil {
ifdTagId = mi.TagId
} else if log.Is(err, ErrChildIfdNotMapped) == false {
log.Panic(err)
}
ib = &IfdBuilder{ ib = &IfdBuilder{
// The right-most part of the IFD-path. ifdIdentity: ii,
name: mi.Name,
// ifdPath describes the current IFD placement within the IFD tree.
ifdPath: ifdPath,
// fqIfdPath describes the current IFD placement within the IFD tree as
// well as being qualified with non-zero indices.
fqIfdPath: fqIfdPath,
// ifdTagId is empty unless it's a child-IFD.
ifdTagId: ifdTagId,
byteOrder: byteOrder, byteOrder: byteOrder,
tags: make([]*BuilderTag, 0), tags: make([]*BuilderTag, 0),
@ -293,25 +259,9 @@ func NewIfdBuilder(ifdMapping *IfdMapping, tagIndex *TagIndex, fqIfdPath string,
// NewIfdBuilderWithExistingIfd creates a new IB using the same header type // NewIfdBuilderWithExistingIfd creates a new IB using the same header type
// information as the given IFD. // information as the given IFD.
func NewIfdBuilderWithExistingIfd(ifd *Ifd) (ib *IfdBuilder) { func NewIfdBuilderWithExistingIfd(ifd *Ifd) (ib *IfdBuilder) {
name := ifd.Name
ifdPath := ifd.IfdPath
fqIfdPath := ifd.FqIfdPath
var ifdTagId uint16
// There is no tag-ID for the root IFD. It will never be a child IFD.
if ifdPath != exifcommon.IfdPathStandard {
mi, err := ifd.ifdMapping.GetWithPath(ifdPath)
log.PanicIf(err)
ifdTagId = mi.TagId
}
ib = &IfdBuilder{ ib = &IfdBuilder{
name: name, ifdIdentity: ifd.IfdIdentity(),
ifdPath: ifdPath,
fqIfdPath: fqIfdPath,
ifdTagId: ifdTagId,
byteOrder: ifd.ByteOrder, byteOrder: ifd.ByteOrder,
existingOffset: ifd.Offset, existingOffset: ifd.Offset,
ifdMapping: ifd.ifdMapping, ifdMapping: ifd.ifdMapping,
@ -327,7 +277,12 @@ func NewIfdBuilderFromExistingChain(rootIfd *Ifd) (firstIb *IfdBuilder) {
var lastIb *IfdBuilder var lastIb *IfdBuilder
i := 0 i := 0
for thisExistingIfd := rootIfd; thisExistingIfd != nil; thisExistingIfd = thisExistingIfd.NextIfd { for thisExistingIfd := rootIfd; thisExistingIfd != nil; thisExistingIfd = thisExistingIfd.NextIfd {
newIb := NewIfdBuilder(rootIfd.ifdMapping, rootIfd.tagIndex, rootIfd.FqIfdPath, thisExistingIfd.ByteOrder) newIb := NewIfdBuilder(
rootIfd.ifdMapping,
rootIfd.tagIndex,
rootIfd.ifdIdentity,
thisExistingIfd.ByteOrder)
if firstIb == nil { if firstIb == nil {
firstIb = newIb firstIb = newIb
} else { } else {
@ -344,6 +299,10 @@ func NewIfdBuilderFromExistingChain(rootIfd *Ifd) (firstIb *IfdBuilder) {
return firstIb return firstIb
} }
func (ib *IfdBuilder) IfdIdentity() *exifcommon.IfdIdentity {
return ib.ifdIdentity
}
func (ib *IfdBuilder) NextIb() (nextIb *IfdBuilder, err error) { func (ib *IfdBuilder) NextIb() (nextIb *IfdBuilder, err error) {
return ib.nextIb, nil return ib.nextIb, nil
} }
@ -362,7 +321,7 @@ func (ib *IfdBuilder) ChildWithTagId(childIfdTagId uint16) (childIb *IfdBuilder,
childIbThis := bt.value.Ib() childIbThis := bt.value.Ib()
if childIbThis.ifdTagId == childIfdTagId { if childIbThis.IfdIdentity().TagId() == childIfdTagId {
return childIbThis, nil return childIbThis, nil
} }
} }
@ -391,43 +350,37 @@ func getOrCreateIbFromRootIbInner(rootIb *IfdBuilder, parentIb *IfdBuilder, curr
if parentIb != nil { if parentIb != nil {
var err error var err error
parentLineage, err = thisIb.ifdMapping.ResolvePath(parentIb.fqIfdPath) parentLineage, err = thisIb.ifdMapping.ResolvePath(parentIb.IfdIdentity().String())
log.PanicIf(err) log.PanicIf(err)
} }
// Process the current path part. // Process the current path part.
currentItii := currentLineage[0] currentItIi := currentLineage[0]
// Make sure the leftmost part of the FQ IFD-path agrees with the IB we // Make sure the leftmost part of the FQ IFD-path agrees with the IB we
// were given. // were given.
expectedFqRootIfdPath := "" expectedFqRootIfdPath := ""
if parentLineage != nil { if parentLineage != nil {
expectedLineage := append(parentLineage, currentItii) expectedLineage := append(parentLineage, currentItIi)
expectedFqRootIfdPath = thisIb.ifdMapping.PathPhraseFromLineage(expectedLineage) expectedFqRootIfdPath = thisIb.ifdMapping.PathPhraseFromLineage(expectedLineage)
} else { } else {
expectedFqRootIfdPath = thisIb.ifdMapping.PathPhraseFromLineage(currentLineage[:1]) expectedFqRootIfdPath = thisIb.ifdMapping.PathPhraseFromLineage(currentLineage[:1])
} }
if expectedFqRootIfdPath != thisIb.fqIfdPath { if expectedFqRootIfdPath != thisIb.IfdIdentity().String() {
log.Panicf("the FQ IFD-path [%s] we were given does not match the builder's FQ IFD-path [%s]", expectedFqRootIfdPath, thisIb.fqIfdPath) log.Panicf("the FQ IFD-path [%s] we were given does not match the builder's FQ IFD-path [%s]", expectedFqRootIfdPath, thisIb.IfdIdentity().String())
} }
// If we actually wanted a sibling (currentItii.Index > 0) then seek to it, // If we actually wanted a sibling (currentItIi.Index > 0) then seek to it,
// appending new siblings, as required, until we get there. // appending new siblings, as required, until we get there.
for i := 0; i < currentItii.Index; i++ { for i := 0; i < currentItIi.Index; i++ {
if thisIb.nextIb == nil { if thisIb.nextIb == nil {
// Generate an FQ IFD-path for the sibling. It'll use the same // Generate an FQ IFD-path for the sibling. It'll use the same
// non-FQ IFD-path as the current IB. // non-FQ IFD-path as the current IB.
siblingFqIfdPath := "" iiSibling := thisIb.IfdIdentity().NewSibling(i + 1)
if parentLineage != nil { thisIb.nextIb = NewIfdBuilder(thisIb.ifdMapping, thisIb.tagIndex, iiSibling, thisIb.byteOrder)
siblingFqIfdPath = fmt.Sprintf("%s/%s%d", parentIb.fqIfdPath, currentItii.Name, i+1)
} else {
siblingFqIfdPath = fmt.Sprintf("%s%d", currentItii.Name, i+1)
}
thisIb.nextIb = NewIfdBuilder(thisIb.ifdMapping, thisIb.tagIndex, siblingFqIfdPath, thisIb.byteOrder)
} }
thisIb = thisIb.nextIb thisIb = thisIb.nextIb
@ -450,25 +403,31 @@ func getOrCreateIbFromRootIbInner(rootIb *IfdBuilder, parentIb *IfdBuilder, curr
childIb := bt.value.Ib() childIb := bt.value.Ib()
if childIb.ifdTagId == childItii.TagId { if childIb.IfdIdentity().TagId() == childItii.TagId {
foundChild = childIb foundChild = childIb
break break
} }
} }
// If we didn't find the child, add it. // If we didn't find the child, add it.
if foundChild == nil { if foundChild == nil {
thisIbLineage, err := thisIb.ifdMapping.ResolvePath(thisIb.fqIfdPath) currentIfdTag := thisIb.IfdIdentity().IfdTag()
log.PanicIf(err)
childLineage := make([]IfdTagIdAndIndex, len(thisIbLineage)+1) childIfdTag :=
copy(childLineage, thisIbLineage) exifcommon.NewIfdTag(
&currentIfdTag,
childItii.TagId,
childItii.Name)
childLineage[len(childLineage)-1] = childItii iiChild := thisIb.IfdIdentity().NewChild(childIfdTag, 0)
fqIfdChildPath := thisIb.ifdMapping.FqPathPhraseFromLineage(childLineage) foundChild =
NewIfdBuilder(
foundChild = NewIfdBuilder(thisIb.ifdMapping, thisIb.tagIndex, fqIfdChildPath, thisIb.byteOrder) thisIb.ifdMapping,
thisIb.tagIndex,
iiChild,
thisIb.byteOrder)
err = thisIb.AddChildIb(foundChild) err = thisIb.AddChildIb(foundChild)
log.PanicIf(err) log.PanicIf(err)
@ -505,10 +464,10 @@ func (ib *IfdBuilder) String() string {
nextIfdPhrase := "" nextIfdPhrase := ""
if ib.nextIb != nil { if ib.nextIb != nil {
// TODO(dustin): We were setting this to ii.String(), but we were getting hex-data when printing this after building from an existing chain. // TODO(dustin): We were setting this to ii.String(), but we were getting hex-data when printing this after building from an existing chain.
nextIfdPhrase = ib.nextIb.ifdPath nextIfdPhrase = ib.nextIb.IfdIdentity().UnindexedString()
} }
return fmt.Sprintf("IfdBuilder<PATH=[%s] TAG-ID=(0x%04x) COUNT=(%d) OFF=(0x%04x) NEXT-IFD-PATH=[%s]>", ib.ifdPath, ib.ifdTagId, len(ib.tags), ib.existingOffset, nextIfdPhrase) return fmt.Sprintf("IfdBuilder<PATH=[%s] TAG-ID=(0x%04x) COUNT=(%d) OFF=(0x%04x) NEXT-IFD-PATH=[%s]>", ib.IfdIdentity().UnindexedString(), ib.IfdIdentity().TagId(), len(ib.tags), ib.existingOffset, nextIfdPhrase)
} }
func (ib *IfdBuilder) Tags() (tags []*BuilderTag) { func (ib *IfdBuilder) Tags() (tags []*BuilderTag) {
@ -533,7 +492,7 @@ func (ib *IfdBuilder) SetThumbnail(data []byte) (err error) {
} }
}() }()
if ib.ifdPath != exifcommon.IfdPathStandard { if ib.IfdIdentity().UnindexedString() != exifcommon.IfdStandardIfdIdentity.UnindexedString() {
log.Panicf("thumbnails can only go into a root Ifd (and only the second one)") log.Panicf("thumbnails can only go into a root Ifd (and only the second one)")
} }
@ -548,7 +507,7 @@ func (ib *IfdBuilder) SetThumbnail(data []byte) (err error) {
ibtvfb := NewIfdBuilderTagValueFromBytes(ib.thumbnailData) ibtvfb := NewIfdBuilderTagValueFromBytes(ib.thumbnailData)
offsetBt := offsetBt :=
NewBuilderTag( NewBuilderTag(
ib.ifdPath, ib.IfdIdentity().UnindexedString(),
ThumbnailOffsetTagId, ThumbnailOffsetTagId,
exifcommon.TypeLong, exifcommon.TypeLong,
ibtvfb, ibtvfb,
@ -557,10 +516,10 @@ func (ib *IfdBuilder) SetThumbnail(data []byte) (err error) {
err = ib.Set(offsetBt) err = ib.Set(offsetBt)
log.PanicIf(err) log.PanicIf(err)
thumbnailSizeIt, err := ib.tagIndex.Get(ib.ifdPath, ThumbnailSizeTagId) thumbnailSizeIt, err := ib.tagIndex.Get(ib.IfdIdentity().UnindexedString(), ThumbnailSizeTagId)
log.PanicIf(err) log.PanicIf(err)
sizeBt := NewStandardBuilderTag(ib.ifdPath, thumbnailSizeIt, ib.byteOrder, []uint32{uint32(len(ib.thumbnailData))}) sizeBt := NewStandardBuilderTag(ib.IfdIdentity().UnindexedString(), thumbnailSizeIt, ib.byteOrder, []uint32{uint32(len(ib.thumbnailData))})
err = ib.Set(sizeBt) err = ib.Set(sizeBt)
log.PanicIf(err) log.PanicIf(err)
@ -593,7 +552,7 @@ func (ib *IfdBuilder) printTagTree(levels int) {
for i, tag := range currentIb.tags { for i, tag := range currentIb.tags {
isChildIb := false isChildIb := false
_, err := ib.ifdMapping.GetChild(currentIb.ifdPath, tag.tagId) _, err := ib.ifdMapping.GetChild(currentIb.IfdIdentity().UnindexedString(), tag.tagId)
if err == nil { if err == nil {
isChildIb = true isChildIb = true
} else if log.Is(err, ErrChildIfdNotMapped) == false { } else if log.Is(err, ErrChildIfdNotMapped) == false {
@ -662,7 +621,7 @@ func (ib *IfdBuilder) printIfdTree(levels int) {
if len(currentIb.tags) > 0 { if len(currentIb.tags) > 0 {
for _, tag := range currentIb.tags { for _, tag := range currentIb.tags {
isChildIb := false isChildIb := false
_, err := ib.ifdMapping.GetChild(currentIb.ifdPath, tag.tagId) _, err := ib.ifdMapping.GetChild(currentIb.IfdIdentity().UnindexedString(), tag.tagId)
if err == nil { if err == nil {
isChildIb = true isChildIb = true
} else if log.Is(err, ErrChildIfdNotMapped) == false { } else if log.Is(err, ErrChildIfdNotMapped) == false {
@ -697,7 +656,7 @@ func (ib *IfdBuilder) dumpToStrings(thisIb *IfdBuilder, prefix string, tagId uin
siblingIfdIndex := 0 siblingIfdIndex := 0
for ; thisIb != nil; thisIb = thisIb.nextIb { for ; thisIb != nil; thisIb = thisIb.nextIb {
line := fmt.Sprintf("IFD<PARENTS=[%s] FQ-IFD-PATH=[%s] IFD-INDEX=(%d) IFD-TAG-ID=(0x%04x) TAG=[0x%04x]>", prefix, thisIb.fqIfdPath, siblingIfdIndex, thisIb.ifdTagId, tagId) line := fmt.Sprintf("IFD<PARENTS=[%s] FQ-IFD-PATH=[%s] IFD-INDEX=(%d) IFD-TAG-ID=(0x%04x) TAG=[0x%04x]>", prefix, thisIb.IfdIdentity().String(), siblingIfdIndex, thisIb.IfdIdentity().TagId(), tagId)
linesOutput = append(linesOutput, line) linesOutput = append(linesOutput, line)
for i, tag := range thisIb.tags { for i, tag := range thisIb.tags {
@ -705,10 +664,10 @@ func (ib *IfdBuilder) dumpToStrings(thisIb *IfdBuilder, prefix string, tagId uin
childIfdName := "" childIfdName := ""
if tag.value.IsIb() == true { if tag.value.IsIb() == true {
childIb = tag.value.Ib() childIb = tag.value.Ib()
childIfdName = childIb.ifdPath childIfdName = childIb.IfdIdentity().UnindexedString()
} }
line := fmt.Sprintf("TAG<PARENTS=[%s] FQ-IFD-PATH=[%s] IFD-TAG-ID=(0x%04x) CHILD-IFD=[%s] TAG-INDEX=(%d) TAG=[0x%04x]>", prefix, thisIb.fqIfdPath, thisIb.ifdTagId, childIfdName, i, tag.tagId) line := fmt.Sprintf("TAG<PARENTS=[%s] FQ-IFD-PATH=[%s] IFD-TAG-ID=(0x%04x) CHILD-IFD=[%s] TAG-INDEX=(%d) TAG=[0x%04x]>", prefix, thisIb.IfdIdentity().String(), thisIb.IfdIdentity().TagId(), childIfdName, i, tag.tagId)
linesOutput = append(linesOutput, line) linesOutput = append(linesOutput, line)
if childIb == nil { if childIb == nil {
@ -717,9 +676,9 @@ func (ib *IfdBuilder) dumpToStrings(thisIb *IfdBuilder, prefix string, tagId uin
childPrefix := "" childPrefix := ""
if prefix == "" { if prefix == "" {
childPrefix = fmt.Sprintf("%s", thisIb.ifdPath) childPrefix = fmt.Sprintf("%s", thisIb.IfdIdentity().UnindexedString())
} else { } else {
childPrefix = fmt.Sprintf("%s->%s", prefix, thisIb.ifdPath) childPrefix = fmt.Sprintf("%s->%s", prefix, thisIb.IfdIdentity().UnindexedString())
} }
linesOutput = thisIb.dumpToStrings(childIb, childPrefix, tag.tagId, linesOutput) linesOutput = thisIb.dumpToStrings(childIb, childPrefix, tag.tagId, linesOutput)
@ -930,7 +889,7 @@ func (ib *IfdBuilder) FindTagWithName(tagName string) (bt *BuilderTag, err error
} }
}() }()
it, err := ib.tagIndex.GetWithName(ib.ifdPath, tagName) it, err := ib.tagIndex.GetWithName(ib.IfdIdentity().UnindexedString(), tagName)
log.PanicIf(err) log.PanicIf(err)
found, err := ib.FindN(it.Id, 1) found, err := ib.FindN(it.Id, 1)
@ -989,7 +948,7 @@ func (ib *IfdBuilder) AddChildIb(childIb *IfdBuilder) (err error) {
} }
}() }()
if childIb.ifdTagId == 0 { if childIb.IfdIdentity().TagId() == 0 {
log.Panicf("IFD can not be used as a child IFD (not associated with a tag-ID): %v", childIb) log.Panicf("IFD can not be used as a child IFD (not associated with a tag-ID): %v", childIb)
} else if childIb.byteOrder != ib.byteOrder { } else if childIb.byteOrder != ib.byteOrder {
log.Panicf("Child IFD does not have the same byte-order: [%s] != [%s]", childIb.byteOrder, ib.byteOrder) log.Panicf("Child IFD does not have the same byte-order: [%s] != [%s]", childIb.byteOrder, ib.byteOrder)
@ -999,8 +958,8 @@ func (ib *IfdBuilder) AddChildIb(childIb *IfdBuilder) (err error) {
// tag of this type has not been previously added. Note that we just search // tag of this type has not been previously added. Note that we just search
// the current IFD and *not every* IFD. // the current IFD and *not every* IFD.
for _, bt := range childIb.tags { for _, bt := range childIb.tags {
if bt.tagId == childIb.ifdTagId { if bt.tagId == childIb.IfdIdentity().TagId() {
log.Panicf("child-IFD already added: %v", childIb.ifdPath) log.Panicf("child-IFD already added: %v", childIb.IfdIdentity().UnindexedString())
} }
} }
@ -1021,8 +980,8 @@ func (ib *IfdBuilder) NewBuilderTagFromBuilder(childIb *IfdBuilder) (bt *Builder
value := NewIfdBuilderTagValueFromIfdBuilder(childIb) value := NewIfdBuilderTagValueFromIfdBuilder(childIb)
bt = NewChildIfdBuilderTag( bt = NewChildIfdBuilderTag(
ib.ifdPath, ib.IfdIdentity().UnindexedString(),
childIb.ifdTagId, childIb.IfdIdentity().TagId(),
value) value)
return bt return bt
@ -1095,7 +1054,7 @@ func (ib *IfdBuilder) AddTagsFromExisting(ifd *Ifd, includeTagIds []uint16, excl
for _, thisChildIfd := range ifd.Children { for _, thisChildIfd := range ifd.Children {
if thisChildIfd.ParentTagIndex != i { if thisChildIfd.ParentTagIndex != i {
continue continue
} else if thisChildIfd.TagId != 0xffff && thisChildIfd.TagId != ite.TagId() { } else if thisChildIfd.ifdIdentity.TagId() != 0xffff && thisChildIfd.ifdIdentity.TagId() != ite.TagId() {
log.Panicf("child-IFD tag is not correct: TAG-POSITION=(%d) ITE=%s CHILD-IFD=%s", thisChildIfd.ParentTagIndex, ite, thisChildIfd) log.Panicf("child-IFD tag is not correct: TAG-POSITION=(%d) ITE=%s CHILD-IFD=%s", thisChildIfd.ParentTagIndex, ite, thisChildIfd)
} }
@ -1106,7 +1065,7 @@ func (ib *IfdBuilder) AddTagsFromExisting(ifd *Ifd, includeTagIds []uint16, excl
if childIfd == nil { if childIfd == nil {
childTagIds := make([]string, len(ifd.Children)) childTagIds := make([]string, len(ifd.Children))
for j, childIfd := range ifd.Children { for j, childIfd := range ifd.Children {
childTagIds[j] = fmt.Sprintf("0x%04x (parent tag-position %d)", childIfd.TagId, childIfd.ParentTagIndex) childTagIds[j] = fmt.Sprintf("0x%04x (parent tag-position %d)", childIfd.ifdIdentity.TagId(), childIfd.ParentTagIndex)
} }
log.Panicf("could not find child IFD for child ITE: IFD-PATH=[%s] TAG-ID=(0x%04x) CURRENT-TAG-POSITION=(%d) CHILDREN=%v", ite.IfdPath(), ite.TagId(), i, childTagIds) log.Panicf("could not find child IFD for child ITE: IFD-PATH=[%s] TAG-ID=(0x%04x) CURRENT-TAG-POSITION=(%d) CHILDREN=%v", ite.IfdPath(), ite.TagId(), i, childTagIds)
@ -1123,7 +1082,7 @@ func (ib *IfdBuilder) AddTagsFromExisting(ifd *Ifd, includeTagIds []uint16, excl
value := NewIfdBuilderTagValueFromBytes(rawBytes) value := NewIfdBuilderTagValueFromBytes(rawBytes)
bt = NewBuilderTag( bt = NewBuilderTag(
ifd.IfdPath, ifd.ifdIdentity.UnindexedString(),
ite.TagId(), ite.TagId(),
ite.TagType(), ite.TagType(),
value, value,
@ -1146,10 +1105,10 @@ func (ib *IfdBuilder) AddStandard(tagId uint16, value interface{}) (err error) {
} }
}() }()
it, err := ib.tagIndex.Get(ib.ifdPath, tagId) it, err := ib.tagIndex.Get(ib.IfdIdentity().UnindexedString(), tagId)
log.PanicIf(err) log.PanicIf(err)
bt := NewStandardBuilderTag(ib.ifdPath, it, ib.byteOrder, value) bt := NewStandardBuilderTag(ib.IfdIdentity().UnindexedString(), it, ib.byteOrder, value)
err = ib.add(bt) err = ib.add(bt)
log.PanicIf(err) log.PanicIf(err)
@ -1167,10 +1126,10 @@ func (ib *IfdBuilder) AddStandardWithName(tagName string, value interface{}) (er
} }
}() }()
it, err := ib.tagIndex.GetWithName(ib.ifdPath, tagName) it, err := ib.tagIndex.GetWithName(ib.IfdIdentity().UnindexedString(), tagName)
log.PanicIf(err) log.PanicIf(err)
bt := NewStandardBuilderTag(ib.ifdPath, it, ib.byteOrder, value) bt := NewStandardBuilderTag(ib.IfdIdentity().UnindexedString(), it, ib.byteOrder, value)
err = ib.add(bt) err = ib.add(bt)
log.PanicIf(err) log.PanicIf(err)
@ -1189,10 +1148,10 @@ func (ib *IfdBuilder) SetStandard(tagId uint16, value interface{}) (err error) {
// TODO(dustin): !! Add test for this function. // TODO(dustin): !! Add test for this function.
it, err := ib.tagIndex.Get(ib.ifdPath, tagId) it, err := ib.tagIndex.Get(ib.IfdIdentity().UnindexedString(), tagId)
log.PanicIf(err) log.PanicIf(err)
bt := NewStandardBuilderTag(ib.ifdPath, it, ib.byteOrder, value) bt := NewStandardBuilderTag(ib.IfdIdentity().UnindexedString(), it, ib.byteOrder, value)
i, err := ib.Find(tagId) i, err := ib.Find(tagId)
if err != nil { if err != nil {
@ -1220,10 +1179,10 @@ func (ib *IfdBuilder) SetStandardWithName(tagName string, value interface{}) (er
// TODO(dustin): !! Add test for this function. // TODO(dustin): !! Add test for this function.
it, err := ib.tagIndex.GetWithName(ib.ifdPath, tagName) it, err := ib.tagIndex.GetWithName(ib.IfdIdentity().UnindexedString(), tagName)
log.PanicIf(err) log.PanicIf(err)
bt := NewStandardBuilderTag(ib.ifdPath, it, ib.byteOrder, value) bt := NewStandardBuilderTag(ib.IfdIdentity().UnindexedString(), it, ib.byteOrder, value)
i, err := ib.Find(bt.tagId) i, err := ib.Find(bt.tagId)
if err != nil { if err != nil {

View File

@ -273,13 +273,13 @@ func (ibe *IfdByteEncoder) encodeTagToBytes(ib *IfdBuilder, bt *BuilderTag, bw *
if nextIfdOffsetToWrite > 0 { if nextIfdOffsetToWrite > 0 {
var err error var err error
ibe.pushToJournal("encodeTagToBytes", ">", "[%s]->[%s]", ib.ifdPath, bt.value.Ib().ifdPath) ibe.pushToJournal("encodeTagToBytes", ">", "[%s]->[%s]", ib.IfdIdentity().UnindexedString(), bt.value.Ib().IfdIdentity().UnindexedString())
// Create the block of IFD data and everything it requires. // Create the block of IFD data and everything it requires.
childIfdBlock, err = ibe.encodeAndAttachIfd(bt.value.Ib(), nextIfdOffsetToWrite) childIfdBlock, err = ibe.encodeAndAttachIfd(bt.value.Ib(), nextIfdOffsetToWrite)
log.PanicIf(err) log.PanicIf(err)
ibe.pushToJournal("encodeTagToBytes", "<", "[%s]->[%s]", bt.value.Ib().ifdPath, ib.ifdPath) ibe.pushToJournal("encodeTagToBytes", "<", "[%s]->[%s]", bt.value.Ib().IfdIdentity().UnindexedString(), ib.IfdIdentity().UnindexedString())
// Use the next-IFD offset for it. The IFD will actually get // Use the next-IFD offset for it. The IFD will actually get
// attached after we return. // attached after we return.
@ -290,7 +290,7 @@ func (ibe *IfdByteEncoder) encodeTagToBytes(ib *IfdBuilder, bt *BuilderTag, bw *
// No child-IFDs are to be allocated. Finish the entry with a NULL // No child-IFDs are to be allocated. Finish the entry with a NULL
// pointer. // pointer.
ibe.pushToJournal("encodeTagToBytes", "-", "*Not* descending to child: [%s]", bt.value.Ib().ifdPath) ibe.pushToJournal("encodeTagToBytes", "-", "*Not* descending to child: [%s]", bt.value.Ib().IfdIdentity().UnindexedString())
err = bw.WriteUint32(0) err = bw.WriteUint32(0)
log.PanicIf(err) log.PanicIf(err)
@ -426,14 +426,14 @@ func (ibe *IfdByteEncoder) encodeAndAttachIfd(ib *IfdBuilder, ifdAddressableOffs
// Do a dry-run in order to pre-determine its size requirement. // Do a dry-run in order to pre-determine its size requirement.
ibe.pushToJournal("encodeAndAttachIfd", ">", "Beginning encoding process: (%d) [%s]", i, thisIb.ifdPath) ibe.pushToJournal("encodeAndAttachIfd", ">", "Beginning encoding process: (%d) [%s]", i, thisIb.IfdIdentity().UnindexedString())
ibe.pushToJournal("encodeAndAttachIfd", ">", "Calculating size: (%d) [%s]", i, thisIb.ifdPath) ibe.pushToJournal("encodeAndAttachIfd", ">", "Calculating size: (%d) [%s]", i, thisIb.IfdIdentity().UnindexedString())
_, tableSize, allocatedDataSize, _, err := ibe.encodeIfdToBytes(thisIb, ifdAddressableOffset, 0, false) _, tableSize, allocatedDataSize, _, err := ibe.encodeIfdToBytes(thisIb, ifdAddressableOffset, 0, false)
log.PanicIf(err) log.PanicIf(err)
ibe.pushToJournal("encodeAndAttachIfd", "<", "Finished calculating size: (%d) [%s]", i, thisIb.ifdPath) ibe.pushToJournal("encodeAndAttachIfd", "<", "Finished calculating size: (%d) [%s]", i, thisIb.IfdIdentity().UnindexedString())
ifdAddressableOffset += tableSize ifdAddressableOffset += tableSize
nextIfdOffsetToWrite := ifdAddressableOffset + allocatedDataSize nextIfdOffsetToWrite := ifdAddressableOffset + allocatedDataSize
@ -445,7 +445,7 @@ func (ibe *IfdByteEncoder) encodeAndAttachIfd(ib *IfdBuilder, ifdAddressableOffs
setNextIb := thisIb.nextIb != nil setNextIb := thisIb.nextIb != nil
ibe.pushToJournal("encodeAndAttachIfd", ">", "Encoding starting: (%d) [%s] NEXT-IFD-OFFSET-TO-WRITE=(0x%08x)", i, thisIb.ifdPath, nextIfdOffsetToWrite) ibe.pushToJournal("encodeAndAttachIfd", ">", "Encoding starting: (%d) [%s] NEXT-IFD-OFFSET-TO-WRITE=(0x%08x)", i, thisIb.IfdIdentity().UnindexedString(), nextIfdOffsetToWrite)
tableAndAllocated, effectiveTableSize, effectiveAllocatedDataSize, childIfdSizes, err := tableAndAllocated, effectiveTableSize, effectiveAllocatedDataSize, childIfdSizes, err :=
ibe.encodeIfdToBytes(thisIb, ifdAddressableOffset, nextIfdOffsetToWrite, setNextIb) ibe.encodeIfdToBytes(thisIb, ifdAddressableOffset, nextIfdOffsetToWrite, setNextIb)
@ -458,7 +458,7 @@ func (ibe *IfdByteEncoder) encodeAndAttachIfd(ib *IfdBuilder, ifdAddressableOffs
log.Panicf("written allocated-data size does not match the pre-calculated allocated-data size: (%d) != (%d) %s", effectiveAllocatedDataSize, allocatedDataSize, ib) log.Panicf("written allocated-data size does not match the pre-calculated allocated-data size: (%d) != (%d) %s", effectiveAllocatedDataSize, allocatedDataSize, ib)
} }
ibe.pushToJournal("encodeAndAttachIfd", "<", "Encoding done: (%d) [%s]", i, thisIb.ifdPath) ibe.pushToJournal("encodeAndAttachIfd", "<", "Encoding done: (%d) [%s]", i, thisIb.IfdIdentity().UnindexedString())
totalChildIfdSize := uint32(0) totalChildIfdSize := uint32(0)
for _, childIfdSize := range childIfdSizes { for _, childIfdSize := range childIfdSizes {
@ -478,7 +478,7 @@ func (ibe *IfdByteEncoder) encodeAndAttachIfd(ib *IfdBuilder, ifdAddressableOffs
ifdAddressableOffset += allocatedDataSize + totalChildIfdSize ifdAddressableOffset += allocatedDataSize + totalChildIfdSize
ibe.pushToJournal("encodeAndAttachIfd", "<", "Finishing encoding process: (%d) [%s] [FINAL:] NEXT-IFD-OFFSET-TO-WRITE=(0x%08x)", i, ib.ifdPath, nextIfdOffsetToWrite) ibe.pushToJournal("encodeAndAttachIfd", "<", "Finishing encoding process: (%d) [%s] [FINAL:] NEXT-IFD-OFFSET-TO-WRITE=(0x%08x)", i, ib.IfdIdentity().UnindexedString(), nextIfdOffsetToWrite)
i++ i++
} }

View File

@ -196,12 +196,12 @@ func Test_IfdByteEncoder_encodeTagToBytes_bytes_embedded1(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
ti := NewTagIndex() ti := NewTagIndex()
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandardGps, exifcommon.TestDefaultByteOrder) ib := NewIfdBuilder(im, ti, exifcommon.IfdGpsInfoStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
it, err := ti.Get(ib.ifdPath, uint16(0x0000)) it, err := ti.Get(ib.IfdIdentity().UnindexedString(), uint16(0x0000))
log.PanicIf(err) log.PanicIf(err)
bt := NewStandardBuilderTag(exifcommon.IfdPathStandardGps, it, exifcommon.TestDefaultByteOrder, []uint8{uint8(0x12)}) bt := NewStandardBuilderTag(exifcommon.IfdGpsInfoStandardIfdIdentity.UnindexedString(), it, exifcommon.TestDefaultByteOrder, []uint8{uint8(0x12)})
b := new(bytes.Buffer) b := new(bytes.Buffer)
bw := NewByteWriter(b, exifcommon.TestDefaultByteOrder) bw := NewByteWriter(b, exifcommon.TestDefaultByteOrder)
@ -230,12 +230,12 @@ func Test_IfdByteEncoder_encodeTagToBytes_bytes_embedded2(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
ti := NewTagIndex() ti := NewTagIndex()
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandardGps, exifcommon.TestDefaultByteOrder) ib := NewIfdBuilder(im, ti, exifcommon.IfdGpsInfoStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
it, err := ti.Get(ib.ifdPath, uint16(0x0000)) it, err := ti.Get(ib.IfdIdentity().UnindexedString(), uint16(0x0000))
log.PanicIf(err) log.PanicIf(err)
bt := NewStandardBuilderTag(exifcommon.IfdPathStandardGps, it, exifcommon.TestDefaultByteOrder, []uint8{uint8(0x12), uint8(0x34), uint8(0x56), uint8(0x78)}) bt := NewStandardBuilderTag(exifcommon.IfdGpsInfoStandardIfdIdentity.UnindexedString(), it, exifcommon.TestDefaultByteOrder, []uint8{uint8(0x12), uint8(0x34), uint8(0x56), uint8(0x78)})
b := new(bytes.Buffer) b := new(bytes.Buffer)
bw := NewByteWriter(b, exifcommon.TestDefaultByteOrder) bw := NewByteWriter(b, exifcommon.TestDefaultByteOrder)
@ -264,7 +264,7 @@ func Test_IfdByteEncoder_encodeTagToBytes_bytes_allocated(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
ti := NewTagIndex() ti := NewTagIndex()
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandardGps, exifcommon.TestDefaultByteOrder) ib := NewIfdBuilder(im, ti, exifcommon.IfdGpsInfoStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
b := new(bytes.Buffer) b := new(bytes.Buffer)
bw := NewByteWriter(b, exifcommon.TestDefaultByteOrder) bw := NewByteWriter(b, exifcommon.TestDefaultByteOrder)
@ -272,10 +272,10 @@ func Test_IfdByteEncoder_encodeTagToBytes_bytes_allocated(t *testing.T) {
addressableOffset := uint32(0x1234) addressableOffset := uint32(0x1234)
ida := newIfdDataAllocator(addressableOffset) ida := newIfdDataAllocator(addressableOffset)
it, err := ti.Get(ib.ifdPath, uint16(0x0000)) it, err := ti.Get(ib.IfdIdentity().UnindexedString(), uint16(0x0000))
log.PanicIf(err) log.PanicIf(err)
bt := NewStandardBuilderTag(exifcommon.IfdPathStandardGps, it, exifcommon.TestDefaultByteOrder, []uint8{uint8(0x12), uint8(0x34), uint8(0x56), uint8(0x78), uint8(0x9a)}) bt := NewStandardBuilderTag(exifcommon.IfdGpsInfoStandardIfdIdentity.UnindexedString(), it, exifcommon.TestDefaultByteOrder, []uint8{uint8(0x12), uint8(0x34), uint8(0x56), uint8(0x78), uint8(0x9a)})
childIfdBlock, err := ibe.encodeTagToBytes(ib, bt, bw, ida, uint32(0)) childIfdBlock, err := ibe.encodeTagToBytes(ib, bt, bw, ida, uint32(0))
log.PanicIf(err) log.PanicIf(err)
@ -292,7 +292,7 @@ func Test_IfdByteEncoder_encodeTagToBytes_bytes_allocated(t *testing.T) {
// Test that another allocation encodes to the new offset. // Test that another allocation encodes to the new offset.
bt = NewStandardBuilderTag(exifcommon.IfdPathStandardGps, it, exifcommon.TestDefaultByteOrder, []uint8{uint8(0xbc), uint8(0xde), uint8(0xf0), uint8(0x12), uint8(0x34)}) bt = NewStandardBuilderTag(exifcommon.IfdGpsInfoStandardIfdIdentity.UnindexedString(), it, exifcommon.TestDefaultByteOrder, []uint8{uint8(0xbc), uint8(0xde), uint8(0xf0), uint8(0x12), uint8(0x34)})
childIfdBlock, err = ibe.encodeTagToBytes(ib, bt, bw, ida, uint32(0)) childIfdBlock, err = ibe.encodeTagToBytes(ib, bt, bw, ida, uint32(0))
log.PanicIf(err) log.PanicIf(err)
@ -323,7 +323,7 @@ func Test_IfdByteEncoder_encodeTagToBytes_childIfd__withoutAllocate(t *testing.T
log.PanicIf(err) log.PanicIf(err)
ti := NewTagIndex() ti := NewTagIndex()
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder) ib := NewIfdBuilder(im, ti, exifcommon.IfdStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
b := new(bytes.Buffer) b := new(bytes.Buffer)
bw := NewByteWriter(b, exifcommon.TestDefaultByteOrder) bw := NewByteWriter(b, exifcommon.TestDefaultByteOrder)
@ -331,9 +331,9 @@ func Test_IfdByteEncoder_encodeTagToBytes_childIfd__withoutAllocate(t *testing.T
addressableOffset := uint32(0x1234) addressableOffset := uint32(0x1234)
ida := newIfdDataAllocator(addressableOffset) ida := newIfdDataAllocator(addressableOffset)
childIb := NewIfdBuilder(im, ti, exifcommon.IfdPathStandardExif, exifcommon.TestDefaultByteOrder) childIb := NewIfdBuilder(im, ti, exifcommon.IfdExifStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
tagValue := NewIfdBuilderTagValueFromIfdBuilder(childIb) tagValue := NewIfdBuilderTagValueFromIfdBuilder(childIb)
bt := NewChildIfdBuilderTag(exifcommon.IfdPathStandard, exifcommon.IfdExifId, tagValue) bt := NewChildIfdBuilderTag(exifcommon.IfdStandardIfdIdentity.UnindexedString(), exifcommon.IfdExifStandardIfdIdentity.TagId(), tagValue)
nextIfdOffsetToWrite := uint32(0) nextIfdOffsetToWrite := uint32(0)
childIfdBlock, err := ibe.encodeTagToBytes(ib, bt, bw, ida, nextIfdOffsetToWrite) childIfdBlock, err := ibe.encodeTagToBytes(ib, bt, bw, ida, nextIfdOffsetToWrite)
@ -367,10 +367,10 @@ func Test_IfdByteEncoder_encodeTagToBytes_childIfd__withAllocate(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
ti := NewTagIndex() ti := NewTagIndex()
childIb := NewIfdBuilder(im, ti, exifcommon.IfdPathStandardExif, exifcommon.TestDefaultByteOrder) childIb := NewIfdBuilder(im, ti, exifcommon.IfdExifStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
childIbTestTag := &BuilderTag{ childIbTestTag := &BuilderTag{
ifdPath: exifcommon.IfdPathStandardExif, ifdPath: exifcommon.IfdExifStandardIfdIdentity.UnindexedString(),
tagId: 0x8822, tagId: 0x8822,
typeId: exifcommon.TypeShort, typeId: exifcommon.TypeShort,
value: NewIfdBuilderTagValueFromBytes([]byte{0x12, 0x34}), value: NewIfdBuilderTagValueFromBytes([]byte{0x12, 0x34}),
@ -381,7 +381,7 @@ func Test_IfdByteEncoder_encodeTagToBytes_childIfd__withAllocate(t *testing.T) {
// Formally compose the tag that refers to it. // Formally compose the tag that refers to it.
tagValue := NewIfdBuilderTagValueFromIfdBuilder(childIb) tagValue := NewIfdBuilderTagValueFromIfdBuilder(childIb)
bt := NewChildIfdBuilderTag(exifcommon.IfdPathStandard, exifcommon.IfdExifId, tagValue) bt := NewChildIfdBuilderTag(exifcommon.IfdStandardIfdIdentity.UnindexedString(), exifcommon.IfdExifStandardIfdIdentity.TagId(), tagValue)
// Encode the tag. Since we've actually provided an offset at which we can // Encode the tag. Since we've actually provided an offset at which we can
// allocate data, the child-IFD will automatically be encoded, allocated, // allocate data, the child-IFD will automatically be encoded, allocated,
@ -390,7 +390,7 @@ func Test_IfdByteEncoder_encodeTagToBytes_childIfd__withAllocate(t *testing.T) {
ibe := NewIfdByteEncoder() ibe := NewIfdByteEncoder()
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder) ib := NewIfdBuilder(im, ti, exifcommon.IfdStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
b := new(bytes.Buffer) b := new(bytes.Buffer)
bw := NewByteWriter(b, exifcommon.TestDefaultByteOrder) bw := NewByteWriter(b, exifcommon.TestDefaultByteOrder)
@ -422,10 +422,10 @@ func Test_IfdByteEncoder_encodeTagToBytes_childIfd__withAllocate(t *testing.T) {
t.Fatalf("Child IFD is not the right size: (%d)", len(childIfdBlock)) t.Fatalf("Child IFD is not the right size: (%d)", len(childIfdBlock))
} }
iteV, err := ParseOneTag(im, ti, exifcommon.IfdPathStandard, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder, tagBytes) iteV, err := ParseOneTag(im, ti, exifcommon.IfdStandardIfdIdentity, exifcommon.TestDefaultByteOrder, tagBytes)
log.PanicIf(err) log.PanicIf(err)
if iteV.TagId() != exifcommon.IfdExifId { if iteV.TagId() != exifcommon.IfdExifStandardIfdIdentity.TagId() {
t.Fatalf("IFD first tag-ID not correct: (0x%02x)", iteV.TagId()) t.Fatalf("IFD first tag-ID not correct: (0x%02x)", iteV.TagId())
} else if iteV.tagIndex != 0 { } else if iteV.tagIndex != 0 {
t.Fatalf("IFD first tag index not correct: (%d)", iteV.tagIndex) t.Fatalf("IFD first tag index not correct: (%d)", iteV.tagIndex)
@ -435,15 +435,15 @@ func Test_IfdByteEncoder_encodeTagToBytes_childIfd__withAllocate(t *testing.T) {
t.Fatalf("IFD first tag unit-count not correct: (%d)", iteV.UnitCount()) t.Fatalf("IFD first tag unit-count not correct: (%d)", iteV.UnitCount())
} else if iteV.getValueOffset() != nextIfdOffsetToWrite { } else if iteV.getValueOffset() != nextIfdOffsetToWrite {
t.Fatalf("IFD's child-IFD offset (as offset) is not correct: (%d) != (%d)", iteV.getValueOffset(), nextIfdOffsetToWrite) t.Fatalf("IFD's child-IFD offset (as offset) is not correct: (%d) != (%d)", iteV.getValueOffset(), nextIfdOffsetToWrite)
} else if iteV.ChildIfdPath() != exifcommon.IfdPathStandardExif { } else if iteV.ChildIfdPath() != exifcommon.IfdExifStandardIfdIdentity.UnindexedString() {
t.Fatalf("IFD first tag IFD-name name not correct: [%s]", iteV.ChildIfdPath()) t.Fatalf("IFD first tag IFD-name name not correct: [%s]", iteV.ChildIfdPath())
} else if iteV.IfdPath() != exifcommon.IfdPathStandard { } else if iteV.IfdPath() != exifcommon.IfdStandardIfdIdentity.UnindexedString() {
t.Fatalf("IFD first tag parent IFD not correct: %v", iteV.IfdPath()) t.Fatalf("IFD first tag parent IFD not correct: %v", iteV.IfdPath())
} }
// Validate the child's raw IFD bytes. // Validate the child's raw IFD bytes.
childNextIfdOffset, childEntries, err := ParseOneIfd(im, ti, "IFD/Exif", "IFD/Exif", exifcommon.TestDefaultByteOrder, childIfdBlock, nil) childNextIfdOffset, childEntries, err := ParseOneIfd(im, ti, exifcommon.IfdExifStandardIfdIdentity, exifcommon.TestDefaultByteOrder, childIfdBlock, nil)
log.PanicIf(err) log.PanicIf(err)
if childNextIfdOffset != uint32(0) { if childNextIfdOffset != uint32(0) {
@ -464,7 +464,7 @@ func Test_IfdByteEncoder_encodeTagToBytes_childIfd__withAllocate(t *testing.T) {
t.Fatalf("Child IFD first tag unit-count not correct: (%d)", ite.UnitCount()) t.Fatalf("Child IFD first tag unit-count not correct: (%d)", ite.UnitCount())
} else if ite.ChildIfdPath() != "" { } else if ite.ChildIfdPath() != "" {
t.Fatalf("Child IFD first tag IFD-name name not empty: [%s]", ite.ChildIfdPath()) t.Fatalf("Child IFD first tag IFD-name name not empty: [%s]", ite.ChildIfdPath())
} else if ite.IfdPath() != exifcommon.IfdPathStandardExif { } else if ite.IfdPath() != exifcommon.IfdExifStandardIfdIdentity.UnindexedString() {
t.Fatalf("Child IFD first tag parent IFD not correct: %v", ite.IfdPath()) t.Fatalf("Child IFD first tag parent IFD not correct: %v", ite.IfdPath())
} }
} }
@ -491,13 +491,13 @@ func Test_IfdByteEncoder_encodeTagToBytes_simpleTag_allocate(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
ti := NewTagIndex() ti := NewTagIndex()
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder) ib := NewIfdBuilder(im, ti, exifcommon.IfdStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
it, err := ib.tagIndex.Get(ib.ifdPath, uint16(0x000b)) it, err := ib.tagIndex.Get(ib.IfdIdentity().UnindexedString(), uint16(0x000b))
log.PanicIf(err) log.PanicIf(err)
valueString := "testvalue" valueString := "testvalue"
bt := NewStandardBuilderTag(exifcommon.IfdPathStandard, it, exifcommon.TestDefaultByteOrder, valueString) bt := NewStandardBuilderTag(exifcommon.IfdStandardIfdIdentity.UnindexedString(), it, exifcommon.TestDefaultByteOrder, valueString)
b := new(bytes.Buffer) b := new(bytes.Buffer)
bw := NewByteWriter(b, exifcommon.TestDefaultByteOrder) bw := NewByteWriter(b, exifcommon.TestDefaultByteOrder)
@ -525,7 +525,7 @@ func Test_IfdByteEncoder_encodeTagToBytes_simpleTag_allocate(t *testing.T) {
t.Fatalf("Child IFD not have been allocated.") t.Fatalf("Child IFD not have been allocated.")
} }
ite, err := ParseOneTag(im, ti, exifcommon.IfdPathStandard, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder, tagBytes) ite, err := ParseOneTag(im, ti, exifcommon.IfdStandardIfdIdentity, exifcommon.TestDefaultByteOrder, tagBytes)
log.PanicIf(err) log.PanicIf(err)
if ite.TagId() != 0x000b { if ite.TagId() != 0x000b {
@ -538,7 +538,7 @@ func Test_IfdByteEncoder_encodeTagToBytes_simpleTag_allocate(t *testing.T) {
t.Fatalf("Tag unit-count not correct: (%d)", ite.UnitCount()) t.Fatalf("Tag unit-count not correct: (%d)", ite.UnitCount())
} else if ite.ChildIfdPath() != "" { } else if ite.ChildIfdPath() != "" {
t.Fatalf("Tag's IFD-name should be empty: [%s]", ite.ChildIfdPath()) t.Fatalf("Tag's IFD-name should be empty: [%s]", ite.ChildIfdPath())
} else if ite.IfdPath() != exifcommon.IfdPathStandard { } else if ite.IfdPath() != exifcommon.IfdStandardIfdIdentity.UnindexedString() {
t.Fatalf("Tag's parent IFD is not correct: %v", ite.IfdPath()) t.Fatalf("Tag's parent IFD is not correct: %v", ite.IfdPath())
} }
@ -729,7 +729,7 @@ func Test_IfdByteEncoder_EncodeToExif_WithChildAndSibling(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
ti := NewTagIndex() ti := NewTagIndex()
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder) ib := NewIfdBuilder(im, ti, exifcommon.IfdStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
err = ib.AddStandard(0x000b, "asciivalue") err = ib.AddStandard(0x000b, "asciivalue")
log.PanicIf(err) log.PanicIf(err)
@ -739,7 +739,7 @@ func Test_IfdByteEncoder_EncodeToExif_WithChildAndSibling(t *testing.T) {
// Add a child IB right in the middle. // Add a child IB right in the middle.
childIb := NewIfdBuilder(im, ti, exifcommon.IfdPathStandardExif, exifcommon.TestDefaultByteOrder) childIb := NewIfdBuilder(im, ti, exifcommon.IfdExifStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
err = childIb.AddStandardWithName("ISOSpeedRatings", []uint16{0x1122}) err = childIb.AddStandardWithName("ISOSpeedRatings", []uint16{0x1122})
log.PanicIf(err) log.PanicIf(err)
@ -756,7 +756,7 @@ func Test_IfdByteEncoder_EncodeToExif_WithChildAndSibling(t *testing.T) {
// Add another child IB, just to ensure a little more punishment and make // Add another child IB, just to ensure a little more punishment and make
// sure we're managing our allocation offsets correctly. // sure we're managing our allocation offsets correctly.
childIb2 := NewIfdBuilder(im, ti, exifcommon.IfdPathStandardGps, exifcommon.TestDefaultByteOrder) childIb2 := NewIfdBuilder(im, ti, exifcommon.IfdGpsInfoStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
err = childIb2.AddStandardWithName("GPSAltitudeRef", []uint8{0x11, 0x22}) err = childIb2.AddStandardWithName("GPSAltitudeRef", []uint8{0x11, 0x22})
log.PanicIf(err) log.PanicIf(err)
@ -770,7 +770,7 @@ func Test_IfdByteEncoder_EncodeToExif_WithChildAndSibling(t *testing.T) {
// Link to another IB (sibling relationship). The root/standard IFD may // Link to another IB (sibling relationship). The root/standard IFD may
// occur twice in some JPEGs (for thumbnail or FlashPix images). // occur twice in some JPEGs (for thumbnail or FlashPix images).
nextIb := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder) nextIb := NewIfdBuilder(im, ti, exifcommon.IfdStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
err = nextIb.AddStandard(0x0101, []uint32{0x11223344}) err = nextIb.AddStandard(0x0101, []uint32{0x11223344})
log.PanicIf(err) log.PanicIf(err)
@ -844,7 +844,7 @@ func ExampleIfdByteEncoder_EncodeToExif() {
log.PanicIf(err) log.PanicIf(err)
ti := NewTagIndex() ti := NewTagIndex()
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder) ib := NewIfdBuilder(im, ti, exifcommon.IfdStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
err = ib.AddStandardWithName("ProcessingSoftware", "asciivalue") err = ib.AddStandardWithName("ProcessingSoftware", "asciivalue")
log.PanicIf(err) log.PanicIf(err)

View File

@ -20,10 +20,10 @@ func TestIfdBuilder_Add(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
ti := NewTagIndex() ti := NewTagIndex()
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder) ib := NewIfdBuilder(im, ti, exifcommon.IfdStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
bt := &BuilderTag{ bt := &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x11, tagId: 0x11,
value: NewIfdBuilderTagValueFromBytes([]byte("test string")), value: NewIfdBuilderTagValueFromBytes([]byte("test string")),
@ -33,7 +33,7 @@ func TestIfdBuilder_Add(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x22, tagId: 0x22,
value: NewIfdBuilderTagValueFromBytes([]byte("test string2")), value: NewIfdBuilderTagValueFromBytes([]byte("test string2")),
@ -43,7 +43,7 @@ func TestIfdBuilder_Add(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x33, tagId: 0x33,
value: NewIfdBuilderTagValueFromBytes([]byte("test string3")), value: NewIfdBuilderTagValueFromBytes([]byte("test string3")),
@ -55,7 +55,7 @@ func TestIfdBuilder_Add(t *testing.T) {
originalBytes := []byte{0x11, 0x22, 0x33} originalBytes := []byte{0x11, 0x22, 0x33}
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x44, tagId: 0x44,
value: NewIfdBuilderTagValueFromBytes([]byte(originalBytes)), value: NewIfdBuilderTagValueFromBytes([]byte(originalBytes)),
@ -64,9 +64,9 @@ func TestIfdBuilder_Add(t *testing.T) {
err = ib.Add(bt) err = ib.Add(bt)
log.PanicIf(err) log.PanicIf(err)
if ib.ifdPath != exifcommon.IfdPathStandard { if ib.ifdIdentity.UnindexedString() != exifcommon.IfdStandardIfdIdentity.UnindexedString() {
t.Fatalf("IFD name not correct.") t.Fatalf("IFD name not correct.")
} else if ib.ifdTagId != 0 { } else if ib.IfdIdentity().TagId() != 0 {
t.Fatalf("IFD tag-ID not correct.") t.Fatalf("IFD tag-ID not correct.")
} else if ib.byteOrder != exifcommon.TestDefaultByteOrder { } else if ib.byteOrder != exifcommon.TestDefaultByteOrder {
t.Fatalf("IFD byte-order not correct.") t.Fatalf("IFD byte-order not correct.")
@ -113,8 +113,8 @@ func TestIfdBuilder_SetNextIb(t *testing.T) {
ti := NewTagIndex() ti := NewTagIndex()
ib1 := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder) ib1 := NewIfdBuilder(im, ti, exifcommon.IfdStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
ib2 := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder) ib2 := NewIfdBuilder(im, ti, exifcommon.IfdStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
if ib1.nextIb != nil { if ib1.nextIb != nil {
t.Fatalf("Next-IFD for IB1 not initially terminal.") t.Fatalf("Next-IFD for IB1 not initially terminal.")
@ -137,10 +137,10 @@ func TestIfdBuilder_AddChildIb(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
ti := NewTagIndex() ti := NewTagIndex()
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder) ib := NewIfdBuilder(im, ti, exifcommon.IfdStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
bt := &BuilderTag{ bt := &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x11, tagId: 0x11,
value: NewIfdBuilderTagValueFromBytes([]byte("test string")), value: NewIfdBuilderTagValueFromBytes([]byte("test string")),
@ -149,12 +149,12 @@ func TestIfdBuilder_AddChildIb(t *testing.T) {
err = ib.Add(bt) err = ib.Add(bt)
log.PanicIf(err) log.PanicIf(err)
ibChild := NewIfdBuilder(im, ti, exifcommon.IfdPathStandardExif, exifcommon.TestDefaultByteOrder) ibChild := NewIfdBuilder(im, ti, exifcommon.IfdExifStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
err = ib.AddChildIb(ibChild) err = ib.AddChildIb(ibChild)
log.PanicIf(err) log.PanicIf(err)
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x22, tagId: 0x22,
value: NewIfdBuilderTagValueFromBytes([]byte("test string")), value: NewIfdBuilderTagValueFromBytes([]byte("test string")),
@ -165,8 +165,8 @@ func TestIfdBuilder_AddChildIb(t *testing.T) {
if ib.tags[0].tagId != 0x11 { if ib.tags[0].tagId != 0x11 {
t.Fatalf("first tag not correct") t.Fatalf("first tag not correct")
} else if ib.tags[1].tagId != ibChild.ifdTagId { } else if ib.tags[1].tagId != ibChild.IfdIdentity().TagId() {
t.Fatalf("second tag ID does not match child-IFD tag-ID: (0x%04x) != (0x%04x)", ib.tags[1].tagId, ibChild.ifdTagId) t.Fatalf("second tag ID does not match child-IFD tag-ID: (0x%04x) != (0x%04x)", ib.tags[1].tagId, ibChild.IfdIdentity().TagId())
} else if ib.tags[1].value.Ib() != ibChild { } else if ib.tags[1].value.Ib() != ibChild {
t.Fatalf("second tagvalue does not match child-IFD") t.Fatalf("second tagvalue does not match child-IFD")
} else if ib.tags[2].tagId != 0x22 { } else if ib.tags[2].tagId != 0x22 {
@ -196,7 +196,7 @@ func TestIfdBuilder_AddTagsFromExisting(t *testing.T) {
_, index, err := Collect(im, ti, exifData) _, index, err := Collect(im, ti, exifData)
log.PanicIf(err) log.PanicIf(err)
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder) ib := NewIfdBuilder(im, ti, exifcommon.IfdStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
err = ib.AddTagsFromExisting(index.RootIfd, nil, nil) err = ib.AddTagsFromExisting(index.RootIfd, nil, nil)
log.PanicIf(err) log.PanicIf(err)
@ -232,7 +232,7 @@ func TestIfdBuilder_AddTagsFromExisting__Includes(t *testing.T) {
_, index, err := Collect(im, ti, exifData) _, index, err := Collect(im, ti, exifData)
log.PanicIf(err) log.PanicIf(err)
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder) ib := NewIfdBuilder(im, ti, exifcommon.IfdStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
err = ib.AddTagsFromExisting(index.RootIfd, []uint16{0x00ff}, nil) err = ib.AddTagsFromExisting(index.RootIfd, []uint16{0x00ff}, nil)
log.PanicIf(err) log.PanicIf(err)
@ -265,7 +265,7 @@ func TestIfdBuilder_AddTagsFromExisting__Excludes(t *testing.T) {
_, index, err := Collect(im, ti, exifData) _, index, err := Collect(im, ti, exifData)
log.PanicIf(err) log.PanicIf(err)
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder) ib := NewIfdBuilder(im, ti, exifcommon.IfdStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
err = ib.AddTagsFromExisting(index.RootIfd, nil, []uint16{0xff}) err = ib.AddTagsFromExisting(index.RootIfd, nil, []uint16{0xff})
log.PanicIf(err) log.PanicIf(err)
@ -294,10 +294,10 @@ func TestIfdBuilder_FindN__First_1(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
ti := NewTagIndex() ti := NewTagIndex()
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder) ib := NewIfdBuilder(im, ti, exifcommon.IfdStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
bt := &BuilderTag{ bt := &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x11, tagId: 0x11,
value: NewIfdBuilderTagValueFromBytes([]byte("test string")), value: NewIfdBuilderTagValueFromBytes([]byte("test string")),
@ -307,7 +307,7 @@ func TestIfdBuilder_FindN__First_1(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x22, tagId: 0x22,
value: NewIfdBuilderTagValueFromBytes([]byte("test string2")), value: NewIfdBuilderTagValueFromBytes([]byte("test string2")),
@ -317,7 +317,7 @@ func TestIfdBuilder_FindN__First_1(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x33, tagId: 0x33,
value: NewIfdBuilderTagValueFromBytes([]byte("test string3")), value: NewIfdBuilderTagValueFromBytes([]byte("test string3")),
@ -350,10 +350,10 @@ func TestIfdBuilder_FindN__First_2_1Returned(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
ti := NewTagIndex() ti := NewTagIndex()
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder) ib := NewIfdBuilder(im, ti, exifcommon.IfdStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
bt := &BuilderTag{ bt := &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x11, tagId: 0x11,
value: NewIfdBuilderTagValueFromBytes([]byte("test string")), value: NewIfdBuilderTagValueFromBytes([]byte("test string")),
@ -363,7 +363,7 @@ func TestIfdBuilder_FindN__First_2_1Returned(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x22, tagId: 0x22,
value: NewIfdBuilderTagValueFromBytes([]byte("test string2")), value: NewIfdBuilderTagValueFromBytes([]byte("test string2")),
@ -373,7 +373,7 @@ func TestIfdBuilder_FindN__First_2_1Returned(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x33, tagId: 0x33,
value: NewIfdBuilderTagValueFromBytes([]byte("test string3")), value: NewIfdBuilderTagValueFromBytes([]byte("test string3")),
@ -406,10 +406,10 @@ func TestIfdBuilder_FindN__First_2_2Returned(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
ti := NewTagIndex() ti := NewTagIndex()
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder) ib := NewIfdBuilder(im, ti, exifcommon.IfdStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
bt := &BuilderTag{ bt := &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x11, tagId: 0x11,
value: NewIfdBuilderTagValueFromBytes([]byte("test string")), value: NewIfdBuilderTagValueFromBytes([]byte("test string")),
@ -419,7 +419,7 @@ func TestIfdBuilder_FindN__First_2_2Returned(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x22, tagId: 0x22,
value: NewIfdBuilderTagValueFromBytes([]byte("test string2")), value: NewIfdBuilderTagValueFromBytes([]byte("test string2")),
@ -429,7 +429,7 @@ func TestIfdBuilder_FindN__First_2_2Returned(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x33, tagId: 0x33,
value: NewIfdBuilderTagValueFromBytes([]byte("test string3")), value: NewIfdBuilderTagValueFromBytes([]byte("test string3")),
@ -439,7 +439,7 @@ func TestIfdBuilder_FindN__First_2_2Returned(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x11, tagId: 0x11,
value: NewIfdBuilderTagValueFromBytes([]byte("test string4")), value: NewIfdBuilderTagValueFromBytes([]byte("test string4")),
@ -449,7 +449,7 @@ func TestIfdBuilder_FindN__First_2_2Returned(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x11, tagId: 0x11,
value: NewIfdBuilderTagValueFromBytes([]byte("test string5")), value: NewIfdBuilderTagValueFromBytes([]byte("test string5")),
@ -489,10 +489,10 @@ func TestIfdBuilder_FindN__Middle_WithDuplicates(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
ti := NewTagIndex() ti := NewTagIndex()
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder) ib := NewIfdBuilder(im, ti, exifcommon.IfdStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
bt := &BuilderTag{ bt := &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x11, tagId: 0x11,
value: NewIfdBuilderTagValueFromBytes([]byte("test string")), value: NewIfdBuilderTagValueFromBytes([]byte("test string")),
@ -502,7 +502,7 @@ func TestIfdBuilder_FindN__Middle_WithDuplicates(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x22, tagId: 0x22,
value: NewIfdBuilderTagValueFromBytes([]byte("test string2")), value: NewIfdBuilderTagValueFromBytes([]byte("test string2")),
@ -512,7 +512,7 @@ func TestIfdBuilder_FindN__Middle_WithDuplicates(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x33, tagId: 0x33,
value: NewIfdBuilderTagValueFromBytes([]byte("test string3")), value: NewIfdBuilderTagValueFromBytes([]byte("test string3")),
@ -522,7 +522,7 @@ func TestIfdBuilder_FindN__Middle_WithDuplicates(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x11, tagId: 0x11,
value: NewIfdBuilderTagValueFromBytes([]byte("test string4")), value: NewIfdBuilderTagValueFromBytes([]byte("test string4")),
@ -532,7 +532,7 @@ func TestIfdBuilder_FindN__Middle_WithDuplicates(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x11, tagId: 0x11,
value: NewIfdBuilderTagValueFromBytes([]byte("test string5")), value: NewIfdBuilderTagValueFromBytes([]byte("test string5")),
@ -542,7 +542,7 @@ func TestIfdBuilder_FindN__Middle_WithDuplicates(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x33, tagId: 0x33,
value: NewIfdBuilderTagValueFromBytes([]byte("test string6")), value: NewIfdBuilderTagValueFromBytes([]byte("test string6")),
@ -575,10 +575,10 @@ func TestIfdBuilder_FindN__Middle_NoDuplicates(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
ti := NewTagIndex() ti := NewTagIndex()
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder) ib := NewIfdBuilder(im, ti, exifcommon.IfdStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
bt := &BuilderTag{ bt := &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x11, tagId: 0x11,
value: NewIfdBuilderTagValueFromBytes([]byte("test string")), value: NewIfdBuilderTagValueFromBytes([]byte("test string")),
@ -588,7 +588,7 @@ func TestIfdBuilder_FindN__Middle_NoDuplicates(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x22, tagId: 0x22,
value: NewIfdBuilderTagValueFromBytes([]byte("test string2")), value: NewIfdBuilderTagValueFromBytes([]byte("test string2")),
@ -598,7 +598,7 @@ func TestIfdBuilder_FindN__Middle_NoDuplicates(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x33, tagId: 0x33,
value: NewIfdBuilderTagValueFromBytes([]byte("test string3")), value: NewIfdBuilderTagValueFromBytes([]byte("test string3")),
@ -608,7 +608,7 @@ func TestIfdBuilder_FindN__Middle_NoDuplicates(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x11, tagId: 0x11,
value: NewIfdBuilderTagValueFromBytes([]byte("test string4")), value: NewIfdBuilderTagValueFromBytes([]byte("test string4")),
@ -641,7 +641,7 @@ func TestIfdBuilder_FindN__Miss(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
ti := NewTagIndex() ti := NewTagIndex()
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder) ib := NewIfdBuilder(im, ti, exifcommon.IfdStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
found, err := ib.FindN(0x11, 1) found, err := ib.FindN(0x11, 1)
log.PanicIf(err) log.PanicIf(err)
@ -658,10 +658,10 @@ func TestIfdBuilder_Find__Hit(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
ti := NewTagIndex() ti := NewTagIndex()
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder) ib := NewIfdBuilder(im, ti, exifcommon.IfdStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
bt := &BuilderTag{ bt := &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x11, tagId: 0x11,
value: NewIfdBuilderTagValueFromBytes([]byte("test string")), value: NewIfdBuilderTagValueFromBytes([]byte("test string")),
@ -671,7 +671,7 @@ func TestIfdBuilder_Find__Hit(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x22, tagId: 0x22,
value: NewIfdBuilderTagValueFromBytes([]byte("test string2")), value: NewIfdBuilderTagValueFromBytes([]byte("test string2")),
@ -681,7 +681,7 @@ func TestIfdBuilder_Find__Hit(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x33, tagId: 0x33,
value: NewIfdBuilderTagValueFromBytes([]byte("test string3")), value: NewIfdBuilderTagValueFromBytes([]byte("test string3")),
@ -691,7 +691,7 @@ func TestIfdBuilder_Find__Hit(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x11, tagId: 0x11,
value: NewIfdBuilderTagValueFromBytes([]byte("test string4")), value: NewIfdBuilderTagValueFromBytes([]byte("test string4")),
@ -722,10 +722,10 @@ func TestIfdBuilder_Find__Miss(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
ti := NewTagIndex() ti := NewTagIndex()
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder) ib := NewIfdBuilder(im, ti, exifcommon.IfdStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
bt := &BuilderTag{ bt := &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x11, tagId: 0x11,
value: NewIfdBuilderTagValueFromBytes([]byte("test string")), value: NewIfdBuilderTagValueFromBytes([]byte("test string")),
@ -735,7 +735,7 @@ func TestIfdBuilder_Find__Miss(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x22, tagId: 0x22,
value: NewIfdBuilderTagValueFromBytes([]byte("test string2")), value: NewIfdBuilderTagValueFromBytes([]byte("test string2")),
@ -745,7 +745,7 @@ func TestIfdBuilder_Find__Miss(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x33, tagId: 0x33,
value: NewIfdBuilderTagValueFromBytes([]byte("test string3")), value: NewIfdBuilderTagValueFromBytes([]byte("test string3")),
@ -755,7 +755,7 @@ func TestIfdBuilder_Find__Miss(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x11, tagId: 0x11,
value: NewIfdBuilderTagValueFromBytes([]byte("test string4")), value: NewIfdBuilderTagValueFromBytes([]byte("test string4")),
@ -779,10 +779,10 @@ func TestIfdBuilder_Replace(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
ti := NewTagIndex() ti := NewTagIndex()
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder) ib := NewIfdBuilder(im, ti, exifcommon.IfdStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
bt := &BuilderTag{ bt := &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x11, tagId: 0x11,
value: NewIfdBuilderTagValueFromBytes([]byte("test string")), value: NewIfdBuilderTagValueFromBytes([]byte("test string")),
@ -792,7 +792,7 @@ func TestIfdBuilder_Replace(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x22, tagId: 0x22,
value: NewIfdBuilderTagValueFromBytes([]byte("test string2")), value: NewIfdBuilderTagValueFromBytes([]byte("test string2")),
@ -802,7 +802,7 @@ func TestIfdBuilder_Replace(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x33, tagId: 0x33,
value: NewIfdBuilderTagValueFromBytes([]byte("test string3")), value: NewIfdBuilderTagValueFromBytes([]byte("test string3")),
@ -821,7 +821,7 @@ func TestIfdBuilder_Replace(t *testing.T) {
} }
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x99, tagId: 0x99,
value: NewIfdBuilderTagValueFromBytes([]byte("test string4")), value: NewIfdBuilderTagValueFromBytes([]byte("test string4")),
@ -847,10 +847,10 @@ func TestIfdBuilder_ReplaceN(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
ti := NewTagIndex() ti := NewTagIndex()
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder) ib := NewIfdBuilder(im, ti, exifcommon.IfdStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
bt := &BuilderTag{ bt := &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x11, tagId: 0x11,
value: NewIfdBuilderTagValueFromBytes([]byte("test string")), value: NewIfdBuilderTagValueFromBytes([]byte("test string")),
@ -860,7 +860,7 @@ func TestIfdBuilder_ReplaceN(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x22, tagId: 0x22,
value: NewIfdBuilderTagValueFromBytes([]byte("test string2")), value: NewIfdBuilderTagValueFromBytes([]byte("test string2")),
@ -870,7 +870,7 @@ func TestIfdBuilder_ReplaceN(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x33, tagId: 0x33,
value: NewIfdBuilderTagValueFromBytes([]byte("test string3")), value: NewIfdBuilderTagValueFromBytes([]byte("test string3")),
@ -889,7 +889,7 @@ func TestIfdBuilder_ReplaceN(t *testing.T) {
} }
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0xA9, tagId: 0xA9,
value: NewIfdBuilderTagValueFromBytes([]byte("test string4")), value: NewIfdBuilderTagValueFromBytes([]byte("test string4")),
@ -915,10 +915,10 @@ func TestIfdBuilder_DeleteFirst(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
ti := NewTagIndex() ti := NewTagIndex()
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder) ib := NewIfdBuilder(im, ti, exifcommon.IfdStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
bt := &BuilderTag{ bt := &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x11, tagId: 0x11,
value: NewIfdBuilderTagValueFromBytes([]byte("test string")), value: NewIfdBuilderTagValueFromBytes([]byte("test string")),
@ -928,7 +928,7 @@ func TestIfdBuilder_DeleteFirst(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x22, tagId: 0x22,
value: NewIfdBuilderTagValueFromBytes([]byte("test string2")), value: NewIfdBuilderTagValueFromBytes([]byte("test string2")),
@ -938,7 +938,7 @@ func TestIfdBuilder_DeleteFirst(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x22, tagId: 0x22,
value: NewIfdBuilderTagValueFromBytes([]byte("test string3")), value: NewIfdBuilderTagValueFromBytes([]byte("test string3")),
@ -948,7 +948,7 @@ func TestIfdBuilder_DeleteFirst(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x33, tagId: 0x33,
value: NewIfdBuilderTagValueFromBytes([]byte("test string4")), value: NewIfdBuilderTagValueFromBytes([]byte("test string4")),
@ -1017,10 +1017,10 @@ func TestIfdBuilder_DeleteN(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
ti := NewTagIndex() ti := NewTagIndex()
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder) ib := NewIfdBuilder(im, ti, exifcommon.IfdStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
bt := &BuilderTag{ bt := &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x11, tagId: 0x11,
value: NewIfdBuilderTagValueFromBytes([]byte("test string")), value: NewIfdBuilderTagValueFromBytes([]byte("test string")),
@ -1030,7 +1030,7 @@ func TestIfdBuilder_DeleteN(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x22, tagId: 0x22,
value: NewIfdBuilderTagValueFromBytes([]byte("test string2")), value: NewIfdBuilderTagValueFromBytes([]byte("test string2")),
@ -1040,7 +1040,7 @@ func TestIfdBuilder_DeleteN(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x22, tagId: 0x22,
value: NewIfdBuilderTagValueFromBytes([]byte("test string3")), value: NewIfdBuilderTagValueFromBytes([]byte("test string3")),
@ -1050,7 +1050,7 @@ func TestIfdBuilder_DeleteN(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x33, tagId: 0x33,
value: NewIfdBuilderTagValueFromBytes([]byte("test string4")), value: NewIfdBuilderTagValueFromBytes([]byte("test string4")),
@ -1119,10 +1119,10 @@ func TestIfdBuilder_DeleteN_Two(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
ti := NewTagIndex() ti := NewTagIndex()
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder) ib := NewIfdBuilder(im, ti, exifcommon.IfdStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
bt := &BuilderTag{ bt := &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x11, tagId: 0x11,
value: NewIfdBuilderTagValueFromBytes([]byte("test string")), value: NewIfdBuilderTagValueFromBytes([]byte("test string")),
@ -1132,7 +1132,7 @@ func TestIfdBuilder_DeleteN_Two(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x22, tagId: 0x22,
value: NewIfdBuilderTagValueFromBytes([]byte("test string2")), value: NewIfdBuilderTagValueFromBytes([]byte("test string2")),
@ -1142,7 +1142,7 @@ func TestIfdBuilder_DeleteN_Two(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x22, tagId: 0x22,
value: NewIfdBuilderTagValueFromBytes([]byte("test string3")), value: NewIfdBuilderTagValueFromBytes([]byte("test string3")),
@ -1152,7 +1152,7 @@ func TestIfdBuilder_DeleteN_Two(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x33, tagId: 0x33,
value: NewIfdBuilderTagValueFromBytes([]byte("test string4")), value: NewIfdBuilderTagValueFromBytes([]byte("test string4")),
@ -1205,10 +1205,10 @@ func TestIfdBuilder_DeleteAll(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
ti := NewTagIndex() ti := NewTagIndex()
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder) ib := NewIfdBuilder(im, ti, exifcommon.IfdStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
bt := &BuilderTag{ bt := &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x11, tagId: 0x11,
value: NewIfdBuilderTagValueFromBytes([]byte("test string")), value: NewIfdBuilderTagValueFromBytes([]byte("test string")),
@ -1218,7 +1218,7 @@ func TestIfdBuilder_DeleteAll(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x22, tagId: 0x22,
value: NewIfdBuilderTagValueFromBytes([]byte("test string2")), value: NewIfdBuilderTagValueFromBytes([]byte("test string2")),
@ -1228,7 +1228,7 @@ func TestIfdBuilder_DeleteAll(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x22, tagId: 0x22,
value: NewIfdBuilderTagValueFromBytes([]byte("test string3")), value: NewIfdBuilderTagValueFromBytes([]byte("test string3")),
@ -1238,7 +1238,7 @@ func TestIfdBuilder_DeleteAll(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
bt = &BuilderTag{ bt = &BuilderTag{
ifdPath: exifcommon.IfdPathStandard, ifdPath: exifcommon.IfdStandardIfdIdentity.UnindexedString(),
typeId: exifcommon.TypeByte, typeId: exifcommon.TypeByte,
tagId: 0x33, tagId: 0x33,
value: NewIfdBuilderTagValueFromBytes([]byte("test string4")), value: NewIfdBuilderTagValueFromBytes([]byte("test string4")),
@ -1413,7 +1413,7 @@ func TestIfdBuilder_SetStandardWithName_UpdateGps(t *testing.T) {
rootIfd := index.RootIfd rootIfd := index.RootIfd
gpsIfd, err := rootIfd.ChildWithIfdPath(exifcommon.IfdPathStandardGps) gpsIfd, err := rootIfd.ChildWithIfdPath(exifcommon.IfdGpsInfoStandardIfdIdentity)
log.PanicIf(err) log.PanicIf(err)
initialGi, err := gpsIfd.GpsInfo() initialGi, err := gpsIfd.GpsInfo()
@ -1429,7 +1429,7 @@ func TestIfdBuilder_SetStandardWithName_UpdateGps(t *testing.T) {
rootIb := NewIfdBuilderFromExistingChain(rootIfd) rootIb := NewIfdBuilderFromExistingChain(rootIfd)
gpsIb, err := rootIb.ChildWithTagId(exifcommon.IfdGpsId) gpsIb, err := rootIb.ChildWithTagId(exifcommon.IfdGpsInfoStandardIfdIdentity.TagId())
log.PanicIf(err) log.PanicIf(err)
updatedGi := GpsDegrees{ updatedGi := GpsDegrees{
@ -1459,7 +1459,7 @@ func TestIfdBuilder_SetStandardWithName_UpdateGps(t *testing.T) {
// Test. // Test.
updatedGpsIfd, err := updatedRootIfd.ChildWithIfdPath(exifcommon.IfdPathStandardGps) updatedGpsIfd, err := updatedRootIfd.ChildWithIfdPath(exifcommon.IfdGpsInfoStandardIfdIdentity)
log.PanicIf(err) log.PanicIf(err)
recoveredUpdatedGi, err := updatedGpsIfd.GpsInfo() recoveredUpdatedGi, err := updatedGpsIfd.GpsInfo()
@ -1492,7 +1492,7 @@ func ExampleIfdBuilder_SetStandardWithName_updateGps() {
rootIfd := index.RootIfd rootIfd := index.RootIfd
gpsIfd, err := rootIfd.ChildWithIfdPath(exifcommon.IfdPathStandardGps) gpsIfd, err := rootIfd.ChildWithIfdPath(exifcommon.IfdGpsInfoStandardIfdIdentity)
log.PanicIf(err) log.PanicIf(err)
initialGi, err := gpsIfd.GpsInfo() initialGi, err := gpsIfd.GpsInfo()
@ -1504,7 +1504,7 @@ func ExampleIfdBuilder_SetStandardWithName_updateGps() {
rootIb := NewIfdBuilderFromExistingChain(rootIfd) rootIb := NewIfdBuilderFromExistingChain(rootIfd)
gpsIb, err := rootIb.ChildWithTagId(exifcommon.IfdGpsId) gpsIb, err := rootIb.ChildWithTagId(exifcommon.IfdGpsInfoStandardIfdIdentity.TagId())
log.PanicIf(err) log.PanicIf(err)
updatedGi := GpsDegrees{ updatedGi := GpsDegrees{
@ -1534,7 +1534,7 @@ func ExampleIfdBuilder_SetStandardWithName_updateGps() {
// Test. // Test.
updatedGpsIfd, err := updatedRootIfd.ChildWithIfdPath(exifcommon.IfdPathStandardGps) updatedGpsIfd, err := updatedRootIfd.ChildWithIfdPath(exifcommon.IfdGpsInfoStandardIfdIdentity)
log.PanicIf(err) log.PanicIf(err)
recoveredUpdatedGi, err := updatedGpsIfd.GpsInfo() recoveredUpdatedGi, err := updatedGpsIfd.GpsInfo()
@ -2013,21 +2013,21 @@ func TestIfdBuilder_CreateIfdBuilderWithExistingIfd(t *testing.T) {
err := LoadStandardIfds(im) err := LoadStandardIfds(im)
log.PanicIf(err) log.PanicIf(err)
mi, err := im.GetWithPath(exifcommon.IfdPathStandardGps) mi, err := im.GetWithPath(exifcommon.IfdGpsInfoStandardIfdIdentity.UnindexedString())
log.PanicIf(err) log.PanicIf(err)
tagId := mi.TagId tagId := mi.TagId
parentIfd := &Ifd{ parentIfd := &Ifd{
IfdPath: exifcommon.IfdPathStandard, ifdIdentity: exifcommon.IfdStandardIfdIdentity,
tagIndex: ti, tagIndex: ti,
} }
ifd := &Ifd{ ifd := &Ifd{
IfdPath: exifcommon.IfdPathStandardGps, ifdIdentity: exifcommon.IfdGpsInfoStandardIfdIdentity,
ByteOrder: exifcommon.TestDefaultByteOrder, ByteOrder: exifcommon.TestDefaultByteOrder,
Offset: 0x123, Offset: 0x123,
ParentIfd: parentIfd, ParentIfd: parentIfd,
ifdMapping: im, ifdMapping: im,
tagIndex: ti, tagIndex: ti,
@ -2035,9 +2035,9 @@ func TestIfdBuilder_CreateIfdBuilderWithExistingIfd(t *testing.T) {
ib := NewIfdBuilderWithExistingIfd(ifd) ib := NewIfdBuilderWithExistingIfd(ifd)
if ib.ifdPath != ifd.IfdPath { if ib.IfdIdentity().UnindexedString() != ifd.ifdIdentity.UnindexedString() {
t.Fatalf("IFD-name not correct.") t.Fatalf("IFD-name not correct.")
} else if ib.ifdTagId != tagId { } else if ib.IfdIdentity().TagId() != tagId {
t.Fatalf("IFD tag-ID not correct.") t.Fatalf("IFD tag-ID not correct.")
} else if ib.byteOrder != ifd.ByteOrder { } else if ib.byteOrder != ifd.ByteOrder {
t.Fatalf("IFD byte-order not correct.") t.Fatalf("IFD byte-order not correct.")
@ -2049,12 +2049,12 @@ func TestIfdBuilder_CreateIfdBuilderWithExistingIfd(t *testing.T) {
func TestNewStandardBuilderTag__OneUnit(t *testing.T) { func TestNewStandardBuilderTag__OneUnit(t *testing.T) {
ti := NewTagIndex() ti := NewTagIndex()
it, err := ti.Get(exifcommon.IfdPathStandardExif, uint16(0x8833)) it, err := ti.Get(exifcommon.IfdExifStandardIfdIdentity.UnindexedString(), uint16(0x8833))
log.PanicIf(err) log.PanicIf(err)
bt := NewStandardBuilderTag(exifcommon.IfdPathStandardExif, it, exifcommon.TestDefaultByteOrder, []uint32{uint32(0x1234)}) bt := NewStandardBuilderTag(exifcommon.IfdExifStandardIfdIdentity.UnindexedString(), it, exifcommon.TestDefaultByteOrder, []uint32{uint32(0x1234)})
if bt.ifdPath != exifcommon.IfdPathStandardExif { if bt.ifdPath != exifcommon.IfdExifStandardIfdIdentity.UnindexedString() {
t.Fatalf("II in BuilderTag not correct") t.Fatalf("II in BuilderTag not correct")
} else if bt.tagId != 0x8833 { } else if bt.tagId != 0x8833 {
t.Fatalf("tag-ID not correct") t.Fatalf("tag-ID not correct")
@ -2066,12 +2066,12 @@ func TestNewStandardBuilderTag__OneUnit(t *testing.T) {
func TestNewStandardBuilderTag__TwoUnits(t *testing.T) { func TestNewStandardBuilderTag__TwoUnits(t *testing.T) {
ti := NewTagIndex() ti := NewTagIndex()
it, err := ti.Get(exifcommon.IfdPathStandardExif, uint16(0x8833)) it, err := ti.Get(exifcommon.IfdExifStandardIfdIdentity.UnindexedString(), uint16(0x8833))
log.PanicIf(err) log.PanicIf(err)
bt := NewStandardBuilderTag(exifcommon.IfdPathStandardExif, it, exifcommon.TestDefaultByteOrder, []uint32{uint32(0x1234), uint32(0x5678)}) bt := NewStandardBuilderTag(exifcommon.IfdExifStandardIfdIdentity.UnindexedString(), it, exifcommon.TestDefaultByteOrder, []uint32{uint32(0x1234), uint32(0x5678)})
if bt.ifdPath != exifcommon.IfdPathStandardExif { if bt.ifdPath != exifcommon.IfdExifStandardIfdIdentity.UnindexedString() {
t.Fatalf("II in BuilderTag not correct") t.Fatalf("II in BuilderTag not correct")
} else if bt.tagId != 0x8833 { } else if bt.tagId != 0x8833 {
t.Fatalf("tag-ID not correct") t.Fatalf("tag-ID not correct")
@ -2089,7 +2089,7 @@ func TestIfdBuilder_AddStandardWithName(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
ti := NewTagIndex() ti := NewTagIndex()
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder) ib := NewIfdBuilder(im, ti, exifcommon.IfdStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
err = ib.AddStandardWithName("ProcessingSoftware", "some software") err = ib.AddStandardWithName("ProcessingSoftware", "some software")
log.PanicIf(err) log.PanicIf(err)
@ -2100,7 +2100,7 @@ func TestIfdBuilder_AddStandardWithName(t *testing.T) {
bt := ib.tags[0] bt := ib.tags[0]
if bt.ifdPath != exifcommon.IfdPathStandard { if bt.ifdPath != exifcommon.IfdStandardIfdIdentity.UnindexedString() {
t.Fatalf("II not correct: %s", bt.ifdPath) t.Fatalf("II not correct: %s", bt.ifdPath)
} else if bt.tagId != 0x000b { } else if bt.tagId != 0x000b {
t.Fatalf("Tag-ID not correct: (0x%04x)", bt.tagId) t.Fatalf("Tag-ID not correct: (0x%04x)", bt.tagId)
@ -2120,7 +2120,7 @@ func TestGetOrCreateIbFromRootIb__Noop(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
ti := NewTagIndex() ti := NewTagIndex()
rootIb := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder) rootIb := NewIfdBuilder(im, ti, exifcommon.IfdStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
ib, err := GetOrCreateIbFromRootIb(rootIb, "IFD") ib, err := GetOrCreateIbFromRootIb(rootIb, "IFD")
log.PanicIf(err) log.PanicIf(err)
@ -2141,7 +2141,7 @@ func TestGetOrCreateIbFromRootIb__FqNoop(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
ti := NewTagIndex() ti := NewTagIndex()
rootIb := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder) rootIb := NewIfdBuilder(im, ti, exifcommon.IfdStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
ib, err := GetOrCreateIbFromRootIb(rootIb, "IFD0") ib, err := GetOrCreateIbFromRootIb(rootIb, "IFD0")
log.PanicIf(err) log.PanicIf(err)
@ -2162,7 +2162,7 @@ func TestGetOrCreateIbFromRootIb_InvalidChild(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
ti := NewTagIndex() ti := NewTagIndex()
rootIb := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder) rootIb := NewIfdBuilder(im, ti, exifcommon.IfdStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
_, err = GetOrCreateIbFromRootIb(rootIb, "IFD/Invalid") _, err = GetOrCreateIbFromRootIb(rootIb, "IFD/Invalid")
if err == nil { if err == nil {
@ -2186,7 +2186,7 @@ func TestGetOrCreateIbFromRootIb__Child(t *testing.T) {
log.PanicIf(err) log.PanicIf(err)
ti := NewTagIndex() ti := NewTagIndex()
rootIb := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder) rootIb := NewIfdBuilder(im, ti, exifcommon.IfdStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
lines := rootIb.DumpToStrings() lines := rootIb.DumpToStrings()
expected := []string{ expected := []string{
@ -2218,7 +2218,7 @@ func TestGetOrCreateIbFromRootIb__Child(t *testing.T) {
ib, err := GetOrCreateIbFromRootIb(rootIb, "IFD/Exif") ib, err := GetOrCreateIbFromRootIb(rootIb, "IFD/Exif")
log.PanicIf(err) log.PanicIf(err)
if ib.fqIfdPath != "IFD/Exif" { if ib.IfdIdentity().String() != "IFD/Exif" {
t.Fatalf("Returned IB does not have the expected path (IFD/Exif).") t.Fatalf("Returned IB does not have the expected path (IFD/Exif).")
} }
@ -2254,7 +2254,7 @@ func TestGetOrCreateIbFromRootIb__Child(t *testing.T) {
ib, err = GetOrCreateIbFromRootIb(rootIb, "IFD0/Exif/Iop") ib, err = GetOrCreateIbFromRootIb(rootIb, "IFD0/Exif/Iop")
log.PanicIf(err) log.PanicIf(err)
if ib.fqIfdPath != "IFD/Exif/Iop" { if ib.IfdIdentity().String() != "IFD/Exif/Iop" {
t.Fatalf("Returned IB does not have the expected path (IFD/Exif/Iop).") t.Fatalf("Returned IB does not have the expected path (IFD/Exif/Iop).")
} }
@ -2292,7 +2292,7 @@ func TestGetOrCreateIbFromRootIb__Child(t *testing.T) {
ib, err = GetOrCreateIbFromRootIb(rootIb, "IFD1") ib, err = GetOrCreateIbFromRootIb(rootIb, "IFD1")
log.PanicIf(err) log.PanicIf(err)
if ib.fqIfdPath != "IFD1" { if ib.IfdIdentity().String() != "IFD1" {
t.Fatalf("Returned IB does not have the expected path (IFD1).") t.Fatalf("Returned IB does not have the expected path (IFD1).")
} }

View File

@ -210,7 +210,7 @@ func (ie *IfdEnumerate) getByteParser(ifdOffset uint32) (bp *byteParser, err err
return bp, nil return bp, nil
} }
func (ie *IfdEnumerate) parseTag(fqIfdPath string, tagPosition int, bp *byteParser) (ite *IfdTagEntry, err error) { func (ie *IfdEnumerate) parseTag(ii *exifcommon.IfdIdentity, tagPosition int, bp *byteParser) (ite *IfdTagEntry, err error) {
defer func() { defer func() {
if state := recover(); state != nil { if state := recover(); state != nil {
err = log.Wrap(state.(error)) err = log.Wrap(state.(error))
@ -240,11 +240,8 @@ func (ie *IfdEnumerate) parseTag(fqIfdPath string, tagPosition int, bp *bytePars
log.Panic(ErrTagTypeNotValid) log.Panic(ErrTagTypeNotValid)
} }
ifdPath, err := ie.ifdMapping.StripPathPhraseIndices(fqIfdPath)
log.PanicIf(err)
ite = newIfdTagEntry( ite = newIfdTagEntry(
fqIfdPath, ii,
tagId, tagId,
tagPosition, tagPosition,
tagType, tagType,
@ -254,15 +251,18 @@ func (ie *IfdEnumerate) parseTag(fqIfdPath string, tagPosition int, bp *bytePars
ie.exifData[ExifAddressableAreaStart:], ie.exifData[ExifAddressableAreaStart:],
ie.byteOrder) ie.byteOrder)
ifdPath := ii.UnindexedString()
// If it's an IFD but not a standard one, it'll just be seen as a LONG // If it's an IFD but not a standard one, it'll just be seen as a LONG
// (the standard IFD tag type), later, unless we skip it because it's // (the standard IFD tag type), later, unless we skip it because it's
// [likely] not even in the standard list of known tags. // [likely] not even in the standard list of known tags.
mi, err := ie.ifdMapping.GetChild(ifdPath, tagId) mi, err := ie.ifdMapping.GetChild(ifdPath, tagId)
if err == nil { if err == nil {
ite.SetChildIfd( currentIfdTag := ii.IfdTag()
fmt.Sprintf("%s/%s", fqIfdPath, mi.Name),
mi.PathPhrase(), childIt := exifcommon.NewIfdTag(&currentIfdTag, tagId, mi.Name)
mi.Name) iiChild := ii.NewChild(childIt, 0)
ite.SetChildIfd(iiChild)
// We also need to set `tag.ChildFqIfdPath` but can't do it here // We also need to set `tag.ChildFqIfdPath` but can't do it here
// because we don't have the IFD index. // because we don't have the IFD index.
@ -278,7 +278,7 @@ type TagVisitorFn func(fqIfdPath string, ifdIndex int, ite *IfdTagEntry) (err er
// parseIfd decodes the IFD block that we're currently sitting on the first // parseIfd decodes the IFD block that we're currently sitting on the first
// byte of. // byte of.
func (ie *IfdEnumerate) parseIfd(fqIfdPath string, ifdIndex int, bp *byteParser, visitor TagVisitorFn, doDescend bool) (nextIfdOffset uint32, entries []*IfdTagEntry, thumbnailData []byte, err error) { func (ie *IfdEnumerate) parseIfd(ii *exifcommon.IfdIdentity, bp *byteParser, visitor TagVisitorFn, doDescend bool) (nextIfdOffset uint32, entries []*IfdTagEntry, thumbnailData []byte, err error) {
defer func() { defer func() {
if state := recover(); state != nil { if state := recover(); state != nil {
err = log.Wrap(state.(error)) err = log.Wrap(state.(error))
@ -288,7 +288,7 @@ func (ie *IfdEnumerate) parseIfd(fqIfdPath string, ifdIndex int, bp *byteParser,
tagCount, _, err := bp.getUint16() tagCount, _, err := bp.getUint16()
log.PanicIf(err) log.PanicIf(err)
ifdEnumerateLogger.Debugf(nil, "IFD [%s] tag-count: (%d)", fqIfdPath, tagCount) ifdEnumerateLogger.Debugf(nil, "IFD [%s] tag-count: (%d)", ii.String(), tagCount)
entries = make([]*IfdTagEntry, 0) entries = make([]*IfdTagEntry, 0)
@ -296,27 +296,23 @@ func (ie *IfdEnumerate) parseIfd(fqIfdPath string, ifdIndex int, bp *byteParser,
var enumeratorThumbnailSize *IfdTagEntry var enumeratorThumbnailSize *IfdTagEntry
for i := 0; i < int(tagCount); i++ { for i := 0; i < int(tagCount); i++ {
ite, err := ie.parseTag(fqIfdPath, i, bp) ite, err := ie.parseTag(ii, i, bp)
if err != nil { if err != nil {
if log.Is(err, ErrTagTypeNotValid) == true { if log.Is(err, ErrTagTypeNotValid) == true {
// Technically, we have the type on-file in the tags-index, but // Technically, we have the type on-file in the tags-index, but
// if the type stored alongside the data disagrees with it, // if the type stored alongside the data disagrees with it,
// which it apparently does, all bets are off. // which it apparently does, all bets are off.
ifdEnumerateLogger.Warningf(nil, "Tag (0x%04x) in IFD [%s] at position (%d) has invalid type (%d) and will be skipped.", ite.tagId, fqIfdPath, i, ite.tagType) ifdEnumerateLogger.Warningf(nil, "Tag (0x%04x) in IFD [%s] at position (%d) has invalid type (%d) and will be skipped.", ite.tagId, ii, i, ite.tagType)
continue continue
} }
log.Panic(err) log.Panic(err)
} }
// TODO(dustin): This is inefficient. Our IFD paths should have their own type where we can render whatever path we need.
ifdPath, err := ie.ifdMapping.StripPathPhraseIndices(fqIfdPath)
log.PanicIf(err)
tagId := ite.TagId() tagId := ite.TagId()
tagType := ite.TagType() tagType := ite.TagType()
it, err := ie.tagIndex.Get(ifdPath, tagId) it, err := ie.tagIndex.Get(ii.UnindexedString(), tagId)
if err == nil { if err == nil {
// This is a known tag (from the standard, unless the user did // This is a known tag (from the standard, unless the user did
// something different). // something different).
@ -332,7 +328,7 @@ func (ie *IfdEnumerate) parseIfd(fqIfdPath string, ifdIndex int, bp *byteParser,
if it.DoesSupportType(tagType) == false { if it.DoesSupportType(tagType) == false {
ifdEnumerateLogger.Warningf(nil, ifdEnumerateLogger.Warningf(nil,
"Skipping tag [%s] (0x%04x) [%s] with an unexpected type: %v ∉ %v", "Skipping tag [%s] (0x%04x) [%s] with an unexpected type: %v ∉ %v",
ifdPath, tagId, it.Name, ii.UnindexedString(), tagId, it.Name,
tagType, it.SupportedTypes) tagType, it.SupportedTypes)
continue continue
@ -342,7 +338,7 @@ func (ie *IfdEnumerate) parseIfd(fqIfdPath string, ifdIndex int, bp *byteParser,
} }
if visitor != nil { if visitor != nil {
err := visitor(fqIfdPath, ifdIndex, ite) err := visitor(ii.String(), ii.Index(), ite)
log.PanicIf(err) log.PanicIf(err)
} }
@ -384,12 +380,22 @@ func (ie *IfdEnumerate) parseIfd(fqIfdPath string, ifdIndex int, bp *byteParser,
// [likely] not even in the standard list of known tags. // [likely] not even in the standard list of known tags.
if ite.ChildIfdPath() != "" { if ite.ChildIfdPath() != "" {
if doDescend == true { if doDescend == true {
ifdEnumerateLogger.Debugf(nil, "Descending from IFD [%s] to IFD [%s].", fqIfdPath, ite.ChildIfdPath()) ifdEnumerateLogger.Debugf(nil, "Descending from IFD [%s] to IFD [%s].", ii, ite.ChildIfdPath())
err := ie.scan(ite.ChildFqIfdPath(), ite.getValueOffset(), visitor) currentIfdTag := ii.IfdTag()
childIfdTag :=
exifcommon.NewIfdTag(
&currentIfdTag,
ite.TagId(),
ite.ChildIfdName())
iiChild := ii.NewChild(childIfdTag, 0)
err := ie.scan(iiChild, ite.getValueOffset(), visitor)
log.PanicIf(err) log.PanicIf(err)
ifdEnumerateLogger.Debugf(nil, "Ascending from IFD [%s] to IFD [%s].", ite.ChildIfdPath(), fqIfdPath) ifdEnumerateLogger.Debugf(nil, "Ascending from IFD [%s] to IFD [%s].", ite.ChildIfdPath(), ii)
} }
} }
@ -406,7 +412,7 @@ func (ie *IfdEnumerate) parseIfd(fqIfdPath string, ifdIndex int, bp *byteParser,
// This this case, the value is always a length. // This this case, the value is always a length.
length := enumeratorThumbnailSize.getValueOffset() length := enumeratorThumbnailSize.getValueOffset()
ifdEnumerateLogger.Debugf(nil, "Found thumbnail in IFD [%s]. Its offset is (%d) and is (%d) bytes.", fqIfdPath, offset, length) ifdEnumerateLogger.Debugf(nil, "Found thumbnail in IFD [%s]. Its offset is (%d) and is (%d) bytes.", ii, offset, length)
furthestOffset := offset + length furthestOffset := offset + length
@ -452,7 +458,7 @@ func (ie *IfdEnumerate) parseThumbnail(offsetIte, lengthIte *IfdTagEntry) (thumb
// scan parses and enumerates the different IFD blocks and invokes a visitor // scan parses and enumerates the different IFD blocks and invokes a visitor
// callback for each tag. No information is kept or returned. // callback for each tag. No information is kept or returned.
func (ie *IfdEnumerate) scan(ifdName string, ifdOffset uint32, visitor TagVisitorFn) (err error) { func (ie *IfdEnumerate) scan(iiGeneral *exifcommon.IfdIdentity, ifdOffset uint32, visitor TagVisitorFn) (err error) {
defer func() { defer func() {
if state := recover(); state != nil { if state := recover(); state != nil {
err = log.Wrap(state.(error)) err = log.Wrap(state.(error))
@ -462,21 +468,21 @@ func (ie *IfdEnumerate) scan(ifdName string, ifdOffset uint32, visitor TagVisito
// TODO(dustin): Add test // TODO(dustin): Add test
for ifdIndex := 0; ; ifdIndex++ { for ifdIndex := 0; ; ifdIndex++ {
fqIfdPath := FqIfdPath("", ifdName, ifdIndex) iiSibling := iiGeneral.NewSibling(ifdIndex)
ifdEnumerateLogger.Debugf(nil, "Parsing IFD [%s] at offset (0x%04x) (scan).", fqIfdPath, ifdOffset) ifdEnumerateLogger.Debugf(nil, "Parsing IFD [%s] at offset (0x%04x) (scan).", iiSibling.String(), ifdOffset)
bp, err := ie.getByteParser(ifdOffset) bp, err := ie.getByteParser(ifdOffset)
if err != nil { if err != nil {
if err == ErrOffsetInvalid { if err == ErrOffsetInvalid {
ifdEnumerateLogger.Errorf(nil, nil, "IFD [%s] at offset (0x%04x) is unreachable. Terminating scan.", fqIfdPath, ifdOffset) ifdEnumerateLogger.Errorf(nil, nil, "IFD [%s] at offset (0x%04x) is unreachable. Terminating scan.", iiSibling.String(), ifdOffset)
break break
} }
log.Panic(err) log.Panic(err)
} }
nextIfdOffset, _, _, err := ie.parseIfd(fqIfdPath, ifdIndex, bp, visitor, true) nextIfdOffset, _, _, err := ie.parseIfd(iiSibling, bp, visitor, true)
log.PanicIf(err) log.PanicIf(err)
currentOffset := bp.CurrentOffset() currentOffset := bp.CurrentOffset()
@ -496,7 +502,7 @@ func (ie *IfdEnumerate) scan(ifdName string, ifdOffset uint32, visitor TagVisito
// Scan enumerates the different EXIF blocks (called IFDs). `rootIfdName` will // Scan enumerates the different EXIF blocks (called IFDs). `rootIfdName` will
// be "IFD" in the TIFF standard. // be "IFD" in the TIFF standard.
func (ie *IfdEnumerate) Scan(rootIfdName string, ifdOffset uint32, visitor TagVisitorFn) (err error) { func (ie *IfdEnumerate) Scan(rootIi *exifcommon.IfdIdentity, ifdOffset uint32, visitor TagVisitorFn) (err error) {
defer func() { defer func() {
if state := recover(); state != nil { if state := recover(); state != nil {
err = log.Wrap(state.(error)) err = log.Wrap(state.(error))
@ -505,7 +511,7 @@ func (ie *IfdEnumerate) Scan(rootIfdName string, ifdOffset uint32, visitor TagVi
// TODO(dustin): Add test // TODO(dustin): Add test
err = ie.scan(rootIfdName, ifdOffset, visitor) err = ie.scan(rootIi, ifdOffset, visitor)
log.PanicIf(err) log.PanicIf(err)
ifdEnumerateLogger.Debugf(nil, "Scan: It looks like the furthest offset that contained EXIF data in the EXIF blob was (%d) (Scan).", ie.FurthestOffset()) ifdEnumerateLogger.Debugf(nil, "Scan: It looks like the furthest offset that contained EXIF data in the EXIF blob was (%d) (Scan).", ie.FurthestOffset())
@ -519,21 +525,10 @@ type Ifd struct {
// TODO(dustin): !! Why are all of these exported? Stop doing this in the next release. // TODO(dustin): !! Why are all of these exported? Stop doing this in the next release.
// TODO(dustin): Add NextIfd(). // TODO(dustin): Add NextIfd().
ifdIdentity *exifcommon.IfdIdentity
ByteOrder binary.ByteOrder ByteOrder binary.ByteOrder
// Name is the name of the IFD (the rightmost name in the path, sans any
// indices).
Name string
// IfdPath is a simple IFD path (e.g. IFD/GPSInfo). No indices.
IfdPath string
// FqIfdPath is a fully-qualified IFD path (e.g. IFD0/GPSInfo0). With
// indices.
FqIfdPath string
TagId uint16
Id int Id int
ParentIfd *Ifd ParentIfd *Ifd
@ -543,8 +538,6 @@ type Ifd struct {
// instead of as a child). // instead of as a child).
ParentTagIndex int ParentTagIndex int
// Name string
Index int
Offset uint32 Offset uint32
Entries []*IfdTagEntry Entries []*IfdTagEntry
@ -563,17 +556,25 @@ type Ifd struct {
tagIndex *TagIndex tagIndex *TagIndex
} }
// IfdIdentity returns IFD identity that this struct represents.
func (ifd *Ifd) IfdIdentity() *exifcommon.IfdIdentity {
return ifd.ifdIdentity
}
// ChildWithIfdPath returns an `Ifd` struct for the given child of the current // ChildWithIfdPath returns an `Ifd` struct for the given child of the current
// IFD. // IFD.
func (ifd *Ifd) ChildWithIfdPath(ifdPath string) (childIfd *Ifd, err error) { func (ifd *Ifd) ChildWithIfdPath(iiChild *exifcommon.IfdIdentity) (childIfd *Ifd, err error) {
defer func() { defer func() {
if state := recover(); state != nil { if state := recover(); state != nil {
err = log.Wrap(state.(error)) err = log.Wrap(state.(error))
} }
}() }()
// TODO(dustin): This is a bridge while we're introducing the IFD type-system. We should be able to use the (IfdIdentity).Equals() method for this.
ifdPath := iiChild.UnindexedString()
for _, childIfd := range ifd.Children { for _, childIfd := range ifd.Children {
if childIfd.IfdPath == ifdPath { if childIfd.ifdIdentity.UnindexedString() == ifdPath {
return childIfd, nil return childIfd, nil
} }
} }
@ -608,7 +609,7 @@ func (ifd *Ifd) FindTagWithName(tagName string) (results []*IfdTagEntry, err err
} }
}() }()
it, err := ifd.tagIndex.GetWithName(ifd.IfdPath, tagName) it, err := ifd.tagIndex.GetWithName(ifd.ifdIdentity.UnindexedString(), tagName)
if log.Is(err, ErrTagNotFound) == true { if log.Is(err, ErrTagNotFound) == true {
log.Panic(ErrTagNotStandard) log.Panic(ErrTagNotStandard)
} else if err != nil { } else if err != nil {
@ -636,7 +637,7 @@ func (ifd *Ifd) String() string {
parentOffset = ifd.ParentIfd.Offset parentOffset = ifd.ParentIfd.Offset
} }
return fmt.Sprintf("Ifd<ID=(%d) IFD-PATH=[%s] INDEX=(%d) COUNT=(%d) OFF=(0x%04x) CHILDREN=(%d) PARENT=(0x%04x) NEXT-IFD=(0x%04x)>", ifd.Id, ifd.IfdPath, ifd.Index, len(ifd.Entries), ifd.Offset, len(ifd.Children), parentOffset, ifd.NextIfdOffset) return fmt.Sprintf("Ifd<ID=(%d) IFD-PATH=[%s] INDEX=(%d) COUNT=(%d) OFF=(0x%04x) CHILDREN=(%d) PARENT=(0x%04x) NEXT-IFD=(0x%04x)>", ifd.Id, ifd.ifdIdentity.UnindexedString(), ifd.ifdIdentity.Index(), len(ifd.Entries), ifd.Offset, len(ifd.Children), parentOffset, ifd.NextIfdOffset)
} }
// Thumbnail returns the raw thumbnail bytes. This is typically directly // Thumbnail returns the raw thumbnail bytes. This is typically directly
@ -716,7 +717,7 @@ func (ifd *Ifd) printTagTree(populateValues bool, index, level int, nextLink boo
continue continue
} }
it, err := ifd.tagIndex.Get(ifd.IfdPath, ite.TagId()) it, err := ifd.tagIndex.Get(ifd.ifdIdentity.UnindexedString(), ite.TagId())
tagName := "" tagName := ""
if err == nil { if err == nil {
@ -730,10 +731,10 @@ func (ifd *Ifd) printTagTree(populateValues bool, index, level int, nextLink boo
valuePhrase, err = ite.Format() valuePhrase, err = ite.Format()
if err != nil { if err != nil {
if log.Is(err, exifcommon.ErrUnhandledUndefinedTypedTag) == true { if log.Is(err, exifcommon.ErrUnhandledUndefinedTypedTag) == true {
ifdEnumerateLogger.Warningf(nil, "Skipping non-standard undefined tag: [%s] (%04x)", ifd.IfdPath, ite.TagId()) ifdEnumerateLogger.Warningf(nil, "Skipping non-standard undefined tag: [%s] (%04x)", ifd.ifdIdentity.UnindexedString(), ite.TagId())
continue continue
} else if err == exifundefined.ErrUnparseableValue { } else if err == exifundefined.ErrUnparseableValue {
ifdEnumerateLogger.Warningf(nil, "Skipping unparseable undefined tag: [%s] (%04x) [%s]", ifd.IfdPath, ite.TagId(), it.Name) ifdEnumerateLogger.Warningf(nil, "Skipping unparseable undefined tag: [%s] (%04x) [%s]", ifd.ifdIdentity.UnindexedString(), ite.TagId(), it.Name)
continue continue
} }
@ -824,9 +825,9 @@ func (ifd *Ifd) dumpTree(tagsDump []string, level int) []string {
var ifdPhrase string var ifdPhrase string
if ifd.ParentIfd != nil { if ifd.ParentIfd != nil {
ifdPhrase = fmt.Sprintf("[%s]->[%s]:(%d)", ifd.ParentIfd.IfdPath, ifd.IfdPath, ifd.Index) ifdPhrase = fmt.Sprintf("[%s]->[%s]:(%d)", ifd.ParentIfd.ifdIdentity.UnindexedString(), ifd.ifdIdentity.UnindexedString(), ifd.ifdIdentity.Index())
} else { } else {
ifdPhrase = fmt.Sprintf("[ROOT]->[%s]:(%d)", ifd.IfdPath, ifd.Index) ifdPhrase = fmt.Sprintf("[ROOT]->[%s]:(%d)", ifd.ifdIdentity.UnindexedString(), ifd.ifdIdentity.Index())
} }
startBlurb := fmt.Sprintf("%s> IFD %s TOP", indent, ifdPhrase) startBlurb := fmt.Sprintf("%s> IFD %s TOP", indent, ifdPhrase)
@ -857,7 +858,7 @@ func (ifd *Ifd) dumpTree(tagsDump []string, level int) []string {
tagsDump = append(tagsDump, finishBlurb) tagsDump = append(tagsDump, finishBlurb)
if ifd.NextIfd != nil { if ifd.NextIfd != nil {
siblingBlurb := fmt.Sprintf("%s* LINKING TO SIBLING IFD [%s]:(%d)", indent, ifd.NextIfd.IfdPath, ifd.NextIfd.Index) siblingBlurb := fmt.Sprintf("%s* LINKING TO SIBLING IFD [%s]:(%d)", indent, ifd.NextIfd.ifdIdentity.UnindexedString(), ifd.NextIfd.ifdIdentity.Index())
tagsDump = append(tagsDump, siblingBlurb) tagsDump = append(tagsDump, siblingBlurb)
tagsDump = ifd.NextIfd.dumpTree(tagsDump, level) tagsDump = ifd.NextIfd.dumpTree(tagsDump, level)
@ -882,8 +883,8 @@ func (ifd *Ifd) GpsInfo() (gi *GpsInfo, err error) {
gi = new(GpsInfo) gi = new(GpsInfo)
if ifd.IfdPath != exifcommon.IfdPathStandardGps { if ifd.ifdIdentity.UnindexedString() != exifcommon.IfdGpsInfoStandardIfdIdentity.UnindexedString() {
log.Panicf("GPS can only be read on GPS IFD: [%s] != [%s]", ifd.IfdPath, exifcommon.IfdPathStandardGps) log.Panicf("GPS can only be read on GPS IFD: [%s] != [%s]", ifd.ifdIdentity.UnindexedString(), exifcommon.IfdGpsInfoStandardIfdIdentity.UnindexedString())
} }
if tags, found := ifd.EntriesByTagId[TagGpsVersionId]; found == false { if tags, found := ifd.EntriesByTagId[TagGpsVersionId]; found == false {
@ -1045,13 +1046,8 @@ func (ifd *Ifd) EnumerateTagsRecursively(visitor ParsedTagVisitor) (err error) {
// QueuedIfd is one IFD that has been identified but yet to be processed. // QueuedIfd is one IFD that has been identified but yet to be processed.
type QueuedIfd struct { type QueuedIfd struct {
Name string IfdIdentity *exifcommon.IfdIdentity
IfdPath string
FqIfdPath string
TagId uint16
Index int
Offset uint32 Offset uint32
Parent *Ifd Parent *Ifd
@ -1085,14 +1081,8 @@ func (ie *IfdEnumerate) Collect(rootIfdOffset uint32) (index IfdIndex, err error
queue := []QueuedIfd{ queue := []QueuedIfd{
{ {
Name: exifcommon.IfdStandard, IfdIdentity: exifcommon.IfdStandardIfdIdentity,
IfdPath: exifcommon.IfdStandard, Offset: rootIfdOffset,
FqIfdPath: exifcommon.IfdStandard,
TagId: 0xffff,
Index: 0,
Offset: rootIfdOffset,
}, },
} }
@ -1104,18 +1094,14 @@ func (ie *IfdEnumerate) Collect(rootIfdOffset uint32) (index IfdIndex, err error
} }
qi := queue[0] qi := queue[0]
ii := qi.IfdIdentity
name := qi.Name
ifdPath := qi.IfdPath
fqIfdPath := qi.FqIfdPath
currentIndex := qi.Index
offset := qi.Offset offset := qi.Offset
parentIfd := qi.Parent parentIfd := qi.Parent
queue = queue[1:] queue = queue[1:]
ifdEnumerateLogger.Debugf(nil, "Parsing IFD [%s] (%d) at offset (0x%04x) (Collect).", ifdPath, currentIndex, offset) ifdEnumerateLogger.Debugf(nil, "Parsing IFD [%s] (%d) at offset (0x%04x) (Collect).", ii.String(), ii.Index(), offset)
bp, err := ie.getByteParser(offset) bp, err := ie.getByteParser(offset)
if err != nil { if err != nil {
@ -1126,7 +1112,9 @@ func (ie *IfdEnumerate) Collect(rootIfdOffset uint32) (index IfdIndex, err error
log.Panic(err) log.Panic(err)
} }
nextIfdOffset, entries, thumbnailData, err := ie.parseIfd(fqIfdPath, currentIndex, bp, nil, false) // TODO(dustin): We don't need to pass the index in as a separate argument. Get from the II.
nextIfdOffset, entries, thumbnailData, err := ie.parseIfd(ii, bp, nil, false)
log.PanicIf(err) log.PanicIf(err)
currentOffset := bp.CurrentOffset() currentOffset := bp.CurrentOffset()
@ -1149,20 +1137,15 @@ func (ie *IfdEnumerate) Collect(rootIfdOffset uint32) (index IfdIndex, err error
} }
ifd := &Ifd{ ifd := &Ifd{
ifdIdentity: ii,
ByteOrder: ie.byteOrder, ByteOrder: ie.byteOrder,
Name: name,
IfdPath: ifdPath,
FqIfdPath: fqIfdPath,
TagId: qi.TagId,
Id: id, Id: id,
ParentIfd: parentIfd, ParentIfd: parentIfd,
ParentTagIndex: qi.ParentTagIndex, ParentTagIndex: qi.ParentTagIndex,
Index: currentIndex,
Offset: offset, Offset: offset,
Entries: entries, Entries: entries,
EntriesByTagId: entriesByTagId, EntriesByTagId: entriesByTagId,
@ -1184,7 +1167,7 @@ func (ie *IfdEnumerate) Collect(rootIfdOffset uint32) (index IfdIndex, err error
tree[id] = ifd tree[id] = ifd
// Install into by-name buckets. // Install into by-name buckets.
lookup[fqIfdPath] = ifd lookup[ii.String()] = ifd
// Add a link from the previous IFD in the chain to us. // Add a link from the previous IFD in the chain to us.
if previousIfd, found := edges[offset]; found == true { if previousIfd, found := edges[offset]; found == true {
@ -1203,13 +1186,22 @@ func (ie *IfdEnumerate) Collect(rootIfdOffset uint32) (index IfdIndex, err error
continue continue
} }
qi := QueuedIfd{ tagId := ite.TagId()
Name: ite.ChildIfdName(), childIfdName := ite.ChildIfdName()
IfdPath: ite.ChildIfdPath(),
FqIfdPath: ite.ChildFqIfdPath(), currentIfdTag := ii.IfdTag()
TagId: ite.TagId(),
childIfdTag :=
exifcommon.NewIfdTag(
&currentIfdTag,
tagId,
childIfdName)
iiChild := ii.NewChild(childIfdTag, 0)
qi := QueuedIfd{
IfdIdentity: iiChild,
Index: 0,
Offset: ite.getValueOffset(), Offset: ite.getValueOffset(),
Parent: ifd, Parent: ifd,
ParentTagIndex: i, ParentTagIndex: i,
@ -1220,25 +1212,14 @@ func (ie *IfdEnumerate) Collect(rootIfdOffset uint32) (index IfdIndex, err error
// If there's another IFD in the chain. // If there's another IFD in the chain.
if nextIfdOffset != 0 { if nextIfdOffset != 0 {
iiSibling := ii.NewSibling(ii.Index() + 1)
// Allow the next link to know what the previous link was. // Allow the next link to know what the previous link was.
edges[nextIfdOffset] = ifd edges[nextIfdOffset] = ifd
siblingIndex := currentIndex + 1
var parentFqIfdName string
if parentIfd != nil {
parentFqIfdName = parentIfd.FqIfdPath
}
fqIfdPath := FqIfdPath(parentFqIfdName, name, siblingIndex)
qi := QueuedIfd{ qi := QueuedIfd{
Name: name, IfdIdentity: iiSibling,
IfdPath: ifdPath, Offset: nextIfdOffset,
FqIfdPath: fqIfdPath,
TagId: 0xffff,
Index: siblingIndex,
Offset: nextIfdOffset,
} }
queue = append(queue, qi) queue = append(queue, qi)
@ -1267,7 +1248,7 @@ func (ie *IfdEnumerate) setChildrenIndex(ifd *Ifd) (err error) {
childIfdIndex := make(map[string]*Ifd) childIfdIndex := make(map[string]*Ifd)
for _, childIfd := range ifd.Children { for _, childIfd := range ifd.Children {
childIfdIndex[childIfd.IfdPath] = childIfd childIfdIndex[childIfd.ifdIdentity.UnindexedString()] = childIfd
} }
ifd.ChildIfdIndex = childIfdIndex ifd.ChildIfdIndex = childIfdIndex
@ -1300,7 +1281,7 @@ func (ie *IfdEnumerate) FurthestOffset() uint32 {
// in that the numeric index will always be zero (the zeroth child) rather than // in that the numeric index will always be zero (the zeroth child) rather than
// the proper number (if its actually a sibling to the first child, for // the proper number (if its actually a sibling to the first child, for
// instance). // instance).
func ParseOneIfd(ifdMapping *IfdMapping, tagIndex *TagIndex, fqIfdPath, ifdPath string, byteOrder binary.ByteOrder, ifdBlock []byte, visitor TagVisitorFn) (nextIfdOffset uint32, entries []*IfdTagEntry, err error) { func ParseOneIfd(ifdMapping *IfdMapping, tagIndex *TagIndex, ii *exifcommon.IfdIdentity, byteOrder binary.ByteOrder, ifdBlock []byte, visitor TagVisitorFn) (nextIfdOffset uint32, entries []*IfdTagEntry, err error) {
defer func() { defer func() {
if state := recover(); state != nil { if state := recover(); state != nil {
err = log.Wrap(state.(error)) err = log.Wrap(state.(error))
@ -1318,14 +1299,14 @@ func ParseOneIfd(ifdMapping *IfdMapping, tagIndex *TagIndex, fqIfdPath, ifdPath
log.Panic(err) log.Panic(err)
} }
nextIfdOffset, entries, _, err = ie.parseIfd(fqIfdPath, 0, bp, visitor, true) nextIfdOffset, entries, _, err = ie.parseIfd(ii, bp, visitor, true)
log.PanicIf(err) log.PanicIf(err)
return nextIfdOffset, entries, nil return nextIfdOffset, entries, nil
} }
// ParseOneTag is a hack to use an IE to parse a raw tag block. // ParseOneTag is a hack to use an IE to parse a raw tag block.
func ParseOneTag(ifdMapping *IfdMapping, tagIndex *TagIndex, fqIfdPath, ifdPath string, byteOrder binary.ByteOrder, tagBlock []byte) (tag *IfdTagEntry, err error) { func ParseOneTag(ifdMapping *IfdMapping, tagIndex *TagIndex, ii *exifcommon.IfdIdentity, byteOrder binary.ByteOrder, tagBlock []byte) (tag *IfdTagEntry, err error) {
defer func() { defer func() {
if state := recover(); state != nil { if state := recover(); state != nil {
err = log.Wrap(state.(error)) err = log.Wrap(state.(error))
@ -1343,7 +1324,7 @@ func ParseOneTag(ifdMapping *IfdMapping, tagIndex *TagIndex, fqIfdPath, ifdPath
log.Panic(err) log.Panic(err)
} }
tag, err = ie.parseTag(fqIfdPath, 0, bp) tag, err = ie.parseTag(ii, 0, bp)
log.PanicIf(err) log.PanicIf(err)
return tag, nil return tag, nil
@ -1368,8 +1349,8 @@ func FindIfdFromRootIfd(rootIfd *Ifd, ifdPath string) (ifd *Ifd, err error) {
if len(lineage) == 0 { if len(lineage) == 0 {
log.Panicf("IFD path must be non-empty.") log.Panicf("IFD path must be non-empty.")
} else if lineage[0].Name != exifcommon.IfdStandard { } else if lineage[0].Name != exifcommon.IfdStandardIfdIdentity.Name() {
log.Panicf("First IFD path item must be [%s].", exifcommon.IfdStandard) log.Panicf("First IFD path item must be [%s].", exifcommon.IfdStandardIfdIdentity.Name())
} }
desiredRootIndex := lineage[0].Index desiredRootIndex := lineage[0].Index
@ -1389,7 +1370,7 @@ func FindIfdFromRootIfd(rootIfd *Ifd, ifdPath string) (ifd *Ifd, err error) {
for i, itii := range lineage { for i, itii := range lineage {
var hit *Ifd var hit *Ifd
for _, childIfd := range thisIfd.Children { for _, childIfd := range thisIfd.Children {
if childIfd.TagId == itii.TagId { if childIfd.ifdIdentity.TagId() == itii.TagId {
hit = childIfd hit = childIfd
break break
} }
@ -1405,7 +1386,7 @@ func FindIfdFromRootIfd(rootIfd *Ifd, ifdPath string) (ifd *Ifd, err error) {
// If we didn't find the sibling, add it. // If we didn't find the sibling, add it.
for i = 0; i < itii.Index; i++ { for i = 0; i < itii.Index; i++ {
if thisIfd.NextIfd == nil { if thisIfd.NextIfd == nil {
log.Panicf("IFD [%s] does not have (%d) occurrences/siblings", thisIfd.IfdPath, itii.Index) log.Panicf("IFD [%s] does not have (%d) occurrences/siblings", thisIfd.ifdIdentity.UnindexedString(), itii.Index)
} }
thisIfd = thisIfd.NextIfd thisIfd = thisIfd.NextIfd

View File

@ -250,7 +250,7 @@ func TestIfd_GpsInfo(t *testing.T) {
_, index, err := Collect(im, ti, rawExif) _, index, err := Collect(im, ti, rawExif)
log.PanicIf(err) log.PanicIf(err)
ifd, err := index.RootIfd.ChildWithIfdPath(exifcommon.IfdPathStandardGps) ifd, err := index.RootIfd.ChildWithIfdPath(exifcommon.IfdGpsInfoStandardIfdIdentity)
log.PanicIf(err) log.PanicIf(err)
gi, err := ifd.GpsInfo() gi, err := ifd.GpsInfo()
@ -293,7 +293,7 @@ func TestIfd_GpsInfo__2_0_0_0(t *testing.T) {
_, index, err := Collect(im, ti, rawExif) _, index, err := Collect(im, ti, rawExif)
log.PanicIf(err) log.PanicIf(err)
ifd, err := index.RootIfd.ChildWithIfdPath(exifcommon.IfdPathStandardGps) ifd, err := index.RootIfd.ChildWithIfdPath(exifcommon.IfdGpsInfoStandardIfdIdentity)
log.PanicIf(err) log.PanicIf(err)
gi, err := ifd.GpsInfo() gi, err := ifd.GpsInfo()
@ -344,7 +344,7 @@ func TestIfd_EnumerateTagsRecursively(t *testing.T) {
cb := func(ifd *Ifd, ite *IfdTagEntry) error { cb := func(ifd *Ifd, ite *IfdTagEntry) error {
item := [2]interface{}{ item := [2]interface{}{
ifd.IfdPath, ifd.ifdIdentity.UnindexedString(),
int(ite.TagId()), int(ite.TagId()),
} }
@ -527,7 +527,7 @@ func ExampleIfd_GpsInfo() {
_, index, err := Collect(im, ti, rawExif) _, index, err := Collect(im, ti, rawExif)
log.PanicIf(err) log.PanicIf(err)
ifd, err := index.RootIfd.ChildWithIfdPath(exifcommon.IfdPathStandardGps) ifd, err := index.RootIfd.ChildWithIfdPath(exifcommon.IfdGpsInfoStandardIfdIdentity)
log.PanicIf(err) log.PanicIf(err)
gi, err := ifd.GpsInfo() gi, err := ifd.GpsInfo()

View File

@ -47,9 +47,9 @@ type IfdTagEntry struct {
byteOrder binary.ByteOrder byteOrder binary.ByteOrder
} }
func newIfdTagEntry(fqIfdPath string, tagId uint16, tagIndex int, tagType exifcommon.TagTypePrimitive, unitCount uint32, valueOffset uint32, rawValueOffset []byte, addressableData []byte, byteOrder binary.ByteOrder) *IfdTagEntry { func newIfdTagEntry(ii *exifcommon.IfdIdentity, tagId uint16, tagIndex int, tagType exifcommon.TagTypePrimitive, unitCount uint32, valueOffset uint32, rawValueOffset []byte, addressableData []byte, byteOrder binary.ByteOrder) *IfdTagEntry {
return &IfdTagEntry{ return &IfdTagEntry{
fqIfdPath: fqIfdPath, fqIfdPath: ii.String(),
tagId: tagId, tagId: tagId,
tagIndex: tagIndex, tagIndex: tagIndex,
tagType: tagType, tagType: tagType,
@ -231,10 +231,10 @@ func (ite *IfdTagEntry) setIsUnhandledUnknown(isUnhandledUnknown bool) {
} }
// SetChildIfd sets child-IFD information (if we represent a child IFD). // SetChildIfd sets child-IFD information (if we represent a child IFD).
func (ite *IfdTagEntry) SetChildIfd(childFqIfdPath, childIfdPath, childIfdName string) { func (ite *IfdTagEntry) SetChildIfd(ii *exifcommon.IfdIdentity) {
ite.childFqIfdPath = childFqIfdPath ite.childFqIfdPath = ii.String()
ite.childIfdPath = childIfdPath ite.childIfdPath = ii.UnindexedString()
ite.childIfdName = childIfdName ite.childIfdName = ii.Name()
} }
// ChildIfdName returns the name of the child IFD // ChildIfdName returns the name of the child IFD

View File

@ -15,7 +15,7 @@ func TestIfdTagEntry_RawBytes_Allocated(t *testing.T) {
addressableBytes := data addressableBytes := data
ite := newIfdTagEntry( ite := newIfdTagEntry(
exifcommon.IfdPathStandard, exifcommon.IfdStandardIfdIdentity,
0x1, 0x1,
0, 0,
exifcommon.TypeByte, exifcommon.TypeByte,
@ -46,7 +46,7 @@ func TestIfdTagEntry_RawBytes_Embedded(t *testing.T) {
data := []byte{0x11, 0x22, 0x33, 0x44} data := []byte{0x11, 0x22, 0x33, 0x44}
ite := newIfdTagEntry( ite := newIfdTagEntry(
exifcommon.IfdPathStandard, exifcommon.IfdStandardIfdIdentity,
0x1, 0x1,
0, 0,
exifcommon.TypeByte, exifcommon.TypeByte,
@ -66,7 +66,7 @@ func TestIfdTagEntry_RawBytes_Embedded(t *testing.T) {
func TestIfdTagEntry_String(t *testing.T) { func TestIfdTagEntry_String(t *testing.T) {
ite := newIfdTagEntry( ite := newIfdTagEntry(
exifcommon.IfdPathStandard, exifcommon.IfdStandardIfdIdentity,
0x1, 0x1,
0, 0,
exifcommon.TypeByte, exifcommon.TypeByte,

View File

@ -108,12 +108,17 @@ func TestIfdMapping_Get(t *testing.T) {
err := LoadStandardIfds(im) err := LoadStandardIfds(im)
log.PanicIf(err) log.PanicIf(err)
mi, err := im.Get([]uint16{exifcommon.IfdRootId, exifcommon.IfdExifId, exifcommon.IfdIopId}) mi, err := im.Get([]uint16{
exifcommon.IfdStandardIfdIdentity.TagId(),
exifcommon.IfdExifStandardIfdIdentity.TagId(),
exifcommon.IfdExifIopStandardIfdIdentity.TagId(),
})
log.PanicIf(err) log.PanicIf(err)
if mi.ParentTagId != exifcommon.IfdExifId { if mi.ParentTagId != exifcommon.IfdExifStandardIfdIdentity.TagId() {
t.Fatalf("Parent tag-ID not correct") t.Fatalf("Parent tag-ID not correct")
} else if mi.TagId != exifcommon.IfdIopId { } else if mi.TagId != exifcommon.IfdExifIopStandardIfdIdentity.TagId() {
t.Fatalf("Tag-ID not correct") t.Fatalf("Tag-ID not correct")
} else if mi.Name != "Iop" { } else if mi.Name != "Iop" {
t.Fatalf("name not correct") t.Fatalf("name not correct")
@ -131,9 +136,9 @@ func TestIfdMapping_GetWithPath(t *testing.T) {
mi, err := im.GetWithPath("IFD/Exif/Iop") mi, err := im.GetWithPath("IFD/Exif/Iop")
log.PanicIf(err) log.PanicIf(err)
if mi.ParentTagId != exifcommon.IfdExifId { if mi.ParentTagId != exifcommon.IfdExifStandardIfdIdentity.TagId() {
t.Fatalf("Parent tag-ID not correct") t.Fatalf("Parent tag-ID not correct")
} else if mi.TagId != exifcommon.IfdIopId { } else if mi.TagId != exifcommon.IfdExifIopStandardIfdIdentity.TagId() {
t.Fatalf("Tag-ID not correct") t.Fatalf("Tag-ID not correct")
} else if mi.Name != "Iop" { } else if mi.Name != "Iop" {
t.Fatalf("name not correct") t.Fatalf("name not correct")

View File

@ -11,10 +11,10 @@ import (
func TestGet(t *testing.T) { func TestGet(t *testing.T) {
ti := NewTagIndex() ti := NewTagIndex()
it, err := ti.Get(exifcommon.IfdPathStandard, 0x10f) it, err := ti.Get(exifcommon.IfdStandardIfdIdentity.UnindexedString(), 0x10f)
log.PanicIf(err) log.PanicIf(err)
if it.Is(exifcommon.IfdPathStandard, 0x10f) == false || it.IsName(exifcommon.IfdPathStandard, "Make") == false { if it.Is(exifcommon.IfdStandardIfdIdentity.UnindexedString(), 0x10f) == false || it.IsName(exifcommon.IfdStandardIfdIdentity.UnindexedString(), "Make") == false {
t.Fatalf("tag info not correct") t.Fatalf("tag info not correct")
} }
} }
@ -22,10 +22,10 @@ func TestGet(t *testing.T) {
func TestGetWithName(t *testing.T) { func TestGetWithName(t *testing.T) {
ti := NewTagIndex() ti := NewTagIndex()
it, err := ti.GetWithName(exifcommon.IfdPathStandard, "Make") it, err := ti.GetWithName(exifcommon.IfdStandardIfdIdentity.UnindexedString(), "Make")
log.PanicIf(err) log.PanicIf(err)
if it.Is(exifcommon.IfdPathStandard, 0x10f) == false { if it.Is(exifcommon.IfdStandardIfdIdentity.UnindexedString(), 0x10f) == false {
t.Fatalf("tag info not correct") t.Fatalf("tag info not correct")
} }
} }

View File

@ -34,7 +34,7 @@ func getExifSimpleTestIb() *IfdBuilder {
log.PanicIf(err) log.PanicIf(err)
ti := NewTagIndex() ti := NewTagIndex()
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder) ib := NewIfdBuilder(im, ti, exifcommon.IfdStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
err = ib.AddStandard(0x000b, "asciivalue") err = ib.AddStandard(0x000b, "asciivalue")
log.PanicIf(err) log.PanicIf(err)
@ -65,7 +65,7 @@ func getExifSimpleTestIbBytes() []byte {
log.PanicIf(err) log.PanicIf(err)
ti := NewTagIndex() ti := NewTagIndex()
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder) ib := NewIfdBuilder(im, ti, exifcommon.IfdStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
err = ib.AddStandard(0x000b, "asciivalue") err = ib.AddStandard(0x000b, "asciivalue")
log.PanicIf(err) log.PanicIf(err)
@ -119,10 +119,10 @@ func validateExifSimpleTestIb(exifData []byte, t *testing.T) {
if ifd.ByteOrder != exifcommon.TestDefaultByteOrder { if ifd.ByteOrder != exifcommon.TestDefaultByteOrder {
t.Fatalf("IFD byte-order not correct.") t.Fatalf("IFD byte-order not correct.")
} else if ifd.IfdPath != exifcommon.IfdStandard { } else if ifd.ifdIdentity.UnindexedString() != exifcommon.IfdStandardIfdIdentity.UnindexedString() {
t.Fatalf("IFD name not correct.") t.Fatalf("IFD name not correct.")
} else if ifd.Index != 0 { } else if ifd.ifdIdentity.Index() != 0 {
t.Fatalf("IFD index not zero: (%d)", ifd.Index) t.Fatalf("IFD index not zero: (%d)", ifd.ifdIdentity.Index())
} else if ifd.Offset != uint32(0x0008) { } else if ifd.Offset != uint32(0x0008) {
t.Fatalf("IFD offset not correct.") t.Fatalf("IFD offset not correct.")
} else if len(ifd.Entries) != 4 { } else if len(ifd.Entries) != 4 {

View File

@ -142,7 +142,7 @@ func (Codec8828Oecf) Decode(valueContext *exifcommon.ValueContext) (value Encode
func init() { func init() {
registerDecoder( registerDecoder(
exifcommon.IfdPathStandardExif, exifcommon.IfdExifStandardIfdIdentity.UnindexedString(),
0x8828, 0x8828,
Codec8828Oecf{}) Codec8828Oecf{})
} }

View File

@ -63,7 +63,7 @@ func init() {
Codec9000ExifVersion{}) Codec9000ExifVersion{})
registerDecoder( registerDecoder(
exifcommon.IfdPathStandardExif, exifcommon.IfdExifStandardIfdIdentity.UnindexedString(),
0x9000, 0x9000,
Codec9000ExifVersion{}) Codec9000ExifVersion{})
} }

View File

@ -118,7 +118,7 @@ func init() {
CodecExif9101ComponentsConfiguration{}) CodecExif9101ComponentsConfiguration{})
registerDecoder( registerDecoder(
exifcommon.IfdPathStandardExif, exifcommon.IfdExifStandardIfdIdentity.UnindexedString(),
0x9101, 0x9101,
CodecExif9101ComponentsConfiguration{}) CodecExif9101ComponentsConfiguration{})
} }

View File

@ -108,7 +108,7 @@ func init() {
Codec927CMakerNote{}) Codec927CMakerNote{})
registerDecoder( registerDecoder(
exifcommon.IfdPathStandardExif, exifcommon.IfdExifStandardIfdIdentity.UnindexedString(),
0x927c, 0x927c,
Codec927CMakerNote{}) Codec927CMakerNote{})
} }

View File

@ -136,7 +136,7 @@ func init() {
Codec9286UserComment{}) Codec9286UserComment{})
registerDecoder( registerDecoder(
exifcommon.IfdPathStandardExif, exifcommon.IfdExifStandardIfdIdentity.UnindexedString(),
0x9286, 0x9286,
Codec9286UserComment{}) Codec9286UserComment{})
} }

View File

@ -63,7 +63,7 @@ func init() {
CodecA000FlashpixVersion{}) CodecA000FlashpixVersion{})
registerDecoder( registerDecoder(
exifcommon.IfdPathStandardExif, exifcommon.IfdExifStandardIfdIdentity.UnindexedString(),
0xa000, 0xa000,
CodecA000FlashpixVersion{}) CodecA000FlashpixVersion{})
} }

View File

@ -154,7 +154,7 @@ func init() {
CodecA20CSpatialFrequencyResponse{}) CodecA20CSpatialFrequencyResponse{})
registerDecoder( registerDecoder(
exifcommon.IfdPathStandardExif, exifcommon.IfdExifStandardIfdIdentity.UnindexedString(),
0xa20c, 0xa20c,
CodecA20CSpatialFrequencyResponse{}) CodecA20CSpatialFrequencyResponse{})
} }

View File

@ -73,7 +73,7 @@ func init() {
CodecExifA300FileSource{}) CodecExifA300FileSource{})
registerDecoder( registerDecoder(
exifcommon.IfdPathStandardExif, exifcommon.IfdExifStandardIfdIdentity.UnindexedString(),
0xa300, 0xa300,
CodecExifA300FileSource{}) CodecExifA300FileSource{})
} }

View File

@ -70,7 +70,7 @@ func init() {
CodecExifA301SceneType{}) CodecExifA301SceneType{})
registerDecoder( registerDecoder(
exifcommon.IfdPathStandardExif, exifcommon.IfdExifStandardIfdIdentity.UnindexedString(),
0xa301, 0xa301,
CodecExifA301SceneType{}) CodecExifA301SceneType{})
} }

View File

@ -91,7 +91,7 @@ func init() {
CodecA302CfaPattern{}) CodecA302CfaPattern{})
registerDecoder( registerDecoder(
exifcommon.IfdPathStandardExif, exifcommon.IfdExifStandardIfdIdentity.UnindexedString(),
0xa302, 0xa302,
CodecA302CfaPattern{}) CodecA302CfaPattern{})
} }

View File

@ -63,7 +63,7 @@ func init() {
Codec0002InteropVersion{}) Codec0002InteropVersion{})
registerDecoder( registerDecoder(
exifcommon.IfdPathStandardExifIop, exifcommon.IfdExifIopStandardIfdIdentity.UnindexedString(),
0x0002, 0x0002,
Codec0002InteropVersion{}) Codec0002InteropVersion{})
} }

View File

@ -59,7 +59,7 @@ func init() {
Codec001BGPSProcessingMethod{}) Codec001BGPSProcessingMethod{})
registerDecoder( registerDecoder(
exifcommon.IfdPathStandardGps, exifcommon.IfdGpsInfoStandardIfdIdentity.UnindexedString(),
0x001b, 0x001b,
Codec001BGPSProcessingMethod{}) Codec001BGPSProcessingMethod{})
} }

View File

@ -59,7 +59,7 @@ func init() {
Codec001CGPSAreaInformation{}) Codec001CGPSAreaInformation{})
registerDecoder( registerDecoder(
exifcommon.IfdPathStandardGps, exifcommon.IfdGpsInfoStandardIfdIdentity.UnindexedString(),
0x001c, 0x001c,
Codec001CGPSAreaInformation{}) Codec001CGPSAreaInformation{})
} }

View File

@ -212,7 +212,7 @@ func GetFlatExifData(exifData []byte) (exifTags []ExifTag, err error) {
return nil return nil
} }
err = ie.Scan(exifcommon.IfdStandard, eh.FirstIfdOffset, visitor) err = ie.Scan(exifcommon.IfdStandardIfdIdentity, eh.FirstIfdOffset, visitor)
log.PanicIf(err) log.PanicIf(err)
return exifTags, nil return exifTags, nil