mirror of
https://github.com/dsoprea/go-exif.git
synced 2025-05-31 11:41:57 +00:00
ifd_enumerate: Added tests.
- Refactored (IfdTagEntry).ValueBytes() to handle managed undefined values.
This commit is contained in:
parent
f1f23dca82
commit
50eafa98d6
12
exif.go
12
exif.go
@ -135,14 +135,14 @@ func (e *Exif) ParseExifHeader(data []byte) (eh ExifHeader, err error) {
|
|||||||
return eh, nil
|
return eh, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Exif) Visit(exifData []byte, visitor TagVisitor) (err error) {
|
func (e *Exif) Visit(exifData []byte, visitor TagVisitor) (eh ExifHeader, 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))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
eh, err := e.ParseExifHeader(exifData)
|
eh, err = e.ParseExifHeader(exifData)
|
||||||
log.PanicIf(err)
|
log.PanicIf(err)
|
||||||
|
|
||||||
ie := NewIfdEnumerate(exifData, eh.ByteOrder)
|
ie := NewIfdEnumerate(exifData, eh.ByteOrder)
|
||||||
@ -150,17 +150,17 @@ func (e *Exif) Visit(exifData []byte, visitor TagVisitor) (err error) {
|
|||||||
err = ie.Scan(IfdStandard, eh.FirstIfdOffset, visitor)
|
err = ie.Scan(IfdStandard, eh.FirstIfdOffset, visitor)
|
||||||
log.PanicIf(err)
|
log.PanicIf(err)
|
||||||
|
|
||||||
return nil
|
return eh, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Exif) Collect(exifData []byte) (index IfdIndex, err error) {
|
func (e *Exif) Collect(exifData []byte) (eh ExifHeader, index IfdIndex, 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))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
eh, err := e.ParseExifHeader(exifData)
|
eh, err = e.ParseExifHeader(exifData)
|
||||||
log.PanicIf(err)
|
log.PanicIf(err)
|
||||||
|
|
||||||
ie := NewIfdEnumerate(exifData, eh.ByteOrder)
|
ie := NewIfdEnumerate(exifData, eh.ByteOrder)
|
||||||
@ -168,5 +168,5 @@ func (e *Exif) Collect(exifData []byte) (index IfdIndex, err error) {
|
|||||||
index, err = ie.Collect(eh.FirstIfdOffset)
|
index, err = ie.Collect(eh.FirstIfdOffset)
|
||||||
log.PanicIf(err)
|
log.PanicIf(err)
|
||||||
|
|
||||||
return index, nil
|
return eh, index, nil
|
||||||
}
|
}
|
||||||
|
10
exif_test.go
10
exif_test.go
@ -109,7 +109,7 @@ func TestVisit(t *testing.T) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
err = e.Visit(data[foundAt:], visitor)
|
_, err = e.Visit(data[foundAt:], visitor)
|
||||||
log.PanicIf(err)
|
log.PanicIf(err)
|
||||||
|
|
||||||
// for _, line := range tags {
|
// for _, line := range tags {
|
||||||
@ -198,7 +198,7 @@ func TestCollect(t *testing.T) {
|
|||||||
rawExif, err := e.SearchAndExtractExif(filepath)
|
rawExif, err := e.SearchAndExtractExif(filepath)
|
||||||
log.PanicIf(err)
|
log.PanicIf(err)
|
||||||
|
|
||||||
index, err := e.Collect(rawExif)
|
_, index, err := e.Collect(rawExif)
|
||||||
log.PanicIf(err)
|
log.PanicIf(err)
|
||||||
|
|
||||||
rootIfd := index.RootIfd
|
rootIfd := index.RootIfd
|
||||||
@ -257,7 +257,7 @@ func TestCollect(t *testing.T) {
|
|||||||
foundExif := 0
|
foundExif := 0
|
||||||
foundGps := 0
|
foundGps := 0
|
||||||
for _, ite := range lookup[IfdStandard][0].Entries {
|
for _, ite := range lookup[IfdStandard][0].Entries {
|
||||||
if ite.IfdName == IfdExif {
|
if ite.ChildIfdName == IfdExif {
|
||||||
foundExif++
|
foundExif++
|
||||||
|
|
||||||
if IfdTagNames[ite.TagId] != IfdExif {
|
if IfdTagNames[ite.TagId] != IfdExif {
|
||||||
@ -265,7 +265,7 @@ func TestCollect(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ite.IfdName == IfdGps {
|
if ite.ChildIfdName == IfdGps {
|
||||||
foundGps++
|
foundGps++
|
||||||
|
|
||||||
if IfdTagNames[ite.TagId] != IfdGps {
|
if IfdTagNames[ite.TagId] != IfdGps {
|
||||||
@ -282,7 +282,7 @@ func TestCollect(t *testing.T) {
|
|||||||
|
|
||||||
foundIop := 0
|
foundIop := 0
|
||||||
for _, ite := range lookup[IfdExif][0].Entries {
|
for _, ite := range lookup[IfdExif][0].Entries {
|
||||||
if ite.IfdName == IfdIop {
|
if ite.ChildIfdName == IfdIop {
|
||||||
foundIop++
|
foundIop++
|
||||||
|
|
||||||
if IfdTagNames[ite.TagId] != IfdIop {
|
if IfdTagNames[ite.TagId] != IfdIop {
|
||||||
|
@ -29,11 +29,11 @@ type builderTag struct {
|
|||||||
// value is either a value that can be encoded, an IfdBuilder instance (for
|
// value is either a value that can be encoded, an IfdBuilder instance (for
|
||||||
// child IFDs), or an IfdTagEntry instance representing an existing,
|
// child IFDs), or an IfdTagEntry instance representing an existing,
|
||||||
// previously-stored tag.
|
// previously-stored tag.
|
||||||
value interface{}
|
valueBytes interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bt builderTag) String() string {
|
func (bt builderTag) String() string {
|
||||||
return fmt.Sprintf("BuilderTag<TAG-ID=(0x%02x) IFD=[%s] VALUE=[%v]>", bt.tagId, bt.ifdName, bt.value)
|
return fmt.Sprintf("BuilderTag<TAG-ID=(0x%02x) IFD=[%s] VALUE=[%v]>", bt.tagId, bt.ifdName, bt.valueBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -463,7 +463,7 @@ func (ib *IfdBuilder) AddChildIfd(childIfd *IfdBuilder) (err error) {
|
|||||||
bt := builderTag{
|
bt := builderTag{
|
||||||
ifdName: childIfd.ifdName,
|
ifdName: childIfd.ifdName,
|
||||||
tagId: childIfd.ifdTagId,
|
tagId: childIfd.ifdTagId,
|
||||||
value: childIfd,
|
valueBytes: childIfd,
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
@ -474,7 +474,7 @@ func (ib *IfdBuilder) AddChildIfd(childIfd *IfdBuilder) (err error) {
|
|||||||
// AddTagsFromExisting does a verbatim copy of the entries in `ifd` to this
|
// AddTagsFromExisting does a verbatim copy of the entries in `ifd` to this
|
||||||
// builder. It excludes child IFDs. This must be added explicitly via
|
// builder. It excludes child IFDs. This must be added explicitly via
|
||||||
// `AddChildIfd()`.
|
// `AddChildIfd()`.
|
||||||
func (ib *IfdBuilder) AddTagsFromExisting(ifd *Ifd, includeTagIds []uint16, excludeTagIds []uint16) (err error) {
|
func (ib *IfdBuilder) AddTagsFromExisting(ifd *Ifd, itevr *IfdTagEntryValueResolver, includeTagIds []uint16, excludeTagIds []uint16) (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))
|
||||||
@ -498,22 +498,17 @@ func (ib *IfdBuilder) AddTagsFromExisting(ifd *Ifd, includeTagIds []uint16, excl
|
|||||||
// an IfdEnumerator and then be read and re-read (like an IEnumerable vs IList).
|
// an IfdEnumerator and then be read and re-read (like an IEnumerable vs IList).
|
||||||
|
|
||||||
|
|
||||||
// TODO(dustin): !! Finish.
|
for _, ite := range ifd.Entries {
|
||||||
// itevr := NewIfdTagEntryValueResolver(rawExif []byte, ib.byteOrder)
|
|
||||||
// itevr.ValueBytes(ite *IfdTagEntry) (value []byte, err error)
|
|
||||||
|
|
||||||
|
|
||||||
for _, tag := range ifd.Entries {
|
|
||||||
// If we want to add an IFD tag, we'll have to build it first and *then*
|
// If we want to add an IFD tag, we'll have to build it first and *then*
|
||||||
// add it via a different method.
|
// add it via a different method.
|
||||||
if tag.IfdName != "" {
|
if ite.ChildIfdName != "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if excludeTagIds != nil && len(excludeTagIds) > 0 {
|
if excludeTagIds != nil && len(excludeTagIds) > 0 {
|
||||||
found := false
|
found := false
|
||||||
for _, excludedTagId := range excludeTagIds {
|
for _, excludedTagId := range excludeTagIds {
|
||||||
if excludedTagId == tag.TagId {
|
if excludedTagId == ite.TagId {
|
||||||
found = true
|
found = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -529,7 +524,7 @@ func (ib *IfdBuilder) AddTagsFromExisting(ifd *Ifd, includeTagIds []uint16, excl
|
|||||||
|
|
||||||
found := false
|
found := false
|
||||||
for _, includedTagId := range includeTagIds {
|
for _, includedTagId := range includeTagIds {
|
||||||
if includedTagId == tag.TagId {
|
if includedTagId == ite.TagId {
|
||||||
found = true
|
found = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -541,10 +536,14 @@ func (ib *IfdBuilder) AddTagsFromExisting(ifd *Ifd, includeTagIds []uint16, excl
|
|||||||
}
|
}
|
||||||
|
|
||||||
bt := builderTag{
|
bt := builderTag{
|
||||||
tagId: tag.TagId,
|
tagId: ite.TagId,
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(dustin): !! For right now, a IfdTagEntry instance will mean that the value will have to be inherited/copied from an existing offset.
|
if itevr != nil {
|
||||||
value: tag,
|
var err error
|
||||||
|
|
||||||
|
bt.valueBytes, err = itevr.ValueBytes(&ite)
|
||||||
|
log.PanicIf(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err := ib.Add(bt)
|
err := ib.Add(bt)
|
||||||
|
@ -18,21 +18,21 @@ func TestAdd(t *testing.T) {
|
|||||||
|
|
||||||
bt := builderTag{
|
bt := builderTag{
|
||||||
tagId: 0x11,
|
tagId: 0x11,
|
||||||
value: "test string",
|
valueBytes: "test string",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x22,
|
tagId: 0x22,
|
||||||
value: "test string2",
|
valueBytes: "test string2",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x33,
|
tagId: 0x33,
|
||||||
value: "test string3",
|
valueBytes: "test string3",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
@ -41,7 +41,7 @@ func TestAdd(t *testing.T) {
|
|||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x44,
|
tagId: 0x44,
|
||||||
value: originalShorts,
|
valueBytes: originalShorts,
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
@ -64,25 +64,25 @@ func TestAdd(t *testing.T) {
|
|||||||
|
|
||||||
if tags[0].tagId != 0x11 {
|
if tags[0].tagId != 0x11 {
|
||||||
t.Fatalf("tag (0) tag-ID not correct")
|
t.Fatalf("tag (0) tag-ID not correct")
|
||||||
} else if tags[0].value != "test string" {
|
} else if tags[0].valueBytes != "test string" {
|
||||||
t.Fatalf("tag (0) value not correct")
|
t.Fatalf("tag (0) value not correct")
|
||||||
}
|
}
|
||||||
|
|
||||||
if tags[1].tagId != 0x22 {
|
if tags[1].tagId != 0x22 {
|
||||||
t.Fatalf("tag (1) tag-ID not correct")
|
t.Fatalf("tag (1) tag-ID not correct")
|
||||||
} else if tags[1].value != "test string2" {
|
} else if tags[1].valueBytes != "test string2" {
|
||||||
t.Fatalf("tag (1) value not correct")
|
t.Fatalf("tag (1) value not correct")
|
||||||
}
|
}
|
||||||
|
|
||||||
if tags[2].tagId != 0x33 {
|
if tags[2].tagId != 0x33 {
|
||||||
t.Fatalf("tag (2) tag-ID not correct")
|
t.Fatalf("tag (2) tag-ID not correct")
|
||||||
} else if tags[2].value != "test string3" {
|
} else if tags[2].valueBytes != "test string3" {
|
||||||
t.Fatalf("tag (2) value not correct")
|
t.Fatalf("tag (2) value not correct")
|
||||||
}
|
}
|
||||||
|
|
||||||
if tags[3].tagId != 0x44 {
|
if tags[3].tagId != 0x44 {
|
||||||
t.Fatalf("tag (3) tag-ID not correct")
|
t.Fatalf("tag (3) tag-ID not correct")
|
||||||
} else if reflect.DeepEqual(tags[3].value.([]uint16), originalShorts) != true {
|
} else if reflect.DeepEqual(tags[3].valueBytes.([]uint16), originalShorts) != true {
|
||||||
t.Fatalf("tag (3) value not correct")
|
t.Fatalf("tag (3) value not correct")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -111,7 +111,7 @@ func TestAddChildIfd(t *testing.T) {
|
|||||||
|
|
||||||
bt := builderTag{
|
bt := builderTag{
|
||||||
tagId: 0x11,
|
tagId: 0x11,
|
||||||
value: "test string",
|
valueBytes: "test string",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
@ -122,7 +122,7 @@ func TestAddChildIfd(t *testing.T) {
|
|||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x22,
|
tagId: 0x22,
|
||||||
value: "test string",
|
valueBytes: "test string",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
@ -131,7 +131,7 @@ func TestAddChildIfd(t *testing.T) {
|
|||||||
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.ifdTagId {
|
||||||
t.Fatalf("second tag ID does not match child-IFD tag-ID")
|
t.Fatalf("second tag ID does not match child-IFD tag-ID")
|
||||||
} else if ib.tags[1].value != ibChild {
|
} else if ib.tags[1].valueBytes != 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 {
|
||||||
t.Fatalf("third tag not correct")
|
t.Fatalf("third tag not correct")
|
||||||
@ -149,7 +149,7 @@ func TestAddTagsFromExisting(t *testing.T) {
|
|||||||
|
|
||||||
entries[1] = IfdTagEntry{
|
entries[1] = IfdTagEntry{
|
||||||
TagId: 0x22,
|
TagId: 0x22,
|
||||||
IfdName: "some ifd",
|
ChildIfdName: "some ifd",
|
||||||
}
|
}
|
||||||
|
|
||||||
entries[2] = IfdTagEntry{
|
entries[2] = IfdTagEntry{
|
||||||
@ -160,7 +160,7 @@ func TestAddTagsFromExisting(t *testing.T) {
|
|||||||
Entries: entries,
|
Entries: entries,
|
||||||
}
|
}
|
||||||
|
|
||||||
err := ib.AddTagsFromExisting(ifd, nil, nil)
|
err := ib.AddTagsFromExisting(ifd, nil, nil, nil)
|
||||||
log.PanicIf(err)
|
log.PanicIf(err)
|
||||||
|
|
||||||
if ib.tags[0].tagId != 0x11 {
|
if ib.tags[0].tagId != 0x11 {
|
||||||
@ -183,7 +183,7 @@ func TestAddTagsFromExisting__Includes(t *testing.T) {
|
|||||||
|
|
||||||
entries[1] = IfdTagEntry{
|
entries[1] = IfdTagEntry{
|
||||||
TagId: 0x22,
|
TagId: 0x22,
|
||||||
IfdName: "some ifd",
|
ChildIfdName: "some ifd",
|
||||||
}
|
}
|
||||||
|
|
||||||
entries[2] = IfdTagEntry{
|
entries[2] = IfdTagEntry{
|
||||||
@ -194,7 +194,7 @@ func TestAddTagsFromExisting__Includes(t *testing.T) {
|
|||||||
Entries: entries,
|
Entries: entries,
|
||||||
}
|
}
|
||||||
|
|
||||||
err := ib.AddTagsFromExisting(ifd, []uint16 { 0x33 }, nil)
|
err := ib.AddTagsFromExisting(ifd, nil, []uint16 { 0x33 }, nil)
|
||||||
log.PanicIf(err)
|
log.PanicIf(err)
|
||||||
|
|
||||||
if ib.tags[0].tagId != 0x33 {
|
if ib.tags[0].tagId != 0x33 {
|
||||||
@ -215,7 +215,7 @@ func TestAddTagsFromExisting__Excludes(t *testing.T) {
|
|||||||
|
|
||||||
entries[1] = IfdTagEntry{
|
entries[1] = IfdTagEntry{
|
||||||
TagId: 0x22,
|
TagId: 0x22,
|
||||||
IfdName: "some ifd",
|
ChildIfdName: "some ifd",
|
||||||
}
|
}
|
||||||
|
|
||||||
entries[2] = IfdTagEntry{
|
entries[2] = IfdTagEntry{
|
||||||
@ -226,7 +226,7 @@ func TestAddTagsFromExisting__Excludes(t *testing.T) {
|
|||||||
Entries: entries,
|
Entries: entries,
|
||||||
}
|
}
|
||||||
|
|
||||||
err := ib.AddTagsFromExisting(ifd, nil, []uint16 { 0x11 })
|
err := ib.AddTagsFromExisting(ifd, nil, nil, []uint16 { 0x11 })
|
||||||
log.PanicIf(err)
|
log.PanicIf(err)
|
||||||
|
|
||||||
if ib.tags[0].tagId != 0x33 {
|
if ib.tags[0].tagId != 0x33 {
|
||||||
@ -241,21 +241,21 @@ func TestFindN_First_1(t *testing.T) {
|
|||||||
|
|
||||||
bt := builderTag{
|
bt := builderTag{
|
||||||
tagId: 0x11,
|
tagId: 0x11,
|
||||||
value: "test string",
|
valueBytes: "test string",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x22,
|
tagId: 0x22,
|
||||||
value: "test string2",
|
valueBytes: "test string2",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x33,
|
tagId: 0x33,
|
||||||
value: "test string3",
|
valueBytes: "test string3",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
@ -282,21 +282,21 @@ func TestFindN_First_2_1Returned(t *testing.T) {
|
|||||||
|
|
||||||
bt := builderTag{
|
bt := builderTag{
|
||||||
tagId: 0x11,
|
tagId: 0x11,
|
||||||
value: "test string",
|
valueBytes: "test string",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x22,
|
tagId: 0x22,
|
||||||
value: "test string2",
|
valueBytes: "test string2",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x33,
|
tagId: 0x33,
|
||||||
value: "test string3",
|
valueBytes: "test string3",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
@ -323,35 +323,35 @@ func TestFindN_First_2_2Returned(t *testing.T) {
|
|||||||
|
|
||||||
bt := builderTag{
|
bt := builderTag{
|
||||||
tagId: 0x11,
|
tagId: 0x11,
|
||||||
value: "test string",
|
valueBytes: "test string",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x22,
|
tagId: 0x22,
|
||||||
value: "test string2",
|
valueBytes: "test string2",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x33,
|
tagId: 0x33,
|
||||||
value: "test string3",
|
valueBytes: "test string3",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x11,
|
tagId: 0x11,
|
||||||
value: "test string4",
|
valueBytes: "test string4",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x11,
|
tagId: 0x11,
|
||||||
value: "test string5",
|
valueBytes: "test string5",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
@ -370,13 +370,13 @@ func TestFindN_First_2_2Returned(t *testing.T) {
|
|||||||
tags := ib.Tags()
|
tags := ib.Tags()
|
||||||
|
|
||||||
bt = tags[found[0]]
|
bt = tags[found[0]]
|
||||||
if bt.tagId != 0x11 || bt.value != "test string" {
|
if bt.tagId != 0x11 || bt.valueBytes != "test string" {
|
||||||
log.Panicf("Found entry 0 is not correct: (0x%02x) [%s]", bt.tagId, bt.value)
|
log.Panicf("Found entry 0 is not correct: (0x%02x) [%s]", bt.tagId, bt.valueBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
bt = tags[found[1]]
|
bt = tags[found[1]]
|
||||||
if bt.tagId != 0x11 || bt.value != "test string4" {
|
if bt.tagId != 0x11 || bt.valueBytes != "test string4" {
|
||||||
log.Panicf("Found entry 1 is not correct: (0x%02x) [%s]", bt.tagId, bt.value)
|
log.Panicf("Found entry 1 is not correct: (0x%02x) [%s]", bt.tagId, bt.valueBytes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -385,42 +385,42 @@ func TestFindN_Middle_WithDuplicates(t *testing.T) {
|
|||||||
|
|
||||||
bt := builderTag{
|
bt := builderTag{
|
||||||
tagId: 0x11,
|
tagId: 0x11,
|
||||||
value: "test string",
|
valueBytes: "test string",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x22,
|
tagId: 0x22,
|
||||||
value: "test string2",
|
valueBytes: "test string2",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x33,
|
tagId: 0x33,
|
||||||
value: "test string3",
|
valueBytes: "test string3",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x11,
|
tagId: 0x11,
|
||||||
value: "test string4",
|
valueBytes: "test string4",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x11,
|
tagId: 0x11,
|
||||||
value: "test string5",
|
valueBytes: "test string5",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x33,
|
tagId: 0x33,
|
||||||
value: "test string6",
|
valueBytes: "test string6",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
@ -447,28 +447,28 @@ func TestFindN_Middle_NoDuplicates(t *testing.T) {
|
|||||||
|
|
||||||
bt := builderTag{
|
bt := builderTag{
|
||||||
tagId: 0x11,
|
tagId: 0x11,
|
||||||
value: "test string",
|
valueBytes: "test string",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x22,
|
tagId: 0x22,
|
||||||
value: "test string2",
|
valueBytes: "test string2",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x33,
|
tagId: 0x33,
|
||||||
value: "test string3",
|
valueBytes: "test string3",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x11,
|
tagId: 0x11,
|
||||||
value: "test string4",
|
valueBytes: "test string4",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
@ -506,28 +506,28 @@ func TestFind_Hit(t *testing.T) {
|
|||||||
|
|
||||||
bt := builderTag{
|
bt := builderTag{
|
||||||
tagId: 0x11,
|
tagId: 0x11,
|
||||||
value: "test string",
|
valueBytes: "test string",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x22,
|
tagId: 0x22,
|
||||||
value: "test string2",
|
valueBytes: "test string2",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x33,
|
tagId: 0x33,
|
||||||
value: "test string3",
|
valueBytes: "test string3",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x11,
|
tagId: 0x11,
|
||||||
value: "test string4",
|
valueBytes: "test string4",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
@ -552,28 +552,28 @@ func TestFind_Miss(t *testing.T) {
|
|||||||
|
|
||||||
bt := builderTag{
|
bt := builderTag{
|
||||||
tagId: 0x11,
|
tagId: 0x11,
|
||||||
value: "test string",
|
valueBytes: "test string",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x22,
|
tagId: 0x22,
|
||||||
value: "test string2",
|
valueBytes: "test string2",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x33,
|
tagId: 0x33,
|
||||||
value: "test string3",
|
valueBytes: "test string3",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x11,
|
tagId: 0x11,
|
||||||
value: "test string4",
|
valueBytes: "test string4",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
@ -591,21 +591,21 @@ func TestReplace(t *testing.T) {
|
|||||||
|
|
||||||
bt := builderTag{
|
bt := builderTag{
|
||||||
tagId: 0x11,
|
tagId: 0x11,
|
||||||
value: "test string",
|
valueBytes: "test string",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x22,
|
tagId: 0x22,
|
||||||
value: "test string2",
|
valueBytes: "test string2",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x33,
|
tagId: 0x33,
|
||||||
value: "test string3",
|
valueBytes: "test string3",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
@ -621,7 +621,7 @@ func TestReplace(t *testing.T) {
|
|||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x99,
|
tagId: 0x99,
|
||||||
value: "test string4",
|
valueBytes: "test string4",
|
||||||
}
|
}
|
||||||
|
|
||||||
err := ib.Replace(0x22, bt)
|
err := ib.Replace(0x22, bt)
|
||||||
@ -642,21 +642,21 @@ func TestReplaceN(t *testing.T) {
|
|||||||
|
|
||||||
bt := builderTag{
|
bt := builderTag{
|
||||||
tagId: 0x11,
|
tagId: 0x11,
|
||||||
value: "test string",
|
valueBytes: "test string",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x22,
|
tagId: 0x22,
|
||||||
value: "test string2",
|
valueBytes: "test string2",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x33,
|
tagId: 0x33,
|
||||||
value: "test string3",
|
valueBytes: "test string3",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
@ -672,7 +672,7 @@ func TestReplaceN(t *testing.T) {
|
|||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0xA9,
|
tagId: 0xA9,
|
||||||
value: "test string4",
|
valueBytes: "test string4",
|
||||||
}
|
}
|
||||||
|
|
||||||
err := ib.ReplaceAt(1, bt)
|
err := ib.ReplaceAt(1, bt)
|
||||||
@ -693,28 +693,28 @@ func TestDeleteFirst(t *testing.T) {
|
|||||||
|
|
||||||
bt := builderTag{
|
bt := builderTag{
|
||||||
tagId: 0x11,
|
tagId: 0x11,
|
||||||
value: "test string",
|
valueBytes: "test string",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x22,
|
tagId: 0x22,
|
||||||
value: "test string2",
|
valueBytes: "test string2",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x22,
|
tagId: 0x22,
|
||||||
value: "test string3",
|
valueBytes: "test string3",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x33,
|
tagId: 0x33,
|
||||||
value: "test string4",
|
valueBytes: "test string4",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
@ -781,28 +781,28 @@ func TestDeleteN(t *testing.T) {
|
|||||||
|
|
||||||
bt := builderTag{
|
bt := builderTag{
|
||||||
tagId: 0x11,
|
tagId: 0x11,
|
||||||
value: "test string",
|
valueBytes: "test string",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x22,
|
tagId: 0x22,
|
||||||
value: "test string2",
|
valueBytes: "test string2",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x22,
|
tagId: 0x22,
|
||||||
value: "test string3",
|
valueBytes: "test string3",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x33,
|
tagId: 0x33,
|
||||||
value: "test string4",
|
valueBytes: "test string4",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
@ -869,28 +869,28 @@ func TestDeleteN_Two(t *testing.T) {
|
|||||||
|
|
||||||
bt := builderTag{
|
bt := builderTag{
|
||||||
tagId: 0x11,
|
tagId: 0x11,
|
||||||
value: "test string",
|
valueBytes: "test string",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x22,
|
tagId: 0x22,
|
||||||
value: "test string2",
|
valueBytes: "test string2",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x22,
|
tagId: 0x22,
|
||||||
value: "test string3",
|
valueBytes: "test string3",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x33,
|
tagId: 0x33,
|
||||||
value: "test string4",
|
valueBytes: "test string4",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
@ -940,28 +940,28 @@ func TestDeleteAll(t *testing.T) {
|
|||||||
|
|
||||||
bt := builderTag{
|
bt := builderTag{
|
||||||
tagId: 0x11,
|
tagId: 0x11,
|
||||||
value: "test string",
|
valueBytes: "test string",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x22,
|
tagId: 0x22,
|
||||||
value: "test string2",
|
valueBytes: "test string2",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x22,
|
tagId: 0x22,
|
||||||
value: "test string3",
|
valueBytes: "test string3",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
|
|
||||||
bt = builderTag{
|
bt = builderTag{
|
||||||
tagId: 0x33,
|
tagId: 0x33,
|
||||||
value: "test string4",
|
valueBytes: "test string4",
|
||||||
}
|
}
|
||||||
|
|
||||||
ib.Add(bt)
|
ib.Add(bt)
|
||||||
|
@ -137,9 +137,18 @@ type IfdTagEntry struct {
|
|||||||
UnitCount uint32
|
UnitCount uint32
|
||||||
ValueOffset uint32
|
ValueOffset uint32
|
||||||
RawValueOffset []byte
|
RawValueOffset []byte
|
||||||
|
|
||||||
|
// ChildIfdName is a name if this tag represents a child IFD.
|
||||||
|
ChildIfdName string
|
||||||
|
|
||||||
|
// IfdName is the IFD that this tag belongs to.
|
||||||
IfdName string
|
IfdName string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ite IfdTagEntry) String() string {
|
||||||
|
return fmt.Sprintf("IfdTagEntry<TAG-IFD=[%s] TAG-ID=(0x%02x) TAG-TYPE=[%s] UNIT-COUNT=(%d)>", ite.ChildIfdName, ite.TagId, TypeNames[ite.TagType], ite.UnitCount)
|
||||||
|
}
|
||||||
|
|
||||||
func (ite IfdTagEntry) ValueBytes(addressableData []byte, byteOrder binary.ByteOrder) (value []byte, err error) {
|
func (ite IfdTagEntry) ValueBytes(addressableData []byte, byteOrder binary.ByteOrder) (value []byte, err error) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if state := recover(); state != nil {
|
if state := recover(); state != nil {
|
||||||
@ -147,6 +156,28 @@ func (ite IfdTagEntry) ValueBytes(addressableData []byte, byteOrder binary.ByteO
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
if ite.TagType == TypeUndefined {
|
||||||
|
valueContext := ValueContext{
|
||||||
|
UnitCount: ite.UnitCount,
|
||||||
|
ValueOffset: ite.ValueOffset,
|
||||||
|
RawValueOffset: ite.RawValueOffset,
|
||||||
|
AddressableData: addressableData,
|
||||||
|
}
|
||||||
|
|
||||||
|
value, err := UndefinedValue(ite.IfdName, ite.TagId, valueContext, byteOrder)
|
||||||
|
log.PanicIf(err)
|
||||||
|
|
||||||
|
switch value.(type) {
|
||||||
|
case []byte:
|
||||||
|
return value.([]byte), nil
|
||||||
|
case string:
|
||||||
|
return []byte(value.(string)), nil
|
||||||
|
default:
|
||||||
|
// TODO(dustin): !! Finish translating the rest of the types (make reusable and replace into other similar implementations?)
|
||||||
|
log.Panicf("can not produce bytes for unknown-type tag (0x%02x)", ite.TagId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
originalType := NewTagType(ite.TagType, byteOrder)
|
originalType := NewTagType(ite.TagType, byteOrder)
|
||||||
byteCount := uint32(originalType.Size()) * ite.UnitCount
|
byteCount := uint32(originalType.Size()) * ite.UnitCount
|
||||||
|
|
||||||
@ -260,6 +291,7 @@ func (ie *IfdEnumerate) ParseIfd(ifdName string, ifdIndex int, ifdOffset uint32,
|
|||||||
}
|
}
|
||||||
|
|
||||||
tag := IfdTagEntry{
|
tag := IfdTagEntry{
|
||||||
|
IfdName: ifdName,
|
||||||
TagId: tagId,
|
TagId: tagId,
|
||||||
TagIndex: int(i),
|
TagIndex: int(i),
|
||||||
TagType: tagType,
|
TagType: tagType,
|
||||||
@ -270,7 +302,7 @@ func (ie *IfdEnumerate) ParseIfd(ifdName string, ifdIndex int, ifdOffset uint32,
|
|||||||
|
|
||||||
childIfdName, isIfd := IsIfdTag(tagId)
|
childIfdName, isIfd := IsIfdTag(tagId)
|
||||||
if isIfd == true {
|
if isIfd == true {
|
||||||
tag.IfdName = childIfdName
|
tag.ChildIfdName = childIfdName
|
||||||
|
|
||||||
if doDescend == true {
|
if doDescend == true {
|
||||||
ifdEnumerateLogger.Debugf(nil, "Descending to IFD [%s].", childIfdName)
|
ifdEnumerateLogger.Debugf(nil, "Descending to IFD [%s].", childIfdName)
|
||||||
@ -320,7 +352,10 @@ type Ifd struct {
|
|||||||
Name string
|
Name string
|
||||||
Index int
|
Index int
|
||||||
Offset uint32
|
Offset uint32
|
||||||
|
|
||||||
|
// TODO(dustin): !! Add a find method.
|
||||||
Entries []IfdTagEntry
|
Entries []IfdTagEntry
|
||||||
|
|
||||||
Children []*Ifd
|
Children []*Ifd
|
||||||
NextIfdOffset uint32
|
NextIfdOffset uint32
|
||||||
NextIfd *Ifd
|
NextIfd *Ifd
|
||||||
@ -455,12 +490,12 @@ func (ie *IfdEnumerate) Collect(rootIfdOffset uint32) (index IfdIndex, err error
|
|||||||
|
|
||||||
// Determine if any of our entries is a child IFD and queue it.
|
// Determine if any of our entries is a child IFD and queue it.
|
||||||
for _, entry := range entries {
|
for _, entry := range entries {
|
||||||
if entry.IfdName == "" {
|
if entry.ChildIfdName == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
qi := QueuedIfd {
|
qi := QueuedIfd {
|
||||||
Name: entry.IfdName,
|
Name: entry.ChildIfdName,
|
||||||
Index: 0,
|
Index: 0,
|
||||||
Offset: entry.ValueOffset,
|
Offset: entry.ValueOffset,
|
||||||
Parent: &ifd,
|
Parent: &ifd,
|
||||||
|
173
ifd_enumerate_test.go
Normal file
173
ifd_enumerate_test.go
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
package exif
|
||||||
|
|
||||||
|
import (
|
||||||
|
"path"
|
||||||
|
"testing"
|
||||||
|
"bytes"
|
||||||
|
|
||||||
|
"encoding/binary"
|
||||||
|
|
||||||
|
"github.com/dsoprea/go-logging"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestIfdTagEntry_ValueBytes(t *testing.T) {
|
||||||
|
byteOrder := binary.BigEndian
|
||||||
|
ve := NewValueEncoder(byteOrder)
|
||||||
|
|
||||||
|
original := []byte("original text")
|
||||||
|
|
||||||
|
ed, err := ve.encodeBytes(original)
|
||||||
|
log.PanicIf(err)
|
||||||
|
|
||||||
|
// Now, pass the raw encoded value as if it was the entire addressable area
|
||||||
|
// and provide an offset of 0 as if it was a real block of data and this
|
||||||
|
// value happened to be recorded at the beginning.
|
||||||
|
|
||||||
|
ite := IfdTagEntry{
|
||||||
|
TagType: TypeByte,
|
||||||
|
UnitCount: uint32(len(original)),
|
||||||
|
ValueOffset: 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
decodedBytes, err := ite.ValueBytes(ed.Encoded, byteOrder)
|
||||||
|
log.PanicIf(err)
|
||||||
|
|
||||||
|
if bytes.Compare(decodedBytes, original) != 0 {
|
||||||
|
t.Fatalf("Bytes not decoded correctly.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIfdTagEntry_ValueBytes_RealData(t *testing.T) {
|
||||||
|
defer func() {
|
||||||
|
if state := recover(); state != nil {
|
||||||
|
err := log.Wrap(state.(error))
|
||||||
|
log.PrintErrorf(err, "Test failure.")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
e := NewExif()
|
||||||
|
|
||||||
|
filepath := path.Join(assetsPath, "NDM_8901.jpg")
|
||||||
|
|
||||||
|
rawExif, err := e.SearchAndExtractExif(filepath)
|
||||||
|
log.PanicIf(err)
|
||||||
|
|
||||||
|
eh, index, err := e.Collect(rawExif)
|
||||||
|
log.PanicIf(err)
|
||||||
|
|
||||||
|
var ite *IfdTagEntry
|
||||||
|
for _, thisIte := range index.RootIfd.Entries {
|
||||||
|
if thisIte.TagId == 0x0110 {
|
||||||
|
ite = &thisIte
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ite == nil {
|
||||||
|
t.Fatalf("Tag not found.")
|
||||||
|
}
|
||||||
|
|
||||||
|
addressableData := rawExif[ExifAddressableAreaStart:]
|
||||||
|
decodedBytes, err := ite.ValueBytes(addressableData, eh.ByteOrder)
|
||||||
|
log.PanicIf(err)
|
||||||
|
|
||||||
|
expected := []byte("Canon EOS 5D Mark III")
|
||||||
|
expected = append(expected, 0)
|
||||||
|
|
||||||
|
if len(decodedBytes) != int(ite.UnitCount) {
|
||||||
|
t.Fatalf("Decoded bytes not the right count.")
|
||||||
|
} else if bytes.Compare(decodedBytes, expected) != 0 {
|
||||||
|
t.Fatalf("Decoded bytes not correct.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIfdTagEntry_Resolver_ValueBytes(t *testing.T) {
|
||||||
|
defer func() {
|
||||||
|
if state := recover(); state != nil {
|
||||||
|
err := log.Wrap(state.(error))
|
||||||
|
log.PrintErrorf(err, "Test failure.")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
e := NewExif()
|
||||||
|
|
||||||
|
filepath := path.Join(assetsPath, "NDM_8901.jpg")
|
||||||
|
|
||||||
|
rawExif, err := e.SearchAndExtractExif(filepath)
|
||||||
|
log.PanicIf(err)
|
||||||
|
|
||||||
|
eh, index, err := e.Collect(rawExif)
|
||||||
|
log.PanicIf(err)
|
||||||
|
|
||||||
|
var ite *IfdTagEntry
|
||||||
|
for _, thisIte := range index.RootIfd.Entries {
|
||||||
|
if thisIte.TagId == 0x0110 {
|
||||||
|
ite = &thisIte
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ite == nil {
|
||||||
|
t.Fatalf("Tag not found.")
|
||||||
|
}
|
||||||
|
|
||||||
|
itevr := NewIfdTagEntryValueResolver(rawExif, eh.ByteOrder)
|
||||||
|
|
||||||
|
decodedBytes, err := itevr.ValueBytes(ite)
|
||||||
|
log.PanicIf(err)
|
||||||
|
|
||||||
|
expected := []byte("Canon EOS 5D Mark III")
|
||||||
|
expected = append(expected, 0)
|
||||||
|
|
||||||
|
if len(decodedBytes) != int(ite.UnitCount) {
|
||||||
|
t.Fatalf("Decoded bytes not the right count.")
|
||||||
|
} else if bytes.Compare(decodedBytes, expected) != 0 {
|
||||||
|
t.Fatalf("Decoded bytes not correct.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIfdTagEntry_Resolver_ValueBytes__Unknown_Field_And_Nonroot_Ifd(t *testing.T) {
|
||||||
|
defer func() {
|
||||||
|
if state := recover(); state != nil {
|
||||||
|
err := log.Wrap(state.(error))
|
||||||
|
log.PrintErrorf(err, "Test failure.")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
e := NewExif()
|
||||||
|
|
||||||
|
filepath := path.Join(assetsPath, "NDM_8901.jpg")
|
||||||
|
|
||||||
|
rawExif, err := e.SearchAndExtractExif(filepath)
|
||||||
|
log.PanicIf(err)
|
||||||
|
|
||||||
|
eh, index, err := e.Collect(rawExif)
|
||||||
|
log.PanicIf(err)
|
||||||
|
|
||||||
|
ifdExif := index.Lookup[IfdExif][0]
|
||||||
|
|
||||||
|
var ite *IfdTagEntry
|
||||||
|
for _, thisIte := range ifdExif.Entries {
|
||||||
|
if thisIte.TagId == 0x9000 {
|
||||||
|
ite = &thisIte
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ite == nil {
|
||||||
|
t.Fatalf("Tag not found.")
|
||||||
|
}
|
||||||
|
|
||||||
|
itevr := NewIfdTagEntryValueResolver(rawExif, eh.ByteOrder)
|
||||||
|
|
||||||
|
decodedBytes, err := itevr.ValueBytes(ite)
|
||||||
|
log.PanicIf(err)
|
||||||
|
|
||||||
|
expected := []byte { '0', '2', '3', '0' }
|
||||||
|
|
||||||
|
if len(decodedBytes) != int(ite.UnitCount) {
|
||||||
|
t.Fatalf("Decoded bytes not the right count.")
|
||||||
|
} else if bytes.Compare(decodedBytes, expected) != 0 {
|
||||||
|
t.Fatalf("Recovered unknown value is not correct.")
|
||||||
|
}
|
||||||
|
}
|
@ -601,6 +601,8 @@ func UndefinedValue(indexedIfdName string, tagId uint16, valueContext ValueConte
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
typeDecodeLogger.Debugf(nil, "UndefinedValue: IFD=[%s] TAG-ID=(0x%02x)", indexedIfdName, tagId)
|
||||||
|
|
||||||
if indexedIfdName == IfdName(IfdExif, 0) {
|
if indexedIfdName == IfdName(IfdExif, 0) {
|
||||||
if tagId == 0x9000 {
|
if tagId == 0x9000 {
|
||||||
// ExifVersion
|
// ExifVersion
|
||||||
|
Loading…
x
Reference in New Issue
Block a user