-
Notifications
You must be signed in to change notification settings - Fork 73
Add codec for tag 0xC4A5 PrintImageMatching #81
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,11 +1,17 @@ | ||
| github.com/dsoprea/go-exif/v2 v2.0.0-20200321225314-640175a69fe4/go.mod h1:Lm2lMM2zx8p4a34ZemkaUV95AnMl4ZvLbCUbwOvLC2E= | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do not include module changes. |
||
| 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= | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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<VERSION=(%s) BYTES=(%v)>", 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 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The documentation describes how to find an entry count and the list of entries. We can parse things better than just yielding an opaque byte slice, yes? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I could not find any decent documentation on PrintIM. It is not specified in the exif 2.2 spec. The only thing I found was the link I posted above and it does not agree with my images. My images have a 106 byte PrintIM. According to the spec this would mean Header: 8 This works out if there are 15 entries. However here is the actual PrintIM bytes of one of my photos: Bytes 15-16 are Let's say we ignore the count and treat the remaining bytes as 6 byte entries. Here is what we get: and so on. If the first 2 bytes of each entry would designate its tag id we have 2 tag ids of That's why I gave up and decided I would rather keep the tag opaque rather than parse it incorrectly. |
||
|
|
||
| if !bytes.Equal(rawBytes[0:8], PrintImageMatchingHeader[:]) { | ||
| log.Panicf("invalid header for tag 0xC4A5 PrintImageMatching") | ||
| } | ||
|
|
||
| versionLen := bytes.IndexByte(rawBytes[8:], 0) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Validate that |
||
| ev.Version = string(rawBytes[8 : 8+versionLen]) | ||
|
|
||
| return ev, nil | ||
| } | ||
|
|
||
| func init() { | ||
| registerEncoder( | ||
| TagC4A5PrintImageMatching{}, | ||
| CodecC4A5PrintImageMatching{}) | ||
|
|
||
| registerDecoder( | ||
| exifcommon.IfdStandardIfdIdentity.UnindexedString(), | ||
| 0xc4a5, | ||
| CodecC4A5PrintImageMatching{}) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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<VERSION=(0300) BYTES=([1 2 3 4])>" { | ||
| 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) | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do not include module changes.