From e7f5402b24ecd9cf0d3b3930537bd600bf038645 Mon Sep 17 00:00:00 2001 From: Georgi Sabev Date: Thu, 17 Aug 2023 19:55:05 +0300 Subject: [PATCH] Add codec for tag 0xC4A5 PrintImageMatching As the information about this tag is pretty obscure in the internet the codec is fairly basic, just checking the header, parsing the version and keeping the raw bytes. --- v3/go.mod | 3 - v3/go.sum | 6 ++ .../exif_C4A5_print_image_matching.go | 81 ++++++++++++++++++ .../exif_C4A5_print_image_matching_test.go | 83 +++++++++++++++++++ 4 files changed, 170 insertions(+), 3 deletions(-) create mode 100644 v3/undefined/exif_C4A5_print_image_matching.go create mode 100644 v3/undefined/exif_C4A5_print_image_matching_test.go diff --git a/v3/go.mod b/v3/go.mod index e5a18f0..43d94b6 100644 --- a/v3/go.mod +++ b/v3/go.mod @@ -9,10 +9,7 @@ go 1.12 require ( github.com/dsoprea/go-logging v0.0.0-20200710184922-b02d349568dd github.com/dsoprea/go-utility/v2 v2.0.0-20221003172846-a3e1774ef349 - github.com/go-errors/errors v1.4.2 // indirect github.com/golang/geo v0.0.0-20210211234256-740aa86cb551 github.com/jessevdk/go-flags v1.5.0 - golang.org/x/net v0.0.0-20221002022538-bcab6841153b // indirect - golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec // indirect gopkg.in/yaml.v2 v2.4.0 ) diff --git a/v3/go.sum b/v3/go.sum index f69540e..4791437 100644 --- a/v3/go.sum +++ b/v3/go.sum @@ -1,11 +1,17 @@ github.com/dsoprea/go-exif/v2 v2.0.0-20200321225314-640175a69fe4/go.mod h1:Lm2lMM2zx8p4a34ZemkaUV95AnMl4ZvLbCUbwOvLC2E= github.com/dsoprea/go-exif/v3 v3.0.0-20200717053412-08f1b6708903/go.mod h1:0nsO1ce0mh5czxGeLo4+OCZ/C6Eo6ZlMWsz7rH/Gxv8= +github.com/dsoprea/go-exif/v3 v3.0.0-20210625224831-a6301f85c82b/go.mod h1:cg5SNYKHMmzxsr9X6ZeLh/nfBRHHp5PngtEPcujONtk= +github.com/dsoprea/go-exif/v3 v3.0.0-20221003160559-cf5cd88aa559/go.mod h1:rW6DMEv25U9zCtE5ukC7ttBRllXj7g7TAHl7tQrT5No= +github.com/dsoprea/go-exif/v3 v3.0.0-20221003171958-de6cb6e380a8/go.mod h1:akyZEJZ/k5bmbC9gA612ZLQkcED8enS9vuTiuAkENr0= github.com/dsoprea/go-logging v0.0.0-20190624164917-c4f10aab7696/go.mod h1:Nm/x2ZUNRW6Fe5C3LxdY1PyZY5wmDv/s5dkPJ/VB3iA= github.com/dsoprea/go-logging v0.0.0-20200517223158-a10564966e9d/go.mod h1:7I+3Pe2o/YSU88W0hWlm9S22W7XI1JFNJ86U0zPKMf8= github.com/dsoprea/go-logging v0.0.0-20200710184922-b02d349568dd h1:l+vLbuxptsC6VQyQsfD7NnEC8BZuFpz45PgY+pH8YTg= github.com/dsoprea/go-logging v0.0.0-20200710184922-b02d349568dd/go.mod h1:7I+3Pe2o/YSU88W0hWlm9S22W7XI1JFNJ86U0zPKMf8= github.com/dsoprea/go-utility v0.0.0-20200711062821-fab8125e9bdf h1:/w4QxepU4AHh3AuO6/g8y/YIIHH5+aKP3Bj8sg5cqhU= github.com/dsoprea/go-utility v0.0.0-20200711062821-fab8125e9bdf/go.mod h1:95+K3z2L0mqsVYd6yveIv1lmtT3tcQQ3dVakPySffW8= +github.com/dsoprea/go-utility/v2 v2.0.0-20200717064901-2fccff4aa15e/go.mod h1:uAzdkPTub5Y9yQwXe8W4m2XuP0tK4a9Q/dantD0+uaU= +github.com/dsoprea/go-utility/v2 v2.0.0-20221003142440-7a1927d49d9d/go.mod h1:LVjRU0RNUuMDqkPTxcALio0LWPFPXxxFCvVGVAwEpFc= +github.com/dsoprea/go-utility/v2 v2.0.0-20221003160719-7bc88537c05e/go.mod h1:VZ7cB0pTjm1ADBWhJUOHESu4ZYy9JN+ZPqjfiW09EPU= github.com/dsoprea/go-utility/v2 v2.0.0-20221003172846-a3e1774ef349 h1:DilThiXje0z+3UQ5YjYiSRRzVdtamFpvBQXKwMglWqw= github.com/dsoprea/go-utility/v2 v2.0.0-20221003172846-a3e1774ef349/go.mod h1:4GC5sXji84i/p+irqghpPFZBF8tRN/Q7+700G0/DLe8= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= diff --git a/v3/undefined/exif_C4A5_print_image_matching.go b/v3/undefined/exif_C4A5_print_image_matching.go new file mode 100644 index 0000000..ee8dc46 --- /dev/null +++ b/v3/undefined/exif_C4A5_print_image_matching.go @@ -0,0 +1,81 @@ +package exifundefined + +import ( + "bytes" + "encoding/binary" + "fmt" + + log "github.com/dsoprea/go-logging" + + exifcommon "github.com/dsoprea/go-exif/v3/common" +) + +var PrintImageMatchingHeader = []byte{0x50, 0x72, 0x69, 0x6e, 0x74, 0x49, 0x4d, 0x00} + +type TagC4A5PrintImageMatching struct { + Version string + Value []byte +} + +func (TagC4A5PrintImageMatching) EncoderName() string { + return "CodecC4A5PrintImageMatching" +} + +func (ev TagC4A5PrintImageMatching) String() string { + return fmt.Sprintf("TagC4A5PrintImageMatching", ev.Version, ev.Value) +} + +type CodecC4A5PrintImageMatching struct{} + +func (CodecC4A5PrintImageMatching) Encode(value interface{}, byteOrder binary.ByteOrder) (encoded []byte, unitCount uint32, err error) { + defer func() { + if state := recover(); state != nil { + err = log.Wrap(state.(error)) + } + }() + + pim, ok := value.(TagC4A5PrintImageMatching) + if !ok { + log.Panicf("can only encode a TagC4A5PrintImageMatching") + } + + return pim.Value, uint32(len(pim.Value)), nil +} + +func (CodecC4A5PrintImageMatching) Decode(valueContext *exifcommon.ValueContext) (value EncodeableValue, err error) { + // PIM structure explanation: https://www.ozhiker.com/electronics/pjmt/jpeg_info/pim.html Looks like + // there is no sufficient open documentation about this tag: + // https://github.com/Exiv2/exiv2/issues/1419#issuecomment-739723214 + // For that reason we are just preserving its raw bytes + defer func() { + if state := recover(); state != nil { + err = log.Wrap(state.(error)) + } + }() + + ev := TagC4A5PrintImageMatching{} + + valueContext.SetUndefinedValueType(exifcommon.TypeByte) + rawBytes, err := valueContext.ReadBytes() + ev.Value = rawBytes + + if !bytes.Equal(rawBytes[0:8], PrintImageMatchingHeader[:]) { + log.Panicf("invalid header for tag 0xC4A5 PrintImageMatching") + } + + versionLen := bytes.IndexByte(rawBytes[8:], 0) + ev.Version = string(rawBytes[8 : 8+versionLen]) + + return ev, nil +} + +func init() { + registerEncoder( + TagC4A5PrintImageMatching{}, + CodecC4A5PrintImageMatching{}) + + registerDecoder( + exifcommon.IfdStandardIfdIdentity.UnindexedString(), + 0xc4a5, + CodecC4A5PrintImageMatching{}) +} diff --git a/v3/undefined/exif_C4A5_print_image_matching_test.go b/v3/undefined/exif_C4A5_print_image_matching_test.go new file mode 100644 index 0000000..455b89b --- /dev/null +++ b/v3/undefined/exif_C4A5_print_image_matching_test.go @@ -0,0 +1,83 @@ +package exifundefined + +import ( + "bytes" + "reflect" + "testing" + + log "github.com/dsoprea/go-logging" + rifs "github.com/dsoprea/go-utility/v2/filesystem" + + exifcommon "github.com/dsoprea/go-exif/v3/common" +) + +func TestTagC4A5PrintImageMatching_String(t *testing.T) { + ut := TagC4A5PrintImageMatching{ + Version: "0300", + Value: []byte{0x01, 0x02, 0x03, 0x04}, + } + + s := ut.String() + + if s != "TagC4A5PrintImageMatching" { + t.Fatalf("String not correct: [%s]", s) + } +} + +func TestCodecC4A5PrintImageMatching_Encode(t *testing.T) { + rawBytes := []byte{ + 0x50, 0x72, 0x69, 0x6e, 0x74, 0x49, 0x4d, 0x00, + 0x30, 0x33, 0x30, 0x30, 0x00, + 0x01, 0x02, 0x03, 0x04, + } + + ut := TagC4A5PrintImageMatching{ + Version: "0300", + Value: rawBytes, + } + + codec := CodecC4A5PrintImageMatching{} + + encoded, unitCount, err := codec.Encode(ut, exifcommon.TestDefaultByteOrder) + log.PanicIf(err) + + if bytes.Equal(encoded, rawBytes) != true { + exifcommon.DumpBytesClause(encoded) + + t.Fatalf("Encoded bytes not correct.") + } else if unitCount != 17 { + t.Fatalf("Unit-count not correct: (%d)", unitCount) + } +} + +func TestCodecC4A5PrintImageMatching_Decode(t *testing.T) { + rawBytes := []byte{ + 0x50, 0x72, 0x69, 0x6e, 0x74, 0x49, 0x4d, 0x00, + 0x30, 0x33, 0x30, 0x30, 0x00, + 0x01, 0x02, 0x03, 0x04, + } + + valueContext := exifcommon.NewValueContext( + "", + 0, + uint32(len(rawBytes)), + 0, + nil, + rifs.NewSeekableBufferWithBytes(rawBytes), + exifcommon.TypeUndefined, + exifcommon.TestDefaultByteOrder) + + codec := CodecC4A5PrintImageMatching{} + + value, err := codec.Decode(valueContext) + log.PanicIf(err) + + expectedValue := TagC4A5PrintImageMatching{ + Version: "0300", + Value: rawBytes, + } + + if reflect.DeepEqual(value, expectedValue) != true { + t.Fatalf("Decoded value not correct: %s", value) + } +}