mirror of https://github.com/dsoprea/go-exif.git
ifd_enumerate: Added find-by-id and find-by-name to tags in `ifd`.
- Made `(Ifd).Entries` a slice of pointers ([]*IfdTagEntry).pull/3/head
parent
84fe4298c4
commit
8c09d04212
|
@ -0,0 +1,10 @@
|
||||||
|
package exif
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrTagNotFound = errors.New("tag not found")
|
||||||
|
ErrTagNotStandard = errors.New("tag not a standard tag")
|
||||||
|
)
|
|
@ -664,7 +664,7 @@ func (ib *IfdBuilder) AddTagsFromExisting(ifd *Ifd, itevr *IfdTagEntryValueResol
|
||||||
} else {
|
} else {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
valueBytes, err := itevr.ValueBytes(&ite)
|
valueBytes, err := itevr.ValueBytes(ite)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if log.Is(err, ErrUnhandledUnknownTypedTag) == true {
|
if log.Is(err, ErrUnhandledUnknownTypedTag) == true {
|
||||||
ifdBuilderLogger.Warningf(nil, "Unknown-type tag can't be parsed so it can't be copied to the new IFD.")
|
ifdBuilderLogger.Warningf(nil, "Unknown-type tag can't be parsed so it can't be copied to the new IFD.")
|
||||||
|
|
|
@ -152,21 +152,21 @@ func TestAddTagsFromExisting(t *testing.T) {
|
||||||
|
|
||||||
ib := NewIfdBuilder(RootIi, TestDefaultByteOrder)
|
ib := NewIfdBuilder(RootIi, TestDefaultByteOrder)
|
||||||
|
|
||||||
entries := make([]IfdTagEntry, 3)
|
entries := make([]*IfdTagEntry, 3)
|
||||||
|
|
||||||
entries[0] = IfdTagEntry{
|
entries[0] = &IfdTagEntry{
|
||||||
TagId: 0x11,
|
TagId: 0x11,
|
||||||
TagType: TypeByte,
|
TagType: TypeByte,
|
||||||
UnitCount: 4,
|
UnitCount: 4,
|
||||||
RawValueOffset: []byte { 0x12, 0, 0, 0 },
|
RawValueOffset: []byte { 0x12, 0, 0, 0 },
|
||||||
}
|
}
|
||||||
|
|
||||||
entries[1] = IfdTagEntry{
|
entries[1] = &IfdTagEntry{
|
||||||
TagId: 0x22,
|
TagId: 0x22,
|
||||||
ChildIfdName: "some ifd",
|
ChildIfdName: "some ifd",
|
||||||
}
|
}
|
||||||
|
|
||||||
entries[2] = IfdTagEntry{
|
entries[2] = &IfdTagEntry{
|
||||||
TagId: 0x33,
|
TagId: 0x33,
|
||||||
TagType: TypeByte,
|
TagType: TypeByte,
|
||||||
UnitCount: 4,
|
UnitCount: 4,
|
||||||
|
@ -192,18 +192,18 @@ func TestAddTagsFromExisting(t *testing.T) {
|
||||||
func TestAddTagsFromExisting__Includes(t *testing.T) {
|
func TestAddTagsFromExisting__Includes(t *testing.T) {
|
||||||
ib := NewIfdBuilder(RootIi, TestDefaultByteOrder)
|
ib := NewIfdBuilder(RootIi, TestDefaultByteOrder)
|
||||||
|
|
||||||
entries := make([]IfdTagEntry, 3)
|
entries := make([]*IfdTagEntry, 3)
|
||||||
|
|
||||||
entries[0] = IfdTagEntry{
|
entries[0] = &IfdTagEntry{
|
||||||
TagId: 0x11,
|
TagId: 0x11,
|
||||||
}
|
}
|
||||||
|
|
||||||
entries[1] = IfdTagEntry{
|
entries[1] = &IfdTagEntry{
|
||||||
TagId: 0x22,
|
TagId: 0x22,
|
||||||
ChildIfdName: "some ifd",
|
ChildIfdName: "some ifd",
|
||||||
}
|
}
|
||||||
|
|
||||||
entries[2] = IfdTagEntry{
|
entries[2] = &IfdTagEntry{
|
||||||
TagId: 0x33,
|
TagId: 0x33,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,18 +224,18 @@ func TestAddTagsFromExisting__Includes(t *testing.T) {
|
||||||
func TestAddTagsFromExisting__Excludes(t *testing.T) {
|
func TestAddTagsFromExisting__Excludes(t *testing.T) {
|
||||||
ib := NewIfdBuilder(RootIi, TestDefaultByteOrder)
|
ib := NewIfdBuilder(RootIi, TestDefaultByteOrder)
|
||||||
|
|
||||||
entries := make([]IfdTagEntry, 3)
|
entries := make([]*IfdTagEntry, 3)
|
||||||
|
|
||||||
entries[0] = IfdTagEntry{
|
entries[0] = &IfdTagEntry{
|
||||||
TagId: 0x11,
|
TagId: 0x11,
|
||||||
}
|
}
|
||||||
|
|
||||||
entries[1] = IfdTagEntry{
|
entries[1] = &IfdTagEntry{
|
||||||
TagId: 0x22,
|
TagId: 0x22,
|
||||||
ChildIfdName: "some ifd",
|
ChildIfdName: "some ifd",
|
||||||
}
|
}
|
||||||
|
|
||||||
entries[2] = IfdTagEntry{
|
entries[2] = &IfdTagEntry{
|
||||||
TagId: 0x33,
|
TagId: 0x33,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -126,7 +126,7 @@ func (ie *IfdEnumerate) getTagEnumerator(ifdOffset uint32) (ite *IfdTagEnumerato
|
||||||
return ite
|
return ite
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ie *IfdEnumerate) parseTag(ii IfdIdentity, tagIndex int, ite *IfdTagEnumerator) (tag IfdTagEntry, err error) {
|
func (ie *IfdEnumerate) parseTag(ii IfdIdentity, tagIndex int, ite *IfdTagEnumerator) (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))
|
||||||
|
@ -145,7 +145,7 @@ func (ie *IfdEnumerate) parseTag(ii IfdIdentity, tagIndex int, ite *IfdTagEnumer
|
||||||
valueOffset, rawValueOffset, err := ite.getUint32()
|
valueOffset, rawValueOffset, err := ite.getUint32()
|
||||||
log.PanicIf(err)
|
log.PanicIf(err)
|
||||||
|
|
||||||
tag = IfdTagEntry{
|
tag = &IfdTagEntry{
|
||||||
Ii: ii,
|
Ii: ii,
|
||||||
TagId: tagId,
|
TagId: tagId,
|
||||||
TagIndex: tagIndex,
|
TagIndex: tagIndex,
|
||||||
|
@ -173,7 +173,7 @@ type TagVisitor func(ii IfdIdentity, ifdIndex int, tagId uint16, tagType TagType
|
||||||
|
|
||||||
// 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(ii IfdIdentity, ifdIndex int, ite *IfdTagEnumerator, visitor TagVisitor, doDescend bool) (nextIfdOffset uint32, entries []IfdTagEntry, err error) {
|
func (ie *IfdEnumerate) ParseIfd(ii IfdIdentity, ifdIndex int, ite *IfdTagEnumerator, visitor TagVisitor, doDescend bool) (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))
|
||||||
|
@ -185,7 +185,7 @@ func (ie *IfdEnumerate) ParseIfd(ii IfdIdentity, ifdIndex int, ite *IfdTagEnumer
|
||||||
|
|
||||||
ifdEnumerateLogger.Debugf(nil, "Current IFD tag-count: (%d)", tagCount)
|
ifdEnumerateLogger.Debugf(nil, "Current IFD tag-count: (%d)", tagCount)
|
||||||
|
|
||||||
entries = make([]IfdTagEntry, tagCount)
|
entries = make([]*IfdTagEntry, tagCount)
|
||||||
|
|
||||||
for i := 0; i < int(tagCount); i++ {
|
for i := 0; i < int(tagCount); i++ {
|
||||||
tag, err := ie.parseTag(ii, i, ite)
|
tag, err := ie.parseTag(ii, i, ite)
|
||||||
|
@ -269,6 +269,7 @@ func (ie *IfdEnumerate) Scan(ifdOffset uint32, visitor TagVisitor) (err error) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
type Ifd struct {
|
type Ifd struct {
|
||||||
ByteOrder binary.ByteOrder
|
ByteOrder binary.ByteOrder
|
||||||
|
|
||||||
|
@ -278,14 +279,64 @@ type Ifd struct {
|
||||||
Index int
|
Index int
|
||||||
Offset uint32
|
Offset uint32
|
||||||
|
|
||||||
// TODO(dustin): !! Add a find method.
|
Entries []*IfdTagEntry
|
||||||
Entries []IfdTagEntry
|
EntriesByTagId map[uint16][]*IfdTagEntry
|
||||||
|
|
||||||
Children []*Ifd
|
Children []*Ifd
|
||||||
NextIfdOffset uint32
|
NextIfdOffset uint32
|
||||||
NextIfd *Ifd
|
NextIfd *Ifd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindTagWithId returns a list of tags (usually just zero or one) that match
|
||||||
|
// the given tag ID. This is efficient.
|
||||||
|
func (ifd Ifd) FindTagWithId(tagId uint16) (results []*IfdTagEntry, err error) {
|
||||||
|
defer func() {
|
||||||
|
if state := recover(); state != nil {
|
||||||
|
err = log.Wrap(state.(error))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
results, found := ifd.EntriesByTagId[tagId]
|
||||||
|
if found != true {
|
||||||
|
log.Panic(ErrTagNotFound)
|
||||||
|
}
|
||||||
|
|
||||||
|
return results, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindTagWithName returns a list of tags (usually just zero or one) that match
|
||||||
|
// the given tag name. This is not efficient (though the labor is trivial).
|
||||||
|
func (ifd Ifd) FindTagWithName(tagName string) (results []*IfdTagEntry, err error) {
|
||||||
|
defer func() {
|
||||||
|
if state := recover(); state != nil {
|
||||||
|
err = log.Wrap(state.(error))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
ti := NewTagIndex()
|
||||||
|
|
||||||
|
ii := ifd.Identity()
|
||||||
|
it, err := ti.GetWithName(ii, tagName)
|
||||||
|
if log.Is(err, ErrTagNotFound) == true {
|
||||||
|
log.Panic(ErrTagNotStandard)
|
||||||
|
} else if err != nil {
|
||||||
|
log.Panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
results = make([]*IfdTagEntry, 0)
|
||||||
|
for _, ite := range ifd.Entries {
|
||||||
|
if ite.TagId == it.Id {
|
||||||
|
results = append(results, ite)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(results) == 0 {
|
||||||
|
log.Panic(ErrTagNotFound)
|
||||||
|
}
|
||||||
|
|
||||||
|
return results, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (ifd Ifd) String() string {
|
func (ifd Ifd) String() string {
|
||||||
parentOffset := uint32(0)
|
parentOffset := uint32(0)
|
||||||
if ifd.ParentIfd != nil {
|
if ifd.ParentIfd != nil {
|
||||||
|
@ -390,6 +441,16 @@ func (ie *IfdEnumerate) Collect(rootIfdOffset uint32) (index IfdIndex, err error
|
||||||
|
|
||||||
id := len(ifds)
|
id := len(ifds)
|
||||||
|
|
||||||
|
entriesByTagId := make(map[uint16][]*IfdTagEntry)
|
||||||
|
for _, tag := range entries {
|
||||||
|
tags, found := entriesByTagId[tag.TagId]
|
||||||
|
if found == false {
|
||||||
|
tags = make([]*IfdTagEntry, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
entriesByTagId[tag.TagId] = append(tags, tag)
|
||||||
|
}
|
||||||
|
|
||||||
ifd := Ifd{
|
ifd := Ifd{
|
||||||
ByteOrder: ie.byteOrder,
|
ByteOrder: ie.byteOrder,
|
||||||
Id: id,
|
Id: id,
|
||||||
|
@ -398,6 +459,7 @@ func (ie *IfdEnumerate) Collect(rootIfdOffset uint32) (index IfdIndex, err error
|
||||||
Index: index,
|
Index: index,
|
||||||
Offset: offset,
|
Offset: offset,
|
||||||
Entries: entries,
|
Entries: entries,
|
||||||
|
EntriesByTagId: entriesByTagId,
|
||||||
Children: make([]*Ifd, 0),
|
Children: make([]*Ifd, 0),
|
||||||
NextIfdOffset: nextIfdOffset,
|
NextIfdOffset: nextIfdOffset,
|
||||||
}
|
}
|
||||||
|
@ -476,7 +538,7 @@ func (ie *IfdEnumerate) Collect(rootIfdOffset uint32) (index IfdIndex, err error
|
||||||
|
|
||||||
// ParseOneIfd is a hack to use an IE to parse a raw IFD block. Can be used for
|
// ParseOneIfd is a hack to use an IE to parse a raw IFD block. Can be used for
|
||||||
// testing.
|
// testing.
|
||||||
func ParseOneIfd(ii IfdIdentity, byteOrder binary.ByteOrder, ifdBlock []byte, visitor TagVisitor) (nextIfdOffset uint32, entries []IfdTagEntry, err error) {
|
func ParseOneIfd(ii IfdIdentity, byteOrder binary.ByteOrder, ifdBlock []byte, visitor TagVisitor) (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))
|
||||||
|
@ -496,7 +558,7 @@ func ParseOneIfd(ii IfdIdentity, byteOrder binary.ByteOrder, ifdBlock []byte, vi
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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(ii IfdIdentity, byteOrder binary.ByteOrder, tagBlock []byte) (tag IfdTagEntry, err error) {
|
func ParseOneTag(ii 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))
|
||||||
|
|
|
@ -58,7 +58,7 @@ func TestIfdTagEntry_ValueBytes_RealData(t *testing.T) {
|
||||||
var ite *IfdTagEntry
|
var ite *IfdTagEntry
|
||||||
for _, thisIte := range index.RootIfd.Entries {
|
for _, thisIte := range index.RootIfd.Entries {
|
||||||
if thisIte.TagId == 0x0110 {
|
if thisIte.TagId == 0x0110 {
|
||||||
ite = &thisIte
|
ite = thisIte
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,7 @@ func TestIfdTagEntry_Resolver_ValueBytes(t *testing.T) {
|
||||||
var ite *IfdTagEntry
|
var ite *IfdTagEntry
|
||||||
for _, thisIte := range index.RootIfd.Entries {
|
for _, thisIte := range index.RootIfd.Entries {
|
||||||
if thisIte.TagId == 0x0110 {
|
if thisIte.TagId == 0x0110 {
|
||||||
ite = &thisIte
|
ite = thisIte
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -150,7 +150,7 @@ func TestIfdTagEntry_Resolver_ValueBytes__Unknown_Field_And_Nonroot_Ifd(t *testi
|
||||||
var ite *IfdTagEntry
|
var ite *IfdTagEntry
|
||||||
for _, thisIte := range ifdExif.Entries {
|
for _, thisIte := range ifdExif.Entries {
|
||||||
if thisIte.TagId == 0x9000 {
|
if thisIte.TagId == 0x9000 {
|
||||||
ite = &thisIte
|
ite = thisIte
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -172,3 +172,108 @@ func TestIfdTagEntry_Resolver_ValueBytes__Unknown_Field_And_Nonroot_Ifd(t *testi
|
||||||
t.Fatalf("Recovered unknown value is not correct.")
|
t.Fatalf("Recovered unknown value is not correct.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_Ifd_FindTagWithId_Hit(t *testing.T) {
|
||||||
|
filepath := path.Join(assetsPath, "NDM_8901.jpg")
|
||||||
|
|
||||||
|
e := NewExif()
|
||||||
|
|
||||||
|
rawExif, err := e.SearchAndExtractExif(filepath)
|
||||||
|
log.PanicIf(err)
|
||||||
|
|
||||||
|
_, index, err := e.Collect(rawExif)
|
||||||
|
log.PanicIf(err)
|
||||||
|
|
||||||
|
ifd := index.RootIfd
|
||||||
|
results, err := ifd.FindTagWithId(0x011b)
|
||||||
|
|
||||||
|
if len(results) != 1 {
|
||||||
|
t.Fatalf("Exactly one result was not found: (%d)", len(results))
|
||||||
|
} else if results[0].TagId != 0x011b {
|
||||||
|
t.Fatalf("The result was not expected: %v", results[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_Ifd_FindTagWithId_Miss(t *testing.T) {
|
||||||
|
filepath := path.Join(assetsPath, "NDM_8901.jpg")
|
||||||
|
|
||||||
|
e := NewExif()
|
||||||
|
|
||||||
|
rawExif, err := e.SearchAndExtractExif(filepath)
|
||||||
|
log.PanicIf(err)
|
||||||
|
|
||||||
|
_, index, err := e.Collect(rawExif)
|
||||||
|
log.PanicIf(err)
|
||||||
|
|
||||||
|
ifd := index.RootIfd
|
||||||
|
|
||||||
|
_, err = ifd.FindTagWithId(0xffff)
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("Expected error for not-found tag.")
|
||||||
|
} else if log.Is(err, ErrTagNotFound) == false {
|
||||||
|
log.Panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_Ifd_FindTagWithName_Hit(t *testing.T) {
|
||||||
|
filepath := path.Join(assetsPath, "NDM_8901.jpg")
|
||||||
|
|
||||||
|
e := NewExif()
|
||||||
|
|
||||||
|
rawExif, err := e.SearchAndExtractExif(filepath)
|
||||||
|
log.PanicIf(err)
|
||||||
|
|
||||||
|
_, index, err := e.Collect(rawExif)
|
||||||
|
log.PanicIf(err)
|
||||||
|
|
||||||
|
ifd := index.RootIfd
|
||||||
|
results, err := ifd.FindTagWithName("YResolution")
|
||||||
|
|
||||||
|
if len(results) != 1 {
|
||||||
|
t.Fatalf("Exactly one result was not found: (%d)", len(results))
|
||||||
|
} else if results[0].TagId != 0x011b {
|
||||||
|
t.Fatalf("The result was not expected: %v", results[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_Ifd_FindTagWithName_Miss(t *testing.T) {
|
||||||
|
filepath := path.Join(assetsPath, "NDM_8901.jpg")
|
||||||
|
|
||||||
|
e := NewExif()
|
||||||
|
|
||||||
|
rawExif, err := e.SearchAndExtractExif(filepath)
|
||||||
|
log.PanicIf(err)
|
||||||
|
|
||||||
|
_, index, err := e.Collect(rawExif)
|
||||||
|
log.PanicIf(err)
|
||||||
|
|
||||||
|
ifd := index.RootIfd
|
||||||
|
|
||||||
|
_, err = ifd.FindTagWithName("PlanarConfiguration")
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("Expected error for not-found tag.")
|
||||||
|
} else if log.Is(err, ErrTagNotFound) == false {
|
||||||
|
log.Panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_Ifd_FindTagWithName_NonStandard(t *testing.T) {
|
||||||
|
filepath := path.Join(assetsPath, "NDM_8901.jpg")
|
||||||
|
|
||||||
|
e := NewExif()
|
||||||
|
|
||||||
|
rawExif, err := e.SearchAndExtractExif(filepath)
|
||||||
|
log.PanicIf(err)
|
||||||
|
|
||||||
|
_, index, err := e.Collect(rawExif)
|
||||||
|
log.PanicIf(err)
|
||||||
|
|
||||||
|
ifd := index.RootIfd
|
||||||
|
|
||||||
|
_, err = ifd.FindTagWithName("GeorgeNotAtHome")
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("Expected error for not-found tag.")
|
||||||
|
} else if log.Is(err, ErrTagNotStandard) == false {
|
||||||
|
log.Panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
4
tags.go
4
tags.go
|
@ -4,7 +4,6 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"fmt"
|
"fmt"
|
||||||
"errors"
|
|
||||||
|
|
||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
"github.com/dsoprea/go-logging"
|
"github.com/dsoprea/go-logging"
|
||||||
|
@ -81,7 +80,6 @@ var (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
tagsLogger = log.NewLogger("exif.tags")
|
tagsLogger = log.NewLogger("exif.tags")
|
||||||
ErrTagNotFound = errors.New("tag not found")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -270,7 +268,7 @@ func (ti *TagIndex) GetWithName(ii IfdIdentity, name string) (it *IndexedTag, er
|
||||||
|
|
||||||
it, found := ti.tagsByIfdR[ii.IfdName][name]
|
it, found := ti.tagsByIfdR[ii.IfdName][name]
|
||||||
if found != true {
|
if found != true {
|
||||||
log.Panicf("tag with IFD [%s] and name [%s] not known", ii.IfdName, name)
|
log.Panic(ErrTagNotFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
return it, nil
|
return it, nil
|
||||||
|
|
Loading…
Reference in New Issue