MakerNotes now print size and SHA1

- tags_unknown.go: Unhandled unknown values are now wrapped in a
  TagUnknownType_UnknownValue rather than returning an error. This is
  now used to print byte-counts and SHA1s for unhandled values.

- tags_unknown.go: UnparseableUnknownTagValuePlaceholder now has message
  "!UNKNOWN" rather than "!UNPARSEABLE".
pull/28/head
Dustin Oprea 2019-11-02 03:46:00 -04:00
parent 4802cf93f4
commit 3dda8c2115
6 changed files with 53 additions and 10 deletions

File diff suppressed because one or more lines are too long

View File

@ -65,7 +65,7 @@ IFD-PATH=[IFD/Exif] ID=(0x9204) NAME=[ExposureBiasValue] COUNT=(1) TYPE=[SRATION
IFD-PATH=[IFD/Exif] ID=(0x9207) NAME=[MeteringMode] COUNT=(1) TYPE=[SHORT] VALUE=[5]
IFD-PATH=[IFD/Exif] ID=(0x9209) NAME=[Flash] COUNT=(1) TYPE=[SHORT] VALUE=[16]
IFD-PATH=[IFD/Exif] ID=(0x920a) NAME=[FocalLength] COUNT=(1) TYPE=[RATIONAL] VALUE=[16/1]
IFD-PATH=[IFD/Exif] ID=(0x927c) NAME=[MakerNote] COUNT=(8152) TYPE=[UNDEFINED] VALUE=[MakerNote<TYPE-ID=[28 00 01 00 03 00 31 00 00 00 74 05 00 00 02 00 03 00 04 00]>]
IFD-PATH=[IFD/Exif] ID=(0x927c) NAME=[MakerNote] COUNT=(8152) TYPE=[UNDEFINED] VALUE=[MakerNote<TYPE-ID=[28 00 01 00 03 00 31 00 00 00 74 05 00 00 02 00 03 00 04 00] LEN=(8152) SHA1=[d4154aa7df5474efe7ab38de2595919b9b4cc29f]>]
IFD-PATH=[IFD/Exif] ID=(0x9286) NAME=[UserComment] COUNT=(264) TYPE=[UNDEFINED] VALUE=[UserComment<SIZE=(256) ENCODING=[UNDEFINED] V=[0 0 0 0 0 0 0 0]... LEN=(256)>]
IFD-PATH=[IFD/Exif] ID=(0x9290) NAME=[SubSecTime] COUNT=(3) TYPE=[ASCII] VALUE=[00]
IFD-PATH=[IFD/Exif] ID=(0x9291) NAME=[SubSecTimeOriginal] COUNT=(3) TYPE=[ASCII] VALUE=[00]

View File

@ -131,7 +131,7 @@ func TestVisit(t *testing.T) {
"IFD-PATH=[IFD/Exif] ID=(0x9207) NAME=[MeteringMode] COUNT=(1) TYPE=[SHORT] VALUE=[5]",
"IFD-PATH=[IFD/Exif] ID=(0x9209) NAME=[Flash] COUNT=(1) TYPE=[SHORT] VALUE=[16]",
"IFD-PATH=[IFD/Exif] ID=(0x920a) NAME=[FocalLength] COUNT=(1) TYPE=[RATIONAL] VALUE=[16/1]",
"IFD-PATH=[IFD/Exif] ID=(0x927c) NAME=[MakerNote] COUNT=(8152) TYPE=[UNDEFINED] VALUE=[MakerNote<TYPE-ID=[28 00 01 00 03 00 31 00 00 00 74 05 00 00 02 00 03 00 04 00]>]",
"IFD-PATH=[IFD/Exif] ID=(0x927c) NAME=[MakerNote] COUNT=(8152) TYPE=[UNDEFINED] VALUE=[MakerNote<TYPE-ID=[28 00 01 00 03 00 31 00 00 00 74 05 00 00 02 00 03 00 04 00] LEN=(8152) SHA1=[d4154aa7df5474efe7ab38de2595919b9b4cc29f]>]",
"IFD-PATH=[IFD/Exif] ID=(0x9286) NAME=[UserComment] COUNT=(264) TYPE=[UNDEFINED] VALUE=[UserComment<SIZE=(256) ENCODING=[UNDEFINED] V=[0 0 0 0 0 0 0 0]... LEN=(256)>]",
"IFD-PATH=[IFD/Exif] ID=(0x9290) NAME=[SubSecTime] COUNT=(3) TYPE=[ASCII] VALUE=[00]",
"IFD-PATH=[IFD/Exif] ID=(0x9291) NAME=[SubSecTimeOriginal] COUNT=(3) TYPE=[ASCII] VALUE=[00]",

View File

@ -259,6 +259,9 @@ func (ie *IfdEnumerate) resolveTagValue(ite *IfdTagEntry) (valueBytes []byte, is
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:
@ -268,7 +271,7 @@ func (ie *IfdEnumerate) resolveTagValue(ite *IfdTagEntry) (valueBytes []byte, is
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): [%s]", ite.TagId, reflect.TypeOf(value))
log.Panicf("can not produce bytes for unknown-type tag (0x%04x) (1): [%s]", ite.TagId, reflect.TypeOf(value))
}
}
} else {

View File

@ -104,6 +104,9 @@ func (ite IfdTagEntry) ValueBytes(addressableData []byte, byteOrder binary.ByteO
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:
@ -113,7 +116,7 @@ func (ite IfdTagEntry) ValueBytes(addressableData []byte, byteOrder binary.ByteO
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): [%s]", ite.TagId, reflect.TypeOf(value))
log.Panicf("can not produce bytes for unknown-type tag (0x%04x) (2): [%s]", ite.TagId, reflect.TypeOf(value))
}
}

View File

@ -5,13 +5,14 @@ import (
"fmt"
"strings"
"crypto/sha1"
"encoding/binary"
"github.com/dsoprea/go-logging"
)
const (
UnparseableUnknownTagValuePlaceholder = "!UNPARSEABLE"
UnparseableUnknownTagValuePlaceholder = "!UNKNOWN"
)
const (
@ -126,7 +127,14 @@ func (mn TagUnknownType_927C_MakerNote) String() string {
parts[i] = fmt.Sprintf("%02x", c)
}
return fmt.Sprintf("MakerNote<TYPE-ID=[%s]>", strings.Join(parts, " "))
h := sha1.New()
_, err := h.Write(mn.MakerNoteBytes)
log.PanicIf(err)
digest := h.Sum(nil)
return fmt.Sprintf("MakerNote<TYPE-ID=[%s] LEN=(%d) SHA1=[%020x]>", strings.Join(parts, " "), len(mn.MakerNoteBytes), digest)
}
func (uc TagUnknownType_927C_MakerNote) ValueBytes() (value []byte, err error) {
@ -199,6 +207,24 @@ func EncodeUndefined(ifdPath string, tagId uint16, value interface{}) (ed Encode
return EncodedData{}, nil
}
type TagUnknownType_UnknownValue []byte
func (tutuv TagUnknownType_UnknownValue) String() string {
parts := make([]string, len(tutuv))
for i, c := range tutuv {
parts[i] = fmt.Sprintf("%02x", c)
}
h := sha1.New()
_, err := h.Write(tutuv)
log.PanicIf(err)
digest := h.Sum(nil)
return fmt.Sprintf("Unknown<DATA=[%s] LEN=(%d) SHA1=[%020x]>", strings.Join(parts, " "), len(tutuv), digest)
}
// UndefinedValue knows how to resolve the value for most unknown-type tags.
func UndefinedValue(ifdPath string, tagId uint16, valueContext ValueContext, byteOrder binary.ByteOrder) (value interface{}, err error) {
defer func() {
@ -347,9 +373,20 @@ func UndefinedValue(ifdPath string, tagId uint16, valueContext ValueContext, byt
//
// complex: 0xa302, 0xa20c, 0x8828
// long: 0xa301, 0xa300
//
// 0xa40b is device-specific and unhandled.
log.Panic(ErrUnhandledUnknownTypedTag)
return nil, nil
// Return encapsulated data rather than an error so that we can at least
// print/profile the opaque data.
tt := NewTagType(TypeByte, byteOrder)
valueBytes, err := tt.ReadByteValues(valueContext)
log.PanicIf(err)
tutuv := TagUnknownType_UnknownValue(valueBytes)
return tutuv, nil
// log.Panic(ErrUnhandledUnknownTypedTag)
// return nil, nil
}