tags.go: 'Get' functions now take an exifcommon.IfdIdentity

dustin/master
Dustin Oprea 2020-05-24 11:07:46 -04:00
parent 1a12aec48f
commit 75b5552112
9 changed files with 46 additions and 45 deletions

View File

@ -63,6 +63,7 @@ func TestVisit(t *testing.T) {
tags := make([]string, 0)
// DEPRECATED(dustin): fqIfdPath and ifdIndex are now redundant. Remove in next module version.
visitor := func(fqIfdPath string, ifdIndex int, ite *IfdTagEntry) (err error) {
defer func() {
if state := recover(); state != nil {
@ -73,14 +74,12 @@ func TestVisit(t *testing.T) {
tagId := ite.TagId()
tagType := ite.TagType()
ii := ite.ifdIdentity
ifdPath, err := im.StripPathPhraseIndices(fqIfdPath)
log.PanicIf(err)
it, err := ti.Get(ifdPath, tagId)
it, err := ti.Get(ii, tagId)
if err != nil {
if log.Is(err, ErrTagNotFound) {
fmt.Printf("Unknown tag: [%s] (%04x)\n", ifdPath, tagId)
fmt.Printf("Unknown tag: [%s] (%04x)\n", ii.String(), tagId)
return nil
} else {
log.Panic(err)
@ -90,7 +89,7 @@ func TestVisit(t *testing.T) {
valueString, err := ite.FormatFirst()
log.PanicIf(err)
description := fmt.Sprintf("IFD-PATH=[%s] ID=(0x%04x) NAME=[%s] COUNT=(%d) TYPE=[%s] VALUE=[%s]", ifdPath, tagId, it.Name, ite.UnitCount(), tagType.String(), valueString)
description := fmt.Sprintf("IFD-PATH=[%s] ID=(0x%04x) NAME=[%s] COUNT=(%d) TYPE=[%s] VALUE=[%s]", ii.String(), tagId, it.Name, ite.UnitCount(), tagType.String(), valueString)
tags = append(tags, description)
return nil
@ -157,12 +156,12 @@ func TestVisit(t *testing.T) {
"IFD-PATH=[IFD/Exif] ID=(0xa435) NAME=[LensSerialNumber] COUNT=(11) TYPE=[ASCII] VALUE=[2400001068]",
"IFD-PATH=[IFD] ID=(0x8825) NAME=[GPSTag] COUNT=(1) TYPE=[LONG] VALUE=[9554]",
"IFD-PATH=[IFD/GPSInfo] ID=(0x0000) NAME=[GPSVersionID] COUNT=(4) TYPE=[BYTE] VALUE=[02 03 00 00]",
"IFD-PATH=[IFD] ID=(0x0103) NAME=[Compression] COUNT=(1) TYPE=[SHORT] VALUE=[6]",
"IFD-PATH=[IFD] ID=(0x011a) NAME=[XResolution] COUNT=(1) TYPE=[RATIONAL] VALUE=[72/1]",
"IFD-PATH=[IFD] ID=(0x011b) NAME=[YResolution] COUNT=(1) TYPE=[RATIONAL] VALUE=[72/1]",
"IFD-PATH=[IFD] ID=(0x0128) NAME=[ResolutionUnit] COUNT=(1) TYPE=[SHORT] VALUE=[2]",
"IFD-PATH=[IFD] ID=(0x0201) NAME=[JPEGInterchangeFormat] COUNT=(1) TYPE=[LONG] VALUE=[11444]",
"IFD-PATH=[IFD] ID=(0x0202) NAME=[JPEGInterchangeFormatLength] COUNT=(1) TYPE=[LONG] VALUE=[21491]",
"IFD-PATH=[IFD1] ID=(0x0103) NAME=[Compression] COUNT=(1) TYPE=[SHORT] VALUE=[6]",
"IFD-PATH=[IFD1] ID=(0x011a) NAME=[XResolution] COUNT=(1) TYPE=[RATIONAL] VALUE=[72/1]",
"IFD-PATH=[IFD1] ID=(0x011b) NAME=[YResolution] COUNT=(1) TYPE=[RATIONAL] VALUE=[72/1]",
"IFD-PATH=[IFD1] ID=(0x0128) NAME=[ResolutionUnit] COUNT=(1) TYPE=[SHORT] VALUE=[2]",
"IFD-PATH=[IFD1] ID=(0x0201) NAME=[JPEGInterchangeFormat] COUNT=(1) TYPE=[LONG] VALUE=[11444]",
"IFD-PATH=[IFD1] ID=(0x0202) NAME=[JPEGInterchangeFormatLength] COUNT=(1) TYPE=[LONG] VALUE=[21491]",
}
if reflect.DeepEqual(tags, expected) == false {

View File

@ -516,7 +516,7 @@ func (ib *IfdBuilder) SetThumbnail(data []byte) (err error) {
err = ib.Set(offsetBt)
log.PanicIf(err)
thumbnailSizeIt, err := ib.tagIndex.Get(ib.IfdIdentity().UnindexedString(), ThumbnailSizeTagId)
thumbnailSizeIt, err := ib.tagIndex.Get(ib.IfdIdentity(), ThumbnailSizeTagId)
log.PanicIf(err)
sizeBt := NewStandardBuilderTag(ib.IfdIdentity().UnindexedString(), thumbnailSizeIt, ib.byteOrder, []uint32{uint32(len(ib.thumbnailData))})
@ -565,7 +565,7 @@ func (ib *IfdBuilder) printTagTree(levels int) {
if isChildIb == true {
tagName = "<Child IFD>"
} else {
it, err := ib.tagIndex.Get(tag.ifdPath, tag.tagId)
it, err := ib.tagIndex.Get(ib.ifdIdentity, tag.tagId)
if log.Is(err, ErrTagNotFound) == true {
tagName = "<UNKNOWN>"
} else if err != nil {
@ -889,7 +889,7 @@ func (ib *IfdBuilder) FindTagWithName(tagName string) (bt *BuilderTag, err error
}
}()
it, err := ib.tagIndex.GetWithName(ib.IfdIdentity().UnindexedString(), tagName)
it, err := ib.tagIndex.GetWithName(ib.IfdIdentity(), tagName)
log.PanicIf(err)
found, err := ib.FindN(it.Id, 1)
@ -1105,7 +1105,7 @@ func (ib *IfdBuilder) AddStandard(tagId uint16, value interface{}) (err error) {
}
}()
it, err := ib.tagIndex.Get(ib.IfdIdentity().UnindexedString(), tagId)
it, err := ib.tagIndex.Get(ib.IfdIdentity(), tagId)
log.PanicIf(err)
bt := NewStandardBuilderTag(ib.IfdIdentity().UnindexedString(), it, ib.byteOrder, value)
@ -1126,7 +1126,7 @@ func (ib *IfdBuilder) AddStandardWithName(tagName string, value interface{}) (er
}
}()
it, err := ib.tagIndex.GetWithName(ib.IfdIdentity().UnindexedString(), tagName)
it, err := ib.tagIndex.GetWithName(ib.IfdIdentity(), tagName)
log.PanicIf(err)
bt := NewStandardBuilderTag(ib.IfdIdentity().UnindexedString(), it, ib.byteOrder, value)
@ -1148,7 +1148,7 @@ func (ib *IfdBuilder) SetStandard(tagId uint16, value interface{}) (err error) {
// TODO(dustin): !! Add test for this function.
it, err := ib.tagIndex.Get(ib.IfdIdentity().UnindexedString(), tagId)
it, err := ib.tagIndex.Get(ib.IfdIdentity(), tagId)
log.PanicIf(err)
bt := NewStandardBuilderTag(ib.IfdIdentity().UnindexedString(), it, ib.byteOrder, value)
@ -1179,7 +1179,7 @@ func (ib *IfdBuilder) SetStandardWithName(tagName string, value interface{}) (er
// TODO(dustin): !! Add test for this function.
it, err := ib.tagIndex.GetWithName(ib.IfdIdentity().UnindexedString(), tagName)
it, err := ib.tagIndex.GetWithName(ib.IfdIdentity(), tagName)
log.PanicIf(err)
bt := NewStandardBuilderTag(ib.IfdIdentity().UnindexedString(), it, ib.byteOrder, value)

View File

@ -198,7 +198,7 @@ func Test_IfdByteEncoder_encodeTagToBytes_bytes_embedded1(t *testing.T) {
ti := NewTagIndex()
ib := NewIfdBuilder(im, ti, exifcommon.IfdGpsInfoStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
it, err := ti.Get(ib.IfdIdentity().UnindexedString(), uint16(0x0000))
it, err := ti.Get(ib.IfdIdentity(), uint16(0x0000))
log.PanicIf(err)
bt := NewStandardBuilderTag(exifcommon.IfdGpsInfoStandardIfdIdentity.UnindexedString(), it, exifcommon.TestDefaultByteOrder, []uint8{uint8(0x12)})
@ -232,7 +232,7 @@ func Test_IfdByteEncoder_encodeTagToBytes_bytes_embedded2(t *testing.T) {
ti := NewTagIndex()
ib := NewIfdBuilder(im, ti, exifcommon.IfdGpsInfoStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
it, err := ti.Get(ib.IfdIdentity().UnindexedString(), uint16(0x0000))
it, err := ti.Get(ib.IfdIdentity(), uint16(0x0000))
log.PanicIf(err)
bt := NewStandardBuilderTag(exifcommon.IfdGpsInfoStandardIfdIdentity.UnindexedString(), it, exifcommon.TestDefaultByteOrder, []uint8{uint8(0x12), uint8(0x34), uint8(0x56), uint8(0x78)})
@ -272,7 +272,7 @@ func Test_IfdByteEncoder_encodeTagToBytes_bytes_allocated(t *testing.T) {
addressableOffset := uint32(0x1234)
ida := newIfdDataAllocator(addressableOffset)
it, err := ti.Get(ib.IfdIdentity().UnindexedString(), uint16(0x0000))
it, err := ti.Get(ib.IfdIdentity(), uint16(0x0000))
log.PanicIf(err)
bt := NewStandardBuilderTag(exifcommon.IfdGpsInfoStandardIfdIdentity.UnindexedString(), it, exifcommon.TestDefaultByteOrder, []uint8{uint8(0x12), uint8(0x34), uint8(0x56), uint8(0x78), uint8(0x9a)})
@ -493,7 +493,7 @@ func Test_IfdByteEncoder_encodeTagToBytes_simpleTag_allocate(t *testing.T) {
ti := NewTagIndex()
ib := NewIfdBuilder(im, ti, exifcommon.IfdStandardIfdIdentity, exifcommon.TestDefaultByteOrder)
it, err := ib.tagIndex.Get(ib.IfdIdentity().UnindexedString(), uint16(0x000b))
it, err := ib.tagIndex.Get(ib.IfdIdentity(), uint16(0x000b))
log.PanicIf(err)
valueString := "testvalue"

View File

@ -2049,7 +2049,7 @@ func TestIfdBuilder_CreateIfdBuilderWithExistingIfd(t *testing.T) {
func TestNewStandardBuilderTag__OneUnit(t *testing.T) {
ti := NewTagIndex()
it, err := ti.Get(exifcommon.IfdExifStandardIfdIdentity.UnindexedString(), uint16(0x8833))
it, err := ti.Get(exifcommon.IfdExifStandardIfdIdentity, uint16(0x8833))
log.PanicIf(err)
bt := NewStandardBuilderTag(exifcommon.IfdExifStandardIfdIdentity.UnindexedString(), it, exifcommon.TestDefaultByteOrder, []uint32{uint32(0x1234)})
@ -2066,7 +2066,7 @@ func TestNewStandardBuilderTag__OneUnit(t *testing.T) {
func TestNewStandardBuilderTag__TwoUnits(t *testing.T) {
ti := NewTagIndex()
it, err := ti.Get(exifcommon.IfdExifStandardIfdIdentity.UnindexedString(), uint16(0x8833))
it, err := ti.Get(exifcommon.IfdExifStandardIfdIdentity, uint16(0x8833))
log.PanicIf(err)
bt := NewStandardBuilderTag(exifcommon.IfdExifStandardIfdIdentity.UnindexedString(), it, exifcommon.TestDefaultByteOrder, []uint32{uint32(0x1234), uint32(0x5678)})

View File

@ -312,7 +312,7 @@ func (ie *IfdEnumerate) parseIfd(ii *exifcommon.IfdIdentity, bp *byteParser, vis
tagId := ite.TagId()
tagType := ite.TagType()
it, err := ie.tagIndex.Get(ii.UnindexedString(), tagId)
it, err := ie.tagIndex.Get(ii, tagId)
if err == nil {
// This is a known tag (from the standard, unless the user did
// something different).
@ -609,7 +609,7 @@ func (ifd *Ifd) FindTagWithName(tagName string) (results []*IfdTagEntry, err err
}
}()
it, err := ifd.tagIndex.GetWithName(ifd.ifdIdentity.UnindexedString(), tagName)
it, err := ifd.tagIndex.GetWithName(ifd.ifdIdentity, tagName)
if log.Is(err, ErrTagNotFound) == true {
log.Panic(ErrTagNotStandard)
} else if err != nil {
@ -717,7 +717,7 @@ func (ifd *Ifd) printTagTree(populateValues bool, index, level int, nextLink boo
continue
}
it, err := ifd.tagIndex.Get(ifd.ifdIdentity.UnindexedString(), ite.TagId())
it, err := ifd.tagIndex.Get(ifd.ifdIdentity, ite.TagId())
tagName := ""
if err == nil {

View File

@ -38,8 +38,7 @@ type IfdTagEntry struct {
// TODO(dustin): !! IB's host the child-IBs directly in the tag, but that's not the case here. Refactor to accomodate it for a consistent experience.
// fqIfdPath is the IFD that this tag belongs to.
fqIfdPath string
ifdIdentity *exifcommon.IfdIdentity
isUnhandledUnknown bool
@ -49,7 +48,7 @@ type IfdTagEntry struct {
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{
fqIfdPath: ii.String(),
ifdIdentity: ii,
tagId: tagId,
tagIndex: tagIndex,
tagType: tagType,
@ -63,12 +62,12 @@ func newIfdTagEntry(ii *exifcommon.IfdIdentity, tagId uint16, tagIndex int, tagT
// String returns a stringified representation of the struct.
func (ite *IfdTagEntry) String() string {
return fmt.Sprintf("IfdTagEntry<TAG-IFD-PATH=[%s] TAG-ID=(0x%04x) TAG-TYPE=[%s] UNIT-COUNT=(%d)>", ite.fqIfdPath, ite.tagId, ite.tagType.String(), ite.unitCount)
return fmt.Sprintf("IfdTagEntry<TAG-IFD-PATH=[%s] TAG-ID=(0x%04x) TAG-TYPE=[%s] UNIT-COUNT=(%d)>", ite.ifdIdentity.String(), ite.tagId, ite.tagType.String(), ite.unitCount)
}
// IfdPath returns the fully-qualified path of the IFD that owns this tag.
func (ite *IfdTagEntry) IfdPath() string {
return ite.fqIfdPath
return ite.ifdIdentity.String()
}
// TagId returns the ID of the tag that we represent. The combination of
@ -80,13 +79,13 @@ func (ite *IfdTagEntry) TagId() uint16 {
// IsThumbnailOffset returns true if the tag has the IFD and tag-ID of a
// thumbnail offset.
func (ite *IfdTagEntry) IsThumbnailOffset() bool {
return ite.tagId == ThumbnailOffsetTagId && ite.fqIfdPath == ThumbnailFqIfdPath
return ite.tagId == ThumbnailOffsetTagId && ite.ifdIdentity.String() == ThumbnailFqIfdPath
}
// IsThumbnailSize returns true if the tag has the IFD and tag-ID of a thumbnail
// size.
func (ite *IfdTagEntry) IsThumbnailSize() bool {
return ite.tagId == ThumbnailSizeTagId && ite.fqIfdPath == ThumbnailFqIfdPath
return ite.tagId == ThumbnailSizeTagId && ite.ifdIdentity.String() == ThumbnailFqIfdPath
}
// TagType is the type of value for this tag.
@ -256,7 +255,7 @@ func (ite *IfdTagEntry) ChildFqIfdPath() string {
func (ite *IfdTagEntry) getValueContext() *exifcommon.ValueContext {
return exifcommon.NewValueContext(
ite.fqIfdPath,
ite.ifdIdentity.String(),
ite.tagId,
ite.unitCount,
ite.valueOffset,

View File

@ -111,6 +111,8 @@ func (it *IndexedTag) Is(ifdPath string, id uint16) bool {
return it.Id == id && it.IfdPath == ifdPath
}
// WidestSupportedType returns the largest type that this tag's value can
// occupy
func (it *IndexedTag) WidestSupportedType() exifcommon.TagTypePrimitive {
if len(it.SupportedTypes) == 0 {
log.Panicf("IndexedTag [%s] (%d) has no supported types.", it.IfdPath, it.Id)
@ -208,7 +210,7 @@ func (ti *TagIndex) Add(it *IndexedTag) (err error) {
// Get returns information about the non-IFD tag given a tag ID. `ifdPath` must
// not be fully-qualified.
func (ti *TagIndex) Get(ifdPath string, id uint16) (it *IndexedTag, err error) {
func (ti *TagIndex) Get(ii *exifcommon.IfdIdentity, id uint16) (it *IndexedTag, err error) {
defer func() {
if state := recover(); state != nil {
err = log.Wrap(state.(error))
@ -220,6 +222,8 @@ func (ti *TagIndex) Get(ifdPath string, id uint16) (it *IndexedTag, err error) {
log.PanicIf(err)
}
ifdPath := ii.UnindexedString()
family, found := ti.tagsByIfd[ifdPath]
if found == false {
return nil, ErrTagNotFound
@ -234,7 +238,7 @@ func (ti *TagIndex) Get(ifdPath string, id uint16) (it *IndexedTag, err error) {
}
// GetWithName returns information about the non-IFD tag given a tag name.
func (ti *TagIndex) GetWithName(ifdPath string, name string) (it *IndexedTag, err error) {
func (ti *TagIndex) GetWithName(ii *exifcommon.IfdIdentity, name string) (it *IndexedTag, err error) {
defer func() {
if state := recover(); state != nil {
err = log.Wrap(state.(error))
@ -246,6 +250,8 @@ func (ti *TagIndex) GetWithName(ifdPath string, name string) (it *IndexedTag, er
log.PanicIf(err)
}
ifdPath := ii.UnindexedString()
it, found := ti.tagsByIfdR[ifdPath][name]
if found != true {
log.Panic(ErrTagNotFound)

View File

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

View File

@ -141,12 +141,9 @@ func GetFlatExifData(exifData []byte) (exifTags []ExifTag, err error) {
visitor := func(fqIfdPath string, ifdIndex int, ite *IfdTagEntry) (err error) {
tagId := ite.TagId()
ii := ite.ifdIdentity
// TODO(dustin): This is inefficient. Our IFD paths should have their own type where we can render whatever path we need.
ifdPath, err := im.StripPathPhraseIndices(fqIfdPath)
log.PanicIf(err)
it, err := ti.Get(ifdPath, ite.tagId)
it, err := ti.Get(ii, ite.tagId)
if err != nil {
if log.Is(err, ErrTagNotFound) != true {
log.Panic(err)