mirror of
https://github.com/hanzoai/goexif.git
synced 2026-09-30 22:36:24 +00:00
250 lines
7.8 KiB
Go
250 lines
7.8 KiB
Go
package tiff
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/binary"
|
|
"encoding/hex"
|
|
"flag"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
)
|
|
|
|
var dataDir = flag.String("test_data_dir", ".", "Directory where the data files for testing are located")
|
|
|
|
type input struct {
|
|
tgId string
|
|
tpe string
|
|
nVals string
|
|
offset string
|
|
val string
|
|
}
|
|
|
|
type output struct {
|
|
id uint16
|
|
typ DataType
|
|
count uint32
|
|
val []byte
|
|
}
|
|
|
|
type tagTest struct {
|
|
big input // big endian
|
|
little input // little endian
|
|
out output
|
|
}
|
|
|
|
///////////////////////////////////////////////
|
|
//// Big endian Tests /////////////////////////
|
|
///////////////////////////////////////////////
|
|
var set1 = []tagTest{
|
|
//////////// string type //////////////
|
|
tagTest{
|
|
// {"TgId", "TYPE", "N-VALUES", "OFFSET--", "VAL..."},
|
|
input{"0003", "0002", "00000002", "11000000", ""},
|
|
input{"0300", "0200", "02000000", "11000000", ""},
|
|
output{0x0003, DataType(0x0002), 0x0002, []byte{0x11, 0x00}},
|
|
},
|
|
tagTest{
|
|
input{"0001", "0002", "00000006", "00000012", "111213141516"},
|
|
input{"0100", "0200", "06000000", "12000000", "111213141516"},
|
|
output{0x0001, DataType(0x0002), 0x0006, []byte{0x11, 0x12, 0x13, 0x14, 0x15, 0x16}},
|
|
},
|
|
// broken Count, because it includes all trailing NULL bytes, as is the case in
|
|
// https://user-images.githubusercontent.com/2621/39392188-71a66fc4-4a66-11e8-9e3b-694163efa643.jpg
|
|
tagTest{
|
|
input{"0001", "0002", "00000009", "00000012", "111213141516000000"},
|
|
input{"0100", "0200", "09000000", "12000000", "111213141516000000"},
|
|
output{0x0001, DataType(0x0002), 0x0009, []byte{0x11, 0x12, 0x13, 0x14, 0x15, 0x16}},
|
|
},
|
|
//////////// int (1-byte) type ////////////////
|
|
tagTest{
|
|
input{"0001", "0001", "00000001", "11000000", ""},
|
|
input{"0100", "0100", "01000000", "11000000", ""},
|
|
output{0x0001, DataType(0x0001), 0x0001, []byte{0x11}},
|
|
},
|
|
tagTest{
|
|
input{"0001", "0001", "00000005", "00000010", "1112131415"},
|
|
input{"0100", "0100", "05000000", "10000000", "1112131415"},
|
|
output{0x0001, DataType(0x0001), 0x0005, []byte{0x11, 0x12, 0x13, 0x14, 0x15}},
|
|
},
|
|
tagTest{
|
|
input{"0001", "0006", "00000001", "11000000", ""},
|
|
input{"0100", "0600", "01000000", "11000000", ""},
|
|
output{0x0001, DataType(0x0006), 0x0001, []byte{0x11}},
|
|
},
|
|
tagTest{
|
|
input{"0001", "0006", "00000005", "00000010", "1112131415"},
|
|
input{"0100", "0600", "05000000", "10000000", "1112131415"},
|
|
output{0x0001, DataType(0x0006), 0x0005, []byte{0x11, 0x12, 0x13, 0x14, 0x15}},
|
|
},
|
|
//////////// int (2-byte) types ////////////////
|
|
tagTest{
|
|
input{"0001", "0003", "00000002", "11111212", ""},
|
|
input{"0100", "0300", "02000000", "11111212", ""},
|
|
output{0x0001, DataType(0x0003), 0x0002, []byte{0x11, 0x11, 0x12, 0x12}},
|
|
},
|
|
tagTest{
|
|
input{"0001", "0003", "00000003", "00000010", "111213141516"},
|
|
input{"0100", "0300", "03000000", "10000000", "111213141516"},
|
|
output{0x0001, DataType(0x0003), 0x0003, []byte{0x11, 0x12, 0x13, 0x14, 0x15, 0x16}},
|
|
},
|
|
tagTest{
|
|
input{"0001", "0008", "00000001", "11120000", ""},
|
|
input{"0100", "0800", "01000000", "11120000", ""},
|
|
output{0x0001, DataType(0x0008), 0x0001, []byte{0x11, 0x12}},
|
|
},
|
|
tagTest{
|
|
input{"0001", "0008", "00000003", "00000100", "111213141516"},
|
|
input{"0100", "0800", "03000000", "00100000", "111213141516"},
|
|
output{0x0001, DataType(0x0008), 0x0003, []byte{0x11, 0x12, 0x13, 0x14, 0x15, 0x16}},
|
|
},
|
|
//////////// int (4-byte) types ////////////////
|
|
tagTest{
|
|
input{"0001", "0004", "00000001", "11121314", ""},
|
|
input{"0100", "0400", "01000000", "11121314", ""},
|
|
output{0x0001, DataType(0x0004), 0x0001, []byte{0x11, 0x12, 0x13, 0x14}},
|
|
},
|
|
tagTest{
|
|
input{"0001", "0004", "00000002", "00000010", "1112131415161718"},
|
|
input{"0100", "0400", "02000000", "10000000", "1112131415161718"},
|
|
output{0x0001, DataType(0x0004), 0x0002, []byte{0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18}},
|
|
},
|
|
tagTest{
|
|
input{"0001", "0009", "00000001", "11121314", ""},
|
|
input{"0100", "0900", "01000000", "11121314", ""},
|
|
output{0x0001, DataType(0x0009), 0x0001, []byte{0x11, 0x12, 0x13, 0x14}},
|
|
},
|
|
tagTest{
|
|
input{"0001", "0009", "00000002", "00000011", "1112131415161819"},
|
|
input{"0100", "0900", "02000000", "11000000", "1112131415161819"},
|
|
output{0x0001, DataType(0x0009), 0x0002, []byte{0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x18, 0x19}},
|
|
},
|
|
//////////// rational types ////////////////////
|
|
tagTest{
|
|
input{"0001", "0005", "00000001", "00000010", "1112131415161718"},
|
|
input{"0100", "0500", "01000000", "10000000", "1112131415161718"},
|
|
output{0x0001, DataType(0x0005), 0x0001, []byte{0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18}},
|
|
},
|
|
tagTest{
|
|
input{"0001", "000A", "00000001", "00000011", "1112131415161819"},
|
|
input{"0100", "0A00", "01000000", "11000000", "1112131415161819"},
|
|
output{0x0001, DataType(0x000A), 0x0001, []byte{0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x18, 0x19}},
|
|
},
|
|
//////////// float types ///////////////////////
|
|
tagTest{
|
|
input{"0001", "0005", "00000001", "00000010", "1112131415161718"},
|
|
input{"0100", "0500", "01000000", "10000000", "1112131415161718"},
|
|
output{0x0001, DataType(0x0005), 0x0001, []byte{0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18}},
|
|
},
|
|
tagTest{
|
|
input{"0101", "000A", "00000001", "00000011", "1112131415161819"},
|
|
input{"0101", "0A00", "01000000", "11000000", "1112131415161819"},
|
|
output{0x0101, DataType(0x000A), 0x0001, []byte{0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x18, 0x19}},
|
|
},
|
|
}
|
|
|
|
func TestDecodeTag(t *testing.T) {
|
|
for i, tst := range set1 {
|
|
testSingle(t, binary.BigEndian, tst.big, tst.out, i)
|
|
testSingle(t, binary.LittleEndian, tst.little, tst.out, i)
|
|
}
|
|
}
|
|
|
|
func testSingle(t *testing.T, order binary.ByteOrder, in input, out output, i int) {
|
|
data := buildInput(in, order)
|
|
buf := bytes.NewReader(data)
|
|
tg, err := DecodeTag(buf, order)
|
|
if err != nil {
|
|
t.Errorf("(%v) tag %v%+v decode failed: %v", order, i, in, err)
|
|
return
|
|
}
|
|
|
|
if tg.Id != out.id {
|
|
t.Errorf("(%v) tag %v id decode: expected %v, got %v", order, i, out.id, tg.Id)
|
|
}
|
|
if tg.Type != out.typ {
|
|
t.Errorf("(%v) tag %v type decode: expected %v, got %v", order, i, out.typ, tg.Type)
|
|
}
|
|
if tg.Count != out.count {
|
|
t.Errorf("(%v) tag %v component count decode: expected %v, got %v", order, i, out.count, tg.Count)
|
|
}
|
|
if tg.Type == DTAscii && in.val != "" {
|
|
strOut := string(out.val)
|
|
if tg.strVal != strOut {
|
|
t.Errorf("(%v) tag %v string value decode: expected %q, got %q", order, i, strOut, tg.strVal)
|
|
}
|
|
} else {
|
|
if !bytes.Equal(tg.Val, out.val) {
|
|
t.Errorf("(%v) tag %v value decode: expected %q, got %q", order, i, out.val, tg.Val)
|
|
}
|
|
}
|
|
}
|
|
|
|
// buildInputBig creates a byte-slice based on big-endian ordered input
|
|
func buildInput(in input, order binary.ByteOrder) []byte {
|
|
data := make([]byte, 0)
|
|
d, _ := hex.DecodeString(in.tgId)
|
|
data = append(data, d...)
|
|
d, _ = hex.DecodeString(in.tpe)
|
|
data = append(data, d...)
|
|
d, _ = hex.DecodeString(in.nVals)
|
|
data = append(data, d...)
|
|
d, _ = hex.DecodeString(in.offset)
|
|
data = append(data, d...)
|
|
|
|
if in.val != "" {
|
|
off := order.Uint32(d)
|
|
for i := 0; i < int(off)-12; i++ {
|
|
data = append(data, 0xFF)
|
|
}
|
|
|
|
d, _ = hex.DecodeString(in.val)
|
|
data = append(data, d...)
|
|
}
|
|
|
|
return data
|
|
}
|
|
|
|
func TestDecode(t *testing.T) {
|
|
name := filepath.Join(*dataDir, "sample1.tif")
|
|
f, err := os.Open(name)
|
|
if err != nil {
|
|
t.Fatalf("%v\n", err)
|
|
}
|
|
|
|
tif, err := Decode(f)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
t.Log(tif)
|
|
}
|
|
|
|
func TestDecodeTag_blob(t *testing.T) {
|
|
buf := bytes.NewReader(data())
|
|
buf.Seek(10, 1)
|
|
tg, err := DecodeTag(buf, binary.LittleEndian)
|
|
if err != nil {
|
|
t.Fatalf("tag decode failed: %v", err)
|
|
}
|
|
|
|
t.Logf("tag: %v+\n", tg)
|
|
n, d, err := tg.Rat2(0)
|
|
if err != nil {
|
|
t.Fatalf("tag decoded wrong type: %v", err)
|
|
}
|
|
t.Logf("tag rat val: %v/%v\n", n, d)
|
|
}
|
|
|
|
func data() []byte {
|
|
s1 := "49492A000800000002001A0105000100"
|
|
s1 += "00002600000069870400010000001102"
|
|
s1 += "0000000000004800000001000000"
|
|
|
|
dat, err := hex.DecodeString(s1)
|
|
if err != nil {
|
|
panic("invalid string fixture")
|
|
}
|
|
return dat
|
|
}
|