mirror of https://github.com/dsoprea/go-exif.git
ifd_tag_entry: Added full test coverage.
- bytes are now stringified to a hex-byte representation.pull/3/head
parent
d265631db3
commit
b18da0cc3d
|
@ -641,8 +641,8 @@
|
|||
"tag_type_id": 1,
|
||||
"tag_type_name": "BYTE",
|
||||
"unit_count": 4,
|
||||
"value": "2",
|
||||
"value_string": "2"
|
||||
"value": "0x02",
|
||||
"value_string": "0x02"
|
||||
},
|
||||
{
|
||||
"ifd_name": "IFD",
|
||||
|
|
|
@ -89,7 +89,7 @@ IFD=[Exif] ID=(0xa432) NAME=[LensSpecification] COUNT=(4) TYPE=[RATIONAL] VALUE=
|
|||
IFD=[Exif] ID=(0xa434) NAME=[LensModel] COUNT=(22) TYPE=[ASCII] VALUE=[EF16-35mm f/4L IS USM]
|
||||
IFD=[Exif] ID=(0xa435) NAME=[LensSerialNumber] COUNT=(11) TYPE=[ASCII] VALUE=[2400001068]
|
||||
IFD=[IFD] ID=(0x8825) NAME=[GPSTag] COUNT=(1) TYPE=[LONG] VALUE=[9554]
|
||||
IFD=[GPSInfo] ID=(0x0000) NAME=[GPSVersionID] COUNT=(4) TYPE=[BYTE] VALUE=[2]
|
||||
IFD=[GPSInfo] ID=(0x0000) NAME=[GPSVersionID] COUNT=(4) TYPE=[BYTE] VALUE=[0x02]
|
||||
IFD=[IFD] ID=(0x0103) NAME=[Compression] COUNT=(1) TYPE=[SHORT] VALUE=[6]
|
||||
IFD=[IFD] ID=(0x011a) NAME=[XResolution] COUNT=(1) TYPE=[RATIONAL] VALUE=[72/1]
|
||||
IFD=[IFD] ID=(0x011b) NAME=[YResolution] COUNT=(1) TYPE=[RATIONAL] VALUE=[72/1]
|
||||
|
|
22
exif_test.go
22
exif_test.go
|
@ -169,7 +169,7 @@ func TestVisit(t *testing.T) {
|
|||
"IFD=[Exif] ID=(0xa434) NAME=[LensModel] COUNT=(22) TYPE=[ASCII] VALUE=[EF16-35mm f/4L IS USM]",
|
||||
"IFD=[Exif] ID=(0xa435) NAME=[LensSerialNumber] COUNT=(11) TYPE=[ASCII] VALUE=[2400001068]",
|
||||
"IFD=[IFD] ID=(0x8825) NAME=[GPSTag] COUNT=(1) TYPE=[LONG] VALUE=[9554]",
|
||||
"IFD=[GPSInfo] ID=(0x0000) NAME=[GPSVersionID] COUNT=(4) TYPE=[BYTE] VALUE=[2]",
|
||||
"IFD=[GPSInfo] ID=(0x0000) NAME=[GPSVersionID] COUNT=(4) TYPE=[BYTE] VALUE=[0x02]",
|
||||
"IFD=[IFD] ID=(0x0103) NAME=[Compression] COUNT=(1) TYPE=[SHORT] VALUE=[6]",
|
||||
"IFD=[IFD] ID=(0x011a) NAME=[XResolution] COUNT=(1) TYPE=[RATIONAL] VALUE=[72/1]",
|
||||
"IFD=[IFD] ID=(0x011b) NAME=[YResolution] COUNT=(1) TYPE=[RATIONAL] VALUE=[72/1]",
|
||||
|
@ -179,7 +179,25 @@ func TestVisit(t *testing.T) {
|
|||
}
|
||||
|
||||
if reflect.DeepEqual(tags, expected) == false {
|
||||
t.Fatalf("tags not correct:\n%v", tags)
|
||||
fmt.Printf("\n")
|
||||
fmt.Printf("ACTUAL:\n")
|
||||
fmt.Printf("\n")
|
||||
|
||||
for _, line := range tags {
|
||||
fmt.Println(line)
|
||||
}
|
||||
|
||||
fmt.Printf("\n")
|
||||
fmt.Printf("EXPECTED:\n")
|
||||
fmt.Printf("\n")
|
||||
|
||||
for _, line := range expected {
|
||||
fmt.Println(line)
|
||||
}
|
||||
|
||||
fmt.Printf("\n")
|
||||
|
||||
t.Fatalf("tags not correct.")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -568,7 +568,7 @@ func validateExifSimpleTestIb(exifData []byte, t *testing.T) {
|
|||
t.Fatalf("Tag-ID for entry (%d) not correct: (0x%02x) != (0x%02x)", i, e.TagId, expected[i].tagId)
|
||||
}
|
||||
|
||||
value, err := e.Value(TestDefaultByteOrder, addressableData)
|
||||
value, err := e.Value(addressableData, TestDefaultByteOrder)
|
||||
log.PanicIf(err)
|
||||
|
||||
if reflect.DeepEqual(value, expected[i].value) != true {
|
||||
|
@ -742,7 +742,7 @@ func Test_IfdByteEncoder_EncodeToExif(t *testing.T) {
|
|||
validateExifSimpleTestIb(exifData, t)
|
||||
}
|
||||
|
||||
func Test_IfdByteEncoder_EncodeToExif_WithChild(t *testing.T) {
|
||||
func Test_IfdByteEncoder_EncodeToExif_WithChildAndSibling(t *testing.T) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err := log.Wrap(state.(error))
|
||||
|
@ -780,10 +780,11 @@ func Test_IfdByteEncoder_EncodeToExif_WithChild(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
|
||||
// TODO(dustin): !! Finish this.
|
||||
// // Link to another IB (sibling relationship). The root IFD may occur twice
|
||||
// // in some JPEGs (for thumbnail or FlashPix images).
|
||||
// Link to another IB (sibling relationship). The root IFD may occur twice
|
||||
// in some JPEGs (for thumbnail or FlashPix images).
|
||||
|
||||
|
||||
// TODO(dustin): !! Debugging.
|
||||
// nextIb := NewIfdBuilder(RootIi, TestDefaultByteOrder)
|
||||
|
||||
// err = nextIb.AddFromConfig(0x0101, []uint32 { 0x11223344 })
|
||||
|
@ -874,7 +875,7 @@ func ExampleIfdByteEncoder_EncodeToExif() {
|
|||
addressableData := exifData[ExifAddressableAreaStart:]
|
||||
|
||||
for i, e := range index.RootIfd.Entries {
|
||||
value, err := e.Value(EncodeDefaultByteOrder, addressableData)
|
||||
value, err := e.Value(addressableData, EncodeDefaultByteOrder)
|
||||
log.PanicIf(err)
|
||||
|
||||
fmt.Printf("%d: %s %v\n", i, e, value)
|
||||
|
@ -949,7 +950,7 @@ func ExampleIfdByteEncoder_EncodeToExif() {
|
|||
// addressableData := exifData[ExifAddressableAreaStart:]
|
||||
|
||||
// for i, e := range index.RootIfd.Entries {
|
||||
// value, err := e.Value(EncodeDefaultByteOrder, addressableData)
|
||||
// value, err := e.Value(addressableData, EncodeDefaultByteOrder)
|
||||
// log.PanicIf(err)
|
||||
|
||||
// fmt.Printf("%d: %s %v\n", i, e, value)
|
||||
|
|
|
@ -33,7 +33,7 @@ func (ite IfdTagEntry) String() string {
|
|||
}
|
||||
|
||||
// ValueString renders a string from whatever the value in this tag is.
|
||||
func (ite IfdTagEntry) ValueString(byteOrder binary.ByteOrder, addressableData []byte) (value string, err error) {
|
||||
func (ite IfdTagEntry) ValueString(addressableData []byte, byteOrder binary.ByteOrder) (value string, err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
|
@ -125,7 +125,7 @@ func (ite IfdTagEntry) ValueBytes(addressableData []byte, byteOrder binary.ByteO
|
|||
}
|
||||
|
||||
// Value returns the specific, parsed, typed value from the tag.
|
||||
func (ite IfdTagEntry) Value(byteOrder binary.ByteOrder, addressableData []byte) (value interface{}, err error) {
|
||||
func (ite IfdTagEntry) Value(addressableData []byte, byteOrder binary.ByteOrder) (value interface{}, err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
|
|
|
@ -0,0 +1,185 @@
|
|||
package exif
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"bytes"
|
||||
|
||||
"github.com/dsoprea/go-logging"
|
||||
)
|
||||
|
||||
func Test_IfdTagEntry_ValueString_Allocated(t *testing.T) {
|
||||
ite := IfdTagEntry{
|
||||
TagId: 0x1,
|
||||
TagIndex: 0,
|
||||
TagType: TypeByte,
|
||||
UnitCount: 6,
|
||||
ValueOffset: 0x0,
|
||||
RawValueOffset: []byte { 0x0, 0x0, 0x0, 0x0 },
|
||||
Ii: RootIi,
|
||||
}
|
||||
|
||||
data := []byte { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 }
|
||||
|
||||
value, err := ite.ValueString(data, TestDefaultByteOrder)
|
||||
log.PanicIf(err)
|
||||
|
||||
expected := "11 22 33 44 55 66"
|
||||
if value != expected {
|
||||
t.Fatalf("Value not expected: [%s] != [%s]", value, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func Test_IfdTagEntry_ValueString_Embedded(t *testing.T) {
|
||||
data := []byte { 0x11, 0x22, 0x33, 0x44 }
|
||||
|
||||
ite := IfdTagEntry{
|
||||
TagId: 0x1,
|
||||
TagIndex: 0,
|
||||
TagType: TypeByte,
|
||||
UnitCount: 4,
|
||||
ValueOffset: 0,
|
||||
RawValueOffset: data,
|
||||
Ii: RootIi,
|
||||
}
|
||||
|
||||
value, err := ite.ValueString(nil, TestDefaultByteOrder)
|
||||
log.PanicIf(err)
|
||||
|
||||
expected := "11 22 33 44"
|
||||
if value != expected {
|
||||
t.Fatalf("Value not expected: [%s] != [%s]", value, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func Test_IfdTagEntry_ValueBytes_Allocated(t *testing.T) {
|
||||
ite := IfdTagEntry{
|
||||
TagId: 0x1,
|
||||
TagIndex: 0,
|
||||
TagType: TypeByte,
|
||||
UnitCount: 6,
|
||||
ValueOffset: 0x0,
|
||||
RawValueOffset: []byte { 0x0, 0x0, 0x0, 0x0 },
|
||||
Ii: RootIi,
|
||||
}
|
||||
|
||||
data := []byte { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 }
|
||||
|
||||
value, err := ite.ValueBytes(data, TestDefaultByteOrder)
|
||||
log.PanicIf(err)
|
||||
|
||||
if bytes.Compare(value, data) != 0 {
|
||||
t.Fatalf("Value not expected: [%s] != [%s]", value, data)
|
||||
}
|
||||
}
|
||||
|
||||
func Test_IfdTagEntry_ValueBytes_Embedded(t *testing.T) {
|
||||
data := []byte { 0x11, 0x22, 0x33, 0x44 }
|
||||
|
||||
ite := IfdTagEntry{
|
||||
TagId: 0x1,
|
||||
TagIndex: 0,
|
||||
TagType: TypeByte,
|
||||
UnitCount: 4,
|
||||
ValueOffset: 0x0,
|
||||
RawValueOffset: data,
|
||||
Ii: RootIi,
|
||||
}
|
||||
|
||||
value, err := ite.ValueBytes(nil, TestDefaultByteOrder)
|
||||
log.PanicIf(err)
|
||||
|
||||
if bytes.Compare(value, data) != 0 {
|
||||
t.Fatalf("Value not expected: [%s] != [%s]", value, data)
|
||||
}
|
||||
}
|
||||
|
||||
func Test_IfdTagEntry_Value_Normal(t *testing.T) {
|
||||
data := []byte { 0x11, 0x22, 0x33, 0x44 }
|
||||
|
||||
ite := IfdTagEntry{
|
||||
TagId: 0x1,
|
||||
TagIndex: 0,
|
||||
TagType: TypeByte,
|
||||
UnitCount: 4,
|
||||
ValueOffset: 0x0,
|
||||
RawValueOffset: data,
|
||||
Ii: RootIi,
|
||||
}
|
||||
|
||||
value, err := ite.Value(nil, TestDefaultByteOrder)
|
||||
log.PanicIf(err)
|
||||
|
||||
if bytes.Compare(value.([]byte), data) != 0 {
|
||||
t.Fatalf("Value not expected: [%s] != [%s]", value, data)
|
||||
}
|
||||
}
|
||||
|
||||
func Test_IfdTagEntry_Value_Unknown(t *testing.T) {
|
||||
data := []uint8 { '0', '2', '3', '0' }
|
||||
|
||||
ite := IfdTagEntry{
|
||||
TagId: 0x9000,
|
||||
TagIndex: 0,
|
||||
TagType: TypeUndefined,
|
||||
UnitCount: 4,
|
||||
ValueOffset: 0x0,
|
||||
RawValueOffset: data,
|
||||
Ii: ExifIi,
|
||||
}
|
||||
|
||||
value, err := ite.Value(nil, TestDefaultByteOrder)
|
||||
log.PanicIf(err)
|
||||
|
||||
gs := value.(TagUnknownType_GeneralString)
|
||||
|
||||
vb, err := gs.ValueBytes()
|
||||
log.PanicIf(err)
|
||||
|
||||
if bytes.Compare(vb, data) != 0 {
|
||||
t.Fatalf("Value not expected: [%s] != [%s]", value, data)
|
||||
}
|
||||
}
|
||||
|
||||
func Test_IfdTagEntry_String(t *testing.T) {
|
||||
ite := IfdTagEntry{
|
||||
TagId: 0x1,
|
||||
TagIndex: 0,
|
||||
TagType: TypeByte,
|
||||
UnitCount: 6,
|
||||
ValueOffset: 0x0,
|
||||
RawValueOffset: []byte { 0x0, 0x0, 0x0, 0x0 },
|
||||
Ii: RootIi,
|
||||
}
|
||||
|
||||
expected := "IfdTagEntry<TAG-IFD=[] TAG-ID=(0x01) TAG-TYPE=[BYTE] UNIT-COUNT=(6)>"
|
||||
if ite.String() != expected {
|
||||
t.Fatalf("string representation not expected: [%s] != [%s]", ite.String(), expected)
|
||||
}
|
||||
}
|
||||
|
||||
func Test_IfdTagEntryValueResolver_ValueBytes(t *testing.T) {
|
||||
ite := IfdTagEntry{
|
||||
TagId: 0x1,
|
||||
TagIndex: 0,
|
||||
TagType: TypeByte,
|
||||
UnitCount: 6,
|
||||
ValueOffset: 0x0,
|
||||
RawValueOffset: []byte { 0x0, 0x0, 0x0, 0x0 },
|
||||
Ii: RootIi,
|
||||
}
|
||||
|
||||
exifData := make([]byte, ExifAddressableAreaStart + 6)
|
||||
copy(exifData, ExifHeaderPrefixBytes)
|
||||
|
||||
allocatedData := []byte { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 }
|
||||
copy(exifData[ExifAddressableAreaStart:], allocatedData)
|
||||
|
||||
itevr := NewIfdTagEntryValueResolver(exifData, TestDefaultByteOrder)
|
||||
|
||||
value, err := itevr.ValueBytes(&ite)
|
||||
log.PanicIf(err)
|
||||
|
||||
if bytes.Compare(value, allocatedData) != 0 {
|
||||
t.Fatalf("bytes not expected: %v != %v", value, allocatedData)
|
||||
}
|
||||
}
|
4
type.go
4
type.go
|
@ -582,9 +582,9 @@ func (tt TagType) ResolveAsString(valueContext ValueContext, justFirst bool) (va
|
|||
log.PanicIf(err)
|
||||
|
||||
if justFirst == false {
|
||||
return fmt.Sprintf("%v", raw), nil
|
||||
return DumpBytesToString(raw), nil
|
||||
} else if valueContext.UnitCount > 0 {
|
||||
return fmt.Sprintf("%v", raw[0]), nil
|
||||
return fmt.Sprintf("0x%02x", raw[0]), nil
|
||||
} else {
|
||||
return "", nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue