mirror of https://github.com/dsoprea/go-exif.git
New integration of common/ and undefined/ subpackages
- common/type.go: Add FormatFromType() . - Renamed common/type_encode.go to common/value_encoder.go .for/master
parent
5c7dc45079
commit
32a5d88770
|
@ -3,6 +3,7 @@ package exifcommon
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
|
@ -93,6 +94,22 @@ func (tagType TagTypePrimitive) Size() int {
|
|||
}
|
||||
}
|
||||
|
||||
// IsValid returns true if tagType is a valid type.
|
||||
func (tagType TagTypePrimitive) IsValid() bool {
|
||||
|
||||
// TODO(dustin): Add test
|
||||
|
||||
return tagType == TypeByte ||
|
||||
tagType == TypeAscii ||
|
||||
tagType == TypeAsciiNoNul ||
|
||||
tagType == TypeShort ||
|
||||
tagType == TypeLong ||
|
||||
tagType == TypeRational ||
|
||||
tagType == TypeSignedLong ||
|
||||
tagType == TypeSignedRational ||
|
||||
tagType == TypeUndefined
|
||||
}
|
||||
|
||||
var (
|
||||
// TODO(dustin): Rename TypeNames() to typeNames() and add getter.
|
||||
TypeNames = map[TagTypePrimitive]string{
|
||||
|
@ -108,7 +125,7 @@ var (
|
|||
TypeAsciiNoNul: "_ASCII_NO_NUL",
|
||||
}
|
||||
|
||||
TypeNamesR = map[string]TagTypePrimitive{}
|
||||
typeNamesR = map[string]TagTypePrimitive{}
|
||||
)
|
||||
|
||||
type Rational struct {
|
||||
|
@ -123,14 +140,134 @@ type SignedRational struct {
|
|||
|
||||
// Format returns a stringified value for the given encoding. Automatically
|
||||
// parses. Automatically calculates count based on type size.
|
||||
func Format(rawBytes []byte, tagType TagTypePrimitive, justFirst bool, byteOrder binary.ByteOrder) (value string, err error) {
|
||||
func FormatFromType(value interface{}, justFirst bool) (phrase string, err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
}
|
||||
}()
|
||||
|
||||
// TODO(dustin): !! Add tests
|
||||
// TODO(dustin): !! Add test
|
||||
|
||||
switch t := value.(type) {
|
||||
case []byte:
|
||||
return DumpBytesToString(t), nil
|
||||
case string:
|
||||
return t, nil
|
||||
case []uint16:
|
||||
if len(t) == 0 {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
if justFirst == true {
|
||||
var valueSuffix string
|
||||
if len(t) > 1 {
|
||||
valueSuffix = "..."
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%v%s", t[0], valueSuffix), nil
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%v", t), nil
|
||||
case []uint32:
|
||||
if len(t) == 0 {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
if justFirst == true {
|
||||
var valueSuffix string
|
||||
if len(t) > 1 {
|
||||
valueSuffix = "..."
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%v%s", t[0], valueSuffix), nil
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%v", t), nil
|
||||
case []Rational:
|
||||
if len(t) == 0 {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
parts := make([]string, len(t))
|
||||
for i, r := range t {
|
||||
parts[i] = fmt.Sprintf("%d/%d", r.Numerator, r.Denominator)
|
||||
|
||||
if justFirst == true {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if justFirst == true {
|
||||
var valueSuffix string
|
||||
if len(t) > 1 {
|
||||
valueSuffix = "..."
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%v%s", parts[0], valueSuffix), nil
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%v", parts), nil
|
||||
case []int32:
|
||||
if len(t) == 0 {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
if justFirst == true {
|
||||
var valueSuffix string
|
||||
if len(t) > 1 {
|
||||
valueSuffix = "..."
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%v%s", t[0], valueSuffix), nil
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%v", t), nil
|
||||
case []SignedRational:
|
||||
if len(t) == 0 {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
parts := make([]string, len(t))
|
||||
for i, r := range t {
|
||||
parts[i] = fmt.Sprintf("%d/%d", r.Numerator, r.Denominator)
|
||||
|
||||
if justFirst == true {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if justFirst == true {
|
||||
var valueSuffix string
|
||||
if len(t) > 1 {
|
||||
valueSuffix = "..."
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%v%s", parts[0], valueSuffix), nil
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%v", parts), nil
|
||||
default:
|
||||
// Affects only "unknown" values, in general.
|
||||
log.Panicf("type can not be formatted into string: %v", reflect.TypeOf(value).Name())
|
||||
|
||||
// Never called.
|
||||
return "", nil
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(dustin): Rename Format() to FormatFromBytes()
|
||||
|
||||
// Format returns a stringified value for the given encoding. Automatically
|
||||
// parses. Automatically calculates count based on type size.
|
||||
func Format(rawBytes []byte, tagType TagTypePrimitive, justFirst bool, byteOrder binary.ByteOrder) (phrase string, err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
}
|
||||
}()
|
||||
|
||||
// TODO(dustin): !! Add test
|
||||
|
||||
typeSize := tagType.Size()
|
||||
|
||||
|
@ -144,109 +281,61 @@ func Format(rawBytes []byte, tagType TagTypePrimitive, justFirst bool, byteOrder
|
|||
|
||||
// Truncate the items if it's not bytes or a string and we just want the first.
|
||||
|
||||
valueSuffix := ""
|
||||
if justFirst == true && unitCount > 1 && tagType != TypeByte && tagType != TypeAscii && tagType != TypeAsciiNoNul {
|
||||
unitCount = 1
|
||||
valueSuffix = "..."
|
||||
}
|
||||
var value interface{}
|
||||
|
||||
if tagType == TypeByte {
|
||||
items, err := parser.ParseBytes(rawBytes, unitCount)
|
||||
switch tagType {
|
||||
case TypeByte:
|
||||
var err error
|
||||
|
||||
value, err = parser.ParseBytes(rawBytes, unitCount)
|
||||
log.PanicIf(err)
|
||||
case TypeAscii:
|
||||
var err error
|
||||
|
||||
return DumpBytesToString(items), nil
|
||||
} else if tagType == TypeAscii {
|
||||
phrase, err := parser.ParseAscii(rawBytes, unitCount)
|
||||
value, err = parser.ParseAscii(rawBytes, unitCount)
|
||||
log.PanicIf(err)
|
||||
case TypeAsciiNoNul:
|
||||
var err error
|
||||
|
||||
return phrase, nil
|
||||
} else if tagType == TypeAsciiNoNul {
|
||||
phrase, err := parser.ParseAsciiNoNul(rawBytes, unitCount)
|
||||
value, err = parser.ParseAsciiNoNul(rawBytes, unitCount)
|
||||
log.PanicIf(err)
|
||||
case TypeShort:
|
||||
var err error
|
||||
|
||||
return phrase, nil
|
||||
} else if tagType == TypeShort {
|
||||
items, err := parser.ParseShorts(rawBytes, unitCount, byteOrder)
|
||||
value, err = parser.ParseShorts(rawBytes, unitCount, byteOrder)
|
||||
log.PanicIf(err)
|
||||
case TypeLong:
|
||||
var err error
|
||||
|
||||
if len(items) > 0 {
|
||||
if justFirst == true {
|
||||
return fmt.Sprintf("%v%s", items[0], valueSuffix), nil
|
||||
} else {
|
||||
return fmt.Sprintf("%v", items), nil
|
||||
}
|
||||
} else {
|
||||
return "", nil
|
||||
}
|
||||
} else if tagType == TypeLong {
|
||||
items, err := parser.ParseLongs(rawBytes, unitCount, byteOrder)
|
||||
value, err = parser.ParseLongs(rawBytes, unitCount, byteOrder)
|
||||
log.PanicIf(err)
|
||||
case TypeRational:
|
||||
var err error
|
||||
|
||||
if len(items) > 0 {
|
||||
if justFirst == true {
|
||||
return fmt.Sprintf("%v%s", items[0], valueSuffix), nil
|
||||
} else {
|
||||
return fmt.Sprintf("%v", items), nil
|
||||
}
|
||||
} else {
|
||||
return "", nil
|
||||
}
|
||||
} else if tagType == TypeRational {
|
||||
items, err := parser.ParseRationals(rawBytes, unitCount, byteOrder)
|
||||
value, err = parser.ParseRationals(rawBytes, unitCount, byteOrder)
|
||||
log.PanicIf(err)
|
||||
case TypeSignedLong:
|
||||
var err error
|
||||
|
||||
if len(items) > 0 {
|
||||
parts := make([]string, len(items))
|
||||
for i, r := range items {
|
||||
parts[i] = fmt.Sprintf("%d/%d", r.Numerator, r.Denominator)
|
||||
}
|
||||
|
||||
if justFirst == true {
|
||||
return fmt.Sprintf("%v%s", parts[0], valueSuffix), nil
|
||||
} else {
|
||||
return fmt.Sprintf("%v", parts), nil
|
||||
}
|
||||
} else {
|
||||
return "", nil
|
||||
}
|
||||
} else if tagType == TypeSignedLong {
|
||||
items, err := parser.ParseSignedLongs(rawBytes, unitCount, byteOrder)
|
||||
value, err = parser.ParseSignedLongs(rawBytes, unitCount, byteOrder)
|
||||
log.PanicIf(err)
|
||||
case TypeSignedRational:
|
||||
var err error
|
||||
|
||||
if len(items) > 0 {
|
||||
if justFirst == true {
|
||||
return fmt.Sprintf("%v%s", items[0], valueSuffix), nil
|
||||
} else {
|
||||
return fmt.Sprintf("%v", items), nil
|
||||
}
|
||||
} else {
|
||||
return "", nil
|
||||
}
|
||||
} else if tagType == TypeSignedRational {
|
||||
items, err := parser.ParseSignedRationals(rawBytes, unitCount, byteOrder)
|
||||
value, err = parser.ParseSignedRationals(rawBytes, unitCount, byteOrder)
|
||||
log.PanicIf(err)
|
||||
|
||||
parts := make([]string, len(items))
|
||||
for i, r := range items {
|
||||
parts[i] = fmt.Sprintf("%d/%d", r.Numerator, r.Denominator)
|
||||
}
|
||||
|
||||
if len(items) > 0 {
|
||||
if justFirst == true {
|
||||
return fmt.Sprintf("%v%s", parts[0], valueSuffix), nil
|
||||
} else {
|
||||
return fmt.Sprintf("%v", parts), nil
|
||||
}
|
||||
} else {
|
||||
return "", nil
|
||||
}
|
||||
} else {
|
||||
default:
|
||||
// Affects only "unknown" values, in general.
|
||||
log.Panicf("value of type [%s] can not be formatted into string", tagType.String())
|
||||
|
||||
// Never called.
|
||||
return "", nil
|
||||
}
|
||||
|
||||
phrase, err = FormatFromType(value, justFirst)
|
||||
log.PanicIf(err)
|
||||
|
||||
return phrase, nil
|
||||
}
|
||||
|
||||
// TranslateStringToType converts user-provided strings to properly-typed
|
||||
|
@ -323,8 +412,15 @@ func TranslateStringToType(tagType TagTypePrimitive, valueString string) (value
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
// GetTypeByName returns the `TagTypePrimitive` for the given type name.
|
||||
// Returns (0) if not valid.
|
||||
func GetTypeByName(typeName string) (tagType TagTypePrimitive, found bool) {
|
||||
tagType, found = typeNamesR[typeName]
|
||||
return tagType, found
|
||||
}
|
||||
|
||||
func init() {
|
||||
for typeId, typeName := range TypeNames {
|
||||
TypeNamesR[typeName] = typeId
|
||||
typeNamesR[typeName] = typeId
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"github.com/dsoprea/go-logging"
|
||||
)
|
||||
|
||||
// DumpBytes prints a list of hex-encoded bytes.
|
||||
func DumpBytes(data []byte) {
|
||||
fmt.Printf("DUMP: ")
|
||||
for _, x := range data {
|
||||
|
@ -16,6 +17,8 @@ func DumpBytes(data []byte) {
|
|||
fmt.Printf("\n")
|
||||
}
|
||||
|
||||
// DumpBytesClause prints a list like DumpBytes(), but encapsulated in
|
||||
// "[]byte { ... }".
|
||||
func DumpBytesClause(data []byte) {
|
||||
fmt.Printf("DUMP: ")
|
||||
|
||||
|
@ -32,6 +35,7 @@ func DumpBytesClause(data []byte) {
|
|||
fmt.Printf(" }\n")
|
||||
}
|
||||
|
||||
// DumpBytesToString returns a stringified list of hex-encoded bytes.
|
||||
func DumpBytesToString(data []byte) string {
|
||||
b := new(bytes.Buffer)
|
||||
|
||||
|
@ -48,6 +52,7 @@ func DumpBytesToString(data []byte) string {
|
|||
return b.String()
|
||||
}
|
||||
|
||||
// DumpBytesClauseToString returns a comma-separated list of hex-encoded bytes.
|
||||
func DumpBytesClauseToString(data []byte) string {
|
||||
b := new(bytes.Buffer)
|
||||
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
package exifcommon
|
||||
|
||||
import (
|
||||
"testing"
|
||||
// "github.com/dsoprea/go-logging"
|
||||
)
|
||||
|
||||
func TestDumpBytes(t *testing.T) {
|
||||
DumpBytes([]byte{1, 2, 3, 4})
|
||||
}
|
||||
|
||||
func TestDumpBytesClause(t *testing.T) {
|
||||
DumpBytesClause([]byte{1, 2, 3, 4})
|
||||
}
|
||||
|
||||
func TestDumpBytesToString(t *testing.T) {
|
||||
s := DumpBytesToString([]byte{1, 2, 3, 4})
|
||||
if s != "01 02 03 04" {
|
||||
t.Fatalf("String not correct: [%s]", s)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDumpBytesClauseToString(t *testing.T) {
|
||||
s := DumpBytesClauseToString([]byte{1, 2, 3, 4})
|
||||
if s != "0x01, 0x02, 0x03, 0x04" {
|
||||
t.Fatalf("Stringified clause is not correct: [%s]", s)
|
||||
}
|
||||
}
|
|
@ -32,7 +32,7 @@ type ValueContext struct {
|
|||
// TODO(dustin): We can update newValueContext() to derive `valueOffset` itself (from `rawValueOffset`).
|
||||
|
||||
// newValueContext returns a new ValueContext struct.
|
||||
func newValueContext(ifdPath string, tagId uint16, unitCount, valueOffset uint32, rawValueOffset, addressableData []byte, tagType TagTypePrimitive, byteOrder binary.ByteOrder) *ValueContext {
|
||||
func NewValueContext(ifdPath string, tagId uint16, unitCount, valueOffset uint32, rawValueOffset, addressableData []byte, tagType TagTypePrimitive, byteOrder binary.ByteOrder) *ValueContext {
|
||||
return &ValueContext{
|
||||
unitCount: unitCount,
|
||||
valueOffset: valueOffset,
|
||||
|
@ -138,6 +138,14 @@ func (vc *ValueContext) readRawEncoded() (rawBytes []byte, err error) {
|
|||
}
|
||||
}
|
||||
|
||||
// ReadRawEncoded returns the encoded bytes for the value that we represent.
|
||||
func (vc *ValueContext) ReadRawEncoded() (rawBytes []byte, err error) {
|
||||
|
||||
// TODO(dustin): Remove this method and rename readRawEncoded in its place.
|
||||
|
||||
return vc.readRawEncoded()
|
||||
}
|
||||
|
||||
// Format returns a string representation for the value.
|
||||
//
|
||||
// Where the type is not ASCII, `justFirst` indicates whether to just stringify
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
func TestNewValueContext(t *testing.T) {
|
||||
rawValueOffset := []byte{0, 0, 0, 22}
|
||||
addressableData := []byte{1, 2, 3, 4}
|
||||
vc := newValueContext("aa/bb", 0x1234, 11, 22, rawValueOffset, addressableData, TypeLong, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, 11, 22, rawValueOffset, addressableData, TypeLong, TestDefaultByteOrder)
|
||||
|
||||
if vc.ifdPath != "aa/bb" {
|
||||
t.Fatalf("ifdPath not correct: [%s]", vc.ifdPath)
|
||||
|
@ -48,7 +48,7 @@ func TestValueContext_SetUndefinedValueType__ErrorWhenNotUndefined(t *testing.T)
|
|||
|
||||
rawValueOffset := []byte{0, 0, 0, 22}
|
||||
addressableData := []byte{1, 2, 3, 4}
|
||||
vc := newValueContext("aa/bb", 0x1234, 11, 22, rawValueOffset, addressableData, TypeLong, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, 11, 22, rawValueOffset, addressableData, TypeLong, TestDefaultByteOrder)
|
||||
|
||||
vc.SetUndefinedValueType(TypeLong)
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ func TestValueContext_SetUndefinedValueType__ErrorWhenNotUndefined(t *testing.T)
|
|||
func TestValueContext_SetUndefinedValueType__Ok(t *testing.T) {
|
||||
rawValueOffset := []byte{0, 0, 0, 22}
|
||||
addressableData := []byte{1, 2, 3, 4}
|
||||
vc := newValueContext("aa/bb", 0x1234, 11, 22, rawValueOffset, addressableData, TypeUndefined, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, 11, 22, rawValueOffset, addressableData, TypeUndefined, TestDefaultByteOrder)
|
||||
|
||||
vc.SetUndefinedValueType(TypeLong)
|
||||
|
||||
|
@ -72,7 +72,7 @@ func TestValueContext_SetUndefinedValueType__Ok(t *testing.T) {
|
|||
func TestValueContext_effectiveValueType(t *testing.T) {
|
||||
rawValueOffset := []byte{0, 0, 0, 22}
|
||||
addressableData := []byte{1, 2, 3, 4}
|
||||
vc := newValueContext("aa/bb", 0x1234, 11, 22, rawValueOffset, addressableData, TypeUndefined, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, 11, 22, rawValueOffset, addressableData, TypeUndefined, TestDefaultByteOrder)
|
||||
|
||||
vc.SetUndefinedValueType(TypeLong)
|
||||
|
||||
|
@ -88,7 +88,7 @@ func TestValueContext_effectiveValueType(t *testing.T) {
|
|||
func TestValueContext_UnitCount(t *testing.T) {
|
||||
rawValueOffset := []byte{0, 0, 0, 22}
|
||||
addressableData := []byte{1, 2, 3, 4}
|
||||
vc := newValueContext("aa/bb", 0x1234, 11, 22, rawValueOffset, addressableData, TypeUndefined, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, 11, 22, rawValueOffset, addressableData, TypeUndefined, TestDefaultByteOrder)
|
||||
|
||||
if vc.UnitCount() != 11 {
|
||||
t.Fatalf("UnitCount() not correct: (%d)", vc.UnitCount())
|
||||
|
@ -98,7 +98,7 @@ func TestValueContext_UnitCount(t *testing.T) {
|
|||
func TestValueContext_ValueOffset(t *testing.T) {
|
||||
rawValueOffset := []byte{0, 0, 0, 22}
|
||||
addressableData := []byte{1, 2, 3, 4}
|
||||
vc := newValueContext("aa/bb", 0x1234, 11, 22, rawValueOffset, addressableData, TypeUndefined, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, 11, 22, rawValueOffset, addressableData, TypeUndefined, TestDefaultByteOrder)
|
||||
|
||||
if vc.ValueOffset() != 22 {
|
||||
t.Fatalf("ValueOffset() not correct: (%d)", vc.ValueOffset())
|
||||
|
@ -108,7 +108,7 @@ func TestValueContext_ValueOffset(t *testing.T) {
|
|||
func TestValueContext_RawValueOffset(t *testing.T) {
|
||||
rawValueOffset := []byte{0, 0, 0, 22}
|
||||
addressableData := []byte{1, 2, 3, 4}
|
||||
vc := newValueContext("aa/bb", 0x1234, 11, 22, rawValueOffset, addressableData, TypeUndefined, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, 11, 22, rawValueOffset, addressableData, TypeUndefined, TestDefaultByteOrder)
|
||||
|
||||
if bytes.Equal(vc.RawValueOffset(), rawValueOffset) != true {
|
||||
t.Fatalf("RawValueOffset() not correct: %v", vc.RawValueOffset())
|
||||
|
@ -118,7 +118,7 @@ func TestValueContext_RawValueOffset(t *testing.T) {
|
|||
func TestValueContext_AddressableData(t *testing.T) {
|
||||
rawValueOffset := []byte{0, 0, 0, 22}
|
||||
addressableData := []byte{1, 2, 3, 4}
|
||||
vc := newValueContext("aa/bb", 0x1234, 11, 22, rawValueOffset, addressableData, TypeUndefined, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, 11, 22, rawValueOffset, addressableData, TypeUndefined, TestDefaultByteOrder)
|
||||
|
||||
if bytes.Equal(vc.AddressableData(), addressableData) != true {
|
||||
t.Fatalf("AddressableData() not correct: %v", vc.AddressableData())
|
||||
|
@ -128,7 +128,7 @@ func TestValueContext_AddressableData(t *testing.T) {
|
|||
func TestValueContext_ByteOrder(t *testing.T) {
|
||||
rawValueOffset := []byte{0, 0, 0, 22}
|
||||
addressableData := []byte{1, 2, 3, 4}
|
||||
vc := newValueContext("aa/bb", 0x1234, 11, 22, rawValueOffset, addressableData, TypeUndefined, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, 11, 22, rawValueOffset, addressableData, TypeUndefined, TestDefaultByteOrder)
|
||||
|
||||
if vc.ByteOrder() != TestDefaultByteOrder {
|
||||
t.Fatalf("ByteOrder() not correct: %v", vc.ByteOrder())
|
||||
|
@ -138,7 +138,7 @@ func TestValueContext_ByteOrder(t *testing.T) {
|
|||
func TestValueContext_IfdPath(t *testing.T) {
|
||||
rawValueOffset := []byte{0, 0, 0, 22}
|
||||
addressableData := []byte{1, 2, 3, 4}
|
||||
vc := newValueContext("aa/bb", 0x1234, 11, 22, rawValueOffset, addressableData, TypeUndefined, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, 11, 22, rawValueOffset, addressableData, TypeUndefined, TestDefaultByteOrder)
|
||||
|
||||
if vc.IfdPath() != "aa/bb" {
|
||||
t.Fatalf("IfdPath() not correct: [%s]", vc.IfdPath())
|
||||
|
@ -148,7 +148,7 @@ func TestValueContext_IfdPath(t *testing.T) {
|
|||
func TestValueContext_TagId(t *testing.T) {
|
||||
rawValueOffset := []byte{0, 0, 0, 22}
|
||||
addressableData := []byte{1, 2, 3, 4}
|
||||
vc := newValueContext("aa/bb", 0x1234, 11, 22, rawValueOffset, addressableData, TypeUndefined, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, 11, 22, rawValueOffset, addressableData, TypeUndefined, TestDefaultByteOrder)
|
||||
|
||||
if vc.TagId() != 0x1234 {
|
||||
t.Fatalf("TagId() not correct: (%d)", vc.TagId())
|
||||
|
@ -159,7 +159,7 @@ func TestValueContext_isEmbedded__True(t *testing.T) {
|
|||
unitCount := uint32(4)
|
||||
rawValueOffset := []byte{0, 0, 0, 22}
|
||||
addressableData := []byte{1, 2, 3, 4}
|
||||
vc := newValueContext("aa/bb", 0x1234, unitCount, 22, rawValueOffset, addressableData, TypeByte, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, unitCount, 22, rawValueOffset, addressableData, TypeByte, TestDefaultByteOrder)
|
||||
|
||||
if vc.isEmbedded() != true {
|
||||
t.Fatalf("isEmbedded() not correct: %v", vc.isEmbedded())
|
||||
|
@ -170,7 +170,7 @@ func TestValueContext_isEmbedded__False(t *testing.T) {
|
|||
unitCount := uint32(5)
|
||||
rawValueOffset := []byte{0, 0, 0, 22}
|
||||
addressableData := []byte{1, 2, 3, 4}
|
||||
vc := newValueContext("aa/bb", 0x1234, unitCount, 22, rawValueOffset, addressableData, TypeByte, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, unitCount, 22, rawValueOffset, addressableData, TypeByte, TestDefaultByteOrder)
|
||||
|
||||
if vc.isEmbedded() != false {
|
||||
t.Fatalf("isEmbedded() not correct: %v", vc.isEmbedded())
|
||||
|
@ -186,7 +186,7 @@ func TestValueContext_readRawEncoded__IsEmbedded(t *testing.T) {
|
|||
valueOffset := uint32(0)
|
||||
|
||||
addressableData := []byte{}
|
||||
vc := newValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeByte, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeByte, TestDefaultByteOrder)
|
||||
|
||||
recovered, err := vc.readRawEncoded()
|
||||
log.PanicIf(err)
|
||||
|
@ -208,7 +208,7 @@ func TestValueContext_readRawEncoded__IsRelative(t *testing.T) {
|
|||
addressableData := []byte{1, 2, 3, 4}
|
||||
addressableData = append(addressableData, data...)
|
||||
|
||||
vc := newValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeByte, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeByte, TestDefaultByteOrder)
|
||||
|
||||
recovered, err := vc.readRawEncoded()
|
||||
log.PanicIf(err)
|
||||
|
@ -228,7 +228,7 @@ func TestValueContext_Format__Byte(t *testing.T) {
|
|||
addressableData := []byte{0, 0, 0, 0}
|
||||
addressableData = append(addressableData, data...)
|
||||
|
||||
vc := newValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeByte, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeByte, TestDefaultByteOrder)
|
||||
|
||||
value, err := vc.Format()
|
||||
log.PanicIf(err)
|
||||
|
@ -248,7 +248,7 @@ func TestValueContext_Format__Ascii(t *testing.T) {
|
|||
addressableData := []byte{0, 0, 0, 0}
|
||||
addressableData = append(addressableData, data...)
|
||||
|
||||
vc := newValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeAscii, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeAscii, TestDefaultByteOrder)
|
||||
|
||||
value, err := vc.Format()
|
||||
log.PanicIf(err)
|
||||
|
@ -268,7 +268,7 @@ func TestValueContext_Format__AsciiNoNul(t *testing.T) {
|
|||
addressableData := []byte{0, 0, 0, 0}
|
||||
addressableData = append(addressableData, data...)
|
||||
|
||||
vc := newValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeAsciiNoNul, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeAsciiNoNul, TestDefaultByteOrder)
|
||||
|
||||
value, err := vc.Format()
|
||||
log.PanicIf(err)
|
||||
|
@ -288,7 +288,7 @@ func TestValueContext_Format__Short(t *testing.T) {
|
|||
addressableData := []byte{0, 0, 0, 0}
|
||||
addressableData = append(addressableData, data...)
|
||||
|
||||
vc := newValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeShort, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeShort, TestDefaultByteOrder)
|
||||
|
||||
value, err := vc.Format()
|
||||
log.PanicIf(err)
|
||||
|
@ -308,7 +308,7 @@ func TestValueContext_Format__Long(t *testing.T) {
|
|||
addressableData := []byte{0, 0, 0, 0}
|
||||
addressableData = append(addressableData, data...)
|
||||
|
||||
vc := newValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeLong, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeLong, TestDefaultByteOrder)
|
||||
|
||||
value, err := vc.Format()
|
||||
log.PanicIf(err)
|
||||
|
@ -332,7 +332,7 @@ func TestValueContext_Format__Rational(t *testing.T) {
|
|||
addressableData := []byte{0, 0, 0, 0}
|
||||
addressableData = append(addressableData, data...)
|
||||
|
||||
vc := newValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeRational, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeRational, TestDefaultByteOrder)
|
||||
|
||||
value, err := vc.Format()
|
||||
log.PanicIf(err)
|
||||
|
@ -352,7 +352,7 @@ func TestValueContext_Format__SignedLong(t *testing.T) {
|
|||
addressableData := []byte{0, 0, 0, 0}
|
||||
addressableData = append(addressableData, data...)
|
||||
|
||||
vc := newValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeSignedLong, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeSignedLong, TestDefaultByteOrder)
|
||||
|
||||
value, err := vc.Format()
|
||||
log.PanicIf(err)
|
||||
|
@ -376,7 +376,7 @@ func TestValueContext_Format__SignedRational(t *testing.T) {
|
|||
addressableData := []byte{0, 0, 0, 0}
|
||||
addressableData = append(addressableData, data...)
|
||||
|
||||
vc := newValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeSignedRational, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeSignedRational, TestDefaultByteOrder)
|
||||
|
||||
value, err := vc.Format()
|
||||
log.PanicIf(err)
|
||||
|
@ -409,7 +409,7 @@ func TestValueContext_Format__Undefined__NoEffectiveType(t *testing.T) {
|
|||
addressableData := []byte{0, 0, 0, 0}
|
||||
addressableData = append(addressableData, data...)
|
||||
|
||||
vc := newValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeUndefined, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeUndefined, TestDefaultByteOrder)
|
||||
|
||||
value, err := vc.Format()
|
||||
log.PanicIf(err)
|
||||
|
@ -429,7 +429,7 @@ func TestValueContext_Format__Undefined__HasEffectiveType(t *testing.T) {
|
|||
addressableData := []byte{0, 0, 0, 0}
|
||||
addressableData = append(addressableData, data...)
|
||||
|
||||
vc := newValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeUndefined, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeUndefined, TestDefaultByteOrder)
|
||||
|
||||
vc.SetUndefinedValueType(TypeAscii)
|
||||
|
||||
|
@ -451,7 +451,7 @@ func TestValueContext_FormatFirst__Bytes(t *testing.T) {
|
|||
addressableData := []byte{0, 0, 0, 0}
|
||||
addressableData = append(addressableData, data...)
|
||||
|
||||
vc := newValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeByte, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeByte, TestDefaultByteOrder)
|
||||
|
||||
value, err := vc.FormatFirst()
|
||||
log.PanicIf(err)
|
||||
|
@ -471,7 +471,7 @@ func TestValueContext_FormatFirst__String(t *testing.T) {
|
|||
addressableData := []byte{0, 0, 0, 0}
|
||||
addressableData = append(addressableData, data...)
|
||||
|
||||
vc := newValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeAscii, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeAscii, TestDefaultByteOrder)
|
||||
|
||||
value, err := vc.FormatFirst()
|
||||
log.PanicIf(err)
|
||||
|
@ -491,7 +491,7 @@ func TestValueContext_FormatFirst__List(t *testing.T) {
|
|||
addressableData := []byte{0, 0, 0, 0}
|
||||
addressableData = append(addressableData, data...)
|
||||
|
||||
vc := newValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeShort, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeShort, TestDefaultByteOrder)
|
||||
|
||||
value, err := vc.FormatFirst()
|
||||
log.PanicIf(err)
|
||||
|
@ -511,7 +511,7 @@ func TestValueContext_ReadBytes(t *testing.T) {
|
|||
addressableData := []byte{0, 0, 0, 0}
|
||||
addressableData = append(addressableData, data...)
|
||||
|
||||
vc := newValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeByte, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeByte, TestDefaultByteOrder)
|
||||
|
||||
value, err := vc.ReadBytes()
|
||||
log.PanicIf(err)
|
||||
|
@ -531,7 +531,7 @@ func TestValueContext_ReadAscii(t *testing.T) {
|
|||
addressableData := []byte{0, 0, 0, 0}
|
||||
addressableData = append(addressableData, data...)
|
||||
|
||||
vc := newValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeAscii, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeAscii, TestDefaultByteOrder)
|
||||
|
||||
value, err := vc.ReadAscii()
|
||||
log.PanicIf(err)
|
||||
|
@ -551,7 +551,7 @@ func TestValueContext_ReadAsciiNoNul(t *testing.T) {
|
|||
addressableData := []byte{0, 0, 0, 0}
|
||||
addressableData = append(addressableData, data...)
|
||||
|
||||
vc := newValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeAsciiNoNul, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeAsciiNoNul, TestDefaultByteOrder)
|
||||
|
||||
value, err := vc.ReadAsciiNoNul()
|
||||
log.PanicIf(err)
|
||||
|
@ -571,7 +571,7 @@ func TestValueContext_ReadShorts(t *testing.T) {
|
|||
addressableData := []byte{0, 0, 0, 0}
|
||||
addressableData = append(addressableData, data...)
|
||||
|
||||
vc := newValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeShort, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeShort, TestDefaultByteOrder)
|
||||
|
||||
value, err := vc.ReadShorts()
|
||||
log.PanicIf(err)
|
||||
|
@ -591,7 +591,7 @@ func TestValueContext_ReadLongs(t *testing.T) {
|
|||
addressableData := []byte{0, 0, 0, 0}
|
||||
addressableData = append(addressableData, data...)
|
||||
|
||||
vc := newValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeLong, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeLong, TestDefaultByteOrder)
|
||||
|
||||
value, err := vc.ReadLongs()
|
||||
log.PanicIf(err)
|
||||
|
@ -615,7 +615,7 @@ func TestValueContext_ReadRationals(t *testing.T) {
|
|||
addressableData := []byte{0, 0, 0, 0}
|
||||
addressableData = append(addressableData, data...)
|
||||
|
||||
vc := newValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeRational, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeRational, TestDefaultByteOrder)
|
||||
|
||||
value, err := vc.ReadRationals()
|
||||
log.PanicIf(err)
|
||||
|
@ -640,7 +640,7 @@ func TestValueContext_ReadSignedLongs(t *testing.T) {
|
|||
addressableData := []byte{0, 0, 0, 0}
|
||||
addressableData = append(addressableData, data...)
|
||||
|
||||
vc := newValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeSignedLong, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeSignedLong, TestDefaultByteOrder)
|
||||
|
||||
value, err := vc.ReadSignedLongs()
|
||||
log.PanicIf(err)
|
||||
|
@ -664,7 +664,7 @@ func TestValueContext_ReadSignedRationals(t *testing.T) {
|
|||
addressableData := []byte{0, 0, 0, 0}
|
||||
addressableData = append(addressableData, data...)
|
||||
|
||||
vc := newValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeSignedRational, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeSignedRational, TestDefaultByteOrder)
|
||||
|
||||
value, err := vc.ReadSignedRationals()
|
||||
log.PanicIf(err)
|
||||
|
@ -689,7 +689,7 @@ func TestValueContext_Values__Byte(t *testing.T) {
|
|||
addressableData := []byte{0, 0, 0, 0}
|
||||
addressableData = append(addressableData, data...)
|
||||
|
||||
vc := newValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeByte, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeByte, TestDefaultByteOrder)
|
||||
|
||||
value, err := vc.Values()
|
||||
log.PanicIf(err)
|
||||
|
@ -709,7 +709,7 @@ func TestValueContext_Values__Ascii(t *testing.T) {
|
|||
addressableData := []byte{0, 0, 0, 0}
|
||||
addressableData = append(addressableData, data...)
|
||||
|
||||
vc := newValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeAscii, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeAscii, TestDefaultByteOrder)
|
||||
|
||||
value, err := vc.Values()
|
||||
log.PanicIf(err)
|
||||
|
@ -729,7 +729,7 @@ func TestValueContext_Values__AsciiNoNul(t *testing.T) {
|
|||
addressableData := []byte{0, 0, 0, 0}
|
||||
addressableData = append(addressableData, data...)
|
||||
|
||||
vc := newValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeAsciiNoNul, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeAsciiNoNul, TestDefaultByteOrder)
|
||||
|
||||
value, err := vc.Values()
|
||||
log.PanicIf(err)
|
||||
|
@ -749,7 +749,7 @@ func TestValueContext_Values__Short(t *testing.T) {
|
|||
addressableData := []byte{0, 0, 0, 0}
|
||||
addressableData = append(addressableData, data...)
|
||||
|
||||
vc := newValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeShort, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeShort, TestDefaultByteOrder)
|
||||
|
||||
value, err := vc.Values()
|
||||
log.PanicIf(err)
|
||||
|
@ -769,7 +769,7 @@ func TestValueContext_Values__Long(t *testing.T) {
|
|||
addressableData := []byte{0, 0, 0, 0}
|
||||
addressableData = append(addressableData, data...)
|
||||
|
||||
vc := newValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeLong, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeLong, TestDefaultByteOrder)
|
||||
|
||||
value, err := vc.Values()
|
||||
log.PanicIf(err)
|
||||
|
@ -793,7 +793,7 @@ func TestValueContext_Values__Rational(t *testing.T) {
|
|||
addressableData := []byte{0, 0, 0, 0}
|
||||
addressableData = append(addressableData, data...)
|
||||
|
||||
vc := newValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeRational, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeRational, TestDefaultByteOrder)
|
||||
|
||||
value, err := vc.Values()
|
||||
log.PanicIf(err)
|
||||
|
@ -818,7 +818,7 @@ func TestValueContext_Values__SignedLong(t *testing.T) {
|
|||
addressableData := []byte{0, 0, 0, 0}
|
||||
addressableData = append(addressableData, data...)
|
||||
|
||||
vc := newValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeSignedLong, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeSignedLong, TestDefaultByteOrder)
|
||||
|
||||
value, err := vc.Values()
|
||||
log.PanicIf(err)
|
||||
|
@ -842,7 +842,7 @@ func TestValueContext_Values__SignedRational(t *testing.T) {
|
|||
addressableData := []byte{0, 0, 0, 0}
|
||||
addressableData = append(addressableData, data...)
|
||||
|
||||
vc := newValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeSignedRational, TestDefaultByteOrder)
|
||||
vc := NewValueContext("aa/bb", 0x1234, unitCount, valueOffset, rawValueOffset, addressableData, TypeSignedRational, TestDefaultByteOrder)
|
||||
|
||||
value, err := vc.Values()
|
||||
log.PanicIf(err)
|
||||
|
|
|
@ -187,8 +187,6 @@ func (ve *ValueEncoder) Encode(value interface{}) (ed EncodedData, err error) {
|
|||
}
|
||||
}()
|
||||
|
||||
// TODO(dustin): This is redundant with EncodeWithType. Refactor one to use the other.
|
||||
|
||||
switch value.(type) {
|
||||
case []byte:
|
||||
ed, err = ve.encodeBytes(value.([]byte))
|
|
@ -177,7 +177,7 @@ func ParseExifHeader(data []byte) (eh ExifHeader, err error) {
|
|||
}
|
||||
|
||||
// Visit recursively invokes a callback for every tag.
|
||||
func Visit(rootIfdName string, ifdMapping *IfdMapping, tagIndex *TagIndex, exifData []byte, visitor RawTagVisitor) (eh ExifHeader, err error) {
|
||||
func Visit(rootIfdName string, ifdMapping *IfdMapping, tagIndex *TagIndex, exifData []byte, visitor RawTagWalk) (eh ExifHeader, err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
|
|
|
@ -11,13 +11,28 @@ import (
|
|||
"io/ioutil"
|
||||
|
||||
"github.com/dsoprea/go-logging"
|
||||
|
||||
"github.com/dsoprea/go-exif/v2/common"
|
||||
"github.com/dsoprea/go-exif/v2/undefined"
|
||||
)
|
||||
|
||||
type innerVisitorCall func(fqIfdPath string, ifdIndex int, tagId uint16, tagType exifcommon.TagTypePrimitive, valueContext *exifcommon.ValueContext) (err error)
|
||||
|
||||
type visitorWrapper struct {
|
||||
f innerVisitorCall
|
||||
}
|
||||
|
||||
func (vw *visitorWrapper) Visit(fqIfdPath string, ifdIndex int, tagId uint16, tagType exifcommon.TagTypePrimitive, valueContext *exifcommon.ValueContext) (err error) {
|
||||
return vw.f(fqIfdPath, ifdIndex, tagId, tagType, valueContext)
|
||||
}
|
||||
|
||||
func TestVisit(t *testing.T) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err := log.Wrap(state.(error))
|
||||
log.PrintErrorf(err, "Exif failure.")
|
||||
log.PrintError(err)
|
||||
|
||||
t.Fatalf("Test failure.")
|
||||
}
|
||||
}()
|
||||
|
||||
|
@ -56,7 +71,7 @@ func TestVisit(t *testing.T) {
|
|||
|
||||
tags := make([]string, 0)
|
||||
|
||||
visitor := func(fqIfdPath string, ifdIndex int, tagId uint16, tagType TagType, valueContext ValueContext) (err error) {
|
||||
visitor := func(fqIfdPath string, ifdIndex int, tagId uint16, tagType exifcommon.TagTypePrimitive, valueContext *exifcommon.ValueContext) (err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
|
@ -78,10 +93,10 @@ func TestVisit(t *testing.T) {
|
|||
}
|
||||
|
||||
valueString := ""
|
||||
if tagType.Type() == TypeUndefined {
|
||||
value, err := valueContext.Undefined()
|
||||
if tagType == exifcommon.TypeUndefined {
|
||||
value, err := exifundefined.Decode(fqIfdPath, tagId, valueContext, valueContext.ByteOrder())
|
||||
if err != nil {
|
||||
if err == ErrUnhandledUnknownTypedTag {
|
||||
if err == exifcommon.ErrUnhandledUnknownTypedTag {
|
||||
valueString = "!UNDEFINED!"
|
||||
} else {
|
||||
log.Panic(err)
|
||||
|
@ -90,17 +105,23 @@ func TestVisit(t *testing.T) {
|
|||
|
||||
valueString = fmt.Sprintf("%v", value)
|
||||
} else {
|
||||
var err error
|
||||
|
||||
valueString, err = valueContext.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, valueContext.UnitCount(), tagType.Name(), valueString)
|
||||
description := fmt.Sprintf("IFD-PATH=[%s] ID=(0x%04x) NAME=[%s] COUNT=(%d) TYPE=[%s] VALUE=[%s]", ifdPath, tagId, it.Name, valueContext.UnitCount(), tagType.String(), valueString)
|
||||
tags = append(tags, description)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
_, err = Visit(IfdStandard, im, ti, data[foundAt:], visitor)
|
||||
vw := &visitorWrapper{
|
||||
f: visitor,
|
||||
}
|
||||
|
||||
_, err = Visit(exifcommon.IfdStandard, im, ti, data[foundAt:], vw)
|
||||
log.PanicIf(err)
|
||||
|
||||
expected := []string{
|
||||
|
@ -124,7 +145,7 @@ func TestVisit(t *testing.T) {
|
|||
"IFD-PATH=[IFD/Exif] ID=(0x9000) NAME=[ExifVersion] COUNT=(4) TYPE=[UNDEFINED] VALUE=[0230]",
|
||||
"IFD-PATH=[IFD/Exif] ID=(0x9003) NAME=[DateTimeOriginal] COUNT=(20) TYPE=[ASCII] VALUE=[2017:12:02 08:18:50]",
|
||||
"IFD-PATH=[IFD/Exif] ID=(0x9004) NAME=[DateTimeDigitized] COUNT=(20) TYPE=[ASCII] VALUE=[2017:12:02 08:18:50]",
|
||||
"IFD-PATH=[IFD/Exif] ID=(0x9101) NAME=[ComponentsConfiguration] COUNT=(4) TYPE=[UNDEFINED] VALUE=[ComponentsConfiguration<ID=[YCBCR] BYTES=[1 2 3 0]>]",
|
||||
"IFD-PATH=[IFD/Exif] ID=(0x9101) NAME=[ComponentsConfiguration] COUNT=(4) TYPE=[UNDEFINED] VALUE=[Exif9101ComponentsConfiguration<ID=[YCBCR] BYTES=[1 2 3 0]>]",
|
||||
"IFD-PATH=[IFD/Exif] ID=(0x9201) NAME=[ShutterSpeedValue] COUNT=(1) TYPE=[SRATIONAL] VALUE=[614400/65536]",
|
||||
"IFD-PATH=[IFD/Exif] ID=(0x9202) NAME=[ApertureValue] COUNT=(1) TYPE=[RATIONAL] VALUE=[262144/65536]",
|
||||
"IFD-PATH=[IFD/Exif] ID=(0x9204) NAME=[ExposureBiasValue] COUNT=(1) TYPE=[SRATIONAL] VALUE=[0/1]",
|
||||
|
@ -213,7 +234,9 @@ func TestCollect(t *testing.T) {
|
|||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err := log.Wrap(state.(error))
|
||||
log.PrintErrorf(err, "Exif failure.")
|
||||
log.PrintError(err)
|
||||
|
||||
t.Fatalf("Test failure.")
|
||||
}
|
||||
}()
|
||||
|
||||
|
@ -259,52 +282,52 @@ func TestCollect(t *testing.T) {
|
|||
t.Fatalf("Root IFD chain not terminated correctly (2).")
|
||||
}
|
||||
|
||||
if rootIfd.IfdPath != IfdPathStandard {
|
||||
if rootIfd.IfdPath != exifcommon.IfdPathStandard {
|
||||
t.Fatalf("Root IFD is not labeled correctly: [%s]", rootIfd.IfdPath)
|
||||
} else if rootIfd.NextIfd.IfdPath != IfdPathStandard {
|
||||
} else if rootIfd.NextIfd.IfdPath != exifcommon.IfdPathStandard {
|
||||
t.Fatalf("Root IFD sibling is not labeled correctly: [%s]", rootIfd.IfdPath)
|
||||
} else if rootIfd.Children[0].IfdPath != IfdPathStandardExif {
|
||||
} else if rootIfd.Children[0].IfdPath != exifcommon.IfdPathStandardExif {
|
||||
t.Fatalf("Root IFD child (0) is not labeled correctly: [%s]", rootIfd.Children[0].IfdPath)
|
||||
} else if rootIfd.Children[1].IfdPath != IfdPathStandardGps {
|
||||
} else if rootIfd.Children[1].IfdPath != exifcommon.IfdPathStandardGps {
|
||||
t.Fatalf("Root IFD child (1) is not labeled correctly: [%s]", rootIfd.Children[1].IfdPath)
|
||||
} else if rootIfd.Children[0].Children[0].IfdPath != IfdPathStandardExifIop {
|
||||
} else if rootIfd.Children[0].Children[0].IfdPath != exifcommon.IfdPathStandardExifIop {
|
||||
t.Fatalf("Exif IFD child is not an IOP IFD: [%s]", rootIfd.Children[0].Children[0].IfdPath)
|
||||
}
|
||||
|
||||
if lookup[IfdPathStandard][0].IfdPath != IfdPathStandard {
|
||||
if lookup[exifcommon.IfdPathStandard][0].IfdPath != exifcommon.IfdPathStandard {
|
||||
t.Fatalf("Lookup for standard IFD not correct.")
|
||||
} else if lookup[IfdPathStandard][1].IfdPath != IfdPathStandard {
|
||||
} else if lookup[exifcommon.IfdPathStandard][1].IfdPath != exifcommon.IfdPathStandard {
|
||||
t.Fatalf("Lookup for standard IFD not correct.")
|
||||
}
|
||||
|
||||
if lookup[IfdPathStandardExif][0].IfdPath != IfdPathStandardExif {
|
||||
if lookup[exifcommon.IfdPathStandardExif][0].IfdPath != exifcommon.IfdPathStandardExif {
|
||||
t.Fatalf("Lookup for EXIF IFD not correct.")
|
||||
}
|
||||
|
||||
if lookup[IfdPathStandardGps][0].IfdPath != IfdPathStandardGps {
|
||||
if lookup[exifcommon.IfdPathStandardGps][0].IfdPath != exifcommon.IfdPathStandardGps {
|
||||
t.Fatalf("Lookup for GPS IFD not correct.")
|
||||
}
|
||||
|
||||
if lookup[IfdPathStandardExifIop][0].IfdPath != IfdPathStandardExifIop {
|
||||
if lookup[exifcommon.IfdPathStandardExifIop][0].IfdPath != exifcommon.IfdPathStandardExifIop {
|
||||
t.Fatalf("Lookup for IOP IFD not correct.")
|
||||
}
|
||||
|
||||
foundExif := 0
|
||||
foundGps := 0
|
||||
for _, ite := range lookup[IfdPathStandard][0].Entries {
|
||||
if ite.ChildIfdPath == IfdPathStandardExif {
|
||||
for _, ite := range lookup[exifcommon.IfdPathStandard][0].Entries {
|
||||
if ite.ChildIfdPath == exifcommon.IfdPathStandardExif {
|
||||
foundExif++
|
||||
|
||||
if ite.TagId != IfdExifId {
|
||||
t.Fatalf("EXIF IFD tag-ID mismatch: (0x%04x) != (0x%04x)", ite.TagId, IfdExifId)
|
||||
if ite.TagId != exifcommon.IfdExifId {
|
||||
t.Fatalf("EXIF IFD tag-ID mismatch: (0x%04x) != (0x%04x)", ite.TagId, exifcommon.IfdExifId)
|
||||
}
|
||||
}
|
||||
|
||||
if ite.ChildIfdPath == IfdPathStandardGps {
|
||||
if ite.ChildIfdPath == exifcommon.IfdPathStandardGps {
|
||||
foundGps++
|
||||
|
||||
if ite.TagId != IfdGpsId {
|
||||
t.Fatalf("GPS IFD tag-ID mismatch: (0x%04x) != (0x%04x)", ite.TagId, IfdGpsId)
|
||||
if ite.TagId != exifcommon.IfdGpsId {
|
||||
t.Fatalf("GPS IFD tag-ID mismatch: (0x%04x) != (0x%04x)", ite.TagId, exifcommon.IfdGpsId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -316,12 +339,12 @@ func TestCollect(t *testing.T) {
|
|||
}
|
||||
|
||||
foundIop := 0
|
||||
for _, ite := range lookup[IfdPathStandardExif][0].Entries {
|
||||
if ite.ChildIfdPath == IfdPathStandardExifIop {
|
||||
for _, ite := range lookup[exifcommon.IfdPathStandardExif][0].Entries {
|
||||
if ite.ChildIfdPath == exifcommon.IfdPathStandardExifIop {
|
||||
foundIop++
|
||||
|
||||
if ite.TagId != IfdIopId {
|
||||
t.Fatalf("IOP IFD tag-ID mismatch: (0x%04x) != (0x%04x)", ite.TagId, IfdIopId)
|
||||
if ite.TagId != exifcommon.IfdIopId {
|
||||
t.Fatalf("IOP IFD tag-ID mismatch: (0x%04x) != (0x%04x)", ite.TagId, exifcommon.IfdIopId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -343,13 +366,13 @@ func TestParseExifHeader(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestExif_BuildAndParseExifHeader(t *testing.T) {
|
||||
headerBytes, err := BuildExifHeader(TestDefaultByteOrder, 0x11223344)
|
||||
headerBytes, err := BuildExifHeader(exifcommon.TestDefaultByteOrder, 0x11223344)
|
||||
log.PanicIf(err)
|
||||
|
||||
eh, err := ParseExifHeader(headerBytes)
|
||||
log.PanicIf(err)
|
||||
|
||||
if eh.ByteOrder != TestDefaultByteOrder {
|
||||
if eh.ByteOrder != exifcommon.TestDefaultByteOrder {
|
||||
t.Fatalf("Byte-order of EXIF header not correct.")
|
||||
} else if eh.FirstIfdOffset != 0x11223344 {
|
||||
t.Fatalf("First IFD offset not correct.")
|
||||
|
@ -357,7 +380,7 @@ func TestExif_BuildAndParseExifHeader(t *testing.T) {
|
|||
}
|
||||
|
||||
func ExampleBuildExifHeader() {
|
||||
headerBytes, err := BuildExifHeader(TestDefaultByteOrder, 0x11223344)
|
||||
headerBytes, err := BuildExifHeader(exifcommon.TestDefaultByteOrder, 0x11223344)
|
||||
log.PanicIf(err)
|
||||
|
||||
eh, err := ParseExifHeader(headerBytes)
|
||||
|
|
10
v2/ifd.go
10
v2/ifd.go
|
@ -6,6 +6,8 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/dsoprea/go-logging"
|
||||
|
||||
"github.com/dsoprea/go-exif/v2/common"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -363,16 +365,16 @@ func LoadStandardIfds(im *IfdMapping) (err error) {
|
|||
}
|
||||
}()
|
||||
|
||||
err = im.Add([]uint16{}, IfdRootId, IfdStandard)
|
||||
err = im.Add([]uint16{}, exifcommon.IfdRootId, exifcommon.IfdStandard)
|
||||
log.PanicIf(err)
|
||||
|
||||
err = im.Add([]uint16{IfdRootId}, IfdExifId, IfdExif)
|
||||
err = im.Add([]uint16{exifcommon.IfdRootId}, exifcommon.IfdExifId, exifcommon.IfdExif)
|
||||
log.PanicIf(err)
|
||||
|
||||
err = im.Add([]uint16{IfdRootId, IfdExifId}, IfdIopId, IfdIop)
|
||||
err = im.Add([]uint16{exifcommon.IfdRootId, exifcommon.IfdExifId}, exifcommon.IfdIopId, exifcommon.IfdIop)
|
||||
log.PanicIf(err)
|
||||
|
||||
err = im.Add([]uint16{IfdRootId}, IfdGpsId, IfdGps)
|
||||
err = im.Add([]uint16{exifcommon.IfdRootId}, exifcommon.IfdGpsId, exifcommon.IfdGps)
|
||||
log.PanicIf(err)
|
||||
|
||||
return nil
|
||||
|
|
|
@ -13,6 +13,9 @@ import (
|
|||
"encoding/binary"
|
||||
|
||||
"github.com/dsoprea/go-logging"
|
||||
|
||||
"github.com/dsoprea/go-exif/v2/common"
|
||||
"github.com/dsoprea/go-exif/v2/undefined"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -94,7 +97,7 @@ type BuilderTag struct {
|
|||
ifdPath string
|
||||
|
||||
tagId uint16
|
||||
typeId TagTypePrimitive
|
||||
typeId exifcommon.TagTypePrimitive
|
||||
|
||||
// value is either a value that can be encoded, an IfdBuilder instance (for
|
||||
// child IFDs), or an IfdTagEntry instance representing an existing,
|
||||
|
@ -106,7 +109,7 @@ type BuilderTag struct {
|
|||
byteOrder binary.ByteOrder
|
||||
}
|
||||
|
||||
func NewBuilderTag(ifdPath string, tagId uint16, typeId TagTypePrimitive, value *IfdBuilderTagValue, byteOrder binary.ByteOrder) *BuilderTag {
|
||||
func NewBuilderTag(ifdPath string, tagId uint16, typeId exifcommon.TagTypePrimitive, value *IfdBuilderTagValue, byteOrder binary.ByteOrder) *BuilderTag {
|
||||
return &BuilderTag{
|
||||
ifdPath: ifdPath,
|
||||
tagId: tagId,
|
||||
|
@ -120,7 +123,7 @@ func NewChildIfdBuilderTag(ifdPath string, tagId uint16, value *IfdBuilderTagVal
|
|||
return &BuilderTag{
|
||||
ifdPath: ifdPath,
|
||||
tagId: tagId,
|
||||
typeId: TypeLong,
|
||||
typeId: exifcommon.TypeLong,
|
||||
value: value,
|
||||
}
|
||||
}
|
||||
|
@ -135,13 +138,13 @@ func (bt *BuilderTag) String() string {
|
|||
if bt.value.IsBytes() == true {
|
||||
var err error
|
||||
|
||||
valueString, err = Format(bt.value.Bytes(), bt.typeId, false, bt.byteOrder)
|
||||
valueString, err = exifcommon.Format(bt.value.Bytes(), bt.typeId, false, bt.byteOrder)
|
||||
log.PanicIf(err)
|
||||
} else {
|
||||
valueString = fmt.Sprintf("%v", bt.value)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("BuilderTag<IFD-PATH=[%s] TAG-ID=(0x%04x) TAG-TYPE=[%s] VALUE=[%s]>", bt.ifdPath, bt.tagId, TypeNames[bt.typeId], valueString)
|
||||
return fmt.Sprintf("BuilderTag<IFD-PATH=[%s] TAG-ID=(0x%04x) TAG-TYPE=[%s] VALUE=[%s]>", bt.ifdPath, bt.tagId, bt.typeId.String(), valueString)
|
||||
}
|
||||
|
||||
func (bt *BuilderTag) SetValue(byteOrder binary.ByteOrder, value interface{}) (err error) {
|
||||
|
@ -153,19 +156,24 @@ func (bt *BuilderTag) SetValue(byteOrder binary.ByteOrder, value interface{}) (e
|
|||
|
||||
// TODO(dustin): !! Add test.
|
||||
|
||||
tt := NewTagType(bt.typeId, byteOrder)
|
||||
ve := NewValueEncoder(byteOrder)
|
||||
var ed exifcommon.EncodedData
|
||||
if bt.typeId == exifcommon.TypeUndefined {
|
||||
encodeable := value.(exifundefined.EncodeableValue)
|
||||
|
||||
var ed EncodedData
|
||||
if bt.typeId == TypeUndefined {
|
||||
var err error
|
||||
|
||||
ed, err = EncodeUndefined(bt.ifdPath, bt.tagId, value)
|
||||
encoded, unitCount, err := exifundefined.Encode(encodeable, byteOrder)
|
||||
log.PanicIf(err)
|
||||
|
||||
ed = exifcommon.EncodedData{
|
||||
Type: exifcommon.TypeUndefined,
|
||||
Encoded: encoded,
|
||||
UnitCount: unitCount,
|
||||
}
|
||||
} else {
|
||||
ve := exifcommon.NewValueEncoder(byteOrder)
|
||||
|
||||
var err error
|
||||
|
||||
ed, err = ve.EncodeWithType(tt, value)
|
||||
ed, err = ve.Encode(value)
|
||||
log.PanicIf(err)
|
||||
}
|
||||
|
||||
|
@ -177,30 +185,29 @@ func (bt *BuilderTag) SetValue(byteOrder binary.ByteOrder, value interface{}) (e
|
|||
// NewStandardBuilderTag constructs a `BuilderTag` instance. The type is looked
|
||||
// up. `ii` is the type of IFD that owns this tag.
|
||||
func NewStandardBuilderTag(ifdPath string, it *IndexedTag, byteOrder binary.ByteOrder, value interface{}) *BuilderTag {
|
||||
typeId := it.Type
|
||||
tt := NewTagType(typeId, byteOrder)
|
||||
var rawBytes []byte
|
||||
if it.Type == exifcommon.TypeUndefined {
|
||||
encodeable := value.(exifundefined.EncodeableValue)
|
||||
|
||||
ve := NewValueEncoder(byteOrder)
|
||||
|
||||
var ed EncodedData
|
||||
if it.Type == TypeUndefined {
|
||||
var err error
|
||||
|
||||
ed, err = EncodeUndefined(ifdPath, it.Id, value)
|
||||
rawBytes, _, err = exifundefined.Encode(encodeable, byteOrder)
|
||||
log.PanicIf(err)
|
||||
} else {
|
||||
var err error
|
||||
ve := exifcommon.NewValueEncoder(byteOrder)
|
||||
|
||||
ed, err = ve.EncodeWithType(tt, value)
|
||||
ed, err := ve.Encode(value)
|
||||
log.PanicIf(err)
|
||||
|
||||
rawBytes = ed.Encoded
|
||||
}
|
||||
|
||||
tagValue := NewIfdBuilderTagValueFromBytes(ed.Encoded)
|
||||
tagValue := NewIfdBuilderTagValueFromBytes(rawBytes)
|
||||
|
||||
return NewBuilderTag(
|
||||
ifdPath,
|
||||
it.Id,
|
||||
typeId,
|
||||
it.Type,
|
||||
tagValue,
|
||||
byteOrder)
|
||||
}
|
||||
|
@ -288,7 +295,7 @@ func NewIfdBuilderWithExistingIfd(ifd *Ifd) (ib *IfdBuilder) {
|
|||
var ifdTagId uint16
|
||||
|
||||
// There is no tag-ID for the root IFD. It will never be a child IFD.
|
||||
if ifdPath != IfdPathStandard {
|
||||
if ifdPath != exifcommon.IfdPathStandard {
|
||||
mi, err := ifd.ifdMapping.GetWithPath(ifdPath)
|
||||
log.PanicIf(err)
|
||||
|
||||
|
@ -523,7 +530,7 @@ func (ib *IfdBuilder) SetThumbnail(data []byte) (err error) {
|
|||
}
|
||||
}()
|
||||
|
||||
if ib.ifdPath != IfdPathStandard {
|
||||
if ib.ifdPath != exifcommon.IfdPathStandard {
|
||||
log.Panicf("thumbnails can only go into a root Ifd (and only the second one)")
|
||||
}
|
||||
|
||||
|
@ -540,7 +547,7 @@ func (ib *IfdBuilder) SetThumbnail(data []byte) (err error) {
|
|||
NewBuilderTag(
|
||||
ib.ifdPath,
|
||||
ThumbnailOffsetTagId,
|
||||
TypeLong,
|
||||
exifcommon.TypeLong,
|
||||
ibtvfb,
|
||||
ib.byteOrder)
|
||||
|
||||
|
@ -1113,13 +1120,15 @@ func (ib *IfdBuilder) AddTagsFromExisting(ifd *Ifd, itevr *IfdTagEntryValueResol
|
|||
|
||||
var rawBytes []byte
|
||||
|
||||
if ite.TagType == TypeUndefined {
|
||||
// It's an undefined-type value. Try to process, or skip if
|
||||
// we don't know how to.
|
||||
if ite.TagType == exifcommon.TypeUndefined {
|
||||
// It's an undefined-type value. Try to process (or skip if
|
||||
// we don't know how to), and encode back to bytes. This is the
|
||||
// cleanest way of using what we already have to both determine
|
||||
// if we support this tag and producing the bytes for it.
|
||||
|
||||
undefinedInterface, err := valueContext.Undefined()
|
||||
value, err := exifundefined.Decode(ite.IfdPath, ite.TagId, valueContext, ib.byteOrder)
|
||||
if err != nil {
|
||||
if err == ErrUnhandledUnknownTypedTag {
|
||||
if err == exifcommon.ErrUnhandledUnknownTypedTag {
|
||||
// It's an undefined-type tag that we don't handle. If
|
||||
// we don't know how to handle it, we can't know how
|
||||
// many bytes it is and we must skip it.
|
||||
|
@ -1129,19 +1138,14 @@ func (ib *IfdBuilder) AddTagsFromExisting(ifd *Ifd, itevr *IfdTagEntryValueResol
|
|||
log.Panic(err)
|
||||
}
|
||||
|
||||
undefined, ok := undefinedInterface.(UnknownTagValue)
|
||||
if ok != true {
|
||||
log.Panicf("unexpected value returned from undefined-value processor")
|
||||
}
|
||||
|
||||
rawBytes, err = undefined.ValueBytes()
|
||||
rawBytes, _, err = exifundefined.Encode(value, ib.byteOrder)
|
||||
log.PanicIf(err)
|
||||
} else {
|
||||
// It's a value with a standard type.
|
||||
|
||||
var err error
|
||||
|
||||
rawBytes, err = valueContext.readRawEncoded()
|
||||
rawBytes, err = valueContext.ReadRawEncoded()
|
||||
log.PanicIf(err)
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@ import (
|
|||
"encoding/binary"
|
||||
|
||||
"github.com/dsoprea/go-logging"
|
||||
|
||||
"github.com/dsoprea/go-exif/v2/common"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -219,8 +221,8 @@ func (ibe *IfdByteEncoder) encodeTagToBytes(ib *IfdBuilder, bt *BuilderTag, bw *
|
|||
|
||||
if bt.value.IsBytes() == true {
|
||||
effectiveType := bt.typeId
|
||||
if bt.typeId == TypeUndefined {
|
||||
effectiveType = TypeByte
|
||||
if bt.typeId == exifcommon.TypeUndefined {
|
||||
effectiveType = exifcommon.TypeByte
|
||||
}
|
||||
|
||||
// It's a non-unknown value.Calculate the count of values of
|
||||
|
|
|
@ -7,11 +7,13 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/dsoprea/go-logging"
|
||||
|
||||
"github.com/dsoprea/go-exif/v2/common"
|
||||
)
|
||||
|
||||
func Test_ByteWriter_writeAsBytes_uint8(t *testing.T) {
|
||||
b := new(bytes.Buffer)
|
||||
bw := NewByteWriter(b, TestDefaultByteOrder)
|
||||
bw := NewByteWriter(b, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
err := bw.writeAsBytes(uint8(0x12))
|
||||
log.PanicIf(err)
|
||||
|
@ -23,7 +25,7 @@ func Test_ByteWriter_writeAsBytes_uint8(t *testing.T) {
|
|||
|
||||
func Test_ByteWriter_writeAsBytes_uint16(t *testing.T) {
|
||||
b := new(bytes.Buffer)
|
||||
bw := NewByteWriter(b, TestDefaultByteOrder)
|
||||
bw := NewByteWriter(b, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
err := bw.writeAsBytes(uint16(0x1234))
|
||||
log.PanicIf(err)
|
||||
|
@ -35,7 +37,7 @@ func Test_ByteWriter_writeAsBytes_uint16(t *testing.T) {
|
|||
|
||||
func Test_ByteWriter_writeAsBytes_uint32(t *testing.T) {
|
||||
b := new(bytes.Buffer)
|
||||
bw := NewByteWriter(b, TestDefaultByteOrder)
|
||||
bw := NewByteWriter(b, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
err := bw.writeAsBytes(uint32(0x12345678))
|
||||
log.PanicIf(err)
|
||||
|
@ -47,7 +49,7 @@ func Test_ByteWriter_writeAsBytes_uint32(t *testing.T) {
|
|||
|
||||
func Test_ByteWriter_WriteUint16(t *testing.T) {
|
||||
b := new(bytes.Buffer)
|
||||
bw := NewByteWriter(b, TestDefaultByteOrder)
|
||||
bw := NewByteWriter(b, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
err := bw.WriteUint16(uint16(0x1234))
|
||||
log.PanicIf(err)
|
||||
|
@ -59,7 +61,7 @@ func Test_ByteWriter_WriteUint16(t *testing.T) {
|
|||
|
||||
func Test_ByteWriter_WriteUint32(t *testing.T) {
|
||||
b := new(bytes.Buffer)
|
||||
bw := NewByteWriter(b, TestDefaultByteOrder)
|
||||
bw := NewByteWriter(b, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
err := bw.WriteUint32(uint32(0x12345678))
|
||||
log.PanicIf(err)
|
||||
|
@ -71,7 +73,7 @@ func Test_ByteWriter_WriteUint32(t *testing.T) {
|
|||
|
||||
func Test_ByteWriter_WriteFourBytes(t *testing.T) {
|
||||
b := new(bytes.Buffer)
|
||||
bw := NewByteWriter(b, TestDefaultByteOrder)
|
||||
bw := NewByteWriter(b, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
err := bw.WriteFourBytes([]byte{0x11, 0x22, 0x33, 0x44})
|
||||
log.PanicIf(err)
|
||||
|
@ -83,7 +85,7 @@ func Test_ByteWriter_WriteFourBytes(t *testing.T) {
|
|||
|
||||
func Test_ByteWriter_WriteFourBytes_TooMany(t *testing.T) {
|
||||
b := new(bytes.Buffer)
|
||||
bw := NewByteWriter(b, TestDefaultByteOrder)
|
||||
bw := NewByteWriter(b, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
err := bw.WriteFourBytes([]byte{0x11, 0x22, 0x33, 0x44, 0x55})
|
||||
if err == nil {
|
||||
|
@ -194,15 +196,15 @@ func Test_IfdByteEncoder_encodeTagToBytes_bytes_embedded1(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
ti := NewTagIndex()
|
||||
ib := NewIfdBuilder(im, ti, IfdPathStandardGps, TestDefaultByteOrder)
|
||||
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandardGps, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
it, err := ti.Get(ib.ifdPath, uint16(0x0000))
|
||||
log.PanicIf(err)
|
||||
|
||||
bt := NewStandardBuilderTag(IfdPathStandardGps, it, TestDefaultByteOrder, []uint8{uint8(0x12)})
|
||||
bt := NewStandardBuilderTag(exifcommon.IfdPathStandardGps, it, exifcommon.TestDefaultByteOrder, []uint8{uint8(0x12)})
|
||||
|
||||
b := new(bytes.Buffer)
|
||||
bw := NewByteWriter(b, TestDefaultByteOrder)
|
||||
bw := NewByteWriter(b, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
addressableOffset := uint32(0x1234)
|
||||
ida := newIfdDataAllocator(addressableOffset)
|
||||
|
@ -228,15 +230,15 @@ func Test_IfdByteEncoder_encodeTagToBytes_bytes_embedded2(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
ti := NewTagIndex()
|
||||
ib := NewIfdBuilder(im, ti, IfdPathStandardGps, TestDefaultByteOrder)
|
||||
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandardGps, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
it, err := ti.Get(ib.ifdPath, uint16(0x0000))
|
||||
log.PanicIf(err)
|
||||
|
||||
bt := NewStandardBuilderTag(IfdPathStandardGps, it, TestDefaultByteOrder, []uint8{uint8(0x12), uint8(0x34), uint8(0x56), uint8(0x78)})
|
||||
bt := NewStandardBuilderTag(exifcommon.IfdPathStandardGps, it, exifcommon.TestDefaultByteOrder, []uint8{uint8(0x12), uint8(0x34), uint8(0x56), uint8(0x78)})
|
||||
|
||||
b := new(bytes.Buffer)
|
||||
bw := NewByteWriter(b, TestDefaultByteOrder)
|
||||
bw := NewByteWriter(b, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
addressableOffset := uint32(0x1234)
|
||||
ida := newIfdDataAllocator(addressableOffset)
|
||||
|
@ -262,10 +264,10 @@ func Test_IfdByteEncoder_encodeTagToBytes_bytes_allocated(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
ti := NewTagIndex()
|
||||
ib := NewIfdBuilder(im, ti, IfdPathStandardGps, TestDefaultByteOrder)
|
||||
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandardGps, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
b := new(bytes.Buffer)
|
||||
bw := NewByteWriter(b, TestDefaultByteOrder)
|
||||
bw := NewByteWriter(b, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
addressableOffset := uint32(0x1234)
|
||||
ida := newIfdDataAllocator(addressableOffset)
|
||||
|
@ -273,7 +275,7 @@ func Test_IfdByteEncoder_encodeTagToBytes_bytes_allocated(t *testing.T) {
|
|||
it, err := ti.Get(ib.ifdPath, uint16(0x0000))
|
||||
log.PanicIf(err)
|
||||
|
||||
bt := NewStandardBuilderTag(IfdPathStandardGps, it, TestDefaultByteOrder, []uint8{uint8(0x12), uint8(0x34), uint8(0x56), uint8(0x78), uint8(0x9a)})
|
||||
bt := NewStandardBuilderTag(exifcommon.IfdPathStandardGps, it, exifcommon.TestDefaultByteOrder, []uint8{uint8(0x12), uint8(0x34), uint8(0x56), uint8(0x78), uint8(0x9a)})
|
||||
|
||||
childIfdBlock, err := ibe.encodeTagToBytes(ib, bt, bw, ida, uint32(0))
|
||||
log.PanicIf(err)
|
||||
|
@ -290,7 +292,7 @@ func Test_IfdByteEncoder_encodeTagToBytes_bytes_allocated(t *testing.T) {
|
|||
|
||||
// Test that another allocation encodes to the new offset.
|
||||
|
||||
bt = NewStandardBuilderTag(IfdPathStandardGps, it, TestDefaultByteOrder, []uint8{uint8(0xbc), uint8(0xde), uint8(0xf0), uint8(0x12), uint8(0x34)})
|
||||
bt = NewStandardBuilderTag(exifcommon.IfdPathStandardGps, it, exifcommon.TestDefaultByteOrder, []uint8{uint8(0xbc), uint8(0xde), uint8(0xf0), uint8(0x12), uint8(0x34)})
|
||||
|
||||
childIfdBlock, err = ibe.encodeTagToBytes(ib, bt, bw, ida, uint32(0))
|
||||
log.PanicIf(err)
|
||||
|
@ -321,17 +323,17 @@ func Test_IfdByteEncoder_encodeTagToBytes_childIfd__withoutAllocate(t *testing.T
|
|||
log.PanicIf(err)
|
||||
|
||||
ti := NewTagIndex()
|
||||
ib := NewIfdBuilder(im, ti, IfdPathStandard, TestDefaultByteOrder)
|
||||
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
b := new(bytes.Buffer)
|
||||
bw := NewByteWriter(b, TestDefaultByteOrder)
|
||||
bw := NewByteWriter(b, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
addressableOffset := uint32(0x1234)
|
||||
ida := newIfdDataAllocator(addressableOffset)
|
||||
|
||||
childIb := NewIfdBuilder(im, ti, IfdPathStandardExif, TestDefaultByteOrder)
|
||||
childIb := NewIfdBuilder(im, ti, exifcommon.IfdPathStandardExif, exifcommon.TestDefaultByteOrder)
|
||||
tagValue := NewIfdBuilderTagValueFromIfdBuilder(childIb)
|
||||
bt := NewChildIfdBuilderTag(IfdPathStandard, IfdExifId, tagValue)
|
||||
bt := NewChildIfdBuilderTag(exifcommon.IfdPathStandard, exifcommon.IfdExifId, tagValue)
|
||||
|
||||
nextIfdOffsetToWrite := uint32(0)
|
||||
childIfdBlock, err := ibe.encodeTagToBytes(ib, bt, bw, ida, nextIfdOffsetToWrite)
|
||||
|
@ -365,12 +367,12 @@ func Test_IfdByteEncoder_encodeTagToBytes_childIfd__withAllocate(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
ti := NewTagIndex()
|
||||
childIb := NewIfdBuilder(im, ti, IfdPathStandardExif, TestDefaultByteOrder)
|
||||
childIb := NewIfdBuilder(im, ti, exifcommon.IfdPathStandardExif, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
childIbTestTag := &BuilderTag{
|
||||
ifdPath: IfdPathStandardExif,
|
||||
ifdPath: exifcommon.IfdPathStandardExif,
|
||||
tagId: 0x8822,
|
||||
typeId: TypeShort,
|
||||
typeId: exifcommon.TypeShort,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte{0x12, 0x34}),
|
||||
}
|
||||
|
||||
|
@ -379,7 +381,7 @@ func Test_IfdByteEncoder_encodeTagToBytes_childIfd__withAllocate(t *testing.T) {
|
|||
// Formally compose the tag that refers to it.
|
||||
|
||||
tagValue := NewIfdBuilderTagValueFromIfdBuilder(childIb)
|
||||
bt := NewChildIfdBuilderTag(IfdPathStandard, IfdExifId, tagValue)
|
||||
bt := NewChildIfdBuilderTag(exifcommon.IfdPathStandard, exifcommon.IfdExifId, tagValue)
|
||||
|
||||
// Encode the tag. Since we've actually provided an offset at which we can
|
||||
// allocate data, the child-IFD will automatically be encoded, allocated,
|
||||
|
@ -388,10 +390,10 @@ func Test_IfdByteEncoder_encodeTagToBytes_childIfd__withAllocate(t *testing.T) {
|
|||
|
||||
ibe := NewIfdByteEncoder()
|
||||
|
||||
ib := NewIfdBuilder(im, ti, IfdPathStandard, TestDefaultByteOrder)
|
||||
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
b := new(bytes.Buffer)
|
||||
bw := NewByteWriter(b, TestDefaultByteOrder)
|
||||
bw := NewByteWriter(b, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
// addressableOffset is the offset of where large data can be allocated
|
||||
// (which follows the IFD table/block). Large, in that it can't be stored
|
||||
|
@ -420,14 +422,14 @@ func Test_IfdByteEncoder_encodeTagToBytes_childIfd__withAllocate(t *testing.T) {
|
|||
t.Fatalf("Child IFD is not the right size: (%d)", len(childIfdBlock))
|
||||
}
|
||||
|
||||
iteV, err := ParseOneTag(im, ti, fmt.Sprintf("%s%d", IfdPathStandard, 0), IfdPathStandard, TestDefaultByteOrder, tagBytes, false)
|
||||
iteV, err := ParseOneTag(im, ti, fmt.Sprintf("%s%d", exifcommon.IfdPathStandard, 0), exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder, tagBytes, false)
|
||||
log.PanicIf(err)
|
||||
|
||||
if iteV.TagId != IfdExifId {
|
||||
if iteV.TagId != exifcommon.IfdExifId {
|
||||
t.Fatalf("IFD first tag-ID not correct: (0x%02x)", iteV.TagId)
|
||||
} else if iteV.TagIndex != 0 {
|
||||
t.Fatalf("IFD first tag index not correct: (%d)", iteV.TagIndex)
|
||||
} else if iteV.TagType != TypeLong {
|
||||
} else if iteV.TagType != exifcommon.TypeLong {
|
||||
t.Fatalf("IFD first tag type not correct: (%d)", iteV.TagType)
|
||||
} else if iteV.UnitCount != 1 {
|
||||
t.Fatalf("IFD first tag unit-count not correct: (%d)", iteV.UnitCount)
|
||||
|
@ -435,15 +437,15 @@ func Test_IfdByteEncoder_encodeTagToBytes_childIfd__withAllocate(t *testing.T) {
|
|||
t.Fatalf("IFD's child-IFD offset (as offset) is not correct: (%d) != (%d)", iteV.ValueOffset, nextIfdOffsetToWrite)
|
||||
} else if bytes.Compare(iteV.RawValueOffset, []byte{0x0, 0x0, 0x07, 0xd0}) != 0 {
|
||||
t.Fatalf("IFD's child-IFD offset (as raw bytes) is not correct: [%x]", iteV.RawValueOffset)
|
||||
} else if iteV.ChildIfdPath != IfdPathStandardExif {
|
||||
} else if iteV.ChildIfdPath != exifcommon.IfdPathStandardExif {
|
||||
t.Fatalf("IFD first tag IFD-name name not correct: [%s]", iteV.ChildIfdPath)
|
||||
} else if iteV.IfdPath != IfdPathStandard {
|
||||
} else if iteV.IfdPath != exifcommon.IfdPathStandard {
|
||||
t.Fatalf("IFD first tag parent IFD not correct: %v", iteV.IfdPath)
|
||||
}
|
||||
|
||||
// Validate the child's raw IFD bytes.
|
||||
|
||||
childNextIfdOffset, childEntries, err := ParseOneIfd(im, ti, "IFD0/Exif0", "IFD/Exif", TestDefaultByteOrder, childIfdBlock, nil, false)
|
||||
childNextIfdOffset, childEntries, err := ParseOneIfd(im, ti, "IFD0/Exif0", "IFD/Exif", exifcommon.TestDefaultByteOrder, childIfdBlock, nil, false)
|
||||
log.PanicIf(err)
|
||||
|
||||
if childNextIfdOffset != uint32(0) {
|
||||
|
@ -458,7 +460,7 @@ func Test_IfdByteEncoder_encodeTagToBytes_childIfd__withAllocate(t *testing.T) {
|
|||
t.Fatalf("Child IFD first tag-ID not correct: (0x%02x)", ite.TagId)
|
||||
} else if ite.TagIndex != 0 {
|
||||
t.Fatalf("Child IFD first tag index not correct: (%d)", ite.TagIndex)
|
||||
} else if ite.TagType != TypeShort {
|
||||
} else if ite.TagType != exifcommon.TypeShort {
|
||||
t.Fatalf("Child IFD first tag type not correct: (%d)", ite.TagType)
|
||||
} else if ite.UnitCount != 1 {
|
||||
t.Fatalf("Child IFD first tag unit-count not correct: (%d)", ite.UnitCount)
|
||||
|
@ -468,7 +470,7 @@ func Test_IfdByteEncoder_encodeTagToBytes_childIfd__withAllocate(t *testing.T) {
|
|||
t.Fatalf("Child IFD first tag value value (as raw bytes) not correct: [%v]", ite.RawValueOffset)
|
||||
} else if ite.ChildIfdPath != "" {
|
||||
t.Fatalf("Child IFD first tag IFD-name name not empty: [%s]", ite.ChildIfdPath)
|
||||
} else if ite.IfdPath != IfdPathStandardExif {
|
||||
} else if ite.IfdPath != exifcommon.IfdPathStandardExif {
|
||||
t.Fatalf("Child IFD first tag parent IFD not correct: %v", ite.IfdPath)
|
||||
}
|
||||
}
|
||||
|
@ -495,16 +497,16 @@ func Test_IfdByteEncoder_encodeTagToBytes_simpleTag_allocate(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
ti := NewTagIndex()
|
||||
ib := NewIfdBuilder(im, ti, IfdPathStandard, TestDefaultByteOrder)
|
||||
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
it, err := ib.tagIndex.Get(ib.ifdPath, uint16(0x000b))
|
||||
log.PanicIf(err)
|
||||
|
||||
valueString := "testvalue"
|
||||
bt := NewStandardBuilderTag(IfdPathStandard, it, TestDefaultByteOrder, valueString)
|
||||
bt := NewStandardBuilderTag(exifcommon.IfdPathStandard, it, exifcommon.TestDefaultByteOrder, valueString)
|
||||
|
||||
b := new(bytes.Buffer)
|
||||
bw := NewByteWriter(b, TestDefaultByteOrder)
|
||||
bw := NewByteWriter(b, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
// addressableOffset is the offset of where large data can be allocated
|
||||
// (which follows the IFD table/block). Large, in that it can't be stored
|
||||
|
@ -529,14 +531,14 @@ func Test_IfdByteEncoder_encodeTagToBytes_simpleTag_allocate(t *testing.T) {
|
|||
t.Fatalf("Child IFD not have been allocated.")
|
||||
}
|
||||
|
||||
ite, err := ParseOneTag(im, ti, fmt.Sprintf("%s%d", IfdPathStandard, 0), IfdPathStandard, TestDefaultByteOrder, tagBytes, false)
|
||||
ite, err := ParseOneTag(im, ti, fmt.Sprintf("%s%d", exifcommon.IfdPathStandard, 0), exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder, tagBytes, false)
|
||||
log.PanicIf(err)
|
||||
|
||||
if ite.TagId != 0x000b {
|
||||
t.Fatalf("Tag-ID not correct: (0x%02x)", ite.TagId)
|
||||
} else if ite.TagIndex != 0 {
|
||||
t.Fatalf("Tag index not correct: (%d)", ite.TagIndex)
|
||||
} else if ite.TagType != TypeAscii {
|
||||
} else if ite.TagType != exifcommon.TypeAscii {
|
||||
t.Fatalf("Tag type not correct: (%d)", ite.TagType)
|
||||
} else if ite.UnitCount != (uint32(len(valueString) + 1)) {
|
||||
t.Fatalf("Tag unit-count not correct: (%d)", ite.UnitCount)
|
||||
|
@ -546,7 +548,7 @@ func Test_IfdByteEncoder_encodeTagToBytes_simpleTag_allocate(t *testing.T) {
|
|||
t.Fatalf("Tag's value (as raw bytes) is not correct: [%x]", ite.RawValueOffset)
|
||||
} else if ite.ChildIfdPath != "" {
|
||||
t.Fatalf("Tag's IFD-name should be empty: [%s]", ite.ChildIfdPath)
|
||||
} else if ite.IfdPath != IfdPathStandard {
|
||||
} else if ite.IfdPath != exifcommon.IfdPathStandard {
|
||||
t.Fatalf("Tag's parent IFD is not correct: %v", ite.IfdPath)
|
||||
}
|
||||
|
||||
|
@ -617,7 +619,7 @@ func Test_IfdByteEncoder_encodeIfdToBytes_simple(t *testing.T) {
|
|||
}
|
||||
|
||||
if bytes.Compare(tableAndAllocated, expectedIfdAndDataBytes) != 0 {
|
||||
t.Fatalf("IFD table and allocated data not correct: %v", DumpBytesClauseToString(tableAndAllocated))
|
||||
t.Fatalf("IFD table and allocated data not correct: %v", exifcommon.DumpBytesClauseToString(tableAndAllocated))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -655,7 +657,7 @@ func Test_IfdByteEncoder_encodeIfdToBytes_fullExif(t *testing.T) {
|
|||
|
||||
b := new(bytes.Buffer)
|
||||
|
||||
headerBytes, err := BuildExifHeader(TestDefaultByteOrder, ExifDefaultFirstIfdOffset)
|
||||
headerBytes, err := BuildExifHeader(exifcommon.TestDefaultByteOrder, ExifDefaultFirstIfdOffset)
|
||||
log.PanicIf(err)
|
||||
|
||||
_, err = b.Write(headerBytes)
|
||||
|
@ -693,7 +695,7 @@ func Test_IfdByteEncoder_EncodeToExifPayload(t *testing.T) {
|
|||
|
||||
b := new(bytes.Buffer)
|
||||
|
||||
headerBytes, err := BuildExifHeader(TestDefaultByteOrder, ExifDefaultFirstIfdOffset)
|
||||
headerBytes, err := BuildExifHeader(exifcommon.TestDefaultByteOrder, ExifDefaultFirstIfdOffset)
|
||||
log.PanicIf(err)
|
||||
|
||||
_, err = b.Write(headerBytes)
|
||||
|
@ -737,7 +739,7 @@ func Test_IfdByteEncoder_EncodeToExif_WithChildAndSibling(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
ti := NewTagIndex()
|
||||
ib := NewIfdBuilder(im, ti, IfdPathStandard, TestDefaultByteOrder)
|
||||
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
err = ib.AddStandard(0x000b, "asciivalue")
|
||||
log.PanicIf(err)
|
||||
|
@ -747,7 +749,7 @@ func Test_IfdByteEncoder_EncodeToExif_WithChildAndSibling(t *testing.T) {
|
|||
|
||||
// Add a child IB right in the middle.
|
||||
|
||||
childIb := NewIfdBuilder(im, ti, IfdPathStandardExif, TestDefaultByteOrder)
|
||||
childIb := NewIfdBuilder(im, ti, exifcommon.IfdPathStandardExif, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
err = childIb.AddStandardWithName("ISOSpeedRatings", []uint16{0x1122})
|
||||
log.PanicIf(err)
|
||||
|
@ -764,7 +766,7 @@ func Test_IfdByteEncoder_EncodeToExif_WithChildAndSibling(t *testing.T) {
|
|||
// Add another child IB, just to ensure a little more punishment and make
|
||||
// sure we're managing our allocation offsets correctly.
|
||||
|
||||
childIb2 := NewIfdBuilder(im, ti, IfdPathStandardGps, TestDefaultByteOrder)
|
||||
childIb2 := NewIfdBuilder(im, ti, exifcommon.IfdPathStandardGps, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
err = childIb2.AddStandardWithName("GPSAltitudeRef", []uint8{0x11, 0x22})
|
||||
log.PanicIf(err)
|
||||
|
@ -772,13 +774,13 @@ func Test_IfdByteEncoder_EncodeToExif_WithChildAndSibling(t *testing.T) {
|
|||
err = ib.AddChildIb(childIb2)
|
||||
log.PanicIf(err)
|
||||
|
||||
err = ib.AddStandard(0x013e, []Rational{{Numerator: 0x11112222, Denominator: 0x33334444}})
|
||||
err = ib.AddStandard(0x013e, []exifcommon.Rational{{Numerator: 0x11112222, Denominator: 0x33334444}})
|
||||
log.PanicIf(err)
|
||||
|
||||
// Link to another IB (sibling relationship). The root/standard IFD may
|
||||
// occur twice in some JPEGs (for thumbnail or FlashPix images).
|
||||
|
||||
nextIb := NewIfdBuilder(im, ti, IfdPathStandard, TestDefaultByteOrder)
|
||||
nextIb := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
err = nextIb.AddStandard(0x0101, []uint32{0x11223344})
|
||||
log.PanicIf(err)
|
||||
|
@ -852,7 +854,7 @@ func ExampleIfdByteEncoder_EncodeToExif() {
|
|||
log.PanicIf(err)
|
||||
|
||||
ti := NewTagIndex()
|
||||
ib := NewIfdBuilder(im, ti, IfdPathStandard, TestDefaultByteOrder)
|
||||
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
err = ib.AddStandardWithName("ProcessingSoftware", "asciivalue")
|
||||
log.PanicIf(err)
|
||||
|
@ -866,10 +868,10 @@ func ExampleIfdByteEncoder_EncodeToExif() {
|
|||
err = ib.AddStandardWithName("ImageWidth", []uint32{0x44556677})
|
||||
log.PanicIf(err)
|
||||
|
||||
err = ib.AddStandardWithName("WhitePoint", []Rational{{Numerator: 0x11112222, Denominator: 0x33334444}})
|
||||
err = ib.AddStandardWithName("WhitePoint", []exifcommon.Rational{{Numerator: 0x11112222, Denominator: 0x33334444}})
|
||||
log.PanicIf(err)
|
||||
|
||||
err = ib.AddStandardWithName("ShutterSpeedValue", []SignedRational{{Numerator: 0x11112222, Denominator: 0x33334444}})
|
||||
err = ib.AddStandardWithName("ShutterSpeedValue", []exifcommon.SignedRational{{Numerator: 0x11112222, Denominator: 0x33334444}})
|
||||
log.PanicIf(err)
|
||||
|
||||
// Encode it.
|
||||
|
@ -889,7 +891,7 @@ func ExampleIfdByteEncoder_EncodeToExif() {
|
|||
addressableData := exifData[ExifAddressableAreaStart:]
|
||||
|
||||
for i, e := range index.RootIfd.Entries {
|
||||
value, err := e.Value(addressableData, TestDefaultByteOrder)
|
||||
value, err := e.Value(addressableData, exifcommon.TestDefaultByteOrder)
|
||||
log.PanicIf(err)
|
||||
|
||||
fmt.Printf("%d: %s [%v]\n", i, e, value)
|
||||
|
|
|
@ -7,6 +7,8 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/dsoprea/go-exif/v2/common"
|
||||
"github.com/dsoprea/go-exif/v2/undefined"
|
||||
"github.com/dsoprea/go-logging"
|
||||
)
|
||||
|
||||
|
@ -17,11 +19,11 @@ func TestIfdBuilder_Add(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
ti := NewTagIndex()
|
||||
ib := NewIfdBuilder(im, ti, IfdPathStandard, TestDefaultByteOrder)
|
||||
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
bt := &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x11,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string")),
|
||||
}
|
||||
|
@ -30,8 +32,8 @@ func TestIfdBuilder_Add(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x22,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string2")),
|
||||
}
|
||||
|
@ -40,8 +42,8 @@ func TestIfdBuilder_Add(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x33,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string3")),
|
||||
}
|
||||
|
@ -52,8 +54,8 @@ func TestIfdBuilder_Add(t *testing.T) {
|
|||
originalBytes := []byte{0x11, 0x22, 0x33}
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x44,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte(originalBytes)),
|
||||
}
|
||||
|
@ -61,11 +63,11 @@ func TestIfdBuilder_Add(t *testing.T) {
|
|||
err = ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
if ib.ifdPath != IfdPathStandard {
|
||||
if ib.ifdPath != exifcommon.IfdPathStandard {
|
||||
t.Fatalf("IFD name not correct.")
|
||||
} else if ib.ifdTagId != 0 {
|
||||
t.Fatalf("IFD tag-ID not correct.")
|
||||
} else if ib.byteOrder != TestDefaultByteOrder {
|
||||
} else if ib.byteOrder != exifcommon.TestDefaultByteOrder {
|
||||
t.Fatalf("IFD byte-order not correct.")
|
||||
} else if len(ib.tags) != 4 {
|
||||
t.Fatalf("IFD tag-count not correct.")
|
||||
|
@ -110,8 +112,8 @@ func TestIfdBuilder_SetNextIb(t *testing.T) {
|
|||
|
||||
ti := NewTagIndex()
|
||||
|
||||
ib1 := NewIfdBuilder(im, ti, IfdPathStandard, TestDefaultByteOrder)
|
||||
ib2 := NewIfdBuilder(im, ti, IfdPathStandard, TestDefaultByteOrder)
|
||||
ib1 := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder)
|
||||
ib2 := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
if ib1.nextIb != nil {
|
||||
t.Fatalf("Next-IFD for IB1 not initially terminal.")
|
||||
|
@ -134,11 +136,11 @@ func TestIfdBuilder_AddChildIb(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
ti := NewTagIndex()
|
||||
ib := NewIfdBuilder(im, ti, IfdPathStandard, TestDefaultByteOrder)
|
||||
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
bt := &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x11,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string")),
|
||||
}
|
||||
|
@ -146,13 +148,13 @@ func TestIfdBuilder_AddChildIb(t *testing.T) {
|
|||
err = ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
ibChild := NewIfdBuilder(im, ti, IfdPathStandardExif, TestDefaultByteOrder)
|
||||
ibChild := NewIfdBuilder(im, ti, exifcommon.IfdPathStandardExif, exifcommon.TestDefaultByteOrder)
|
||||
err = ib.AddChildIb(ibChild)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x22,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string")),
|
||||
}
|
||||
|
@ -193,7 +195,7 @@ func TestIfdBuilder_AddTagsFromExisting(t *testing.T) {
|
|||
_, index, err := Collect(im, ti, exifData)
|
||||
log.PanicIf(err)
|
||||
|
||||
ib := NewIfdBuilder(im, ti, IfdPathStandard, TestDefaultByteOrder)
|
||||
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
err = ib.AddTagsFromExisting(index.RootIfd, nil, nil, nil)
|
||||
log.PanicIf(err)
|
||||
|
@ -229,7 +231,7 @@ func TestIfdBuilder_AddTagsFromExisting__Includes(t *testing.T) {
|
|||
_, index, err := Collect(im, ti, exifData)
|
||||
log.PanicIf(err)
|
||||
|
||||
ib := NewIfdBuilder(im, ti, IfdPathStandard, TestDefaultByteOrder)
|
||||
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
err = ib.AddTagsFromExisting(index.RootIfd, nil, []uint16{0x00ff}, nil)
|
||||
log.PanicIf(err)
|
||||
|
@ -262,7 +264,7 @@ func TestIfdBuilder_AddTagsFromExisting__Excludes(t *testing.T) {
|
|||
_, index, err := Collect(im, ti, exifData)
|
||||
log.PanicIf(err)
|
||||
|
||||
ib := NewIfdBuilder(im, ti, IfdPathStandard, TestDefaultByteOrder)
|
||||
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
err = ib.AddTagsFromExisting(index.RootIfd, nil, nil, []uint16{0xff})
|
||||
log.PanicIf(err)
|
||||
|
@ -291,11 +293,11 @@ func TestIfdBuilder_FindN__First_1(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
ti := NewTagIndex()
|
||||
ib := NewIfdBuilder(im, ti, IfdPathStandard, TestDefaultByteOrder)
|
||||
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
bt := &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x11,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string")),
|
||||
}
|
||||
|
@ -304,8 +306,8 @@ func TestIfdBuilder_FindN__First_1(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x22,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string2")),
|
||||
}
|
||||
|
@ -314,8 +316,8 @@ func TestIfdBuilder_FindN__First_1(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x33,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string3")),
|
||||
}
|
||||
|
@ -347,11 +349,11 @@ func TestIfdBuilder_FindN__First_2_1Returned(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
ti := NewTagIndex()
|
||||
ib := NewIfdBuilder(im, ti, IfdPathStandard, TestDefaultByteOrder)
|
||||
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
bt := &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x11,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string")),
|
||||
}
|
||||
|
@ -360,8 +362,8 @@ func TestIfdBuilder_FindN__First_2_1Returned(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x22,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string2")),
|
||||
}
|
||||
|
@ -370,8 +372,8 @@ func TestIfdBuilder_FindN__First_2_1Returned(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x33,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string3")),
|
||||
}
|
||||
|
@ -403,11 +405,11 @@ func TestIfdBuilder_FindN__First_2_2Returned(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
ti := NewTagIndex()
|
||||
ib := NewIfdBuilder(im, ti, IfdPathStandard, TestDefaultByteOrder)
|
||||
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
bt := &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x11,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string")),
|
||||
}
|
||||
|
@ -416,8 +418,8 @@ func TestIfdBuilder_FindN__First_2_2Returned(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x22,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string2")),
|
||||
}
|
||||
|
@ -426,8 +428,8 @@ func TestIfdBuilder_FindN__First_2_2Returned(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x33,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string3")),
|
||||
}
|
||||
|
@ -436,8 +438,8 @@ func TestIfdBuilder_FindN__First_2_2Returned(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x11,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string4")),
|
||||
}
|
||||
|
@ -446,8 +448,8 @@ func TestIfdBuilder_FindN__First_2_2Returned(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x11,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string5")),
|
||||
}
|
||||
|
@ -486,11 +488,11 @@ func TestIfdBuilder_FindN__Middle_WithDuplicates(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
ti := NewTagIndex()
|
||||
ib := NewIfdBuilder(im, ti, IfdPathStandard, TestDefaultByteOrder)
|
||||
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
bt := &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x11,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string")),
|
||||
}
|
||||
|
@ -499,8 +501,8 @@ func TestIfdBuilder_FindN__Middle_WithDuplicates(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x22,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string2")),
|
||||
}
|
||||
|
@ -509,8 +511,8 @@ func TestIfdBuilder_FindN__Middle_WithDuplicates(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x33,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string3")),
|
||||
}
|
||||
|
@ -519,8 +521,8 @@ func TestIfdBuilder_FindN__Middle_WithDuplicates(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x11,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string4")),
|
||||
}
|
||||
|
@ -529,8 +531,8 @@ func TestIfdBuilder_FindN__Middle_WithDuplicates(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x11,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string5")),
|
||||
}
|
||||
|
@ -539,8 +541,8 @@ func TestIfdBuilder_FindN__Middle_WithDuplicates(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x33,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string6")),
|
||||
}
|
||||
|
@ -572,11 +574,11 @@ func TestIfdBuilder_FindN__Middle_NoDuplicates(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
ti := NewTagIndex()
|
||||
ib := NewIfdBuilder(im, ti, IfdPathStandard, TestDefaultByteOrder)
|
||||
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
bt := &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x11,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string")),
|
||||
}
|
||||
|
@ -585,8 +587,8 @@ func TestIfdBuilder_FindN__Middle_NoDuplicates(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x22,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string2")),
|
||||
}
|
||||
|
@ -595,8 +597,8 @@ func TestIfdBuilder_FindN__Middle_NoDuplicates(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x33,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string3")),
|
||||
}
|
||||
|
@ -605,8 +607,8 @@ func TestIfdBuilder_FindN__Middle_NoDuplicates(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x11,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string4")),
|
||||
}
|
||||
|
@ -638,7 +640,7 @@ func TestIfdBuilder_FindN__Miss(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
ti := NewTagIndex()
|
||||
ib := NewIfdBuilder(im, ti, IfdPathStandard, TestDefaultByteOrder)
|
||||
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
found, err := ib.FindN(0x11, 1)
|
||||
log.PanicIf(err)
|
||||
|
@ -655,11 +657,11 @@ func TestIfdBuilder_Find__Hit(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
ti := NewTagIndex()
|
||||
ib := NewIfdBuilder(im, ti, IfdPathStandard, TestDefaultByteOrder)
|
||||
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
bt := &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x11,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string")),
|
||||
}
|
||||
|
@ -668,8 +670,8 @@ func TestIfdBuilder_Find__Hit(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x22,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string2")),
|
||||
}
|
||||
|
@ -678,8 +680,8 @@ func TestIfdBuilder_Find__Hit(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x33,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string3")),
|
||||
}
|
||||
|
@ -688,8 +690,8 @@ func TestIfdBuilder_Find__Hit(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x11,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string4")),
|
||||
}
|
||||
|
@ -719,11 +721,11 @@ func TestIfdBuilder_Find__Miss(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
ti := NewTagIndex()
|
||||
ib := NewIfdBuilder(im, ti, IfdPathStandard, TestDefaultByteOrder)
|
||||
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
bt := &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x11,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string")),
|
||||
}
|
||||
|
@ -732,8 +734,8 @@ func TestIfdBuilder_Find__Miss(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x22,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string2")),
|
||||
}
|
||||
|
@ -742,8 +744,8 @@ func TestIfdBuilder_Find__Miss(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x33,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string3")),
|
||||
}
|
||||
|
@ -752,8 +754,8 @@ func TestIfdBuilder_Find__Miss(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x11,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string4")),
|
||||
}
|
||||
|
@ -776,11 +778,11 @@ func TestIfdBuilder_Replace(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
ti := NewTagIndex()
|
||||
ib := NewIfdBuilder(im, ti, IfdPathStandard, TestDefaultByteOrder)
|
||||
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
bt := &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x11,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string")),
|
||||
}
|
||||
|
@ -789,8 +791,8 @@ func TestIfdBuilder_Replace(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x22,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string2")),
|
||||
}
|
||||
|
@ -799,8 +801,8 @@ func TestIfdBuilder_Replace(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x33,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string3")),
|
||||
}
|
||||
|
@ -818,8 +820,8 @@ func TestIfdBuilder_Replace(t *testing.T) {
|
|||
}
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x99,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string4")),
|
||||
}
|
||||
|
@ -844,11 +846,11 @@ func TestIfdBuilder_ReplaceN(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
ti := NewTagIndex()
|
||||
ib := NewIfdBuilder(im, ti, IfdPathStandard, TestDefaultByteOrder)
|
||||
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
bt := &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x11,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string")),
|
||||
}
|
||||
|
@ -857,8 +859,8 @@ func TestIfdBuilder_ReplaceN(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x22,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string2")),
|
||||
}
|
||||
|
@ -867,8 +869,8 @@ func TestIfdBuilder_ReplaceN(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x33,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string3")),
|
||||
}
|
||||
|
@ -886,8 +888,8 @@ func TestIfdBuilder_ReplaceN(t *testing.T) {
|
|||
}
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0xA9,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string4")),
|
||||
}
|
||||
|
@ -912,11 +914,11 @@ func TestIfdBuilder_DeleteFirst(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
ti := NewTagIndex()
|
||||
ib := NewIfdBuilder(im, ti, IfdPathStandard, TestDefaultByteOrder)
|
||||
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
bt := &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x11,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string")),
|
||||
}
|
||||
|
@ -925,8 +927,8 @@ func TestIfdBuilder_DeleteFirst(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x22,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string2")),
|
||||
}
|
||||
|
@ -935,8 +937,8 @@ func TestIfdBuilder_DeleteFirst(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x22,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string3")),
|
||||
}
|
||||
|
@ -945,8 +947,8 @@ func TestIfdBuilder_DeleteFirst(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x33,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string4")),
|
||||
}
|
||||
|
@ -1014,11 +1016,11 @@ func TestIfdBuilder_DeleteN(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
ti := NewTagIndex()
|
||||
ib := NewIfdBuilder(im, ti, IfdPathStandard, TestDefaultByteOrder)
|
||||
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
bt := &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x11,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string")),
|
||||
}
|
||||
|
@ -1027,8 +1029,8 @@ func TestIfdBuilder_DeleteN(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x22,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string2")),
|
||||
}
|
||||
|
@ -1037,8 +1039,8 @@ func TestIfdBuilder_DeleteN(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x22,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string3")),
|
||||
}
|
||||
|
@ -1047,8 +1049,8 @@ func TestIfdBuilder_DeleteN(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x33,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string4")),
|
||||
}
|
||||
|
@ -1116,11 +1118,11 @@ func TestIfdBuilder_DeleteN_Two(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
ti := NewTagIndex()
|
||||
ib := NewIfdBuilder(im, ti, IfdPathStandard, TestDefaultByteOrder)
|
||||
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
bt := &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x11,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string")),
|
||||
}
|
||||
|
@ -1129,8 +1131,8 @@ func TestIfdBuilder_DeleteN_Two(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x22,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string2")),
|
||||
}
|
||||
|
@ -1139,8 +1141,8 @@ func TestIfdBuilder_DeleteN_Two(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x22,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string3")),
|
||||
}
|
||||
|
@ -1149,8 +1151,8 @@ func TestIfdBuilder_DeleteN_Two(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x33,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string4")),
|
||||
}
|
||||
|
@ -1202,11 +1204,11 @@ func TestIfdBuilder_DeleteAll(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
ti := NewTagIndex()
|
||||
ib := NewIfdBuilder(im, ti, IfdPathStandard, TestDefaultByteOrder)
|
||||
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
bt := &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x11,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string")),
|
||||
}
|
||||
|
@ -1215,8 +1217,8 @@ func TestIfdBuilder_DeleteAll(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x22,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string2")),
|
||||
}
|
||||
|
@ -1225,8 +1227,8 @@ func TestIfdBuilder_DeleteAll(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x22,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string3")),
|
||||
}
|
||||
|
@ -1235,8 +1237,8 @@ func TestIfdBuilder_DeleteAll(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
bt = &BuilderTag{
|
||||
ifdPath: IfdPathStandard,
|
||||
typeId: TypeByte,
|
||||
ifdPath: exifcommon.IfdPathStandard,
|
||||
typeId: exifcommon.TypeByte,
|
||||
tagId: 0x33,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte("test string4")),
|
||||
}
|
||||
|
@ -1486,15 +1488,69 @@ func TestIfdBuilder_CreateIfdBuilderFromExistingChain_RealData(t *testing.T) {
|
|||
t.Fatalf("Tag-type not as expected: %d != %d ITE=%s", recoveredIte.TagType, originalIte.TagType, recoveredIte)
|
||||
}
|
||||
|
||||
// TODO(dustin): We're always accessing the addressable-data using the root-IFD. It shouldn't matter, but we'd rather access it from our specific IFD.
|
||||
originalValueBytes, err := originalIte.ValueBytes(originalIndex.RootIfd.addressableData, originalIndex.RootIfd.ByteOrder)
|
||||
log.PanicIf(err)
|
||||
var originalValueBytes []byte
|
||||
|
||||
recoveredValueBytes, err := recoveredIte.ValueBytes(recoveredIndex.RootIfd.addressableData, recoveredIndex.RootIfd.ByteOrder)
|
||||
log.PanicIf(err)
|
||||
if originalIte.TagType == exifcommon.TypeUndefined {
|
||||
var err error
|
||||
|
||||
if bytes.Compare(originalValueBytes, recoveredValueBytes) != 0 {
|
||||
t.Fatalf("bytes of tag content not correct: %s != %s", originalIte, recoveredIte)
|
||||
valueContext :=
|
||||
newValueContextFromTag(
|
||||
originalIte,
|
||||
originalIndex.RootIfd.addressableData,
|
||||
originalIndex.RootIfd.ByteOrder)
|
||||
|
||||
value, err := exifundefined.Decode(
|
||||
originalIte.IfdPath,
|
||||
originalIte.TagId,
|
||||
valueContext,
|
||||
originalIndex.RootIfd.ByteOrder)
|
||||
|
||||
log.PanicIf(err)
|
||||
|
||||
originalValueBytes, _, err = exifundefined.Encode(value, originalIndex.RootIfd.ByteOrder)
|
||||
} else {
|
||||
var err error
|
||||
|
||||
// TODO(dustin): We're always accessing the addressable-data using the root-IFD. It shouldn't matter, but we'd rather access it from our specific IFD.
|
||||
originalValueBytes, err = originalIte.ValueBytes(originalIndex.RootIfd.addressableData, originalIndex.RootIfd.ByteOrder)
|
||||
log.PanicIf(err)
|
||||
}
|
||||
|
||||
var recoveredValueBytes []byte
|
||||
|
||||
if recoveredIte.TagType == exifcommon.TypeUndefined {
|
||||
var err error
|
||||
|
||||
valueContext :=
|
||||
newValueContextFromTag(
|
||||
recoveredIte,
|
||||
recoveredIndex.RootIfd.addressableData,
|
||||
recoveredIndex.RootIfd.ByteOrder)
|
||||
|
||||
value, err := exifundefined.Decode(
|
||||
recoveredIte.IfdPath,
|
||||
recoveredIte.TagId,
|
||||
valueContext,
|
||||
recoveredIndex.RootIfd.ByteOrder)
|
||||
|
||||
log.PanicIf(err)
|
||||
|
||||
recoveredValueBytes, _, err = exifundefined.Encode(value, recoveredIndex.RootIfd.ByteOrder)
|
||||
} else {
|
||||
var err error
|
||||
|
||||
recoveredValueBytes, err = recoveredIte.ValueBytes(recoveredIndex.RootIfd.addressableData, recoveredIndex.RootIfd.ByteOrder)
|
||||
log.PanicIf(err)
|
||||
}
|
||||
|
||||
if bytes.Compare(recoveredValueBytes, originalValueBytes) != 0 {
|
||||
fmt.Printf("ACTUAL: %s\n", originalIte)
|
||||
exifcommon.DumpBytes(recoveredValueBytes)
|
||||
|
||||
fmt.Printf("EXPECTED: %s\n", recoveredIte)
|
||||
exifcommon.DumpBytes(originalValueBytes)
|
||||
|
||||
t.Fatalf("Bytes of tag content not correct.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1529,8 +1585,8 @@ func TestIfdBuilder_CreateIfdBuilderFromExistingChain_RealData(t *testing.T) {
|
|||
// ucBt, err := exifBt.value.Ib().FindTagWithName("UserComment")
|
||||
// log.PanicIf(err)
|
||||
|
||||
// uc := TagUnknownType_9298_UserComment{
|
||||
// EncodingType: TagUnknownType_9298_UserComment_Encoding_ASCII,
|
||||
// uc := exifundefined.Tag9286UserComment{
|
||||
// EncodingType: TagUndefinedType_9286_UserComment_Encoding_ASCII,
|
||||
// EncodingBytes: []byte("TEST COMMENT"),
|
||||
// }
|
||||
|
||||
|
@ -1687,8 +1743,8 @@ func ExampleBuilderTag_SetValue() {
|
|||
// its type-specific struct.
|
||||
|
||||
// TODO(dustin): !! Add an example for setting a non-unknown value, too.
|
||||
uc := TagUnknownType_9298_UserComment{
|
||||
EncodingType: TagUnknownType_9298_UserComment_Encoding_ASCII,
|
||||
uc := exifundefined.Tag9286UserComment{
|
||||
EncodingType: exifundefined.TagUndefinedType_9286_UserComment_Encoding_ASCII,
|
||||
EncodingBytes: []byte("TEST COMMENT"),
|
||||
}
|
||||
|
||||
|
@ -1793,19 +1849,19 @@ func TestIfdBuilder_CreateIfdBuilderWithExistingIfd(t *testing.T) {
|
|||
err := LoadStandardIfds(im)
|
||||
log.PanicIf(err)
|
||||
|
||||
mi, err := im.GetWithPath(IfdPathStandardGps)
|
||||
mi, err := im.GetWithPath(exifcommon.IfdPathStandardGps)
|
||||
log.PanicIf(err)
|
||||
|
||||
tagId := mi.TagId
|
||||
|
||||
parentIfd := &Ifd{
|
||||
IfdPath: IfdPathStandard,
|
||||
IfdPath: exifcommon.IfdPathStandard,
|
||||
tagIndex: ti,
|
||||
}
|
||||
|
||||
ifd := &Ifd{
|
||||
IfdPath: IfdPathStandardGps,
|
||||
ByteOrder: TestDefaultByteOrder,
|
||||
IfdPath: exifcommon.IfdPathStandardGps,
|
||||
ByteOrder: exifcommon.TestDefaultByteOrder,
|
||||
Offset: 0x123,
|
||||
ParentIfd: parentIfd,
|
||||
|
||||
|
@ -1829,12 +1885,12 @@ func TestIfdBuilder_CreateIfdBuilderWithExistingIfd(t *testing.T) {
|
|||
func TestNewStandardBuilderTag__OneUnit(t *testing.T) {
|
||||
ti := NewTagIndex()
|
||||
|
||||
it, err := ti.Get(IfdPathStandardExif, uint16(0x8833))
|
||||
it, err := ti.Get(exifcommon.IfdPathStandardExif, uint16(0x8833))
|
||||
log.PanicIf(err)
|
||||
|
||||
bt := NewStandardBuilderTag(IfdPathStandardExif, it, TestDefaultByteOrder, []uint32{uint32(0x1234)})
|
||||
bt := NewStandardBuilderTag(exifcommon.IfdPathStandardExif, it, exifcommon.TestDefaultByteOrder, []uint32{uint32(0x1234)})
|
||||
|
||||
if bt.ifdPath != IfdPathStandardExif {
|
||||
if bt.ifdPath != exifcommon.IfdPathStandardExif {
|
||||
t.Fatalf("II in BuilderTag not correct")
|
||||
} else if bt.tagId != 0x8833 {
|
||||
t.Fatalf("tag-ID not correct")
|
||||
|
@ -1846,12 +1902,12 @@ func TestNewStandardBuilderTag__OneUnit(t *testing.T) {
|
|||
func TestNewStandardBuilderTag__TwoUnits(t *testing.T) {
|
||||
ti := NewTagIndex()
|
||||
|
||||
it, err := ti.Get(IfdPathStandardExif, uint16(0x8833))
|
||||
it, err := ti.Get(exifcommon.IfdPathStandardExif, uint16(0x8833))
|
||||
log.PanicIf(err)
|
||||
|
||||
bt := NewStandardBuilderTag(IfdPathStandardExif, it, TestDefaultByteOrder, []uint32{uint32(0x1234), uint32(0x5678)})
|
||||
bt := NewStandardBuilderTag(exifcommon.IfdPathStandardExif, it, exifcommon.TestDefaultByteOrder, []uint32{uint32(0x1234), uint32(0x5678)})
|
||||
|
||||
if bt.ifdPath != IfdPathStandardExif {
|
||||
if bt.ifdPath != exifcommon.IfdPathStandardExif {
|
||||
t.Fatalf("II in BuilderTag not correct")
|
||||
} else if bt.tagId != 0x8833 {
|
||||
t.Fatalf("tag-ID not correct")
|
||||
|
@ -1869,7 +1925,7 @@ func TestIfdBuilder_AddStandardWithName(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
ti := NewTagIndex()
|
||||
ib := NewIfdBuilder(im, ti, IfdPathStandard, TestDefaultByteOrder)
|
||||
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
err = ib.AddStandardWithName("ProcessingSoftware", "some software")
|
||||
log.PanicIf(err)
|
||||
|
@ -1880,7 +1936,7 @@ func TestIfdBuilder_AddStandardWithName(t *testing.T) {
|
|||
|
||||
bt := ib.tags[0]
|
||||
|
||||
if bt.ifdPath != IfdPathStandard {
|
||||
if bt.ifdPath != exifcommon.IfdPathStandard {
|
||||
t.Fatalf("II not correct: %s", bt.ifdPath)
|
||||
} else if bt.tagId != 0x000b {
|
||||
t.Fatalf("Tag-ID not correct: (0x%04x)", bt.tagId)
|
||||
|
@ -1900,7 +1956,7 @@ func TestGetOrCreateIbFromRootIb__Noop(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
ti := NewTagIndex()
|
||||
rootIb := NewIfdBuilder(im, ti, IfdPathStandard, TestDefaultByteOrder)
|
||||
rootIb := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
ib, err := GetOrCreateIbFromRootIb(rootIb, "IFD")
|
||||
log.PanicIf(err)
|
||||
|
@ -1921,7 +1977,7 @@ func TestGetOrCreateIbFromRootIb__FqNoop(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
ti := NewTagIndex()
|
||||
rootIb := NewIfdBuilder(im, ti, IfdPathStandard, TestDefaultByteOrder)
|
||||
rootIb := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
ib, err := GetOrCreateIbFromRootIb(rootIb, "IFD0")
|
||||
log.PanicIf(err)
|
||||
|
@ -1942,7 +1998,7 @@ func TestGetOrCreateIbFromRootIb_InvalidChild(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
ti := NewTagIndex()
|
||||
rootIb := NewIfdBuilder(im, ti, IfdPathStandard, TestDefaultByteOrder)
|
||||
rootIb := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
_, err = GetOrCreateIbFromRootIb(rootIb, "IFD/Invalid")
|
||||
if err == nil {
|
||||
|
@ -1966,7 +2022,7 @@ func TestGetOrCreateIbFromRootIb__Child(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
|
||||
ti := NewTagIndex()
|
||||
rootIb := NewIfdBuilder(im, ti, IfdPathStandard, TestDefaultByteOrder)
|
||||
rootIb := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
lines := rootIb.DumpToStrings()
|
||||
expected := []string{
|
||||
|
|
|
@ -4,7 +4,6 @@ import (
|
|||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -12,6 +11,9 @@ import (
|
|||
"encoding/binary"
|
||||
|
||||
"github.com/dsoprea/go-logging"
|
||||
|
||||
"github.com/dsoprea/go-exif/v2/common"
|
||||
"github.com/dsoprea/go-exif/v2/undefined"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -159,7 +161,7 @@ func (ie *IfdEnumerate) parseTag(fqIfdPath string, tagPosition int, ite *IfdTagE
|
|||
tagTypeRaw, _, err := ite.getUint16()
|
||||
log.PanicIf(err)
|
||||
|
||||
tagType := TagTypePrimitive(tagTypeRaw)
|
||||
tagType := exifcommon.TagTypePrimitive(tagTypeRaw)
|
||||
|
||||
unitCount, _, err := ite.getUint32()
|
||||
log.PanicIf(err)
|
||||
|
@ -167,7 +169,7 @@ func (ie *IfdEnumerate) parseTag(fqIfdPath string, tagPosition int, ite *IfdTagE
|
|||
valueOffset, rawValueOffset, err := ite.getUint32()
|
||||
log.PanicIf(err)
|
||||
|
||||
if _, found := TypeNames[tagType]; found == false {
|
||||
if tagType.IsValid() == false {
|
||||
log.Panic(ErrTagTypeNotValid)
|
||||
}
|
||||
|
||||
|
@ -210,7 +212,7 @@ func (ie *IfdEnumerate) parseTag(fqIfdPath string, tagPosition int, ite *IfdTagE
|
|||
return tag, nil
|
||||
}
|
||||
|
||||
func (ie *IfdEnumerate) GetValueContext(ite *IfdTagEntry) *ValueContext {
|
||||
func (ie *IfdEnumerate) GetValueContext(ite *IfdTagEntry) *exifcommon.ValueContext {
|
||||
|
||||
// TODO(dustin): Add test
|
||||
|
||||
|
@ -229,120 +231,56 @@ func (ie *IfdEnumerate) resolveTagValue(ite *IfdTagEntry) (valueBytes []byte, is
|
|||
}
|
||||
}()
|
||||
|
||||
addressableData := ie.exifData[ExifAddressableAreaStart:]
|
||||
valueContext := ie.GetValueContext(ite)
|
||||
|
||||
// Return the exact bytes of the unknown-type value. Returning a string
|
||||
// (`ValueString`) is easy because we can just pass everything to
|
||||
// `Sprintf()`. Returning the raw, typed value (`Value`) is easy
|
||||
// (obviously). However, here, in order to produce the list of bytes, we
|
||||
// need to coerce whatever `Undefined()` returns.
|
||||
if ite.TagType == TypeUndefined {
|
||||
valueContext := ie.GetValueContext(ite)
|
||||
|
||||
value, err := valueContext.Undefined()
|
||||
if ite.TagType == exifcommon.TypeUndefined {
|
||||
value, err := exifundefined.Decode(ite.IfdPath, ite.TagId, valueContext, ie.byteOrder)
|
||||
if err != nil {
|
||||
if err == ErrUnhandledUnknownTypedTag {
|
||||
valueBytes = []byte(UnparseableUnknownTagValuePlaceholder)
|
||||
return valueBytes, true, nil
|
||||
if err == exifcommon.ErrUnhandledUnknownTypedTag {
|
||||
return nil, true, nil
|
||||
}
|
||||
|
||||
log.Panic(err)
|
||||
} else {
|
||||
switch value.(type) {
|
||||
case []byte:
|
||||
return value.([]byte), false, nil
|
||||
case TagUnknownType_UnknownValue:
|
||||
b := []byte(value.(TagUnknownType_UnknownValue))
|
||||
return b, false, nil
|
||||
case string:
|
||||
return []byte(value.(string)), false, nil
|
||||
case UnknownTagValue:
|
||||
valueBytes, err := value.(UnknownTagValue).ValueBytes()
|
||||
log.PanicIf(err)
|
||||
|
||||
return valueBytes, false, 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%04x) (1): [%s]", ite.TagId, reflect.TypeOf(value))
|
||||
}
|
||||
}
|
||||
|
||||
encodeable := value.(exifundefined.EncodeableValue)
|
||||
|
||||
valueBytes, _, err = exifundefined.Encode(encodeable, ie.byteOrder)
|
||||
log.PanicIf(err)
|
||||
} else {
|
||||
originalType := NewTagType(ite.TagType, ie.byteOrder)
|
||||
byteCount := uint32(originalType.Type().Size()) * ite.UnitCount
|
||||
var err error
|
||||
|
||||
tt := NewTagType(TypeByte, ie.byteOrder)
|
||||
|
||||
if tt.valueIsEmbedded(byteCount) == true {
|
||||
iteLogger.Debugf(nil, "Reading BYTE value (ITE; embedded).")
|
||||
|
||||
// In this case, the bytes normally used for the offset are actually
|
||||
// data.
|
||||
valueBytes, err = tt.ParseBytes(ite.RawValueOffset, byteCount)
|
||||
log.PanicIf(err)
|
||||
} else {
|
||||
iteLogger.Debugf(nil, "Reading BYTE value (ITE; at offset).")
|
||||
|
||||
valueBytes, err = tt.ParseBytes(addressableData[ite.ValueOffset:], byteCount)
|
||||
log.PanicIf(err)
|
||||
}
|
||||
valueBytes, err = valueContext.ReadRawEncoded()
|
||||
log.PanicIf(err)
|
||||
}
|
||||
|
||||
return valueBytes, false, nil
|
||||
}
|
||||
|
||||
// RawTagVisitorPtr is an optional callback that can get hit for every tag we parse
|
||||
// RawTagWalk is an optional callback that can get hit for every tag we parse
|
||||
// through. `addressableData` is the byte array startign after the EXIF header
|
||||
// (where the offsets of all IFDs and values are calculated from).
|
||||
//
|
||||
// This was reimplemented as an interface to allow for simpler change management
|
||||
// in the future.
|
||||
type RawTagWalk interface {
|
||||
Visit(fqIfdPath string, ifdIndex int, tagId uint16, tagType TagType, valueContext *ValueContext) (err error)
|
||||
Visit(fqIfdPath string, ifdIndex int, tagId uint16, tagType exifcommon.TagTypePrimitive, valueContext *exifcommon.ValueContext) (err error)
|
||||
}
|
||||
|
||||
type RawTagWalkLegacyWrapper struct {
|
||||
legacyVisitor RawTagVisitor
|
||||
}
|
||||
|
||||
func (rtwlw RawTagWalkLegacyWrapper) Visit(fqIfdPath string, ifdIndex int, tagId uint16, tagType TagType, valueContext *ValueContext) (err error) {
|
||||
return rtwlw.legacyVisitor(fqIfdPath, ifdIndex, tagId, tagType, *valueContext)
|
||||
}
|
||||
|
||||
// RawTagVisitor is an optional callback that can get hit for every tag we parse
|
||||
// through. `addressableData` is the byte array startign after the EXIF header
|
||||
// (where the offsets of all IFDs and values are calculated from).
|
||||
//
|
||||
// DEPRECATED(dustin): Use a RawTagWalk instead.
|
||||
type RawTagVisitor func(fqIfdPath string, ifdIndex int, tagId uint16, tagType TagType, valueContext ValueContext) (err error)
|
||||
|
||||
// ParseIfd decodes the IFD block that we're currently sitting on the first
|
||||
// byte of.
|
||||
func (ie *IfdEnumerate) ParseIfd(fqIfdPath string, ifdIndex int, ite *IfdTagEnumerator, visitor interface{}, doDescend bool, resolveValues bool) (nextIfdOffset uint32, entries []*IfdTagEntry, thumbnailData []byte, err error) {
|
||||
func (ie *IfdEnumerate) ParseIfd(fqIfdPath string, ifdIndex int, ite *IfdTagEnumerator, visitor RawTagWalk, doDescend bool, resolveValues bool) (nextIfdOffset uint32, entries []*IfdTagEntry, thumbnailData []byte, err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
}
|
||||
}()
|
||||
|
||||
var visitorWrapper RawTagWalk
|
||||
|
||||
if visitor != nil {
|
||||
var ok bool
|
||||
|
||||
visitorWrapper, ok = visitor.(RawTagWalk)
|
||||
if ok == false {
|
||||
// Legacy usage.
|
||||
|
||||
// `ok` can be `true` but `legacyVisitor` can still be `nil` (when
|
||||
// passed as nil).
|
||||
if legacyVisitor, ok := visitor.(RawTagVisitor); ok == true && legacyVisitor != nil {
|
||||
visitorWrapper = RawTagWalkLegacyWrapper{
|
||||
legacyVisitor: legacyVisitor,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tagCount, _, err := ite.getUint16()
|
||||
log.PanicIf(err)
|
||||
|
||||
|
@ -373,12 +311,10 @@ func (ie *IfdEnumerate) ParseIfd(fqIfdPath string, ifdIndex int, ite *IfdTagEnum
|
|||
continue
|
||||
}
|
||||
|
||||
if visitorWrapper != nil {
|
||||
tt := NewTagType(tag.TagType, ie.byteOrder)
|
||||
|
||||
if visitor != nil {
|
||||
valueContext := ie.GetValueContext(tag)
|
||||
|
||||
err := visitorWrapper.Visit(fqIfdPath, ifdIndex, tag.TagId, tt, valueContext)
|
||||
err := visitor.Visit(fqIfdPath, ifdIndex, tag.TagId, tag.TagType, valueContext)
|
||||
log.PanicIf(err)
|
||||
}
|
||||
|
||||
|
@ -430,7 +366,7 @@ func (ie *IfdEnumerate) parseThumbnail(offsetIte, lengthIte *IfdTagEntry) (thumb
|
|||
length := vList[0]
|
||||
|
||||
// The tag is official a LONG type, but it's actually an offset to a blob of bytes.
|
||||
offsetIte.TagType = TypeByte
|
||||
offsetIte.TagType = exifcommon.TypeByte
|
||||
offsetIte.UnitCount = length
|
||||
|
||||
thumbnailData, err = offsetIte.ValueBytes(addressableData, ie.byteOrder)
|
||||
|
@ -440,7 +376,7 @@ func (ie *IfdEnumerate) parseThumbnail(offsetIte, lengthIte *IfdTagEntry) (thumb
|
|||
}
|
||||
|
||||
// Scan enumerates the different EXIF's IFD blocks.
|
||||
func (ie *IfdEnumerate) scan(fqIfdName string, ifdOffset uint32, visitor interface{}, resolveValues bool) (err error) {
|
||||
func (ie *IfdEnumerate) scan(fqIfdName string, ifdOffset uint32, visitor RawTagWalk, resolveValues bool) (err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
|
@ -466,7 +402,7 @@ func (ie *IfdEnumerate) scan(fqIfdName string, ifdOffset uint32, visitor interfa
|
|||
|
||||
// Scan enumerates the different EXIF blocks (called IFDs). `rootIfdName` will
|
||||
// be "IFD" in the TIFF standard.
|
||||
func (ie *IfdEnumerate) Scan(rootIfdName string, ifdOffset uint32, visitor RawTagVisitor, resolveValue bool) (err error) {
|
||||
func (ie *IfdEnumerate) Scan(rootIfdName string, ifdOffset uint32, visitor RawTagWalk, resolveValue bool) (err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
|
@ -717,8 +653,8 @@ func (ifd *Ifd) printTagTree(populateValues bool, index, level int, nextLink boo
|
|||
|
||||
value, err = ifd.TagValue(tag)
|
||||
if err != nil {
|
||||
if err == ErrUnhandledUnknownTypedTag {
|
||||
value = UnparseableUnknownTagValuePlaceholder
|
||||
if err == exifcommon.ErrUnhandledUnknownTypedTag {
|
||||
value = exifundefined.UnparseableUnknownTagValuePlaceholder
|
||||
} else {
|
||||
log.Panic(err)
|
||||
}
|
||||
|
@ -863,8 +799,8 @@ func (ifd *Ifd) GpsInfo() (gi *GpsInfo, err error) {
|
|||
|
||||
gi = new(GpsInfo)
|
||||
|
||||
if ifd.IfdPath != IfdPathStandardGps {
|
||||
log.Panicf("GPS can only be read on GPS IFD: [%s] != [%s]", ifd.IfdPath, IfdPathStandardGps)
|
||||
if ifd.IfdPath != exifcommon.IfdPathStandardGps {
|
||||
log.Panicf("GPS can only be read on GPS IFD: [%s] != [%s]", ifd.IfdPath, exifcommon.IfdPathStandardGps)
|
||||
}
|
||||
|
||||
if tags, found := ifd.EntriesByTagId[TagVersionId]; found == false {
|
||||
|
@ -926,7 +862,7 @@ func (ifd *Ifd) GpsInfo() (gi *GpsInfo, err error) {
|
|||
|
||||
// Parse location.
|
||||
|
||||
latitudeRaw := latitudeValue.([]Rational)
|
||||
latitudeRaw := latitudeValue.([]exifcommon.Rational)
|
||||
|
||||
gi.Latitude = GpsDegrees{
|
||||
Orientation: latitudeRefValue.(string)[0],
|
||||
|
@ -935,7 +871,7 @@ func (ifd *Ifd) GpsInfo() (gi *GpsInfo, err error) {
|
|||
Seconds: float64(latitudeRaw[2].Numerator) / float64(latitudeRaw[2].Denominator),
|
||||
}
|
||||
|
||||
longitudeRaw := longitudeValue.([]Rational)
|
||||
longitudeRaw := longitudeValue.([]exifcommon.Rational)
|
||||
|
||||
gi.Longitude = GpsDegrees{
|
||||
Orientation: longitudeRefValue.(string)[0],
|
||||
|
@ -956,7 +892,7 @@ func (ifd *Ifd) GpsInfo() (gi *GpsInfo, err error) {
|
|||
altitudeRefValue, err := ifd.TagValue(altitudeRefTags[0])
|
||||
log.PanicIf(err)
|
||||
|
||||
altitudeRaw := altitudeValue.([]Rational)
|
||||
altitudeRaw := altitudeValue.([]exifcommon.Rational)
|
||||
altitude := int(altitudeRaw[0].Numerator / altitudeRaw[0].Denominator)
|
||||
if altitudeRefValue.([]byte)[0] == 1 {
|
||||
altitude *= -1
|
||||
|
@ -984,7 +920,7 @@ func (ifd *Ifd) GpsInfo() (gi *GpsInfo, err error) {
|
|||
timestampValue, err := ifd.TagValue(timestampTags[0])
|
||||
log.PanicIf(err)
|
||||
|
||||
timestampRaw := timestampValue.([]Rational)
|
||||
timestampRaw := timestampValue.([]exifcommon.Rational)
|
||||
|
||||
hour := int(timestampRaw[0].Numerator / timestampRaw[0].Denominator)
|
||||
minute := int(timestampRaw[1].Numerator / timestampRaw[1].Denominator)
|
||||
|
@ -1023,7 +959,7 @@ func (ifd *Ifd) EnumerateTagsRecursively(visitor ParsedTagVisitor) (err error) {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (ifd *Ifd) GetValueContext(ite *IfdTagEntry) *ValueContext {
|
||||
func (ifd *Ifd) GetValueContext(ite *IfdTagEntry) *exifcommon.ValueContext {
|
||||
return newValueContextFromTag(
|
||||
ite,
|
||||
ifd.addressableData,
|
||||
|
@ -1068,9 +1004,9 @@ func (ie *IfdEnumerate) Collect(rootIfdOffset uint32, resolveValues bool) (index
|
|||
|
||||
queue := []QueuedIfd{
|
||||
{
|
||||
Name: IfdStandard,
|
||||
IfdPath: IfdStandard,
|
||||
FqIfdPath: IfdStandard,
|
||||
Name: exifcommon.IfdStandard,
|
||||
IfdPath: exifcommon.IfdStandard,
|
||||
FqIfdPath: exifcommon.IfdStandard,
|
||||
|
||||
TagId: 0xffff,
|
||||
|
||||
|
@ -1258,7 +1194,7 @@ func (ie *IfdEnumerate) setChildrenIndex(ifd *Ifd) (err error) {
|
|||
|
||||
// ParseOneIfd is a hack to use an IE to parse a raw IFD block. Can be used for
|
||||
// testing.
|
||||
func ParseOneIfd(ifdMapping *IfdMapping, tagIndex *TagIndex, fqIfdPath, ifdPath string, byteOrder binary.ByteOrder, ifdBlock []byte, visitor RawTagVisitor, resolveValues bool) (nextIfdOffset uint32, entries []*IfdTagEntry, err error) {
|
||||
func ParseOneIfd(ifdMapping *IfdMapping, tagIndex *TagIndex, fqIfdPath, ifdPath string, byteOrder binary.ByteOrder, ifdBlock []byte, visitor RawTagWalk, resolveValues bool) (nextIfdOffset uint32, entries []*IfdTagEntry, err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
|
@ -1308,8 +1244,8 @@ func FindIfdFromRootIfd(rootIfd *Ifd, ifdPath string) (ifd *Ifd, err error) {
|
|||
|
||||
if len(lineage) == 0 {
|
||||
log.Panicf("IFD path must be non-empty.")
|
||||
} else if lineage[0].Name != IfdStandard {
|
||||
log.Panicf("First IFD path item must be [%s].", IfdStandard)
|
||||
} else if lineage[0].Name != exifcommon.IfdStandard {
|
||||
log.Panicf("First IFD path item must be [%s].", exifcommon.IfdStandard)
|
||||
}
|
||||
|
||||
desiredRootIndex := lineage[0].Index
|
||||
|
|
|
@ -11,15 +11,17 @@ import (
|
|||
"io/ioutil"
|
||||
|
||||
"github.com/dsoprea/go-logging"
|
||||
|
||||
"github.com/dsoprea/go-exif/v2/common"
|
||||
)
|
||||
|
||||
func TestIfdTagEntry_ValueBytes(t *testing.T) {
|
||||
byteOrder := binary.BigEndian
|
||||
ve := NewValueEncoder(byteOrder)
|
||||
ve := exifcommon.NewValueEncoder(byteOrder)
|
||||
|
||||
original := []byte("original text")
|
||||
|
||||
ed, err := ve.encodeBytes(original)
|
||||
ed, err := ve.Encode(original)
|
||||
log.PanicIf(err)
|
||||
|
||||
// Now, pass the raw encoded value as if it was the entire addressable area
|
||||
|
@ -27,7 +29,7 @@ func TestIfdTagEntry_ValueBytes(t *testing.T) {
|
|||
// value happened to be recorded at the beginning.
|
||||
|
||||
ite := IfdTagEntry{
|
||||
TagType: TypeByte,
|
||||
TagType: exifcommon.TypeByte,
|
||||
UnitCount: uint32(len(original)),
|
||||
ValueOffset: 0,
|
||||
}
|
||||
|
@ -264,7 +266,7 @@ func TestIfd_GpsInfo(t *testing.T) {
|
|||
_, index, err := Collect(im, ti, rawExif)
|
||||
log.PanicIf(err)
|
||||
|
||||
ifd, err := index.RootIfd.ChildWithIfdPath(IfdPathStandardGps)
|
||||
ifd, err := index.RootIfd.ChildWithIfdPath(exifcommon.IfdPathStandardGps)
|
||||
log.PanicIf(err)
|
||||
|
||||
gi, err := ifd.GpsInfo()
|
||||
|
@ -482,7 +484,7 @@ func ExampleIfd_GpsInfo() {
|
|||
_, index, err := Collect(im, ti, rawExif)
|
||||
log.PanicIf(err)
|
||||
|
||||
ifd, err := index.RootIfd.ChildWithIfdPath(IfdPathStandardGps)
|
||||
ifd, err := index.RootIfd.ChildWithIfdPath(exifcommon.IfdPathStandardGps)
|
||||
log.PanicIf(err)
|
||||
|
||||
gi, err := ifd.GpsInfo()
|
||||
|
|
|
@ -2,11 +2,13 @@ package exif
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/dsoprea/go-logging"
|
||||
|
||||
"github.com/dsoprea/go-exif/v2/common"
|
||||
"github.com/dsoprea/go-exif/v2/undefined"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -16,7 +18,7 @@ var (
|
|||
type IfdTagEntry struct {
|
||||
TagId uint16
|
||||
TagIndex int
|
||||
TagType TagTypePrimitive
|
||||
TagType exifcommon.TagTypePrimitive
|
||||
UnitCount uint32
|
||||
ValueOffset uint32
|
||||
RawValueOffset []byte
|
||||
|
@ -44,7 +46,7 @@ type IfdTagEntry 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.IfdPath, ite.TagId, TypeNames[ite.TagType], ite.UnitCount)
|
||||
return fmt.Sprintf("IfdTagEntry<TAG-IFD-PATH=[%s] TAG-ID=(0x%04x) TAG-TYPE=[%s] UNIT-COUNT=(%d)>", ite.IfdPath, ite.TagId, ite.TagType.String(), ite.UnitCount)
|
||||
}
|
||||
|
||||
// TODO(dustin): TODO(dustin): Stop exporting IfdPath and TagId.
|
||||
|
@ -60,7 +62,7 @@ func (ite *IfdTagEntry) String() string {
|
|||
// }
|
||||
|
||||
// ValueString renders a string from whatever the value in this tag is.
|
||||
func (ite *IfdTagEntry) ValueString(addressableData []byte, byteOrder binary.ByteOrder) (value string, err error) {
|
||||
func (ite *IfdTagEntry) ValueString(addressableData []byte, byteOrder binary.ByteOrder) (phrase string, err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
|
@ -73,17 +75,23 @@ func (ite *IfdTagEntry) ValueString(addressableData []byte, byteOrder binary.Byt
|
|||
addressableData,
|
||||
byteOrder)
|
||||
|
||||
if ite.TagType == TypeUndefined {
|
||||
valueRaw, err := valueContext.Undefined()
|
||||
if ite.TagType == exifcommon.TypeUndefined {
|
||||
var err error
|
||||
|
||||
value, err := exifundefined.Decode(ite.IfdPath, ite.TagId, valueContext, byteOrder)
|
||||
log.PanicIf(err)
|
||||
|
||||
value = fmt.Sprintf("%v", valueRaw)
|
||||
s := value.(fmt.Stringer)
|
||||
|
||||
phrase = s.String()
|
||||
} else {
|
||||
value, err = valueContext.Format()
|
||||
var err error
|
||||
|
||||
phrase, err = valueContext.Format()
|
||||
log.PanicIf(err)
|
||||
}
|
||||
|
||||
return value, nil
|
||||
return phrase, nil
|
||||
}
|
||||
|
||||
// ValueBytes renders a specific list of bytes from the value in this tag.
|
||||
|
@ -94,60 +102,33 @@ func (ite *IfdTagEntry) ValueBytes(addressableData []byte, byteOrder binary.Byte
|
|||
}
|
||||
}()
|
||||
|
||||
valueContext :=
|
||||
newValueContextFromTag(
|
||||
ite,
|
||||
addressableData,
|
||||
byteOrder)
|
||||
|
||||
// Return the exact bytes of the unknown-type value. Returning a string
|
||||
// (`ValueString`) is easy because we can just pass everything to
|
||||
// `Sprintf()`. Returning the raw, typed value (`Value`) is easy
|
||||
// (obviously). However, here, in order to produce the list of bytes, we
|
||||
// need to coerce whatever `Undefined()` returns.
|
||||
if ite.TagType == TypeUndefined {
|
||||
valueContext :=
|
||||
newValueContextFromTag(
|
||||
ite,
|
||||
addressableData,
|
||||
byteOrder)
|
||||
|
||||
value, err := valueContext.Undefined()
|
||||
if ite.TagType == exifcommon.TypeUndefined {
|
||||
value, err := exifundefined.Decode(ite.IfdPath, ite.TagId, valueContext, byteOrder)
|
||||
log.PanicIf(err)
|
||||
|
||||
switch value.(type) {
|
||||
case []byte:
|
||||
return value.([]byte), nil
|
||||
case TagUnknownType_UnknownValue:
|
||||
b := []byte(value.(TagUnknownType_UnknownValue))
|
||||
return b, nil
|
||||
case string:
|
||||
return []byte(value.(string)), nil
|
||||
case UnknownTagValue:
|
||||
valueBytes, err := value.(UnknownTagValue).ValueBytes()
|
||||
log.PanicIf(err)
|
||||
ve := exifcommon.NewValueEncoder(byteOrder)
|
||||
|
||||
return valueBytes, 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%04x) (2): [%s]", ite.TagId, reflect.TypeOf(value))
|
||||
}
|
||||
}
|
||||
|
||||
originalType := NewTagType(ite.TagType, byteOrder)
|
||||
byteCount := uint32(originalType.Type().Size()) * ite.UnitCount
|
||||
|
||||
tt := NewTagType(TypeByte, byteOrder)
|
||||
|
||||
if tt.valueIsEmbedded(byteCount) == true {
|
||||
iteLogger.Debugf(nil, "Reading BYTE value (ITE; embedded).")
|
||||
|
||||
// In this case, the bytes normally used for the offset are actually
|
||||
// data.
|
||||
value, err = tt.ParseBytes(ite.RawValueOffset, byteCount)
|
||||
ed, err := ve.Encode(value)
|
||||
log.PanicIf(err)
|
||||
|
||||
return ed.Encoded, nil
|
||||
} else {
|
||||
iteLogger.Debugf(nil, "Reading BYTE value (ITE; at offset).")
|
||||
|
||||
value, err = tt.ParseBytes(addressableData[ite.ValueOffset:], byteCount)
|
||||
rawBytes, err := valueContext.ReadRawEncoded()
|
||||
log.PanicIf(err)
|
||||
}
|
||||
|
||||
return value, nil
|
||||
return rawBytes, nil
|
||||
}
|
||||
}
|
||||
|
||||
// Value returns the specific, parsed, typed value from the tag.
|
||||
|
@ -164,13 +145,15 @@ func (ite *IfdTagEntry) Value(addressableData []byte, byteOrder binary.ByteOrder
|
|||
addressableData,
|
||||
byteOrder)
|
||||
|
||||
if ite.TagType == TypeUndefined {
|
||||
value, err = valueContext.Undefined()
|
||||
if ite.TagType == exifcommon.TypeUndefined {
|
||||
var err error
|
||||
|
||||
value, err = exifundefined.Decode(ite.IfdPath, ite.TagId, valueContext, byteOrder)
|
||||
log.PanicIf(err)
|
||||
} else {
|
||||
tt := NewTagType(ite.TagType, byteOrder)
|
||||
var err error
|
||||
|
||||
value, err = tt.Resolve(valueContext)
|
||||
value, err = valueContext.Values()
|
||||
log.PanicIf(err)
|
||||
}
|
||||
|
||||
|
@ -206,7 +189,7 @@ func (itevr *IfdTagEntryValueResolver) ValueBytes(ite *IfdTagEntry) (value []byt
|
|||
itevr.addressableData,
|
||||
itevr.byteOrder)
|
||||
|
||||
rawBytes, err := valueContext.readRawEncoded()
|
||||
rawBytes, err := valueContext.ReadRawEncoded()
|
||||
log.PanicIf(err)
|
||||
|
||||
return rawBytes, nil
|
||||
|
|
|
@ -2,25 +2,28 @@ package exif
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/dsoprea/go-logging"
|
||||
|
||||
"github.com/dsoprea/go-exif/v2/common"
|
||||
)
|
||||
|
||||
func TestIfdTagEntry_ValueString_Allocated(t *testing.T) {
|
||||
ite := IfdTagEntry{
|
||||
TagId: 0x1,
|
||||
TagIndex: 0,
|
||||
TagType: TypeByte,
|
||||
TagType: exifcommon.TypeByte,
|
||||
UnitCount: 6,
|
||||
ValueOffset: 0x0,
|
||||
RawValueOffset: []byte{0x0, 0x0, 0x0, 0x0},
|
||||
IfdPath: IfdPathStandard,
|
||||
IfdPath: exifcommon.IfdPathStandard,
|
||||
}
|
||||
|
||||
data := []byte{0x11, 0x22, 0x33, 0x44, 0x55, 0x66}
|
||||
|
||||
value, err := ite.ValueString(data, TestDefaultByteOrder)
|
||||
value, err := ite.ValueString(data, exifcommon.TestDefaultByteOrder)
|
||||
log.PanicIf(err)
|
||||
|
||||
expected := "11 22 33 44 55 66"
|
||||
|
@ -35,14 +38,14 @@ func TestIfdTagEntry_ValueString_Embedded(t *testing.T) {
|
|||
ite := IfdTagEntry{
|
||||
TagId: 0x1,
|
||||
TagIndex: 0,
|
||||
TagType: TypeByte,
|
||||
TagType: exifcommon.TypeByte,
|
||||
UnitCount: 4,
|
||||
ValueOffset: 0,
|
||||
RawValueOffset: data,
|
||||
IfdPath: IfdPathStandard,
|
||||
IfdPath: exifcommon.IfdPathStandard,
|
||||
}
|
||||
|
||||
value, err := ite.ValueString(nil, TestDefaultByteOrder)
|
||||
value, err := ite.ValueString(nil, exifcommon.TestDefaultByteOrder)
|
||||
log.PanicIf(err)
|
||||
|
||||
expected := "11 22 33 44"
|
||||
|
@ -51,20 +54,29 @@ func TestIfdTagEntry_ValueString_Embedded(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestIfdTagEntry_ValueString_Unknown(t *testing.T) {
|
||||
func TestIfdTagEntry_ValueString_Undefined(t *testing.T) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err := log.Wrap(state.(error))
|
||||
log.PrintError(err)
|
||||
|
||||
t.Fatalf("Test failure.")
|
||||
}
|
||||
}()
|
||||
|
||||
data := []uint8{'0', '2', '3', '0'}
|
||||
|
||||
ite := IfdTagEntry{
|
||||
TagId: 0x9000,
|
||||
TagIndex: 0,
|
||||
TagType: TypeUndefined,
|
||||
TagType: exifcommon.TypeUndefined,
|
||||
UnitCount: 4,
|
||||
ValueOffset: 0x0,
|
||||
RawValueOffset: data,
|
||||
IfdPath: IfdPathStandardExif,
|
||||
IfdPath: exifcommon.IfdPathStandardExif,
|
||||
}
|
||||
|
||||
value, err := ite.ValueString(nil, TestDefaultByteOrder)
|
||||
value, err := ite.ValueString(nil, exifcommon.TestDefaultByteOrder)
|
||||
log.PanicIf(err)
|
||||
|
||||
expected := "0230"
|
||||
|
@ -77,16 +89,16 @@ func TestIfdTagEntry_ValueBytes_Allocated(t *testing.T) {
|
|||
ite := IfdTagEntry{
|
||||
TagId: 0x1,
|
||||
TagIndex: 0,
|
||||
TagType: TypeByte,
|
||||
TagType: exifcommon.TypeByte,
|
||||
UnitCount: 6,
|
||||
ValueOffset: 0x0,
|
||||
RawValueOffset: []byte{0x0, 0x0, 0x0, 0x0},
|
||||
IfdPath: IfdPathStandard,
|
||||
IfdPath: exifcommon.IfdPathStandard,
|
||||
}
|
||||
|
||||
data := []byte{0x11, 0x22, 0x33, 0x44, 0x55, 0x66}
|
||||
|
||||
value, err := ite.ValueBytes(data, TestDefaultByteOrder)
|
||||
value, err := ite.ValueBytes(data, exifcommon.TestDefaultByteOrder)
|
||||
log.PanicIf(err)
|
||||
|
||||
if bytes.Compare(value, data) != 0 {
|
||||
|
@ -100,14 +112,14 @@ func TestIfdTagEntry_ValueBytes_Embedded(t *testing.T) {
|
|||
ite := IfdTagEntry{
|
||||
TagId: 0x1,
|
||||
TagIndex: 0,
|
||||
TagType: TypeByte,
|
||||
TagType: exifcommon.TypeByte,
|
||||
UnitCount: 4,
|
||||
ValueOffset: 0x0,
|
||||
RawValueOffset: data,
|
||||
IfdPath: IfdPathStandard,
|
||||
IfdPath: exifcommon.IfdPathStandard,
|
||||
}
|
||||
|
||||
value, err := ite.ValueBytes(nil, TestDefaultByteOrder)
|
||||
value, err := ite.ValueBytes(nil, exifcommon.TestDefaultByteOrder)
|
||||
log.PanicIf(err)
|
||||
|
||||
if bytes.Compare(value, data) != 0 {
|
||||
|
@ -121,14 +133,14 @@ func TestIfdTagEntry_Value_Normal(t *testing.T) {
|
|||
ite := IfdTagEntry{
|
||||
TagId: 0x1,
|
||||
TagIndex: 0,
|
||||
TagType: TypeByte,
|
||||
TagType: exifcommon.TypeByte,
|
||||
UnitCount: 4,
|
||||
ValueOffset: 0x0,
|
||||
RawValueOffset: data,
|
||||
IfdPath: IfdPathStandard,
|
||||
IfdPath: exifcommon.IfdPathStandard,
|
||||
}
|
||||
|
||||
value, err := ite.Value(nil, TestDefaultByteOrder)
|
||||
value, err := ite.Value(nil, exifcommon.TestDefaultByteOrder)
|
||||
log.PanicIf(err)
|
||||
|
||||
if bytes.Compare(value.([]byte), data) != 0 {
|
||||
|
@ -136,29 +148,27 @@ func TestIfdTagEntry_Value_Normal(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestIfdTagEntry_Value_Unknown(t *testing.T) {
|
||||
func TestIfdTagEntry_Value_Undefined(t *testing.T) {
|
||||
data := []uint8{'0', '2', '3', '0'}
|
||||
|
||||
ite := IfdTagEntry{
|
||||
TagId: 0x9000,
|
||||
TagIndex: 0,
|
||||
TagType: TypeUndefined,
|
||||
TagType: exifcommon.TypeUndefined,
|
||||
UnitCount: 4,
|
||||
ValueOffset: 0x0,
|
||||
RawValueOffset: data,
|
||||
IfdPath: IfdPathStandardExif,
|
||||
IfdPath: exifcommon.IfdPathStandardExif,
|
||||
}
|
||||
|
||||
value, err := ite.Value(nil, TestDefaultByteOrder)
|
||||
value, err := ite.Value(nil, exifcommon.TestDefaultByteOrder)
|
||||
log.PanicIf(err)
|
||||
|
||||
gs := value.(TagUnknownType_GeneralString)
|
||||
s := value.(fmt.Stringer)
|
||||
recovered := []byte(s.String())
|
||||
|
||||
vb, err := gs.ValueBytes()
|
||||
log.PanicIf(err)
|
||||
|
||||
if bytes.Compare(vb, data) != 0 {
|
||||
t.Fatalf("Value not expected: [%s] != [%s]", value, data)
|
||||
if bytes.Compare(recovered, data) != 0 {
|
||||
t.Fatalf("Value not expected: [%s] != [%s]", recovered, data)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -166,11 +176,11 @@ func TestIfdTagEntry_String(t *testing.T) {
|
|||
ite := IfdTagEntry{
|
||||
TagId: 0x1,
|
||||
TagIndex: 0,
|
||||
TagType: TypeByte,
|
||||
TagType: exifcommon.TypeByte,
|
||||
UnitCount: 6,
|
||||
ValueOffset: 0x0,
|
||||
RawValueOffset: []byte{0x0, 0x0, 0x0, 0x0},
|
||||
IfdPath: IfdPathStandard,
|
||||
IfdPath: exifcommon.IfdPathStandard,
|
||||
}
|
||||
|
||||
expected := "IfdTagEntry<TAG-IFD-PATH=[IFD] TAG-ID=(0x0001) TAG-TYPE=[BYTE] UNIT-COUNT=(6)>"
|
||||
|
@ -185,21 +195,21 @@ func TestIfdTagEntryValueResolver_ValueBytes(t *testing.T) {
|
|||
ite := IfdTagEntry{
|
||||
TagId: 0x1,
|
||||
TagIndex: 0,
|
||||
TagType: TypeByte,
|
||||
TagType: exifcommon.TypeByte,
|
||||
UnitCount: uint32(len(allocatedData)),
|
||||
ValueOffset: 0x8,
|
||||
RawValueOffset: []byte{0x0, 0x0, 0x0, 0x0},
|
||||
IfdPath: IfdPathStandard,
|
||||
IfdPath: exifcommon.IfdPathStandard,
|
||||
}
|
||||
|
||||
headerBytes, err := BuildExifHeader(TestDefaultByteOrder, uint32(0))
|
||||
headerBytes, err := BuildExifHeader(exifcommon.TestDefaultByteOrder, uint32(0))
|
||||
log.PanicIf(err)
|
||||
|
||||
exifData := make([]byte, len(headerBytes)+len(allocatedData))
|
||||
copy(exifData[0:], headerBytes)
|
||||
copy(exifData[len(headerBytes):], allocatedData)
|
||||
|
||||
itevr := NewIfdTagEntryValueResolver(exifData, TestDefaultByteOrder)
|
||||
itevr := NewIfdTagEntryValueResolver(exifData, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
value, err := itevr.ValueBytes(&ite)
|
||||
log.PanicIf(err)
|
||||
|
|
|
@ -7,6 +7,8 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/dsoprea/go-logging"
|
||||
|
||||
"github.com/dsoprea/go-exif/v2/common"
|
||||
)
|
||||
|
||||
func TestIfdMapping_Add(t *testing.T) {
|
||||
|
@ -106,12 +108,12 @@ func TestIfdMapping_Get(t *testing.T) {
|
|||
err := LoadStandardIfds(im)
|
||||
log.PanicIf(err)
|
||||
|
||||
mi, err := im.Get([]uint16{IfdRootId, IfdExifId, IfdIopId})
|
||||
mi, err := im.Get([]uint16{exifcommon.IfdRootId, exifcommon.IfdExifId, exifcommon.IfdIopId})
|
||||
log.PanicIf(err)
|
||||
|
||||
if mi.ParentTagId != IfdExifId {
|
||||
if mi.ParentTagId != exifcommon.IfdExifId {
|
||||
t.Fatalf("Parent tag-ID not correct")
|
||||
} else if mi.TagId != IfdIopId {
|
||||
} else if mi.TagId != exifcommon.IfdIopId {
|
||||
t.Fatalf("Tag-ID not correct")
|
||||
} else if mi.Name != "Iop" {
|
||||
t.Fatalf("name not correct")
|
||||
|
@ -129,9 +131,9 @@ func TestIfdMapping_GetWithPath(t *testing.T) {
|
|||
mi, err := im.GetWithPath("IFD/Exif/Iop")
|
||||
log.PanicIf(err)
|
||||
|
||||
if mi.ParentTagId != IfdExifId {
|
||||
if mi.ParentTagId != exifcommon.IfdExifId {
|
||||
t.Fatalf("Parent tag-ID not correct")
|
||||
} else if mi.TagId != IfdIopId {
|
||||
} else if mi.TagId != exifcommon.IfdIopId {
|
||||
t.Fatalf("Tag-ID not correct")
|
||||
} else if mi.Name != "Iop" {
|
||||
t.Fatalf("name not correct")
|
||||
|
|
|
@ -5,6 +5,8 @@ import (
|
|||
|
||||
"github.com/dsoprea/go-logging"
|
||||
"gopkg.in/yaml.v2"
|
||||
|
||||
"github.com/dsoprea/go-exif/v2/common"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -59,7 +61,7 @@ type IndexedTag struct {
|
|||
Id uint16
|
||||
Name string
|
||||
IfdPath string
|
||||
Type TagTypePrimitive
|
||||
Type exifcommon.TagTypePrimitive
|
||||
}
|
||||
|
||||
func (it *IndexedTag) String() string {
|
||||
|
@ -203,7 +205,7 @@ func LoadStandardTags(ti *TagIndex) (err error) {
|
|||
continue
|
||||
}
|
||||
|
||||
tagTypeId, found := TypeNamesR[tagTypeName]
|
||||
tagTypeId, found := exifcommon.GetTypeByName(tagTypeName)
|
||||
if found == false {
|
||||
log.Panicf("type [%s] for [%s] not valid", tagTypeName, tagName)
|
||||
continue
|
||||
|
|
|
@ -4,15 +4,17 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/dsoprea/go-logging"
|
||||
|
||||
"github.com/dsoprea/go-exif/v2/common"
|
||||
)
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
ti := NewTagIndex()
|
||||
|
||||
it, err := ti.Get(IfdPathStandard, 0x10f)
|
||||
it, err := ti.Get(exifcommon.IfdPathStandard, 0x10f)
|
||||
log.PanicIf(err)
|
||||
|
||||
if it.Is(IfdPathStandard, 0x10f) == false || it.IsName(IfdPathStandard, "Make") == false {
|
||||
if it.Is(exifcommon.IfdPathStandard, 0x10f) == false || it.IsName(exifcommon.IfdPathStandard, "Make") == false {
|
||||
t.Fatalf("tag info not correct")
|
||||
}
|
||||
}
|
||||
|
@ -20,10 +22,10 @@ func TestGet(t *testing.T) {
|
|||
func TestGetWithName(t *testing.T) {
|
||||
ti := NewTagIndex()
|
||||
|
||||
it, err := ti.GetWithName(IfdPathStandard, "Make")
|
||||
it, err := ti.GetWithName(exifcommon.IfdPathStandard, "Make")
|
||||
log.PanicIf(err)
|
||||
|
||||
if it.Is(IfdPathStandard, 0x10f) == false || it.Is(IfdPathStandard, 0x10f) == false {
|
||||
if it.Is(exifcommon.IfdPathStandard, 0x10f) == false {
|
||||
t.Fatalf("tag info not correct")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@ import (
|
|||
"io/ioutil"
|
||||
|
||||
"github.com/dsoprea/go-logging"
|
||||
|
||||
"github.com/dsoprea/go-exif/v2/common"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -32,7 +34,7 @@ func getExifSimpleTestIb() *IfdBuilder {
|
|||
log.PanicIf(err)
|
||||
|
||||
ti := NewTagIndex()
|
||||
ib := NewIfdBuilder(im, ti, IfdPathStandard, TestDefaultByteOrder)
|
||||
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
err = ib.AddStandard(0x000b, "asciivalue")
|
||||
log.PanicIf(err)
|
||||
|
@ -43,7 +45,7 @@ func getExifSimpleTestIb() *IfdBuilder {
|
|||
err = ib.AddStandard(0x0100, []uint32{0x33445566})
|
||||
log.PanicIf(err)
|
||||
|
||||
err = ib.AddStandard(0x013e, []Rational{{Numerator: 0x11112222, Denominator: 0x33334444}})
|
||||
err = ib.AddStandard(0x013e, []exifcommon.Rational{{Numerator: 0x11112222, Denominator: 0x33334444}})
|
||||
log.PanicIf(err)
|
||||
|
||||
return ib
|
||||
|
@ -63,7 +65,7 @@ func getExifSimpleTestIbBytes() []byte {
|
|||
log.PanicIf(err)
|
||||
|
||||
ti := NewTagIndex()
|
||||
ib := NewIfdBuilder(im, ti, IfdPathStandard, TestDefaultByteOrder)
|
||||
ib := NewIfdBuilder(im, ti, exifcommon.IfdPathStandard, exifcommon.TestDefaultByteOrder)
|
||||
|
||||
err = ib.AddStandard(0x000b, "asciivalue")
|
||||
log.PanicIf(err)
|
||||
|
@ -74,7 +76,7 @@ func getExifSimpleTestIbBytes() []byte {
|
|||
err = ib.AddStandard(0x0100, []uint32{0x33445566})
|
||||
log.PanicIf(err)
|
||||
|
||||
err = ib.AddStandard(0x013e, []Rational{{Numerator: 0x11112222, Denominator: 0x33334444}})
|
||||
err = ib.AddStandard(0x013e, []exifcommon.Rational{{Numerator: 0x11112222, Denominator: 0x33334444}})
|
||||
log.PanicIf(err)
|
||||
|
||||
ibe := NewIfdByteEncoder()
|
||||
|
@ -103,7 +105,7 @@ func validateExifSimpleTestIb(exifData []byte, t *testing.T) {
|
|||
eh, index, err := Collect(im, ti, exifData)
|
||||
log.PanicIf(err)
|
||||
|
||||
if eh.ByteOrder != TestDefaultByteOrder {
|
||||
if eh.ByteOrder != exifcommon.TestDefaultByteOrder {
|
||||
t.Fatalf("EXIF byte-order is not correct: %v", eh.ByteOrder)
|
||||
} else if eh.FirstIfdOffset != ExifDefaultFirstIfdOffset {
|
||||
t.Fatalf("EXIF first IFD-offset not correct: (0x%02x)", eh.FirstIfdOffset)
|
||||
|
@ -115,9 +117,9 @@ func validateExifSimpleTestIb(exifData []byte, t *testing.T) {
|
|||
|
||||
ifd := index.RootIfd
|
||||
|
||||
if ifd.ByteOrder != TestDefaultByteOrder {
|
||||
if ifd.ByteOrder != exifcommon.TestDefaultByteOrder {
|
||||
t.Fatalf("IFD byte-order not correct.")
|
||||
} else if ifd.IfdPath != IfdStandard {
|
||||
} else if ifd.IfdPath != exifcommon.IfdStandard {
|
||||
t.Fatalf("IFD name not correct.")
|
||||
} else if ifd.Index != 0 {
|
||||
t.Fatalf("IFD index not zero: (%d)", ifd.Index)
|
||||
|
@ -142,7 +144,7 @@ func validateExifSimpleTestIb(exifData []byte, t *testing.T) {
|
|||
{tagId: 0x000b, value: "asciivalue"},
|
||||
{tagId: 0x00ff, value: []uint16{0x1122}},
|
||||
{tagId: 0x0100, value: []uint32{0x33445566}},
|
||||
{tagId: 0x013e, value: []Rational{{Numerator: 0x11112222, Denominator: 0x33334444}}},
|
||||
{tagId: 0x013e, value: []exifcommon.Rational{{Numerator: 0x11112222, Denominator: 0x33334444}}},
|
||||
}
|
||||
|
||||
for i, e := range ifd.Entries {
|
||||
|
@ -150,7 +152,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(addressableData, TestDefaultByteOrder)
|
||||
value, err := e.Value(addressableData, exifcommon.TestDefaultByteOrder)
|
||||
log.PanicIf(err)
|
||||
|
||||
if reflect.DeepEqual(value, expected[i].value) != true {
|
|
@ -1,8 +1,6 @@
|
|||
package exifundefined
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/dsoprea/go-logging"
|
||||
|
@ -10,14 +8,14 @@ import (
|
|||
"github.com/dsoprea/go-exif/v2/common"
|
||||
)
|
||||
|
||||
func Encode(value interface{}, byteOrder binary.ByteOrder) (encoded []byte, unitCount uint32, err error) {
|
||||
func Encode(value EncodeableValue, byteOrder binary.ByteOrder) (encoded []byte, unitCount uint32, err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
}
|
||||
}()
|
||||
|
||||
encoderName := reflect.TypeOf(value).Name()
|
||||
encoderName := value.EncoderName()
|
||||
|
||||
encoder, found := encoders[encoderName]
|
||||
if found == false {
|
||||
|
@ -31,7 +29,7 @@ func Encode(value interface{}, byteOrder binary.ByteOrder) (encoded []byte, unit
|
|||
}
|
||||
|
||||
// UndefinedValue knows how to resolve the value for most unknown-type tags.
|
||||
func Decode(ifdPath string, tagId uint16, valueContext *exifcommon.ValueContext, byteOrder binary.ByteOrder) (value interface{}, err error) {
|
||||
func Decode(ifdPath string, tagId uint16, valueContext *exifcommon.ValueContext, byteOrder binary.ByteOrder) (value EncodeableValue, err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package exifundefined
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/dsoprea/go-logging"
|
||||
|
||||
"github.com/dsoprea/go-exif/v2/common"
|
||||
|
@ -13,10 +15,18 @@ type Tag8828Oecf struct {
|
|||
Values []exifcommon.SignedRational
|
||||
}
|
||||
|
||||
func (oecf Tag8828Oecf) String() string {
|
||||
return fmt.Sprintf("Tag8828Oecf<COLUMNS=(%d) ROWS=(%d)>", oecf.Columns, oecf.Rows)
|
||||
}
|
||||
|
||||
func (oecf Tag8828Oecf) EncoderName() string {
|
||||
return "Codec8828Oecf"
|
||||
}
|
||||
|
||||
type Codec8828Oecf struct {
|
||||
}
|
||||
|
||||
func (Codec8828Oecf) Decode(valueContext *exifcommon.ValueContext) (value interface{}, err error) {
|
||||
func (Codec8828Oecf) Decode(valueContext *exifcommon.ValueContext) (value EncodeableValue, err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
|
|
|
@ -1,15 +1,44 @@
|
|||
package exifundefined
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/dsoprea/go-logging"
|
||||
|
||||
"github.com/dsoprea/go-exif/v2/common"
|
||||
)
|
||||
|
||||
type Tag9000ExifVersion struct {
|
||||
string
|
||||
}
|
||||
|
||||
func (Tag9000ExifVersion) EncoderName() string {
|
||||
return "Codec9000ExifVersion"
|
||||
}
|
||||
|
||||
func (ev Tag9000ExifVersion) String() string {
|
||||
return ev.string
|
||||
}
|
||||
|
||||
type Codec9000ExifVersion struct {
|
||||
}
|
||||
|
||||
func (Codec9000ExifVersion) Decode(valueContext *exifcommon.ValueContext) (value interface{}, err error) {
|
||||
func (Codec9000ExifVersion) Encode(value interface{}, byteOrder binary.ByteOrder) (encoded []byte, unitCount uint32, err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
}
|
||||
}()
|
||||
|
||||
s, ok := value.(Tag9000ExifVersion)
|
||||
if ok == false {
|
||||
log.Panicf("can only encode a Tag9000ExifVersion")
|
||||
}
|
||||
|
||||
return []byte(s.string), uint32(len(s.string)), nil
|
||||
}
|
||||
|
||||
func (Codec9000ExifVersion) Decode(valueContext *exifcommon.ValueContext) (value EncodeableValue, err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
|
@ -21,10 +50,14 @@ func (Codec9000ExifVersion) Decode(valueContext *exifcommon.ValueContext) (value
|
|||
valueString, err := valueContext.ReadAsciiNoNul()
|
||||
log.PanicIf(err)
|
||||
|
||||
return TagUndefinedGeneralString(valueString), nil
|
||||
return Tag9000ExifVersion{valueString}, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
registerEncoder(
|
||||
Tag9000ExifVersion{},
|
||||
Codec9000ExifVersion{})
|
||||
|
||||
registerDecoder(
|
||||
exifcommon.IfdPathStandardExif,
|
||||
0x9000,
|
||||
|
|
|
@ -55,6 +55,10 @@ type TagExif9101ComponentsConfiguration struct {
|
|||
ConfigurationBytes []byte
|
||||
}
|
||||
|
||||
func (TagExif9101ComponentsConfiguration) EncoderName() string {
|
||||
return "CodecExif9101ComponentsConfiguration"
|
||||
}
|
||||
|
||||
func (cc TagExif9101ComponentsConfiguration) String() string {
|
||||
return fmt.Sprintf("Exif9101ComponentsConfiguration<ID=[%s] BYTES=%v>", TagUndefinedType_9101_ComponentsConfiguration_Names[cc.ConfigurationId], cc.ConfigurationBytes)
|
||||
}
|
||||
|
@ -79,7 +83,7 @@ func (CodecExif9101ComponentsConfiguration) Encode(value interface{}, byteOrder
|
|||
return cc.ConfigurationBytes, uint32(len(cc.ConfigurationBytes)), nil
|
||||
}
|
||||
|
||||
func (CodecExif9101ComponentsConfiguration) Decode(valueContext *exifcommon.ValueContext) (value interface{}, err error) {
|
||||
func (CodecExif9101ComponentsConfiguration) Decode(valueContext *exifcommon.ValueContext) (value EncodeableValue, err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
|
|
|
@ -17,6 +17,10 @@ type Tag927CMakerNote struct {
|
|||
MakerNoteBytes []byte
|
||||
}
|
||||
|
||||
func (Tag927CMakerNote) EncoderName() string {
|
||||
return "Codec927CMakerNote"
|
||||
}
|
||||
|
||||
func (mn Tag927CMakerNote) String() string {
|
||||
parts := make([]string, 20)
|
||||
for i, c := range mn.MakerNoteType {
|
||||
|
@ -53,7 +57,7 @@ func (Codec927CMakerNote) Encode(value interface{}, byteOrder binary.ByteOrder)
|
|||
return mn.MakerNoteBytes, uint32(len(mn.MakerNoteBytes)), nil
|
||||
}
|
||||
|
||||
func (Codec927CMakerNote) Decode(valueContext *exifcommon.ValueContext) (value interface{}, err error) {
|
||||
func (Codec927CMakerNote) Decode(valueContext *exifcommon.ValueContext) (value EncodeableValue, err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
|
|
|
@ -43,6 +43,10 @@ type Tag9286UserComment struct {
|
|||
EncodingBytes []byte
|
||||
}
|
||||
|
||||
func (Tag9286UserComment) EncoderName() string {
|
||||
return "Codec9286UserComment"
|
||||
}
|
||||
|
||||
func (uc Tag9286UserComment) String() string {
|
||||
var valuePhrase string
|
||||
|
||||
|
@ -85,7 +89,7 @@ func (Codec9286UserComment) Encode(value interface{}, byteOrder binary.ByteOrder
|
|||
return encoded, uint32(len(encoded)), nil
|
||||
}
|
||||
|
||||
func (Codec9286UserComment) Decode(valueContext *exifcommon.ValueContext) (value interface{}, err error) {
|
||||
func (Codec9286UserComment) Decode(valueContext *exifcommon.ValueContext) (value EncodeableValue, err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
|
|
|
@ -1,15 +1,44 @@
|
|||
package exifundefined
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/dsoprea/go-logging"
|
||||
|
||||
"github.com/dsoprea/go-exif/v2/common"
|
||||
)
|
||||
|
||||
type TagA000FlashpixVersion struct {
|
||||
string
|
||||
}
|
||||
|
||||
func (TagA000FlashpixVersion) EncoderName() string {
|
||||
return "CodecA000FlashpixVersion"
|
||||
}
|
||||
|
||||
func (fv TagA000FlashpixVersion) String() string {
|
||||
return fv.string
|
||||
}
|
||||
|
||||
type CodecA000FlashpixVersion struct {
|
||||
}
|
||||
|
||||
func (CodecA000FlashpixVersion) Decode(valueContext *exifcommon.ValueContext) (value interface{}, err error) {
|
||||
func (CodecA000FlashpixVersion) Encode(value interface{}, byteOrder binary.ByteOrder) (encoded []byte, unitCount uint32, err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
}
|
||||
}()
|
||||
|
||||
s, ok := value.(TagA000FlashpixVersion)
|
||||
if ok == false {
|
||||
log.Panicf("can only encode a TagA000FlashpixVersion")
|
||||
}
|
||||
|
||||
return []byte(s.string), uint32(len(s.string)), nil
|
||||
}
|
||||
|
||||
func (CodecA000FlashpixVersion) Decode(valueContext *exifcommon.ValueContext) (value EncodeableValue, err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
|
@ -21,10 +50,14 @@ func (CodecA000FlashpixVersion) Decode(valueContext *exifcommon.ValueContext) (v
|
|||
valueString, err := valueContext.ReadAsciiNoNul()
|
||||
log.PanicIf(err)
|
||||
|
||||
return TagUndefinedGeneralString(valueString), nil
|
||||
return TagA000FlashpixVersion{valueString}, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
registerEncoder(
|
||||
TagA000FlashpixVersion{},
|
||||
CodecA000FlashpixVersion{})
|
||||
|
||||
registerDecoder(
|
||||
exifcommon.IfdPathStandardExif,
|
||||
0xa000,
|
||||
|
|
|
@ -2,6 +2,7 @@ package exifundefined
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
|
||||
"encoding/binary"
|
||||
|
||||
|
@ -17,6 +18,14 @@ type TagA20CSpatialFrequencyResponse struct {
|
|||
Values []exifcommon.Rational
|
||||
}
|
||||
|
||||
func (TagA20CSpatialFrequencyResponse) EncoderName() string {
|
||||
return "CodecA20CSpatialFrequencyResponse"
|
||||
}
|
||||
|
||||
func (sfr TagA20CSpatialFrequencyResponse) String() string {
|
||||
return fmt.Sprintf("CodecA20CSpatialFrequencyResponse<COLUMNS=(%d) ROWS=(%d)>", sfr.Columns, sfr.Rows)
|
||||
}
|
||||
|
||||
type CodecA20CSpatialFrequencyResponse struct {
|
||||
}
|
||||
|
||||
|
@ -69,7 +78,7 @@ func (CodecA20CSpatialFrequencyResponse) Encode(value interface{}, byteOrder bin
|
|||
return encoded, uint32(len(encoded)), nil
|
||||
}
|
||||
|
||||
func (CodecA20CSpatialFrequencyResponse) Decode(valueContext *exifcommon.ValueContext) (value interface{}, err error) {
|
||||
func (CodecA20CSpatialFrequencyResponse) Decode(valueContext *exifcommon.ValueContext) (value EncodeableValue, err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
|
@ -141,11 +150,11 @@ func (CodecA20CSpatialFrequencyResponse) Decode(valueContext *exifcommon.ValueCo
|
|||
|
||||
func init() {
|
||||
registerEncoder(
|
||||
TagA302CfaPattern{},
|
||||
CodecA302CfaPattern{})
|
||||
TagA20CSpatialFrequencyResponse{},
|
||||
CodecA20CSpatialFrequencyResponse{})
|
||||
|
||||
registerDecoder(
|
||||
exifcommon.IfdPathStandardExif,
|
||||
0xa302,
|
||||
CodecA302CfaPattern{})
|
||||
0xa20c,
|
||||
CodecA20CSpatialFrequencyResponse{})
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package exifundefined
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/dsoprea/go-logging"
|
||||
|
@ -10,6 +12,14 @@ import (
|
|||
|
||||
type TagExifA300FileSource uint32
|
||||
|
||||
func (TagExifA300FileSource) EncoderName() string {
|
||||
return "CodecExifA300FileSource"
|
||||
}
|
||||
|
||||
func (af TagExifA300FileSource) String() string {
|
||||
return fmt.Sprintf("%d", af)
|
||||
}
|
||||
|
||||
const (
|
||||
TagUndefinedType_A300_SceneType_Others TagExifA300FileSource = 0
|
||||
TagUndefinedType_A300_SceneType_ScannerOfTransparentType TagExifA300FileSource = 1
|
||||
|
@ -42,7 +52,7 @@ func (CodecExifA300FileSource) Encode(value interface{}, byteOrder binary.ByteOr
|
|||
return ed.Encoded, uint32(int(ed.UnitCount)), nil
|
||||
}
|
||||
|
||||
func (CodecExifA300FileSource) Decode(valueContext *exifcommon.ValueContext) (value interface{}, err error) {
|
||||
func (CodecExifA300FileSource) Decode(valueContext *exifcommon.ValueContext) (value EncodeableValue, err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package exifundefined
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/dsoprea/go-logging"
|
||||
|
@ -10,6 +12,14 @@ import (
|
|||
|
||||
type TagExifA301SceneType uint32
|
||||
|
||||
func (TagExifA301SceneType) EncoderName() string {
|
||||
return "CodecExifA301SceneType"
|
||||
}
|
||||
|
||||
func (st TagExifA301SceneType) String() string {
|
||||
return fmt.Sprintf("%d", st)
|
||||
}
|
||||
|
||||
const (
|
||||
TagUndefinedType_A301_SceneType_DirectlyPhotographedImage TagExifA301SceneType = 1
|
||||
)
|
||||
|
@ -39,7 +49,7 @@ func (CodecExifA301SceneType) Encode(value interface{}, byteOrder binary.ByteOrd
|
|||
return ed.Encoded, uint32(int(ed.UnitCount)), nil
|
||||
}
|
||||
|
||||
func (CodecExifA301SceneType) Decode(valueContext *exifcommon.ValueContext) (value interface{}, err error) {
|
||||
func (CodecExifA301SceneType) Decode(valueContext *exifcommon.ValueContext) (value EncodeableValue, err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
|
|
|
@ -2,6 +2,7 @@ package exifundefined
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
|
||||
"encoding/binary"
|
||||
|
||||
|
@ -16,6 +17,14 @@ type TagA302CfaPattern struct {
|
|||
CfaValue []byte
|
||||
}
|
||||
|
||||
func (TagA302CfaPattern) EncoderName() string {
|
||||
return "CodecA302CfaPattern"
|
||||
}
|
||||
|
||||
func (cp TagA302CfaPattern) String() string {
|
||||
return fmt.Sprintf("TagA302CfaPattern<HORZ-REPEAT=(%d) VERT-REPEAT=(%d)>", cp.HorizontalRepeat, cp.VerticalRepeat)
|
||||
}
|
||||
|
||||
type CodecA302CfaPattern struct {
|
||||
}
|
||||
|
||||
|
@ -51,7 +60,7 @@ func (CodecA302CfaPattern) Encode(value interface{}, byteOrder binary.ByteOrder)
|
|||
return encoded, uint32(len(encoded)), nil
|
||||
}
|
||||
|
||||
func (CodecA302CfaPattern) Decode(valueContext *exifcommon.ValueContext) (value interface{}, err error) {
|
||||
func (CodecA302CfaPattern) Decode(valueContext *exifcommon.ValueContext) (value EncodeableValue, err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
|
|
|
@ -1,15 +1,44 @@
|
|||
package exifundefined
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/dsoprea/go-logging"
|
||||
|
||||
"github.com/dsoprea/go-exif/v2/common"
|
||||
)
|
||||
|
||||
type Tag0002InteropVersion struct {
|
||||
string
|
||||
}
|
||||
|
||||
func (Tag0002InteropVersion) EncoderName() string {
|
||||
return "Codec0002InteropVersion"
|
||||
}
|
||||
|
||||
func (iv Tag0002InteropVersion) String() string {
|
||||
return iv.string
|
||||
}
|
||||
|
||||
type Codec0002InteropVersion struct {
|
||||
}
|
||||
|
||||
func (Codec0002InteropVersion) Decode(valueContext *exifcommon.ValueContext) (value interface{}, err error) {
|
||||
func (Codec0002InteropVersion) Encode(value interface{}, byteOrder binary.ByteOrder) (encoded []byte, unitCount uint32, err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
}
|
||||
}()
|
||||
|
||||
s, ok := value.(Tag0002InteropVersion)
|
||||
if ok == false {
|
||||
log.Panicf("can only encode a Tag0002InteropVersion")
|
||||
}
|
||||
|
||||
return []byte(s.string), uint32(len(s.string)), nil
|
||||
}
|
||||
|
||||
func (Codec0002InteropVersion) Decode(valueContext *exifcommon.ValueContext) (value EncodeableValue, err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
|
@ -21,10 +50,14 @@ func (Codec0002InteropVersion) Decode(valueContext *exifcommon.ValueContext) (va
|
|||
valueString, err := valueContext.ReadAsciiNoNul()
|
||||
log.PanicIf(err)
|
||||
|
||||
return TagUndefinedGeneralString(valueString), nil
|
||||
return Tag0002InteropVersion{valueString}, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
registerEncoder(
|
||||
Tag0002InteropVersion{},
|
||||
Codec0002InteropVersion{})
|
||||
|
||||
registerDecoder(
|
||||
exifcommon.IfdPathStandardExifIop,
|
||||
0x0002,
|
||||
|
|
|
@ -1,15 +1,44 @@
|
|||
package exifundefined
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/dsoprea/go-logging"
|
||||
|
||||
"github.com/dsoprea/go-exif/v2/common"
|
||||
)
|
||||
|
||||
type Tag001BGPSProcessingMethod struct {
|
||||
string
|
||||
}
|
||||
|
||||
func (Tag001BGPSProcessingMethod) EncoderName() string {
|
||||
return "Codec001BGPSProcessingMethod"
|
||||
}
|
||||
|
||||
func (gpm Tag001BGPSProcessingMethod) String() string {
|
||||
return gpm.string
|
||||
}
|
||||
|
||||
type Codec001BGPSProcessingMethod struct {
|
||||
}
|
||||
|
||||
func (Codec001BGPSProcessingMethod) Decode(valueContext *exifcommon.ValueContext) (value interface{}, err error) {
|
||||
func (Codec001BGPSProcessingMethod) Encode(value interface{}, byteOrder binary.ByteOrder) (encoded []byte, unitCount uint32, err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
}
|
||||
}()
|
||||
|
||||
s, ok := value.(Tag001BGPSProcessingMethod)
|
||||
if ok == false {
|
||||
log.Panicf("can only encode a Tag001BGPSProcessingMethod")
|
||||
}
|
||||
|
||||
return []byte(s.string), uint32(len(s.string)), nil
|
||||
}
|
||||
|
||||
func (Codec001BGPSProcessingMethod) Decode(valueContext *exifcommon.ValueContext) (value EncodeableValue, err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
|
@ -21,10 +50,14 @@ func (Codec001BGPSProcessingMethod) Decode(valueContext *exifcommon.ValueContext
|
|||
valueString, err := valueContext.ReadAsciiNoNul()
|
||||
log.PanicIf(err)
|
||||
|
||||
return TagUndefinedGeneralString(valueString), nil
|
||||
return Tag001BGPSProcessingMethod{valueString}, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
registerEncoder(
|
||||
Tag001BGPSProcessingMethod{},
|
||||
Codec001BGPSProcessingMethod{})
|
||||
|
||||
registerDecoder(
|
||||
exifcommon.IfdPathStandardGps,
|
||||
0x001b,
|
||||
|
|
|
@ -1,15 +1,44 @@
|
|||
package exifundefined
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/dsoprea/go-logging"
|
||||
|
||||
"github.com/dsoprea/go-exif/v2/common"
|
||||
)
|
||||
|
||||
type Tag001CGPSAreaInformation struct {
|
||||
string
|
||||
}
|
||||
|
||||
func (Tag001CGPSAreaInformation) EncoderName() string {
|
||||
return "Codec001CGPSAreaInformation"
|
||||
}
|
||||
|
||||
func (gai Tag001CGPSAreaInformation) String() string {
|
||||
return gai.string
|
||||
}
|
||||
|
||||
type Codec001CGPSAreaInformation struct {
|
||||
}
|
||||
|
||||
func (Codec001CGPSAreaInformation) Decode(valueContext *exifcommon.ValueContext) (value interface{}, err error) {
|
||||
func (Codec001CGPSAreaInformation) Encode(value interface{}, byteOrder binary.ByteOrder) (encoded []byte, unitCount uint32, err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
}
|
||||
}()
|
||||
|
||||
s, ok := value.(Tag001CGPSAreaInformation)
|
||||
if ok == false {
|
||||
log.Panicf("can only encode a Tag001CGPSAreaInformation")
|
||||
}
|
||||
|
||||
return []byte(s.string), uint32(len(s.string)), nil
|
||||
}
|
||||
|
||||
func (Codec001CGPSAreaInformation) Decode(valueContext *exifcommon.ValueContext) (value EncodeableValue, err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
|
@ -21,10 +50,14 @@ func (Codec001CGPSAreaInformation) Decode(valueContext *exifcommon.ValueContext)
|
|||
valueString, err := valueContext.ReadAsciiNoNul()
|
||||
log.PanicIf(err)
|
||||
|
||||
return TagUndefinedGeneralString(valueString), nil
|
||||
return Tag001CGPSAreaInformation{valueString}, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
registerEncoder(
|
||||
Tag001CGPSAreaInformation{},
|
||||
Codec001CGPSAreaInformation{})
|
||||
|
||||
registerDecoder(
|
||||
exifcommon.IfdPathStandardGps,
|
||||
0x001c,
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package exifundefined
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"github.com/dsoprea/go-logging"
|
||||
)
|
||||
|
||||
|
@ -11,11 +9,11 @@ type UndefinedTagHandle struct {
|
|||
TagId uint16
|
||||
}
|
||||
|
||||
func registerEncoder(entity interface{}, encoder UndefinedValueEncoder) {
|
||||
typeName := reflect.TypeOf(entity).Name()
|
||||
func registerEncoder(entity EncodeableValue, encoder UndefinedValueEncoder) {
|
||||
typeName := entity.EncoderName()
|
||||
|
||||
_, found := encoders[typeName]
|
||||
if found != true {
|
||||
if found == true {
|
||||
log.Panicf("encoder already registered: %v", typeName)
|
||||
}
|
||||
|
||||
|
@ -29,7 +27,7 @@ func registerDecoder(ifdPath string, tagId uint16, decoder UndefinedValueDecoder
|
|||
}
|
||||
|
||||
_, found := decoders[uth]
|
||||
if found != true {
|
||||
if found == true {
|
||||
log.Panicf("decoder already registered: %v", uth)
|
||||
}
|
||||
|
||||
|
|
|
@ -22,24 +22,19 @@ type UndefinedValueEncoder interface {
|
|||
Encode(value interface{}, byteOrder binary.ByteOrder) (encoded []byte, unitCount uint32, err error)
|
||||
}
|
||||
|
||||
type EncodeableValue interface {
|
||||
EncoderName() string
|
||||
}
|
||||
|
||||
// UndefinedValueEncoder knows how to decode an undefined-type tag's value from
|
||||
// bytes.
|
||||
type UndefinedValueDecoder interface {
|
||||
Decode(valueContext *exifcommon.ValueContext) (value interface{}, err error)
|
||||
Decode(valueContext *exifcommon.ValueContext) (value EncodeableValue, err error)
|
||||
}
|
||||
|
||||
// TODO(dustin): Rename `UnknownTagValue` to `UndefinedTagValue`.
|
||||
// OBSOLETE(dustin): Use a `UndefinedValueEncoder` instead of an `UnknownTagValue`.
|
||||
type TagUndefinedType_UnknownValue []byte
|
||||
|
||||
type UnknownTagValue interface {
|
||||
ValueBytes() ([]byte, error)
|
||||
}
|
||||
|
||||
// TODO(dustin): Rename `TagUnknownType_UnknownValue` to `TagUndefinedType_UnknownValue`.
|
||||
|
||||
type TagUnknownType_UnknownValue []byte
|
||||
|
||||
func (tutuv TagUnknownType_UnknownValue) String() string {
|
||||
func (tutuv TagUndefinedType_UnknownValue) String() string {
|
||||
parts := make([]string, len(tutuv))
|
||||
for i, c := range tutuv {
|
||||
parts[i] = fmt.Sprintf("%02x", c)
|
||||
|
@ -54,5 +49,3 @@ func (tutuv TagUnknownType_UnknownValue) String() string {
|
|||
|
||||
return fmt.Sprintf("Unknown<DATA=[%s] LEN=(%d) SHA1=[%020x]>", strings.Join(parts, " "), len(tutuv), digest)
|
||||
}
|
||||
|
||||
type TagUndefinedGeneralString string
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
package exif
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/dsoprea/go-logging"
|
||||
|
||||
"github.com/dsoprea/go-exif/v2/common"
|
||||
"github.com/dsoprea/go-exif/v2/undefined"
|
||||
)
|
||||
|
||||
// ParseExifFullTimestamp parses dates like "2018:11:30 13:01:49" into a UTC
|
||||
|
@ -75,10 +77,10 @@ type ExifTag struct {
|
|||
TagId uint16 `json:"id"`
|
||||
TagName string `json:"name"`
|
||||
|
||||
TagTypeId TagTypePrimitive `json:"type_id"`
|
||||
TagTypeName string `json:"type_name"`
|
||||
Value interface{} `json:"value"`
|
||||
ValueBytes []byte `json:"value_bytes"`
|
||||
TagTypeId exifcommon.TagTypePrimitive `json:"type_id"`
|
||||
TagTypeName string `json:"type_name"`
|
||||
Value interface{} `json:"value"`
|
||||
ValueBytes []byte `json:"value_bytes"`
|
||||
|
||||
ChildIfdPath string `json:"child_ifd_path"`
|
||||
}
|
||||
|
@ -126,15 +128,15 @@ func GetFlatExifData(exifData []byte) (exifTags []ExifTag, err error) {
|
|||
|
||||
value, err := ifd.TagValue(ite)
|
||||
if err != nil {
|
||||
if err == ErrUnhandledUnknownTypedTag {
|
||||
value = UnparseableUnknownTagValuePlaceholder
|
||||
if err == exifcommon.ErrUnhandledUnknownTypedTag {
|
||||
value = exifundefined.UnparseableUnknownTagValuePlaceholder
|
||||
} else {
|
||||
log.Panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
valueBytes, err := ifd.TagValueBytes(ite)
|
||||
if err != nil && err != ErrUnhandledUnknownTypedTag {
|
||||
if err != nil && err != exifcommon.ErrUnhandledUnknownTypedTag {
|
||||
log.Panic(err)
|
||||
}
|
||||
|
||||
|
@ -143,7 +145,7 @@ func GetFlatExifData(exifData []byte) (exifTags []ExifTag, err error) {
|
|||
TagId: ite.TagId,
|
||||
TagName: tagName,
|
||||
TagTypeId: ite.TagType,
|
||||
TagTypeName: TypeNames[ite.TagType],
|
||||
TagTypeName: ite.TagType.String(),
|
||||
Value: value,
|
||||
ValueBytes: valueBytes,
|
||||
ChildIfdPath: ite.ChildIfdPath,
|
||||
|
|
|
@ -1,80 +1,13 @@
|
|||
package exif
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/dsoprea/go-logging"
|
||||
)
|
||||
|
||||
func TestDumpBytes(t *testing.T) {
|
||||
f, err := ioutil.TempFile(os.TempDir(), "utilitytest")
|
||||
log.PanicIf(err)
|
||||
|
||||
defer os.Remove(f.Name())
|
||||
|
||||
originalStdout := os.Stdout
|
||||
os.Stdout = f
|
||||
|
||||
DumpBytes([]byte{0x11, 0x22})
|
||||
|
||||
os.Stdout = originalStdout
|
||||
|
||||
_, err = f.Seek(0, 0)
|
||||
log.PanicIf(err)
|
||||
|
||||
content, err := ioutil.ReadAll(f)
|
||||
log.PanicIf(err)
|
||||
|
||||
if string(content) != "DUMP: 11 22 \n" {
|
||||
t.Fatalf("content not correct: [%s]", string(content))
|
||||
}
|
||||
}
|
||||
|
||||
func TestDumpBytesClause(t *testing.T) {
|
||||
f, err := ioutil.TempFile(os.TempDir(), "utilitytest")
|
||||
log.PanicIf(err)
|
||||
|
||||
defer os.Remove(f.Name())
|
||||
|
||||
originalStdout := os.Stdout
|
||||
os.Stdout = f
|
||||
|
||||
DumpBytesClause([]byte{0x11, 0x22})
|
||||
|
||||
os.Stdout = originalStdout
|
||||
|
||||
_, err = f.Seek(0, 0)
|
||||
log.PanicIf(err)
|
||||
|
||||
content, err := ioutil.ReadAll(f)
|
||||
log.PanicIf(err)
|
||||
|
||||
if string(content) != "DUMP: []byte { 0x11, 0x22 }\n" {
|
||||
t.Fatalf("content not correct: [%s]", string(content))
|
||||
}
|
||||
}
|
||||
|
||||
func TestDumpBytesToString(t *testing.T) {
|
||||
s := DumpBytesToString([]byte{0x12, 0x34, 0x56})
|
||||
|
||||
if s != "12 34 56" {
|
||||
t.Fatalf("result not expected")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDumpBytesClauseToString(t *testing.T) {
|
||||
s := DumpBytesClauseToString([]byte{0x12, 0x34, 0x56})
|
||||
|
||||
if s != "0x12, 0x34, 0x56" {
|
||||
t.Fatalf("result not expected")
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseExifFullTimestamp(t *testing.T) {
|
||||
timestamp, err := ParseExifFullTimestamp("2018:11:30 13:01:49")
|
||||
log.PanicIf(err)
|
||||
|
|
|
@ -2,10 +2,12 @@ package exif
|
|||
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/dsoprea/go-exif/v2/common"
|
||||
)
|
||||
|
||||
func newValueContextFromTag(ite *IfdTagEntry, addressableData []byte, byteOrder binary.ByteOrder) *ValueContext {
|
||||
return newValueContext(
|
||||
func newValueContextFromTag(ite *IfdTagEntry, addressableData []byte, byteOrder binary.ByteOrder) *exifcommon.ValueContext {
|
||||
return exifcommon.NewValueContext(
|
||||
ite.IfdPath,
|
||||
ite.TagId,
|
||||
ite.UnitCount,
|
||||
|
|
Loading…
Reference in New Issue