mirror of https://github.com/dsoprea/go-exif.git
ifd_builder: Now embed type in `builderTag`.
- We were automatically looking this up but this will prevent users from having a mechanism to use custom tags.pull/3/head
parent
b748843a75
commit
16586eb8cb
|
@ -66,6 +66,7 @@ type builderTag struct {
|
|||
ii IfdIdentity
|
||||
|
||||
tagId uint16
|
||||
typeId uint16
|
||||
|
||||
// value is either a value that can be encoded, an IfdBuilder instance (for
|
||||
// child IFDs), or an IfdTagEntry instance representing an existing,
|
||||
|
@ -73,10 +74,34 @@ type builderTag struct {
|
|||
value *IfdBuilderTagValue
|
||||
}
|
||||
|
||||
func NewBuilderTag(ii IfdIdentity, tagId uint16, value *IfdBuilderTagValue) builderTag {
|
||||
func NewBuilderTag(ii IfdIdentity, tagId uint16, typeId uint16, value *IfdBuilderTagValue) builderTag {
|
||||
return builderTag{
|
||||
ii: ii,
|
||||
tagId: tagId,
|
||||
typeId: typeId,
|
||||
value: value,
|
||||
}
|
||||
}
|
||||
|
||||
func NewStandardBuilderTag(ii IfdIdentity, tagId uint16, value *IfdBuilderTagValue) builderTag {
|
||||
ti := NewTagIndex()
|
||||
|
||||
it, err := ti.Get(ii, tagId)
|
||||
log.PanicIf(err)
|
||||
|
||||
return builderTag{
|
||||
ii: ii,
|
||||
tagId: tagId,
|
||||
typeId: it.Type,
|
||||
value: value,
|
||||
}
|
||||
}
|
||||
|
||||
func NewChildIfdTag(ii IfdIdentity, tagId uint16, value *IfdBuilderTagValue) builderTag {
|
||||
return builderTag{
|
||||
ii: ii,
|
||||
tagId: tagId,
|
||||
typeId: TypeLong,
|
||||
value: value,
|
||||
}
|
||||
}
|
||||
|
@ -102,18 +127,21 @@ func (bt builderTag) String() string {
|
|||
// NewBuilderTagFromConfig allows us to easily generate solid, consistent tags
|
||||
// for testing with. `ii` is the tpye of IFD that owns this tag.
|
||||
func NewBuilderTagFromConfig(ii IfdIdentity, tagId uint16, byteOrder binary.ByteOrder, value interface{}) builderTag {
|
||||
var typeId uint16
|
||||
var tagValue *IfdBuilderTagValue
|
||||
|
||||
switch value.(type) {
|
||||
case *IfdBuilder:
|
||||
tagValue = NewIfdBuilderTagValueFromIfdBuilder(value.(*IfdBuilder))
|
||||
typeId = TypeLong
|
||||
default:
|
||||
ti := NewTagIndex()
|
||||
|
||||
it, err := ti.Get(ii, tagId)
|
||||
log.PanicIf(err)
|
||||
|
||||
tt := NewTagType(it.Type, byteOrder)
|
||||
typeId = it.Type
|
||||
tt := NewTagType(typeId, byteOrder)
|
||||
|
||||
ve := NewValueEncoder(byteOrder)
|
||||
|
||||
|
@ -123,11 +151,11 @@ func NewBuilderTagFromConfig(ii IfdIdentity, tagId uint16, byteOrder binary.Byte
|
|||
tagValue = NewIfdBuilderTagValueFromBytes(ed.Encoded)
|
||||
}
|
||||
|
||||
return builderTag{
|
||||
ii: ii,
|
||||
tagId: tagId,
|
||||
value: tagValue,
|
||||
}
|
||||
return NewBuilderTag(
|
||||
ii,
|
||||
tagId,
|
||||
typeId,
|
||||
tagValue)
|
||||
}
|
||||
|
||||
// NewBuilderTagFromConfigWithName allows us to easily generate solid, consistent tags
|
||||
|
@ -148,11 +176,11 @@ func NewBuilderTagFromConfigWithName(ii IfdIdentity, tagName string, byteOrder b
|
|||
|
||||
tagValue := NewIfdBuilderTagValueFromBytes(ed.Encoded)
|
||||
|
||||
return builderTag{
|
||||
ii: ii,
|
||||
tagId: it.Id,
|
||||
value: tagValue,
|
||||
}
|
||||
return NewBuilderTag(
|
||||
ii,
|
||||
it.Id,
|
||||
it.Type,
|
||||
tagValue)
|
||||
}
|
||||
|
||||
|
||||
|
@ -554,11 +582,10 @@ func (ib *IfdBuilder) AddChildIb(childIb *IfdBuilder) (err error) {
|
|||
|
||||
value := NewIfdBuilderTagValueFromIfdBuilder(childIb)
|
||||
|
||||
bt := builderTag{
|
||||
ii: childIb.ii,
|
||||
tagId: childIb.ifdTagId,
|
||||
value: value,
|
||||
}
|
||||
bt := NewChildIfdTag(
|
||||
childIb.ii,
|
||||
childIb.ifdTagId,
|
||||
value)
|
||||
|
||||
ib.tags = append(ib.tags, bt)
|
||||
|
||||
|
@ -614,6 +641,7 @@ func (ib *IfdBuilder) AddTagsFromExisting(ifd *Ifd, itevr *IfdTagEntryValueResol
|
|||
|
||||
bt := builderTag{
|
||||
tagId: ite.TagId,
|
||||
typeId: ite.TagType,
|
||||
}
|
||||
|
||||
if itevr == nil {
|
||||
|
|
|
@ -144,30 +144,20 @@ func (ibe *IfdByteEncoder) encodeTagToBytes(ib *IfdBuilder, bt *builderTag, bw *
|
|||
}
|
||||
}()
|
||||
|
||||
ti := NewTagIndex()
|
||||
|
||||
// Write tag-ID.
|
||||
err = bw.WriteUint16(bt.tagId)
|
||||
log.PanicIf(err)
|
||||
|
||||
// Write type.
|
||||
|
||||
it, err := ti.Get(ib.ii, bt.tagId)
|
||||
log.PanicIf(err)
|
||||
|
||||
// Works for both values and child IFDs (which have an official size of
|
||||
// LONG).
|
||||
err = bw.WriteUint16(it.Type)
|
||||
err = bw.WriteUint16(bt.typeId)
|
||||
log.PanicIf(err)
|
||||
|
||||
// Write unit-count.
|
||||
|
||||
// TODO(dustin): !! Test that we write a list of shorts, uints, etc.. correctly.
|
||||
// TODO(dustin): !! Make sure we test all of the different cases below.
|
||||
|
||||
if bt.value.IsBytes() == true {
|
||||
effectiveType := it.Type
|
||||
if it.Type == TypeUndefined {
|
||||
effectiveType := bt.typeId
|
||||
if bt.typeId == TypeUndefined {
|
||||
effectiveType = TypeByte
|
||||
}
|
||||
|
||||
|
|
|
@ -180,6 +180,13 @@ func Test_IfdByteEncoder__Arithmetic(t *testing.T) {
|
|||
}
|
||||
|
||||
func Test_IfdByteEncoder_encodeTagToBytes_bytes_embedded1(t *testing.T) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err := log.Wrap(state.(error))
|
||||
log.PrintErrorf(err, "Test failure.")
|
||||
}
|
||||
}()
|
||||
|
||||
ibe := NewIfdByteEncoder()
|
||||
|
||||
ib := NewIfdBuilder(GpsIi, TestDefaultByteOrder)
|
||||
|
@ -313,11 +320,10 @@ func Test_IfdByteEncoder_encodeTagToBytes_childIfd__withAllocate(t *testing.T) {
|
|||
|
||||
childIb := NewIfdBuilder(ExifIi, TestDefaultByteOrder)
|
||||
|
||||
childIbTestTag := builderTag{
|
||||
ii: ExifIi,
|
||||
tagId: 0x8822,
|
||||
value: NewIfdBuilderTagValueFromBytes([]byte { 0x12, 0x34 }),
|
||||
}
|
||||
childIbTestTag := NewStandardBuilderTag(
|
||||
ExifIi,
|
||||
0x8822,
|
||||
NewIfdBuilderTagValueFromBytes([]byte { 0x12, 0x34 }))
|
||||
|
||||
childIb.Add(childIbTestTag)
|
||||
|
||||
|
@ -795,6 +801,3 @@ func ExampleIfdByteEncoder_EncodeToExif() {
|
|||
}
|
||||
|
||||
// TODO(dustin): !! Write test with both chained and child IFDs
|
||||
|
||||
// TODO(dustin): !! Test specific unknown-type tags.
|
||||
// TODO(dustin): !! Test what happens with unhandled unknown-type tags (though it should never get to this point in the normal workflow).
|
||||
|
|
|
@ -9,10 +9,6 @@ import (
|
|||
"github.com/dsoprea/go-logging"
|
||||
)
|
||||
|
||||
|
||||
// TODO(dustin): !! We need to have knowledge of the types so that we can validate or induce extra info for the adds.
|
||||
|
||||
|
||||
func TestAdd(t *testing.T) {
|
||||
ib := NewIfdBuilder(RootIi, TestDefaultByteOrder)
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ func TestUndefinedValue_ExifVersion(t *testing.T) {
|
|||
// have the bytes.
|
||||
|
||||
encodedValue := NewIfdBuilderTagValueFromBytes(ed.Encoded)
|
||||
bt := NewBuilderTag(ii, 0x9000, encodedValue)
|
||||
bt := NewStandardBuilderTag(ii, 0x9000, encodedValue)
|
||||
|
||||
|
||||
// Stage the build.
|
||||
|
@ -73,3 +73,6 @@ func TestUndefinedValue_ExifVersion(t *testing.T) {
|
|||
t.Fatalf("Tag's parent IFD is not correct: %v", ite.Ii)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(dustin): !! Add tests for remaining, well-defined unknown
|
||||
// TODO(dustin): !! Test what happens with unhandled unknown-type tags (though it should never get to this point in the normal workflow).
|
||||
|
|
Loading…
Reference in New Issue