mirror of https://github.com/dsoprea/go-exif.git
value_context.go: We now store the IFD-path and tag-ID on the value-context
This allows us to add an API for accessing an undefined-value/structure directly on ValueContext. - ifd_tag_entry.go: Fixed several methods on `IfdTagEntry` to be by- reference. It was a latent bug that they weren't. - value_context.go: Added `newValueContextFromTag` to streamline the changes above.pull/28/head
parent
e6b94637a3
commit
71b242c269
|
@ -210,6 +210,18 @@ func (ie *IfdEnumerate) parseTag(fqIfdPath string, tagPosition int, ite *IfdTagE
|
||||||
return tag, nil
|
return tag, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ie *IfdEnumerate) GetValueContext(ite *IfdTagEntry) *ValueContext {
|
||||||
|
|
||||||
|
// TODO(dustin): Add test
|
||||||
|
|
||||||
|
addressableData := ie.exifData[ExifAddressableAreaStart:]
|
||||||
|
|
||||||
|
return newValueContextFromTag(
|
||||||
|
ite,
|
||||||
|
addressableData,
|
||||||
|
ie.byteOrder)
|
||||||
|
}
|
||||||
|
|
||||||
func (ie *IfdEnumerate) resolveTagValue(ite *IfdTagEntry) (valueBytes []byte, isUnhandledUnknown bool, err error) {
|
func (ie *IfdEnumerate) resolveTagValue(ite *IfdTagEntry) (valueBytes []byte, isUnhandledUnknown bool, err error) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if state := recover(); state != nil {
|
if state := recover(); state != nil {
|
||||||
|
@ -225,15 +237,7 @@ func (ie *IfdEnumerate) resolveTagValue(ite *IfdTagEntry) (valueBytes []byte, is
|
||||||
// (obviously). However, here, in order to produce the list of bytes, we
|
// (obviously). However, here, in order to produce the list of bytes, we
|
||||||
// need to coerce whatever `UndefinedValue()` returns.
|
// need to coerce whatever `UndefinedValue()` returns.
|
||||||
if ite.TagType == TypeUndefined {
|
if ite.TagType == TypeUndefined {
|
||||||
valueContext :=
|
valueContext := ie.GetValueContext(ite)
|
||||||
newValueContext(
|
|
||||||
ite.UnitCount,
|
|
||||||
ite.ValueOffset,
|
|
||||||
ite.RawValueOffset,
|
|
||||||
addressableData,
|
|
||||||
ite.TagType,
|
|
||||||
ie.byteOrder,
|
|
||||||
)
|
|
||||||
|
|
||||||
value, err := UndefinedValue(ite.IfdPath, ite.TagId, valueContext, ie.byteOrder)
|
value, err := UndefinedValue(ite.IfdPath, ite.TagId, valueContext, ie.byteOrder)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -372,16 +376,9 @@ func (ie *IfdEnumerate) ParseIfd(fqIfdPath string, ifdIndex int, ite *IfdTagEnum
|
||||||
if visitorWrapper != nil {
|
if visitorWrapper != nil {
|
||||||
tt := NewTagType(tag.TagType, ie.byteOrder)
|
tt := NewTagType(tag.TagType, ie.byteOrder)
|
||||||
|
|
||||||
vc :=
|
valueContext := ie.GetValueContext(tag)
|
||||||
newValueContext(
|
|
||||||
tag.UnitCount,
|
|
||||||
tag.ValueOffset,
|
|
||||||
tag.RawValueOffset,
|
|
||||||
ie.exifData[ExifAddressableAreaStart:],
|
|
||||||
tag.TagType,
|
|
||||||
ie.byteOrder)
|
|
||||||
|
|
||||||
err := visitorWrapper.Visit(fqIfdPath, ifdIndex, tag.TagId, tt, vc)
|
err := visitorWrapper.Visit(fqIfdPath, ifdIndex, tag.TagId, tt, valueContext)
|
||||||
log.PanicIf(err)
|
log.PanicIf(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,34 +43,31 @@ type IfdTagEntry struct {
|
||||||
isUnhandledUnknown bool
|
isUnhandledUnknown bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ite IfdTagEntry) String() string {
|
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, TypeNames[ite.TagType], ite.UnitCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValueString renders a string from whatever the value in this tag is.
|
// 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) (value string, err error) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if state := recover(); state != nil {
|
if state := recover(); state != nil {
|
||||||
err = log.Wrap(state.(error))
|
err = log.Wrap(state.(error))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
vc :=
|
valueContext :=
|
||||||
newValueContext(
|
newValueContextFromTag(
|
||||||
ite.UnitCount,
|
ite,
|
||||||
ite.ValueOffset,
|
|
||||||
ite.RawValueOffset,
|
|
||||||
addressableData,
|
addressableData,
|
||||||
ite.TagType,
|
|
||||||
byteOrder)
|
byteOrder)
|
||||||
|
|
||||||
if ite.TagType == TypeUndefined {
|
if ite.TagType == TypeUndefined {
|
||||||
valueRaw, err := UndefinedValue(ite.IfdPath, ite.TagId, vc, byteOrder)
|
valueRaw, err := UndefinedValue(ite.IfdPath, ite.TagId, valueContext, byteOrder)
|
||||||
log.PanicIf(err)
|
log.PanicIf(err)
|
||||||
|
|
||||||
value = fmt.Sprintf("%v", valueRaw)
|
value = fmt.Sprintf("%v", valueRaw)
|
||||||
} else {
|
} else {
|
||||||
value, err = vc.Format()
|
value, err = valueContext.Format()
|
||||||
log.PanicIf(err)
|
log.PanicIf(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +75,7 @@ func (ite IfdTagEntry) ValueString(addressableData []byte, byteOrder binary.Byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValueBytes renders a specific list of bytes from the value in this tag.
|
// ValueBytes renders a specific list of bytes from the value in this tag.
|
||||||
func (ite IfdTagEntry) ValueBytes(addressableData []byte, byteOrder binary.ByteOrder) (value []byte, err error) {
|
func (ite *IfdTagEntry) ValueBytes(addressableData []byte, byteOrder binary.ByteOrder) (value []byte, err error) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if state := recover(); state != nil {
|
if state := recover(); state != nil {
|
||||||
err = log.Wrap(state.(error))
|
err = log.Wrap(state.(error))
|
||||||
|
@ -92,12 +89,9 @@ func (ite IfdTagEntry) ValueBytes(addressableData []byte, byteOrder binary.ByteO
|
||||||
// need to coerce whatever `UndefinedValue()` returns.
|
// need to coerce whatever `UndefinedValue()` returns.
|
||||||
if ite.TagType == TypeUndefined {
|
if ite.TagType == TypeUndefined {
|
||||||
valueContext :=
|
valueContext :=
|
||||||
newValueContext(
|
newValueContextFromTag(
|
||||||
ite.UnitCount,
|
ite,
|
||||||
ite.ValueOffset,
|
|
||||||
ite.RawValueOffset,
|
|
||||||
addressableData,
|
addressableData,
|
||||||
ite.TagType,
|
|
||||||
byteOrder)
|
byteOrder)
|
||||||
|
|
||||||
value, err := UndefinedValue(ite.IfdPath, ite.TagId, valueContext, byteOrder)
|
value, err := UndefinedValue(ite.IfdPath, ite.TagId, valueContext, byteOrder)
|
||||||
|
@ -145,29 +139,26 @@ func (ite IfdTagEntry) ValueBytes(addressableData []byte, byteOrder binary.ByteO
|
||||||
}
|
}
|
||||||
|
|
||||||
// Value returns the specific, parsed, typed value from the tag.
|
// Value returns the specific, parsed, typed value from the tag.
|
||||||
func (ite IfdTagEntry) Value(addressableData []byte, byteOrder binary.ByteOrder) (value interface{}, err error) {
|
func (ite *IfdTagEntry) Value(addressableData []byte, byteOrder binary.ByteOrder) (value interface{}, err error) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if state := recover(); state != nil {
|
if state := recover(); state != nil {
|
||||||
err = log.Wrap(state.(error))
|
err = log.Wrap(state.(error))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
vc :=
|
valueContext :=
|
||||||
newValueContext(
|
newValueContextFromTag(
|
||||||
ite.UnitCount,
|
ite,
|
||||||
ite.ValueOffset,
|
|
||||||
ite.RawValueOffset,
|
|
||||||
addressableData,
|
addressableData,
|
||||||
ite.TagType,
|
|
||||||
byteOrder)
|
byteOrder)
|
||||||
|
|
||||||
if ite.TagType == TypeUndefined {
|
if ite.TagType == TypeUndefined {
|
||||||
value, err = UndefinedValue(ite.IfdPath, ite.TagId, vc, byteOrder)
|
value, err = UndefinedValue(ite.IfdPath, ite.TagId, valueContext, byteOrder)
|
||||||
log.PanicIf(err)
|
log.PanicIf(err)
|
||||||
} else {
|
} else {
|
||||||
tt := NewTagType(ite.TagType, byteOrder)
|
tt := NewTagType(ite.TagType, byteOrder)
|
||||||
|
|
||||||
value, err = tt.Resolve(vc)
|
value, err = tt.Resolve(valueContext)
|
||||||
log.PanicIf(err)
|
log.PanicIf(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,9 +28,12 @@ type ValueContext struct {
|
||||||
// undefinedValueUnitCount is the effective unit-count to use if this is an
|
// undefinedValueUnitCount is the effective unit-count to use if this is an
|
||||||
// "undefined" value.
|
// "undefined" value.
|
||||||
undefinedValueUnitCount uint32
|
undefinedValueUnitCount uint32
|
||||||
|
|
||||||
|
ifdPath string
|
||||||
|
tagId uint16
|
||||||
}
|
}
|
||||||
|
|
||||||
func newValueContext(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{
|
return &ValueContext{
|
||||||
unitCount: unitCount,
|
unitCount: unitCount,
|
||||||
valueOffset: valueOffset,
|
valueOffset: valueOffset,
|
||||||
|
@ -39,9 +42,24 @@ func newValueContext(unitCount, valueOffset uint32, rawValueOffset, addressableD
|
||||||
|
|
||||||
tagType: tagType,
|
tagType: tagType,
|
||||||
byteOrder: byteOrder,
|
byteOrder: byteOrder,
|
||||||
|
|
||||||
|
ifdPath: ifdPath,
|
||||||
|
tagId: tagId,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newValueContextFromTag(ite *IfdTagEntry, addressableData []byte, byteOrder binary.ByteOrder) *ValueContext {
|
||||||
|
return newValueContext(
|
||||||
|
ite.IfdPath,
|
||||||
|
ite.TagId,
|
||||||
|
ite.UnitCount,
|
||||||
|
ite.ValueOffset,
|
||||||
|
ite.RawValueOffset,
|
||||||
|
addressableData,
|
||||||
|
ite.TagType,
|
||||||
|
byteOrder)
|
||||||
|
}
|
||||||
|
|
||||||
func (vc *ValueContext) SetUnknownValueParameters(tagType TagTypePrimitive, unitCount uint32) {
|
func (vc *ValueContext) SetUnknownValueParameters(tagType TagTypePrimitive, unitCount uint32) {
|
||||||
vc.undefinedValueTagType = tagType
|
vc.undefinedValueTagType = tagType
|
||||||
vc.undefinedValueUnitCount = unitCount
|
vc.undefinedValueUnitCount = unitCount
|
||||||
|
|
Loading…
Reference in New Issue