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
|
||||
}
|
||||
|
||||
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) {
|
||||
defer func() {
|
||||
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
|
||||
// need to coerce whatever `UndefinedValue()` returns.
|
||||
if ite.TagType == TypeUndefined {
|
||||
valueContext :=
|
||||
newValueContext(
|
||||
ite.UnitCount,
|
||||
ite.ValueOffset,
|
||||
ite.RawValueOffset,
|
||||
addressableData,
|
||||
ite.TagType,
|
||||
ie.byteOrder,
|
||||
)
|
||||
valueContext := ie.GetValueContext(ite)
|
||||
|
||||
value, err := UndefinedValue(ite.IfdPath, ite.TagId, valueContext, ie.byteOrder)
|
||||
if err != nil {
|
||||
|
@ -372,16 +376,9 @@ func (ie *IfdEnumerate) ParseIfd(fqIfdPath string, ifdIndex int, ite *IfdTagEnum
|
|||
if visitorWrapper != nil {
|
||||
tt := NewTagType(tag.TagType, ie.byteOrder)
|
||||
|
||||
vc :=
|
||||
newValueContext(
|
||||
tag.UnitCount,
|
||||
tag.ValueOffset,
|
||||
tag.RawValueOffset,
|
||||
ie.exifData[ExifAddressableAreaStart:],
|
||||
tag.TagType,
|
||||
ie.byteOrder)
|
||||
valueContext := ie.GetValueContext(tag)
|
||||
|
||||
err := visitorWrapper.Visit(fqIfdPath, ifdIndex, tag.TagId, tt, vc)
|
||||
err := visitorWrapper.Visit(fqIfdPath, ifdIndex, tag.TagId, tt, valueContext)
|
||||
log.PanicIf(err)
|
||||
}
|
||||
|
||||
|
|
|
@ -43,34 +43,31 @@ type IfdTagEntry struct {
|
|||
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)
|
||||
}
|
||||
|
||||
// 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() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
}
|
||||
}()
|
||||
|
||||
vc :=
|
||||
newValueContext(
|
||||
ite.UnitCount,
|
||||
ite.ValueOffset,
|
||||
ite.RawValueOffset,
|
||||
valueContext :=
|
||||
newValueContextFromTag(
|
||||
ite,
|
||||
addressableData,
|
||||
ite.TagType,
|
||||
byteOrder)
|
||||
|
||||
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)
|
||||
|
||||
value = fmt.Sprintf("%v", valueRaw)
|
||||
} else {
|
||||
value, err = vc.Format()
|
||||
value, err = valueContext.Format()
|
||||
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.
|
||||
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() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
|
@ -92,12 +89,9 @@ func (ite IfdTagEntry) ValueBytes(addressableData []byte, byteOrder binary.ByteO
|
|||
// need to coerce whatever `UndefinedValue()` returns.
|
||||
if ite.TagType == TypeUndefined {
|
||||
valueContext :=
|
||||
newValueContext(
|
||||
ite.UnitCount,
|
||||
ite.ValueOffset,
|
||||
ite.RawValueOffset,
|
||||
newValueContextFromTag(
|
||||
ite,
|
||||
addressableData,
|
||||
ite.TagType,
|
||||
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.
|
||||
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() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
}
|
||||
}()
|
||||
|
||||
vc :=
|
||||
newValueContext(
|
||||
ite.UnitCount,
|
||||
ite.ValueOffset,
|
||||
ite.RawValueOffset,
|
||||
valueContext :=
|
||||
newValueContextFromTag(
|
||||
ite,
|
||||
addressableData,
|
||||
ite.TagType,
|
||||
byteOrder)
|
||||
|
||||
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)
|
||||
} else {
|
||||
tt := NewTagType(ite.TagType, byteOrder)
|
||||
|
||||
value, err = tt.Resolve(vc)
|
||||
value, err = tt.Resolve(valueContext)
|
||||
log.PanicIf(err)
|
||||
}
|
||||
|
||||
|
|
|
@ -28,9 +28,12 @@ type ValueContext struct {
|
|||
// undefinedValueUnitCount is the effective unit-count to use if this is an
|
||||
// "undefined" value.
|
||||
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{
|
||||
unitCount: unitCount,
|
||||
valueOffset: valueOffset,
|
||||
|
@ -39,9 +42,24 @@ func newValueContext(unitCount, valueOffset uint32, rawValueOffset, addressableD
|
|||
|
||||
tagType: tagType,
|
||||
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) {
|
||||
vc.undefinedValueTagType = tagType
|
||||
vc.undefinedValueUnitCount = unitCount
|
||||
|
|
Loading…
Reference in New Issue