summaryrefslogtreecommitdiff
path: root/vendor/github.com/dsoprea/go-exif/v3/undefined
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/dsoprea/go-exif/v3/undefined')
-rw-r--r--vendor/github.com/dsoprea/go-exif/v3/undefined/README.md4
-rw-r--r--vendor/github.com/dsoprea/go-exif/v3/undefined/accessor.go62
-rw-r--r--vendor/github.com/dsoprea/go-exif/v3/undefined/exif_8828_oecf.go148
-rw-r--r--vendor/github.com/dsoprea/go-exif/v3/undefined/exif_9000_exif_version.go69
-rw-r--r--vendor/github.com/dsoprea/go-exif/v3/undefined/exif_9101_components_configuration.go124
-rw-r--r--vendor/github.com/dsoprea/go-exif/v3/undefined/exif_927C_maker_note.go114
-rw-r--r--vendor/github.com/dsoprea/go-exif/v3/undefined/exif_9286_user_comment.go142
-rw-r--r--vendor/github.com/dsoprea/go-exif/v3/undefined/exif_A000_flashpix_version.go69
-rw-r--r--vendor/github.com/dsoprea/go-exif/v3/undefined/exif_A20C_spatial_frequency_response.go160
-rw-r--r--vendor/github.com/dsoprea/go-exif/v3/undefined/exif_A300_file_source.go79
-rw-r--r--vendor/github.com/dsoprea/go-exif/v3/undefined/exif_A301_scene_type.go76
-rw-r--r--vendor/github.com/dsoprea/go-exif/v3/undefined/exif_A302_cfa_pattern.go97
-rw-r--r--vendor/github.com/dsoprea/go-exif/v3/undefined/exif_iop_0002_interop_version.go69
-rw-r--r--vendor/github.com/dsoprea/go-exif/v3/undefined/gps_001B_gps_processing_method.go65
-rw-r--r--vendor/github.com/dsoprea/go-exif/v3/undefined/gps_001C_gps_area_information.go65
-rw-r--r--vendor/github.com/dsoprea/go-exif/v3/undefined/registration.go42
-rw-r--r--vendor/github.com/dsoprea/go-exif/v3/undefined/type.go44
17 files changed, 1429 insertions, 0 deletions
diff --git a/vendor/github.com/dsoprea/go-exif/v3/undefined/README.md b/vendor/github.com/dsoprea/go-exif/v3/undefined/README.md
new file mode 100644
index 000000000..d2caa6e51
--- /dev/null
+++ b/vendor/github.com/dsoprea/go-exif/v3/undefined/README.md
@@ -0,0 +1,4 @@
+
+## 0xa40b
+
+The specification is not specific/clear enough to be handled. Without a working example ,we're deferring until some point in the future when either we or someone else has a better understanding.
diff --git a/vendor/github.com/dsoprea/go-exif/v3/undefined/accessor.go b/vendor/github.com/dsoprea/go-exif/v3/undefined/accessor.go
new file mode 100644
index 000000000..11a21e1f0
--- /dev/null
+++ b/vendor/github.com/dsoprea/go-exif/v3/undefined/accessor.go
@@ -0,0 +1,62 @@
+package exifundefined
+
+import (
+ "encoding/binary"
+
+ "github.com/dsoprea/go-logging"
+
+ "github.com/dsoprea/go-exif/v3/common"
+)
+
+// Encode encodes the given encodeable undefined value to bytes.
+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 := value.EncoderName()
+
+ encoder, found := encoders[encoderName]
+ if found == false {
+ log.Panicf("no encoder registered for type [%s]", encoderName)
+ }
+
+ encoded, unitCount, err = encoder.Encode(value, byteOrder)
+ log.PanicIf(err)
+
+ return encoded, unitCount, nil
+}
+
+// Decode constructs a value from raw encoded bytes
+func Decode(valueContext *exifcommon.ValueContext) (value EncodeableValue, err error) {
+ defer func() {
+ if state := recover(); state != nil {
+ err = log.Wrap(state.(error))
+ }
+ }()
+
+ uth := UndefinedTagHandle{
+ IfdPath: valueContext.IfdPath(),
+ TagId: valueContext.TagId(),
+ }
+
+ decoder, found := decoders[uth]
+ if found == false {
+ // We have no choice but to return the error. We have no way of knowing how
+ // much data there is without already knowing what data-type this tag is.
+ return nil, exifcommon.ErrUnhandledUndefinedTypedTag
+ }
+
+ value, err = decoder.Decode(valueContext)
+ if err != nil {
+ if err == ErrUnparseableValue {
+ return nil, err
+ }
+
+ log.Panic(err)
+ }
+
+ return value, nil
+}
diff --git a/vendor/github.com/dsoprea/go-exif/v3/undefined/exif_8828_oecf.go b/vendor/github.com/dsoprea/go-exif/v3/undefined/exif_8828_oecf.go
new file mode 100644
index 000000000..26f3675ab
--- /dev/null
+++ b/vendor/github.com/dsoprea/go-exif/v3/undefined/exif_8828_oecf.go
@@ -0,0 +1,148 @@
+package exifundefined
+
+import (
+ "bytes"
+ "fmt"
+
+ "encoding/binary"
+
+ "github.com/dsoprea/go-logging"
+
+ "github.com/dsoprea/go-exif/v3/common"
+)
+
+type Tag8828Oecf struct {
+ Columns uint16
+ Rows uint16
+ ColumnNames []string
+ 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) Encode(value interface{}, byteOrder binary.ByteOrder) (encoded []byte, unitCount uint32, err error) {
+ defer func() {
+ if state := recover(); state != nil {
+ err = log.Wrap(state.(error))
+ }
+ }()
+
+ // TODO(dustin): Add test
+
+ oecf, ok := value.(Tag8828Oecf)
+ if ok == false {
+ log.Panicf("can only encode a Tag8828Oecf")
+ }
+
+ b := new(bytes.Buffer)
+
+ err = binary.Write(b, byteOrder, oecf.Columns)
+ log.PanicIf(err)
+
+ err = binary.Write(b, byteOrder, oecf.Rows)
+ log.PanicIf(err)
+
+ for _, name := range oecf.ColumnNames {
+ _, err := b.Write([]byte(name))
+ log.PanicIf(err)
+
+ _, err = b.Write([]byte{0})
+ log.PanicIf(err)
+ }
+
+ ve := exifcommon.NewValueEncoder(byteOrder)
+
+ ed, err := ve.Encode(oecf.Values)
+ log.PanicIf(err)
+
+ _, err = b.Write(ed.Encoded)
+ log.PanicIf(err)
+
+ return b.Bytes(), uint32(b.Len()), nil
+}
+
+func (Codec8828Oecf) Decode(valueContext *exifcommon.ValueContext) (value EncodeableValue, err error) {
+ defer func() {
+ if state := recover(); state != nil {
+ err = log.Wrap(state.(error))
+ }
+ }()
+
+ // TODO(dustin): Add test using known good data.
+
+ valueContext.SetUndefinedValueType(exifcommon.TypeByte)
+
+ valueBytes, err := valueContext.ReadBytes()
+ log.PanicIf(err)
+
+ oecf := Tag8828Oecf{}
+
+ oecf.Columns = valueContext.ByteOrder().Uint16(valueBytes[0:2])
+ oecf.Rows = valueContext.ByteOrder().Uint16(valueBytes[2:4])
+
+ columnNames := make([]string, oecf.Columns)
+
+ // startAt is where the current column name starts.
+ startAt := 4
+
+ // offset is our current position.
+ offset := startAt
+
+ currentColumnNumber := uint16(0)
+
+ for currentColumnNumber < oecf.Columns {
+ if valueBytes[offset] == 0 {
+ columnName := string(valueBytes[startAt:offset])
+ if len(columnName) == 0 {
+ log.Panicf("SFR column (%d) has zero length", currentColumnNumber)
+ }
+
+ columnNames[currentColumnNumber] = columnName
+ currentColumnNumber++
+
+ offset++
+ startAt = offset
+ continue
+ }
+
+ offset++
+ }
+
+ oecf.ColumnNames = columnNames
+
+ rawRationalBytes := valueBytes[offset:]
+
+ rationalSize := exifcommon.TypeSignedRational.Size()
+ if len(rawRationalBytes)%rationalSize > 0 {
+ log.Panicf("OECF signed-rationals not aligned: (%d) %% (%d) > 0", len(rawRationalBytes), rationalSize)
+ }
+
+ rationalCount := len(rawRationalBytes) / rationalSize
+
+ parser := new(exifcommon.Parser)
+
+ byteOrder := valueContext.ByteOrder()
+
+ items, err := parser.ParseSignedRationals(rawRationalBytes, uint32(rationalCount), byteOrder)
+ log.PanicIf(err)
+
+ oecf.Values = items
+
+ return oecf, nil
+}
+
+func init() {
+ registerDecoder(
+ exifcommon.IfdExifStandardIfdIdentity.UnindexedString(),
+ 0x8828,
+ Codec8828Oecf{})
+}
diff --git a/vendor/github.com/dsoprea/go-exif/v3/undefined/exif_9000_exif_version.go b/vendor/github.com/dsoprea/go-exif/v3/undefined/exif_9000_exif_version.go
new file mode 100644
index 000000000..8f18c8114
--- /dev/null
+++ b/vendor/github.com/dsoprea/go-exif/v3/undefined/exif_9000_exif_version.go
@@ -0,0 +1,69 @@
+package exifundefined
+
+import (
+ "encoding/binary"
+
+ "github.com/dsoprea/go-logging"
+
+ "github.com/dsoprea/go-exif/v3/common"
+)
+
+type Tag9000ExifVersion struct {
+ ExifVersion string
+}
+
+func (Tag9000ExifVersion) EncoderName() string {
+ return "Codec9000ExifVersion"
+}
+
+func (ev Tag9000ExifVersion) String() string {
+ return ev.ExifVersion
+}
+
+type Codec9000ExifVersion struct {
+}
+
+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.ExifVersion), uint32(len(s.ExifVersion)), nil
+}
+
+func (Codec9000ExifVersion) Decode(valueContext *exifcommon.ValueContext) (value EncodeableValue, err error) {
+ defer func() {
+ if state := recover(); state != nil {
+ err = log.Wrap(state.(error))
+ }
+ }()
+
+ valueContext.SetUndefinedValueType(exifcommon.TypeAsciiNoNul)
+
+ valueString, err := valueContext.ReadAsciiNoNul()
+ log.PanicIf(err)
+
+ ev := Tag9000ExifVersion{
+ ExifVersion: valueString,
+ }
+
+ return ev, nil
+}
+
+func init() {
+ registerEncoder(
+ Tag9000ExifVersion{},
+ Codec9000ExifVersion{})
+
+ registerDecoder(
+ exifcommon.IfdExifStandardIfdIdentity.UnindexedString(),
+ 0x9000,
+ Codec9000ExifVersion{})
+}
diff --git a/vendor/github.com/dsoprea/go-exif/v3/undefined/exif_9101_components_configuration.go b/vendor/github.com/dsoprea/go-exif/v3/undefined/exif_9101_components_configuration.go
new file mode 100644
index 000000000..e357fe0a6
--- /dev/null
+++ b/vendor/github.com/dsoprea/go-exif/v3/undefined/exif_9101_components_configuration.go
@@ -0,0 +1,124 @@
+package exifundefined
+
+import (
+ "bytes"
+ "fmt"
+
+ "encoding/binary"
+
+ "github.com/dsoprea/go-logging"
+
+ "github.com/dsoprea/go-exif/v3/common"
+)
+
+const (
+ TagUndefinedType_9101_ComponentsConfiguration_Channel_Y = 0x1
+ TagUndefinedType_9101_ComponentsConfiguration_Channel_Cb = 0x2
+ TagUndefinedType_9101_ComponentsConfiguration_Channel_Cr = 0x3
+ TagUndefinedType_9101_ComponentsConfiguration_Channel_R = 0x4
+ TagUndefinedType_9101_ComponentsConfiguration_Channel_G = 0x5
+ TagUndefinedType_9101_ComponentsConfiguration_Channel_B = 0x6
+)
+
+const (
+ TagUndefinedType_9101_ComponentsConfiguration_OTHER = iota
+ TagUndefinedType_9101_ComponentsConfiguration_RGB = iota
+ TagUndefinedType_9101_ComponentsConfiguration_YCBCR = iota
+)
+
+var (
+ TagUndefinedType_9101_ComponentsConfiguration_Names = map[int]string{
+ TagUndefinedType_9101_ComponentsConfiguration_OTHER: "OTHER",
+ TagUndefinedType_9101_ComponentsConfiguration_RGB: "RGB",
+ TagUndefinedType_9101_ComponentsConfiguration_YCBCR: "YCBCR",
+ }
+
+ TagUndefinedType_9101_ComponentsConfiguration_Configurations = map[int][]byte{
+ TagUndefinedType_9101_ComponentsConfiguration_RGB: {
+ TagUndefinedType_9101_ComponentsConfiguration_Channel_R,
+ TagUndefinedType_9101_ComponentsConfiguration_Channel_G,
+ TagUndefinedType_9101_ComponentsConfiguration_Channel_B,
+ 0,
+ },
+
+ TagUndefinedType_9101_ComponentsConfiguration_YCBCR: {
+ TagUndefinedType_9101_ComponentsConfiguration_Channel_Y,
+ TagUndefinedType_9101_ComponentsConfiguration_Channel_Cb,
+ TagUndefinedType_9101_ComponentsConfiguration_Channel_Cr,
+ 0,
+ },
+ }
+)
+
+type TagExif9101ComponentsConfiguration struct {
+ ConfigurationId int
+ 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)
+}
+
+type CodecExif9101ComponentsConfiguration struct {
+}
+
+func (CodecExif9101ComponentsConfiguration) Encode(value interface{}, byteOrder binary.ByteOrder) (encoded []byte, unitCount uint32, err error) {
+ defer func() {
+ if state := recover(); state != nil {
+ err = log.Wrap(state.(error))
+ }
+ }()
+
+ cc, ok := value.(TagExif9101ComponentsConfiguration)
+ if ok == false {
+ log.Panicf("can only encode a TagExif9101ComponentsConfiguration")
+ }
+
+ return cc.ConfigurationBytes, uint32(len(cc.ConfigurationBytes)), nil
+}
+
+func (CodecExif9101ComponentsConfiguration) Decode(valueContext *exifcommon.ValueContext) (value EncodeableValue, err error) {
+ defer func() {
+ if state := recover(); state != nil {
+ err = log.Wrap(state.(error))
+ }
+ }()
+
+ valueContext.SetUndefinedValueType(exifcommon.TypeByte)
+
+ valueBytes, err := valueContext.ReadBytes()
+ log.PanicIf(err)
+
+ for configurationId, configurationBytes := range TagUndefinedType_9101_ComponentsConfiguration_Configurations {
+ if bytes.Equal(configurationBytes, valueBytes) == true {
+ cc := TagExif9101ComponentsConfiguration{
+ ConfigurationId: configurationId,
+ ConfigurationBytes: valueBytes,
+ }
+
+ return cc, nil
+ }
+ }
+
+ cc := TagExif9101ComponentsConfiguration{
+ ConfigurationId: TagUndefinedType_9101_ComponentsConfiguration_OTHER,
+ ConfigurationBytes: valueBytes,
+ }
+
+ return cc, nil
+}
+
+func init() {
+ registerEncoder(
+ TagExif9101ComponentsConfiguration{},
+ CodecExif9101ComponentsConfiguration{})
+
+ registerDecoder(
+ exifcommon.IfdExifStandardIfdIdentity.UnindexedString(),
+ 0x9101,
+ CodecExif9101ComponentsConfiguration{})
+}
diff --git a/vendor/github.com/dsoprea/go-exif/v3/undefined/exif_927C_maker_note.go b/vendor/github.com/dsoprea/go-exif/v3/undefined/exif_927C_maker_note.go
new file mode 100644
index 000000000..f9cd2788e
--- /dev/null
+++ b/vendor/github.com/dsoprea/go-exif/v3/undefined/exif_927C_maker_note.go
@@ -0,0 +1,114 @@
+package exifundefined
+
+import (
+ "fmt"
+ "strings"
+
+ "crypto/sha1"
+ "encoding/binary"
+
+ "github.com/dsoprea/go-logging"
+
+ "github.com/dsoprea/go-exif/v3/common"
+)
+
+type Tag927CMakerNote struct {
+ MakerNoteType []byte
+ MakerNoteBytes []byte
+}
+
+func (Tag927CMakerNote) EncoderName() string {
+ return "Codec927CMakerNote"
+}
+
+func (mn Tag927CMakerNote) String() string {
+ parts := make([]string, len(mn.MakerNoteType))
+
+ for i, c := range mn.MakerNoteType {
+ parts[i] = fmt.Sprintf("%02x", c)
+ }
+
+ 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)
+}
+
+type Codec927CMakerNote struct {
+}
+
+func (Codec927CMakerNote) Encode(value interface{}, byteOrder binary.ByteOrder) (encoded []byte, unitCount uint32, err error) {
+ defer func() {
+ if state := recover(); state != nil {
+ err = log.Wrap(state.(error))
+ }
+ }()
+
+ mn, ok := value.(Tag927CMakerNote)
+ if ok == false {
+ log.Panicf("can only encode a Tag927CMakerNote")
+ }
+
+ // TODO(dustin): Confirm this size against the specification.
+
+ return mn.MakerNoteBytes, uint32(len(mn.MakerNoteBytes)), nil
+}
+
+func (Codec927CMakerNote) Decode(valueContext *exifcommon.ValueContext) (value EncodeableValue, err error) {
+ defer func() {
+ if state := recover(); state != nil {
+ err = log.Wrap(state.(error))
+ }
+ }()
+
+ // MakerNote
+ // TODO(dustin): !! This is the Wild Wild West. This very well might be a child IFD, but any and all OEM's define their own formats. If we're going to be writing changes and this is complete EXIF (which may not have the first eight bytes), it might be fine. However, if these are just IFDs they'll be relative to the main EXIF, this will invalidate the MakerNote data for IFDs and any other implementations that use offsets unless we can interpret them all. It be best to return to this later and just exclude this from being written for now, though means a loss of a wealth of image metadata.
+ // -> We can also just blindly try to interpret as an IFD and just validate that it's looks good (maybe it will even have a 'next ifd' pointer that we can validate is 0x0).
+
+ valueContext.SetUndefinedValueType(exifcommon.TypeByte)
+
+ valueBytes, err := valueContext.ReadBytes()
+ log.PanicIf(err)
+
+ // TODO(dustin): Doesn't work, but here as an example.
+ // ie := NewIfdEnumerate(valueBytes, byteOrder)
+
+ // // TODO(dustin): !! Validate types (might have proprietary types, but it might be worth splitting the list between valid and not valid; maybe fail if a certain proportion are invalid, or maybe aren't less then a certain small integer)?
+ // ii, err := ie.Collect(0x0)
+
+ // for _, entry := range ii.RootIfd.Entries {
+ // fmt.Printf("ENTRY: 0x%02x %d\n", entry.TagId, entry.TagType)
+ // }
+
+ var makerNoteType []byte
+ if len(valueBytes) >= 20 {
+ makerNoteType = valueBytes[:20]
+ } else {
+ makerNoteType = valueBytes
+ }
+
+ mn := Tag927CMakerNote{
+ MakerNoteType: makerNoteType,
+
+ // MakerNoteBytes has the whole length of bytes. There's always
+ // the chance that the first 20 bytes includes actual data.
+ MakerNoteBytes: valueBytes,
+ }
+
+ return mn, nil
+}
+
+func init() {
+ registerEncoder(
+ Tag927CMakerNote{},
+ Codec927CMakerNote{})
+
+ registerDecoder(
+ exifcommon.IfdExifStandardIfdIdentity.UnindexedString(),
+ 0x927c,
+ Codec927CMakerNote{})
+}
diff --git a/vendor/github.com/dsoprea/go-exif/v3/undefined/exif_9286_user_comment.go b/vendor/github.com/dsoprea/go-exif/v3/undefined/exif_9286_user_comment.go
new file mode 100644
index 000000000..320edc145
--- /dev/null
+++ b/vendor/github.com/dsoprea/go-exif/v3/undefined/exif_9286_user_comment.go
@@ -0,0 +1,142 @@
+package exifundefined
+
+import (
+ "bytes"
+ "fmt"
+
+ "encoding/binary"
+
+ "github.com/dsoprea/go-logging"
+
+ "github.com/dsoprea/go-exif/v3/common"
+)
+
+var (
+ exif9286Logger = log.NewLogger("exifundefined.exif_9286_user_comment")
+)
+
+const (
+ TagUndefinedType_9286_UserComment_Encoding_ASCII = iota
+ TagUndefinedType_9286_UserComment_Encoding_JIS = iota
+ TagUndefinedType_9286_UserComment_Encoding_UNICODE = iota
+ TagUndefinedType_9286_UserComment_Encoding_UNDEFINED = iota
+)
+
+var (
+ TagUndefinedType_9286_UserComment_Encoding_Names = map[int]string{
+ TagUndefinedType_9286_UserComment_Encoding_ASCII: "ASCII",
+ TagUndefinedType_9286_UserComment_Encoding_JIS: "JIS",
+ TagUndefinedType_9286_UserComment_Encoding_UNICODE: "UNICODE",
+ TagUndefinedType_9286_UserComment_Encoding_UNDEFINED: "UNDEFINED",
+ }
+
+ TagUndefinedType_9286_UserComment_Encodings = map[int][]byte{
+ TagUndefinedType_9286_UserComment_Encoding_ASCII: {'A', 'S', 'C', 'I', 'I', 0, 0, 0},
+ TagUndefinedType_9286_UserComment_Encoding_JIS: {'J', 'I', 'S', 0, 0, 0, 0, 0},
+ TagUndefinedType_9286_UserComment_Encoding_UNICODE: {'U', 'n', 'i', 'c', 'o', 'd', 'e', 0},
+ TagUndefinedType_9286_UserComment_Encoding_UNDEFINED: {0, 0, 0, 0, 0, 0, 0, 0},
+ }
+)
+
+type Tag9286UserComment struct {
+ EncodingType int
+ EncodingBytes []byte
+}
+
+func (Tag9286UserComment) EncoderName() string {
+ return "Codec9286UserComment"
+}
+
+func (uc Tag9286UserComment) String() string {
+ var valuePhrase string
+
+ if uc.EncodingType == TagUndefinedType_9286_UserComment_Encoding_ASCII {
+ return fmt.Sprintf("[ASCII] %s", string(uc.EncodingBytes))
+ } else {
+ if len(uc.EncodingBytes) <= 8 {
+ valuePhrase = fmt.Sprintf("%v", uc.EncodingBytes)
+ } else {
+ valuePhrase = fmt.Sprintf("%v...", uc.EncodingBytes[:8])
+ }
+ }
+
+ return fmt.Sprintf("UserComment<SIZE=(%d) ENCODING=[%s] V=%v LEN=(%d)>", len(uc.EncodingBytes), TagUndefinedType_9286_UserComment_Encoding_Names[uc.EncodingType], valuePhrase, len(uc.EncodingBytes))
+}
+
+type Codec9286UserComment struct {
+}
+
+func (Codec9286UserComment) Encode(value interface{}, byteOrder binary.ByteOrder) (encoded []byte, unitCount uint32, err error) {
+ defer func() {
+ if state := recover(); state != nil {
+ err = log.Wrap(state.(error))
+ }
+ }()
+
+ uc, ok := value.(Tag9286UserComment)
+ if ok == false {
+ log.Panicf("can only encode a Tag9286UserComment")
+ }
+
+ encodingTypeBytes, found := TagUndefinedType_9286_UserComment_Encodings[uc.EncodingType]
+ if found == false {
+ log.Panicf("encoding-type not valid for unknown-type tag 9286 (UserComment): (%d)", uc.EncodingType)
+ }
+
+ encoded = make([]byte, len(uc.EncodingBytes)+8)
+
+ copy(encoded[:8], encodingTypeBytes)
+ copy(encoded[8:], uc.EncodingBytes)
+
+ // TODO(dustin): Confirm this size against the specification.
+
+ return encoded, uint32(len(encoded)), nil
+}
+
+func (Codec9286UserComment) Decode(valueContext *exifcommon.ValueContext) (value EncodeableValue, err error) {
+ defer func() {
+ if state := recover(); state != nil {
+ err = log.Wrap(state.(error))
+ }
+ }()
+
+ valueContext.SetUndefinedValueType(exifcommon.TypeByte)
+
+ valueBytes, err := valueContext.ReadBytes()
+ log.PanicIf(err)
+
+ if len(valueBytes) < 8 {
+ return nil, ErrUnparseableValue
+ }
+
+ unknownUc := Tag9286UserComment{
+ EncodingType: TagUndefinedType_9286_UserComment_Encoding_UNDEFINED,
+ EncodingBytes: []byte{},
+ }
+
+ encoding := valueBytes[:8]
+ for encodingIndex, encodingBytes := range TagUndefinedType_9286_UserComment_Encodings {
+ if bytes.Compare(encoding, encodingBytes) == 0 {
+ uc := Tag9286UserComment{
+ EncodingType: encodingIndex,
+ EncodingBytes: valueBytes[8:],
+ }
+
+ return uc, nil
+ }
+ }
+
+ exif9286Logger.Warningf(nil, "User-comment encoding not valid. Returning 'unknown' type (the default).")
+ return unknownUc, nil
+}
+
+func init() {
+ registerEncoder(
+ Tag9286UserComment{},
+ Codec9286UserComment{})
+
+ registerDecoder(
+ exifcommon.IfdExifStandardIfdIdentity.UnindexedString(),
+ 0x9286,
+ Codec9286UserComment{})
+}
diff --git a/vendor/github.com/dsoprea/go-exif/v3/undefined/exif_A000_flashpix_version.go b/vendor/github.com/dsoprea/go-exif/v3/undefined/exif_A000_flashpix_version.go
new file mode 100644
index 000000000..4a0fefad7
--- /dev/null
+++ b/vendor/github.com/dsoprea/go-exif/v3/undefined/exif_A000_flashpix_version.go
@@ -0,0 +1,69 @@
+package exifundefined
+
+import (
+ "encoding/binary"
+
+ "github.com/dsoprea/go-logging"
+
+ "github.com/dsoprea/go-exif/v3/common"
+)
+
+type TagA000FlashpixVersion struct {
+ FlashpixVersion string
+}
+
+func (TagA000FlashpixVersion) EncoderName() string {
+ return "CodecA000FlashpixVersion"
+}
+
+func (fv TagA000FlashpixVersion) String() string {
+ return fv.FlashpixVersion
+}
+
+type CodecA000FlashpixVersion struct {
+}
+
+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.FlashpixVersion), uint32(len(s.FlashpixVersion)), nil
+}
+
+func (CodecA000FlashpixVersion) Decode(valueContext *exifcommon.ValueContext) (value EncodeableValue, err error) {
+ defer func() {
+ if state := recover(); state != nil {
+ err = log.Wrap(state.(error))
+ }
+ }()
+
+ valueContext.SetUndefinedValueType(exifcommon.TypeAsciiNoNul)
+
+ valueString, err := valueContext.ReadAsciiNoNul()
+ log.PanicIf(err)
+
+ fv := TagA000FlashpixVersion{
+ FlashpixVersion: valueString,
+ }
+
+ return fv, nil
+}
+
+func init() {
+ registerEncoder(
+ TagA000FlashpixVersion{},
+ CodecA000FlashpixVersion{})
+
+ registerDecoder(
+ exifcommon.IfdExifStandardIfdIdentity.UnindexedString(),
+ 0xa000,
+ CodecA000FlashpixVersion{})
+}
diff --git a/vendor/github.com/dsoprea/go-exif/v3/undefined/exif_A20C_spatial_frequency_response.go b/vendor/github.com/dsoprea/go-exif/v3/undefined/exif_A20C_spatial_frequency_response.go
new file mode 100644
index 000000000..0311175d6
--- /dev/null
+++ b/vendor/github.com/dsoprea/go-exif/v3/undefined/exif_A20C_spatial_frequency_response.go
@@ -0,0 +1,160 @@
+package exifundefined
+
+import (
+ "bytes"
+ "fmt"
+
+ "encoding/binary"
+
+ "github.com/dsoprea/go-logging"
+
+ "github.com/dsoprea/go-exif/v3/common"
+)
+
+type TagA20CSpatialFrequencyResponse struct {
+ Columns uint16
+ Rows uint16
+ ColumnNames []string
+ 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 {
+}
+
+func (CodecA20CSpatialFrequencyResponse) Encode(value interface{}, byteOrder binary.ByteOrder) (encoded []byte, unitCount uint32, err error) {
+ defer func() {
+ if state := recover(); state != nil {
+ err = log.Wrap(state.(error))
+ }
+ }()
+
+ // TODO(dustin): Add test.
+
+ sfr, ok := value.(TagA20CSpatialFrequencyResponse)
+ if ok == false {
+ log.Panicf("can only encode a TagA20CSpatialFrequencyResponse")
+ }
+
+ b := new(bytes.Buffer)
+
+ err = binary.Write(b, byteOrder, sfr.Columns)
+ log.PanicIf(err)
+
+ err = binary.Write(b, byteOrder, sfr.Rows)
+ log.PanicIf(err)
+
+ // Write columns.
+
+ for _, name := range sfr.ColumnNames {
+ _, err := b.WriteString(name)
+ log.PanicIf(err)
+
+ err = b.WriteByte(0)
+ log.PanicIf(err)
+ }
+
+ // Write values.
+
+ ve := exifcommon.NewValueEncoder(byteOrder)
+
+ ed, err := ve.Encode(sfr.Values)
+ log.PanicIf(err)
+
+ _, err = b.Write(ed.Encoded)
+ log.PanicIf(err)
+
+ encoded = b.Bytes()
+
+ // TODO(dustin): Confirm this size against the specification.
+
+ return encoded, uint32(len(encoded)), nil
+}
+
+func (CodecA20CSpatialFrequencyResponse) Decode(valueContext *exifcommon.ValueContext) (value EncodeableValue, err error) {
+ defer func() {
+ if state := recover(); state != nil {
+ err = log.Wrap(state.(error))
+ }
+ }()
+
+ // TODO(dustin): Add test using known good data.
+
+ byteOrder := valueContext.ByteOrder()
+
+ valueContext.SetUndefinedValueType(exifcommon.TypeByte)
+
+ valueBytes, err := valueContext.ReadBytes()
+ log.PanicIf(err)
+
+ sfr := TagA20CSpatialFrequencyResponse{}
+
+ sfr.Columns = byteOrder.Uint16(valueBytes[0:2])
+ sfr.Rows = byteOrder.Uint16(valueBytes[2:4])
+
+ columnNames := make([]string, sfr.Columns)
+
+ // startAt is where the current column name starts.
+ startAt := 4
+
+ // offset is our current position.
+ offset := 4
+
+ currentColumnNumber := uint16(0)
+
+ for currentColumnNumber < sfr.Columns {
+ if valueBytes[offset] == 0 {
+ columnName := string(valueBytes[startAt:offset])
+ if len(columnName) == 0 {
+ log.Panicf("SFR column (%d) has zero length", currentColumnNumber)
+ }
+
+ columnNames[currentColumnNumber] = columnName
+ currentColumnNumber++
+
+ offset++
+ startAt = offset
+ continue
+ }
+
+ offset++
+ }
+
+ sfr.ColumnNames = columnNames
+
+ rawRationalBytes := valueBytes[offset:]
+
+ rationalSize := exifcommon.TypeRational.Size()
+ if len(rawRationalBytes)%rationalSize > 0 {
+ log.Panicf("SFR rationals not aligned: (%d) %% (%d) > 0", len(rawRationalBytes), rationalSize)
+ }
+
+ rationalCount := len(rawRationalBytes) / rationalSize
+
+ parser := new(exifcommon.Parser)
+
+ items, err := parser.ParseRationals(rawRationalBytes, uint32(rationalCount), byteOrder)
+ log.PanicIf(err)
+
+ sfr.Values = items
+
+ return sfr, nil
+}
+
+func init() {
+ registerEncoder(
+ TagA20CSpatialFrequencyResponse{},
+ CodecA20CSpatialFrequencyResponse{})
+
+ registerDecoder(
+ exifcommon.IfdExifStandardIfdIdentity.UnindexedString(),
+ 0xa20c,
+ CodecA20CSpatialFrequencyResponse{})
+}
diff --git a/vendor/github.com/dsoprea/go-exif/v3/undefined/exif_A300_file_source.go b/vendor/github.com/dsoprea/go-exif/v3/undefined/exif_A300_file_source.go
new file mode 100644
index 000000000..f4f3a49f9
--- /dev/null
+++ b/vendor/github.com/dsoprea/go-exif/v3/undefined/exif_A300_file_source.go
@@ -0,0 +1,79 @@
+package exifundefined
+
+import (
+ "fmt"
+
+ "encoding/binary"
+
+ "github.com/dsoprea/go-logging"
+
+ "github.com/dsoprea/go-exif/v3/common"
+)
+
+type TagExifA300FileSource uint32
+
+func (TagExifA300FileSource) EncoderName() string {
+ return "CodecExifA300FileSource"
+}
+
+func (af TagExifA300FileSource) String() string {
+ return fmt.Sprintf("0x%08x", uint32(af))
+}
+
+const (
+ TagUndefinedType_A300_SceneType_Others TagExifA300FileSource = 0
+ TagUndefinedType_A300_SceneType_ScannerOfTransparentType TagExifA300FileSource = 1
+ TagUndefinedType_A300_SceneType_ScannerOfReflexType TagExifA300FileSource = 2
+ TagUndefinedType_A300_SceneType_Dsc TagExifA300FileSource = 3
+)
+
+type CodecExifA300FileSource struct {
+}
+
+func (CodecExifA300FileSource) Encode(value interface{}, byteOrder binary.ByteOrder) (encoded []byte, unitCount uint32, err error) {
+ defer func() {
+ if state := recover(); state != nil {
+ err = log.Wrap(state.(error))
+ }
+ }()
+
+ st, ok := value.(TagExifA300FileSource)
+ if ok == false {
+ log.Panicf("can only encode a TagExifA300FileSource")
+ }
+
+ ve := exifcommon.NewValueEncoder(byteOrder)
+
+ ed, err := ve.Encode([]uint32{uint32(st)})
+ log.PanicIf(err)
+
+ // TODO(dustin): Confirm this size against the specification. It's non-specific about what type it is, but it looks to be no more than a single integer scalar. So, we're assuming it's a LONG.
+
+ return ed.Encoded, 1, nil
+}
+
+func (CodecExifA300FileSource) Decode(valueContext *exifcommon.ValueContext) (value EncodeableValue, err error) {
+ defer func() {
+ if state := recover(); state != nil {
+ err = log.Wrap(state.(error))
+ }
+ }()
+
+ valueContext.SetUndefinedValueType(exifcommon.TypeLong)
+
+ valueLongs, err := valueContext.ReadLongs()
+ log.PanicIf(err)
+
+ return TagExifA300FileSource(valueLongs[0]), nil
+}
+
+func init() {
+ registerEncoder(
+ TagExifA300FileSource(0),
+ CodecExifA300FileSource{})
+
+ registerDecoder(
+ exifcommon.IfdExifStandardIfdIdentity.UnindexedString(),
+ 0xa300,
+ CodecExifA300FileSource{})
+}
diff --git a/vendor/github.com/dsoprea/go-exif/v3/undefined/exif_A301_scene_type.go b/vendor/github.com/dsoprea/go-exif/v3/undefined/exif_A301_scene_type.go
new file mode 100644
index 000000000..a29fd7673
--- /dev/null
+++ b/vendor/github.com/dsoprea/go-exif/v3/undefined/exif_A301_scene_type.go
@@ -0,0 +1,76 @@
+package exifundefined
+
+import (
+ "fmt"
+
+ "encoding/binary"
+
+ "github.com/dsoprea/go-logging"
+
+ "github.com/dsoprea/go-exif/v3/common"
+)
+
+type TagExifA301SceneType uint32
+
+func (TagExifA301SceneType) EncoderName() string {
+ return "CodecExifA301SceneType"
+}
+
+func (st TagExifA301SceneType) String() string {
+ return fmt.Sprintf("0x%08x", uint32(st))
+}
+
+const (
+ TagUndefinedType_A301_SceneType_DirectlyPhotographedImage TagExifA301SceneType = 1
+)
+
+type CodecExifA301SceneType struct {
+}
+
+func (CodecExifA301SceneType) Encode(value interface{}, byteOrder binary.ByteOrder) (encoded []byte, unitCount uint32, err error) {
+ defer func() {
+ if state := recover(); state != nil {
+ err = log.Wrap(state.(error))
+ }
+ }()
+
+ st, ok := value.(TagExifA301SceneType)
+ if ok == false {
+ log.Panicf("can only encode a TagExif9101ComponentsConfiguration")
+ }
+
+ ve := exifcommon.NewValueEncoder(byteOrder)
+
+ ed, err := ve.Encode([]uint32{uint32(st)})
+ log.PanicIf(err)
+
+ // TODO(dustin): Confirm this size against the specification. It's non-specific about what type it is, but it looks to be no more than a single integer scalar. So, we're assuming it's a LONG.
+
+ return ed.Encoded, uint32(int(ed.UnitCount)), nil
+}
+
+func (CodecExifA301SceneType) Decode(valueContext *exifcommon.ValueContext) (value EncodeableValue, err error) {
+ defer func() {
+ if state := recover(); state != nil {
+ err = log.Wrap(state.(error))
+ }
+ }()
+
+ valueContext.SetUndefinedValueType(exifcommon.TypeLong)
+
+ valueLongs, err := valueContext.ReadLongs()
+ log.PanicIf(err)
+
+ return TagExifA301SceneType(valueLongs[0]), nil
+}
+
+func init() {
+ registerEncoder(
+ TagExifA301SceneType(0),
+ CodecExifA301SceneType{})
+
+ registerDecoder(
+ exifcommon.IfdExifStandardIfdIdentity.UnindexedString(),
+ 0xa301,
+ CodecExifA301SceneType{})
+}
diff --git a/vendor/github.com/dsoprea/go-exif/v3/undefined/exif_A302_cfa_pattern.go b/vendor/github.com/dsoprea/go-exif/v3/undefined/exif_A302_cfa_pattern.go
new file mode 100644
index 000000000..88976296d
--- /dev/null
+++ b/vendor/github.com/dsoprea/go-exif/v3/undefined/exif_A302_cfa_pattern.go
@@ -0,0 +1,97 @@
+package exifundefined
+
+import (
+ "bytes"
+ "fmt"
+
+ "encoding/binary"
+
+ "github.com/dsoprea/go-logging"
+
+ "github.com/dsoprea/go-exif/v3/common"
+)
+
+type TagA302CfaPattern struct {
+ HorizontalRepeat uint16
+ VerticalRepeat uint16
+ CfaValue []byte
+}
+
+func (TagA302CfaPattern) EncoderName() string {
+ return "CodecA302CfaPattern"
+}
+
+func (cp TagA302CfaPattern) String() string {
+ return fmt.Sprintf("TagA302CfaPattern<HORZ-REPEAT=(%d) VERT-REPEAT=(%d) CFA-VALUE=(%d)>", cp.HorizontalRepeat, cp.VerticalRepeat, len(cp.CfaValue))
+}
+
+type CodecA302CfaPattern struct {
+}
+
+func (CodecA302CfaPattern) Encode(value interface{}, byteOrder binary.ByteOrder) (encoded []byte, unitCount uint32, err error) {
+ defer func() {
+ if state := recover(); state != nil {
+ err = log.Wrap(state.(error))
+ }
+ }()
+
+ // TODO(dustin): Add test.
+
+ cp, ok := value.(TagA302CfaPattern)
+ if ok == false {
+ log.Panicf("can only encode a TagA302CfaPattern")
+ }
+
+ b := new(bytes.Buffer)
+
+ err = binary.Write(b, byteOrder, cp.HorizontalRepeat)
+ log.PanicIf(err)
+
+ err = binary.Write(b, byteOrder, cp.VerticalRepeat)
+ log.PanicIf(err)
+
+ _, err = b.Write(cp.CfaValue)
+ log.PanicIf(err)
+
+ encoded = b.Bytes()
+
+ // TODO(dustin): Confirm this size against the specification.
+
+ return encoded, uint32(len(encoded)), nil
+}
+
+func (CodecA302CfaPattern) Decode(valueContext *exifcommon.ValueContext) (value EncodeableValue, err error) {
+ defer func() {
+ if state := recover(); state != nil {
+ err = log.Wrap(state.(error))
+ }
+ }()
+
+ // TODO(dustin): Add test using known good data.
+
+ valueContext.SetUndefinedValueType(exifcommon.TypeByte)
+
+ valueBytes, err := valueContext.ReadBytes()
+ log.PanicIf(err)
+
+ cp := TagA302CfaPattern{}
+
+ cp.HorizontalRepeat = valueContext.ByteOrder().Uint16(valueBytes[0:2])
+ cp.VerticalRepeat = valueContext.ByteOrder().Uint16(valueBytes[2:4])
+
+ expectedLength := int(cp.HorizontalRepeat * cp.VerticalRepeat)
+ cp.CfaValue = valueBytes[4 : 4+expectedLength]
+
+ return cp, nil
+}
+
+func init() {
+ registerEncoder(
+ TagA302CfaPattern{},
+ CodecA302CfaPattern{})
+
+ registerDecoder(
+ exifcommon.IfdExifStandardIfdIdentity.UnindexedString(),
+ 0xa302,
+ CodecA302CfaPattern{})
+}
diff --git a/vendor/github.com/dsoprea/go-exif/v3/undefined/exif_iop_0002_interop_version.go b/vendor/github.com/dsoprea/go-exif/v3/undefined/exif_iop_0002_interop_version.go
new file mode 100644
index 000000000..09ec98703
--- /dev/null
+++ b/vendor/github.com/dsoprea/go-exif/v3/undefined/exif_iop_0002_interop_version.go
@@ -0,0 +1,69 @@
+package exifundefined
+
+import (
+ "encoding/binary"
+
+ "github.com/dsoprea/go-logging"
+
+ "github.com/dsoprea/go-exif/v3/common"
+)
+
+type Tag0002InteropVersion struct {
+ InteropVersion string
+}
+
+func (Tag0002InteropVersion) EncoderName() string {
+ return "Codec0002InteropVersion"
+}
+
+func (iv Tag0002InteropVersion) String() string {
+ return iv.InteropVersion
+}
+
+type Codec0002InteropVersion struct {
+}
+
+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.InteropVersion), uint32(len(s.InteropVersion)), nil
+}
+
+func (Codec0002InteropVersion) Decode(valueContext *exifcommon.ValueContext) (value EncodeableValue, err error) {
+ defer func() {
+ if state := recover(); state != nil {
+ err = log.Wrap(state.(error))
+ }
+ }()
+
+ valueContext.SetUndefinedValueType(exifcommon.TypeAsciiNoNul)
+
+ valueString, err := valueContext.ReadAsciiNoNul()
+ log.PanicIf(err)
+
+ iv := Tag0002InteropVersion{
+ InteropVersion: valueString,
+ }
+
+ return iv, nil
+}
+
+func init() {
+ registerEncoder(
+ Tag0002InteropVersion{},
+ Codec0002InteropVersion{})
+
+ registerDecoder(
+ exifcommon.IfdExifIopStandardIfdIdentity.UnindexedString(),
+ 0x0002,
+ Codec0002InteropVersion{})
+}
diff --git a/vendor/github.com/dsoprea/go-exif/v3/undefined/gps_001B_gps_processing_method.go b/vendor/github.com/dsoprea/go-exif/v3/undefined/gps_001B_gps_processing_method.go
new file mode 100644
index 000000000..6f54d2fc6
--- /dev/null
+++ b/vendor/github.com/dsoprea/go-exif/v3/undefined/gps_001B_gps_processing_method.go
@@ -0,0 +1,65 @@
+package exifundefined
+
+import (
+ "encoding/binary"
+
+ "github.com/dsoprea/go-logging"
+
+ "github.com/dsoprea/go-exif/v3/common"
+)
+
+type Tag001BGPSProcessingMethod struct {
+ string
+}
+
+func (Tag001BGPSProcessingMethod) EncoderName() string {
+ return "Codec001BGPSProcessingMethod"
+}
+
+func (gpm Tag001BGPSProcessingMethod) String() string {
+ return gpm.string
+}
+
+type Codec001BGPSProcessingMethod struct {
+}
+
+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))
+ }
+ }()
+
+ valueContext.SetUndefinedValueType(exifcommon.TypeAsciiNoNul)
+
+ valueString, err := valueContext.ReadAsciiNoNul()
+ log.PanicIf(err)
+
+ return Tag001BGPSProcessingMethod{valueString}, nil
+}
+
+func init() {
+ registerEncoder(
+ Tag001BGPSProcessingMethod{},
+ Codec001BGPSProcessingMethod{})
+
+ registerDecoder(
+ exifcommon.IfdGpsInfoStandardIfdIdentity.UnindexedString(),
+ 0x001b,
+ Codec001BGPSProcessingMethod{})
+}
diff --git a/vendor/github.com/dsoprea/go-exif/v3/undefined/gps_001C_gps_area_information.go b/vendor/github.com/dsoprea/go-exif/v3/undefined/gps_001C_gps_area_information.go
new file mode 100644
index 000000000..ffdeb905b
--- /dev/null
+++ b/vendor/github.com/dsoprea/go-exif/v3/undefined/gps_001C_gps_area_information.go
@@ -0,0 +1,65 @@
+package exifundefined
+
+import (
+ "encoding/binary"
+
+ "github.com/dsoprea/go-logging"
+
+ "github.com/dsoprea/go-exif/v3/common"
+)
+
+type Tag001CGPSAreaInformation struct {
+ string
+}
+
+func (Tag001CGPSAreaInformation) EncoderName() string {
+ return "Codec001CGPSAreaInformation"
+}
+
+func (gai Tag001CGPSAreaInformation) String() string {
+ return gai.string
+}
+
+type Codec001CGPSAreaInformation struct {
+}
+
+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))
+ }
+ }()
+
+ valueContext.SetUndefinedValueType(exifcommon.TypeAsciiNoNul)
+
+ valueString, err := valueContext.ReadAsciiNoNul()
+ log.PanicIf(err)
+
+ return Tag001CGPSAreaInformation{valueString}, nil
+}
+
+func init() {
+ registerEncoder(
+ Tag001CGPSAreaInformation{},
+ Codec001CGPSAreaInformation{})
+
+ registerDecoder(
+ exifcommon.IfdGpsInfoStandardIfdIdentity.UnindexedString(),
+ 0x001c,
+ Codec001CGPSAreaInformation{})
+}
diff --git a/vendor/github.com/dsoprea/go-exif/v3/undefined/registration.go b/vendor/github.com/dsoprea/go-exif/v3/undefined/registration.go
new file mode 100644
index 000000000..cccc20a82
--- /dev/null
+++ b/vendor/github.com/dsoprea/go-exif/v3/undefined/registration.go
@@ -0,0 +1,42 @@
+package exifundefined
+
+import (
+ "github.com/dsoprea/go-logging"
+)
+
+// UndefinedTagHandle defines one undefined-type tag with a corresponding
+// decoder.
+type UndefinedTagHandle struct {
+ IfdPath string
+ TagId uint16
+}
+
+func registerEncoder(entity EncodeableValue, encoder UndefinedValueEncoder) {
+ typeName := entity.EncoderName()
+
+ _, found := encoders[typeName]
+ if found == true {
+ log.Panicf("encoder already registered: %v", typeName)
+ }
+
+ encoders[typeName] = encoder
+}
+
+func registerDecoder(ifdPath string, tagId uint16, decoder UndefinedValueDecoder) {
+ uth := UndefinedTagHandle{
+ IfdPath: ifdPath,
+ TagId: tagId,
+ }
+
+ _, found := decoders[uth]
+ if found == true {
+ log.Panicf("decoder already registered: %v", uth)
+ }
+
+ decoders[uth] = decoder
+}
+
+var (
+ encoders = make(map[string]UndefinedValueEncoder)
+ decoders = make(map[UndefinedTagHandle]UndefinedValueDecoder)
+)
diff --git a/vendor/github.com/dsoprea/go-exif/v3/undefined/type.go b/vendor/github.com/dsoprea/go-exif/v3/undefined/type.go
new file mode 100644
index 000000000..ff6ac2b4c
--- /dev/null
+++ b/vendor/github.com/dsoprea/go-exif/v3/undefined/type.go
@@ -0,0 +1,44 @@
+package exifundefined
+
+import (
+ "errors"
+
+ "encoding/binary"
+
+ "github.com/dsoprea/go-exif/v3/common"
+)
+
+const (
+ // UnparseableUnknownTagValuePlaceholder is the string to use for an unknown
+ // undefined tag.
+ UnparseableUnknownTagValuePlaceholder = "!UNKNOWN"
+
+ // UnparseableHandledTagValuePlaceholder is the string to use for a known
+ // value that is not parseable.
+ UnparseableHandledTagValuePlaceholder = "!MALFORMED"
+)
+
+var (
+ // ErrUnparseableValue is the error for a value that we should have been
+ // able to parse but were not able to.
+ ErrUnparseableValue = errors.New("unparseable undefined tag")
+)
+
+// UndefinedValueEncoder knows how to encode an undefined-type tag's value to
+// bytes.
+type UndefinedValueEncoder interface {
+ Encode(value interface{}, byteOrder binary.ByteOrder) (encoded []byte, unitCount uint32, err error)
+}
+
+// EncodeableValue wraps a value with the information that will be needed to re-
+// encode it later.
+type EncodeableValue interface {
+ EncoderName() string
+ String() string
+}
+
+// UndefinedValueDecoder knows how to decode an undefined-type tag's value from
+// bytes.
+type UndefinedValueDecoder interface {
+ Decode(valueContext *exifcommon.ValueContext) (value EncodeableValue, err error)
+}