Moving to glide
23
vendor/github.com/rwcarlsen/goexif/.gitignore
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,23 @@
|
||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
*.sw*
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
71
vendor/github.com/rwcarlsen/goexif/README.md
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,71 @@
|
||||
goexif
|
||||
======
|
||||
|
||||
Provides decoding of basic exif and tiff encoded data. Still in alpha - no guarantees.
|
||||
Suggestions and pull requests are welcome. Functionality is split into two packages - "exif" and "tiff"
|
||||
The exif package depends on the tiff package.
|
||||
Documentation can be found at http://godoc.org/github.com/rwcarlsen/goexif
|
||||
|
||||
Like goexif? - Bitcoin tips welcome: 17M7LFh3ETz4bz83VikB7xuGQskt8K5Lj4
|
||||
|
||||
To install, in a terminal type:
|
||||
|
||||
```
|
||||
go get github.com/rwcarlsen/goexif/exif
|
||||
```
|
||||
|
||||
Or if you just want the tiff package:
|
||||
|
||||
```
|
||||
go get github.com/rwcarlsen/goexif/tiff
|
||||
```
|
||||
|
||||
Example usage:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/rwcarlsen/goexif/exif"
|
||||
"github.com/rwcarlsen/goexif/mknote"
|
||||
)
|
||||
|
||||
func ExampleDecode() {
|
||||
fname := "sample1.jpg"
|
||||
|
||||
f, err := os.Open(fname)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Optionally register camera makenote data parsing - currently Nikon and
|
||||
// Canon are supported.
|
||||
exif.RegisterParsers(mknote.All...)
|
||||
|
||||
x, err := exif.Decode(f)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
camModel, _ := x.Get(exif.Model) // normally, don't ignore errors!
|
||||
fmt.Println(camModel.StringVal())
|
||||
|
||||
focal, _ := x.Get(exif.FocalLength)
|
||||
numer, denom, _ := focal.Rat2(0) // retrieve first (only) rat. value
|
||||
fmt.Printf("%v/%v", numer, denom)
|
||||
|
||||
// Two convenience functions exist for date/time taken and GPS coords:
|
||||
tm, _ := x.DateTime()
|
||||
fmt.Println("Taken: ", tm)
|
||||
|
||||
lat, long, _ := x.LatLong()
|
||||
fmt.Println("lat, long: ", lat, ", ", long)
|
||||
}
|
||||
```
|
||||
|
||||
<!--golang-->
|
||||
[](http://githalytics.com/rwcarlsen/goexif)
|
||||
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/corrupt/huge_tag_exif.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 64 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/corrupt/infinite_loop_exif.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 3.7 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/corrupt/max_uint32_exif.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 64 KiB |
42
vendor/github.com/rwcarlsen/goexif/exif/example_test.go
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,42 @@
|
||||
package exif_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/rwcarlsen/goexif/exif"
|
||||
"github.com/rwcarlsen/goexif/mknote"
|
||||
)
|
||||
|
||||
func ExampleDecode() {
|
||||
fname := "sample1.jpg"
|
||||
|
||||
f, err := os.Open(fname)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Optionally register camera makenote data parsing - currently Nikon and
|
||||
// Canon are supported.
|
||||
exif.RegisterParsers(mknote.All...)
|
||||
|
||||
x, err := exif.Decode(f)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
camModel, _ := x.Get(exif.Model) // normally, don't ignore errors!
|
||||
fmt.Println(camModel.StringVal())
|
||||
|
||||
focal, _ := x.Get(exif.FocalLength)
|
||||
numer, denom, _ := focal.Rat2(0) // retrieve first (only) rat. value
|
||||
fmt.Printf("%v/%v", numer, denom)
|
||||
|
||||
// Two convenience functions exist for date/time taken and GPS coords:
|
||||
tm, _ := x.DateTime()
|
||||
fmt.Println("Taken: ", tm)
|
||||
|
||||
lat, long, _ := x.LatLong()
|
||||
fmt.Println("lat, long: ", lat, ", ", long)
|
||||
}
|
||||
202
vendor/github.com/rwcarlsen/goexif/exif/exif_test.go
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,202 @@
|
||||
package exif
|
||||
|
||||
//go:generate go run regen_regress.go -- regress_expected_test.go
|
||||
//go:generate go fmt regress_expected_test.go
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"math"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/rwcarlsen/goexif/tiff"
|
||||
)
|
||||
|
||||
var dataDir = flag.String("test_data_dir", ".", "Directory where the data files for testing are located")
|
||||
|
||||
func TestDecode(t *testing.T) {
|
||||
fpath := filepath.Join(*dataDir, "samples")
|
||||
f, err := os.Open(fpath)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not open sample directory '%s': %v", fpath, err)
|
||||
}
|
||||
|
||||
names, err := f.Readdirnames(0)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not read sample directory '%s': %v", fpath, err)
|
||||
}
|
||||
|
||||
cnt := 0
|
||||
for _, name := range names {
|
||||
if !strings.HasSuffix(name, ".jpg") {
|
||||
t.Logf("skipping non .jpg file %v", name)
|
||||
continue
|
||||
}
|
||||
t.Logf("testing file %v", name)
|
||||
f, err := os.Open(filepath.Join(fpath, name))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
x, err := Decode(f)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if x == nil {
|
||||
t.Fatalf("No error and yet %v was not decoded", name)
|
||||
}
|
||||
|
||||
t.Logf("checking pic %v", name)
|
||||
x.Walk(&walker{name, t})
|
||||
cnt++
|
||||
}
|
||||
if cnt != len(regressExpected) {
|
||||
t.Errorf("Did not process enough samples, got %d, want %d", cnt, len(regressExpected))
|
||||
}
|
||||
}
|
||||
|
||||
type walker struct {
|
||||
picName string
|
||||
t *testing.T
|
||||
}
|
||||
|
||||
func (w *walker) Walk(field FieldName, tag *tiff.Tag) error {
|
||||
// this needs to be commented out when regenerating regress expected vals
|
||||
pic := regressExpected[w.picName]
|
||||
if pic == nil {
|
||||
w.t.Errorf(" regression data not found")
|
||||
return nil
|
||||
}
|
||||
|
||||
exp, ok := pic[field]
|
||||
if !ok {
|
||||
w.t.Errorf(" regression data does not have field %v", field)
|
||||
return nil
|
||||
}
|
||||
|
||||
s := tag.String()
|
||||
if tag.Count == 1 && s != "\"\"" {
|
||||
s = fmt.Sprintf("[%s]", s)
|
||||
}
|
||||
got := tag.String()
|
||||
|
||||
if exp != got {
|
||||
fmt.Println("s: ", s)
|
||||
fmt.Printf("len(s)=%v\n", len(s))
|
||||
w.t.Errorf(" field %v bad tag: expected '%s', got '%s'", field, exp, got)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestMarshal(t *testing.T) {
|
||||
name := filepath.Join(*dataDir, "sample1.jpg")
|
||||
f, err := os.Open(name)
|
||||
if err != nil {
|
||||
t.Fatalf("%v\n", err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
x, err := Decode(f)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if x == nil {
|
||||
t.Fatal("bad err")
|
||||
}
|
||||
|
||||
b, err := x.MarshalJSON()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
t.Logf("%s", b)
|
||||
}
|
||||
|
||||
func testSingleParseDegreesString(t *testing.T, s string, w float64) {
|
||||
g, err := parseTagDegreesString(s)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if math.Abs(w-g) > 1e-10 {
|
||||
t.Errorf("Wrong parsing result %s: Want %.12f, got %.12f", s, w, g)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseTagDegreesString(t *testing.T) {
|
||||
// semicolon as decimal mark
|
||||
testSingleParseDegreesString(t, "52,00000,50,00000,34,01180", 52.842781055556) // comma as separator
|
||||
testSingleParseDegreesString(t, "52,00000;50,00000;34,01180", 52.842781055556) // semicolon as separator
|
||||
|
||||
// point as decimal mark
|
||||
testSingleParseDegreesString(t, "14.00000,44.00000,34.01180", 14.742781055556) // comma as separator
|
||||
testSingleParseDegreesString(t, "14.00000;44.00000;34.01180", 14.742781055556) // semicolon as separator
|
||||
testSingleParseDegreesString(t, "14.00000;44.00000,34.01180", 14.742781055556) // mixed separators
|
||||
|
||||
testSingleParseDegreesString(t, "-008.0,30.0,03.6", -8.501) // leading zeros
|
||||
|
||||
// no decimal places
|
||||
testSingleParseDegreesString(t, "-10,15,54", -10.265)
|
||||
testSingleParseDegreesString(t, "-10;15;54", -10.265)
|
||||
|
||||
// incorrect mix of comma and point as decimal mark
|
||||
s := "-17,00000,15.00000,04.80000"
|
||||
if _, err := parseTagDegreesString(s); err == nil {
|
||||
t.Error("parseTagDegreesString: false positive for " + s)
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure we error out early when a tag had a count of MaxUint32
|
||||
func TestMaxUint32CountError(t *testing.T) {
|
||||
name := filepath.Join(*dataDir, "corrupt/max_uint32_exif.jpg")
|
||||
f, err := os.Open(name)
|
||||
if err != nil {
|
||||
t.Fatalf("%v\n", err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
_, err = Decode(f)
|
||||
if err == nil {
|
||||
t.Fatal("no error on bad exif data")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "invalid Count offset") {
|
||||
t.Fatal("wrong error:", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure we error out early with tag data sizes larger than the image file
|
||||
func TestHugeTagError(t *testing.T) {
|
||||
name := filepath.Join(*dataDir, "corrupt/huge_tag_exif.jpg")
|
||||
f, err := os.Open(name)
|
||||
if err != nil {
|
||||
t.Fatalf("%v\n", err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
_, err = Decode(f)
|
||||
if err == nil {
|
||||
t.Fatal("no error on bad exif data")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "short read") {
|
||||
t.Fatal("wrong error:", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// Check for a 0-length tag value
|
||||
func TestZeroLengthTagError(t *testing.T) {
|
||||
name := filepath.Join(*dataDir, "corrupt/infinite_loop_exif.jpg")
|
||||
f, err := os.Open(name)
|
||||
if err != nil {
|
||||
t.Fatalf("%v\n", err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
_, err = Decode(f)
|
||||
if err == nil {
|
||||
t.Fatal("no error on bad exif data")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "zero length tag value") {
|
||||
t.Fatal("wrong error:", err.Error())
|
||||
}
|
||||
}
|
||||
2293
vendor/github.com/rwcarlsen/goexif/exif/regress_expected_test.go
сгенерированный
поставляемый
Обычный файл
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2004-01-11-22-45-15-sep-2004-01-11-22-45-15a.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 4.5 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2006-08-03-16-29-38-sep-2006-08-03-16-29-38a.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 9.5 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2006-11-11-19-17-56-sep-2006-11-11-19-17-56a.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 35 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2006-12-10-23-58-20-sep-2006-12-10-23-58-20a.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 8.5 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2006-12-17-07-09-14-sep-2006-12-17-07-09-14a.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 37 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2006-12-21-15-55-26-sep-2006-12-21-15-55-26a.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 16 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2007-01-01-12-00-00-sep-2007-01-01-12-00-00a.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 17 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2007-01-17-21-49-44-sep-2007-01-17-21-49-44a.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 7.8 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2007-02-02-18-13-29-sep-2007-02-02-18-13-29a.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 39 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2007-05-02-17-02-21-sep-2007-05-02-17-02-21a.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 12 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2007-05-12-08-19-07-sep-2007-05-12-08-19-07a.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 35 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2007-05-26-04-49-45-sep-2007-05-26-04-49-45a.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 35 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2007-05-30-14-28-01-sep-2007-05-30-14-28-01a.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 35 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2007-06-06-16-15-25-sep-2007-06-06-16-15-25a.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 35 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2007-06-26-10-13-04-sep-2007-06-26-10-13-04a.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 7.4 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2007-07-13-17-02-30-sep-2007-07-13-17-02-30a.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 21 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2007-08-15-14-42-46-sep-2007-08-15-14-42-46a.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 11 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2007-08-24-02-40-42-sep-2007-08-24-02-40-42a.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 7.5 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2007-11-07-11-40-44-sep-2007-11-07-11-40-44a.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 11 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2008-06-02-10-03-57-sep-2008-06-02-10-03-57a.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 9.5 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2008-06-06-13-29-29-sep-2008-06-06-13-29-29a.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 12 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2008-06-17-01-21-30-sep-2008-06-17-01-21-30a.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 14 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2008-09-02-17-43-48-sep-2008-09-02-17-43-48a.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 5.3 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2009-03-26-09-23-20-sep-2009-03-26-09-23-20a.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 10 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2009-04-11-03-01-38-sep-2009-04-11-03-01-38a.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 42 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2009-04-23-07-21-35-sep-2009-04-23-07-21-35a.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 36 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2009-06-11-19-23-18-sep-2009-06-11-19-23-18a.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 7.6 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2009-06-20-07-59-05-sep-2009-06-20-07-59-05a.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 13 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2009-08-05-08-11-31-sep-2009-08-05-08-11-31a.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 9.7 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2010-06-08-04-44-24-sep-2010-06-08-04-44-24a.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 11 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2010-06-20-20-07-39-sep-2010-06-20-20-07-39a.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 8.4 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2010-09-02-08-43-02-sep-2010-09-02-08-43-02a.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 19 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2011-01-24-22-06-02-sep-2011-01-24-22-06-02a.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 28 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2011-03-07-09-28-03-sep-2011-03-07-09-28-03a.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 10 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2011-05-07-13-02-49-sep-2011-05-07-13-02-49a.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 23 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2011-08-07-19-22-57-sep-2011-08-07-19-22-57a.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 9.7 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2011-10-28-17-50-18-sep-2011-10-28-17-50-18a.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 7.3 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2011-10-28-18-25-43-sep-2011-10-28-18-25-43.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 7.3 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2011-11-18-15-38-34-sep-Photo11181538.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 13 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2012-06-02-10-12-28-sep-2012-06-02-10-12-28.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 31 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2012-09-21-22-07-34-sep-2012-09-21-22-07-34.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 10 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2012-12-19-21-38-40-sep-temple_square1.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 38 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2012-12-21-11-15-19-sep-IMG_0001.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 25 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2013-02-05-23-12-09-sep-DSCI0001.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 11 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2099-08-12-19-59-29-sep-2099-08-12-19-59-29a.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 37 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/2216-11-15-11-46-51-sep-2216-11-15-11-46-51a.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 22 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/FailedHash-NoDate-sep-remembory.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 935 B |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/f1-exif.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 992 B |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/f2-exif.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 994 B |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/f3-exif.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 992 B |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/f4-exif.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 994 B |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/f5-exif.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 980 B |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/f6-exif.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 982 B |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/f7-exif.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 980 B |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/f8-exif.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 982 B |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/geodegrees_as_string.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 22 KiB |
Двоичные данные
vendor/github.com/rwcarlsen/goexif/exif/samples/has-lens-info.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 22 KiB |
60
vendor/github.com/rwcarlsen/goexif/exifstat/main.go
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,60 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/rwcarlsen/goexif/exif"
|
||||
"github.com/rwcarlsen/goexif/mknote"
|
||||
"github.com/rwcarlsen/goexif/tiff"
|
||||
)
|
||||
|
||||
var mnote = flag.Bool("mknote", false, "try to parse makernote data")
|
||||
var thumb = flag.Bool("thumb", false, "dump thumbail data to stdout (for first listed image file)")
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
fnames := flag.Args()
|
||||
|
||||
if *mnote {
|
||||
exif.RegisterParsers(mknote.All...)
|
||||
}
|
||||
|
||||
for _, name := range fnames {
|
||||
f, err := os.Open(name)
|
||||
if err != nil {
|
||||
log.Printf("err on %v: %v", name, err)
|
||||
continue
|
||||
}
|
||||
|
||||
x, err := exif.Decode(f)
|
||||
if err != nil {
|
||||
log.Printf("err on %v: %v", name, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if *thumb {
|
||||
data, err := x.JpegThumbnail()
|
||||
if err != nil {
|
||||
log.Fatal("no thumbnail present")
|
||||
}
|
||||
if _, err := os.Stdout.Write(data); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("\n---- Image '%v' ----\n", name)
|
||||
x.Walk(Walker{})
|
||||
}
|
||||
}
|
||||
|
||||
type Walker struct{}
|
||||
|
||||
func (_ Walker) Walk(name exif.FieldName, tag *tiff.Tag) error {
|
||||
data, _ := tag.MarshalJSON()
|
||||
fmt.Printf(" %v: %v\n", name, string(data))
|
||||
return nil
|
||||
}
|
||||
268
vendor/github.com/rwcarlsen/goexif/mknote/fields.go
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,268 @@
|
||||
package mknote
|
||||
|
||||
import "github.com/rwcarlsen/goexif/exif"
|
||||
|
||||
// Useful resources used in creating these tables:
|
||||
// http://www.exiv2.org/makernote.html
|
||||
// http://www.exiv2.org/tags-canon.html
|
||||
// http://www.exiv2.org/tags-nikon.html
|
||||
|
||||
// Known Maker Note fields
|
||||
const (
|
||||
// common fields
|
||||
ISOSpeed exif.FieldName = "ISOSpeed"
|
||||
ColorMode = "ColorMode"
|
||||
Quality = "Quality"
|
||||
Sharpening = "Sharpening"
|
||||
Focus = "Focus"
|
||||
FlashSetting = "FlashSetting"
|
||||
FlashDevice = "FlashDevice"
|
||||
WhiteBalanceBias = "WhiteBalanceBias"
|
||||
WB_RBLevels = "WB_RBLevels"
|
||||
ProgramShift = "ProgramShift"
|
||||
ExposureDiff = "ExposureDiff"
|
||||
ISOSelection = "ISOSelection"
|
||||
DataDump = "DataDump"
|
||||
Preview = "Preview"
|
||||
FlashComp = "FlashComp"
|
||||
ISOSettings = "ISOSettings"
|
||||
ImageBoundary = "ImageBoundary"
|
||||
FlashExposureComp = "FlashExposureComp"
|
||||
FlashBracketComp = "FlashBracketComp"
|
||||
ExposureBracketComp = "ExposureBracketComp"
|
||||
ImageProcessing = "ImageProcessing"
|
||||
CropHiSpeed = "CropHiSpeed"
|
||||
ExposureTuning = "ExposureTuning"
|
||||
SerialNumber = "SerialNumber"
|
||||
ImageAuthentication = "ImageAuthentication"
|
||||
ActiveDLighting = "ActiveDLighting"
|
||||
VignetteControl = "VignetteControl"
|
||||
ImageAdjustment = "ImageAdjustment"
|
||||
ToneComp = "ToneComp"
|
||||
AuxiliaryLens = "AuxiliaryLens"
|
||||
LensType = "LensType"
|
||||
Lens = "Lens"
|
||||
FocusDistance = "FocusDistance"
|
||||
DigitalZoom = "DigitalZoom"
|
||||
FlashMode = "FlashMode"
|
||||
ShootingMode = "ShootingMode"
|
||||
AutoBracketRelease = "AutoBracketRelease"
|
||||
LensFStops = "LensFStops"
|
||||
ContrastCurve = "ContrastCurve"
|
||||
ColorHue = "ColorHue"
|
||||
SceneMode = "SceneMode"
|
||||
HueAdjustment = "HueAdjustment"
|
||||
NEFCompression = "NEFCompression"
|
||||
NoiseReduction = "NoiseReduction"
|
||||
LinearizationTable = "LinearizationTable"
|
||||
RawImageCenter = "RawImageCenter"
|
||||
SensorPixelSize = "SensorPixelSize"
|
||||
SceneAssist = "SceneAssist"
|
||||
RetouchHistory = "RetouchHistory"
|
||||
ImageDataSize = "ImageDataSize"
|
||||
ImageCount = "ImageCount"
|
||||
DeletedImageCount = "DeletedImageCount"
|
||||
ShutterCount = "ShutterCount"
|
||||
ImageOptimization = "ImageOptimization"
|
||||
SaturationText = "SaturationText"
|
||||
VariProgram = "VariProgram"
|
||||
ImageStabilization = "ImageStabilization"
|
||||
AFResponse = "AFResponse"
|
||||
HighISONoiseReduction = "HighISONoiseReduction"
|
||||
ToningEffect = "ToningEffect"
|
||||
PrintIM = "PrintIM"
|
||||
CaptureData = "CaptureData"
|
||||
CaptureVersion = "CaptureVersion"
|
||||
CaptureOffsets = "CaptureOffsets"
|
||||
ScanIFD = "ScanIFD"
|
||||
ICCProfile = "ICCProfile"
|
||||
CaptureOutput = "CaptureOutput"
|
||||
Panorama = "Panorama"
|
||||
ImageType = "ImageType"
|
||||
FirmwareVersion = "FirmwareVersion"
|
||||
FileNumber = "FileNumber"
|
||||
OwnerName = "OwnerName"
|
||||
CameraInfo = "CameraInfo"
|
||||
CustomFunctions = "CustomFunctions"
|
||||
ModelID = "ModelID"
|
||||
PictureInfo = "PictureInfo"
|
||||
ThumbnailImageValidArea = "ThumbnailImageValidArea"
|
||||
SerialNumberFormat = "SerialNumberFormat"
|
||||
SuperMacro = "SuperMacro"
|
||||
OriginalDecisionDataOffset = "OriginalDecisionDataOffset"
|
||||
WhiteBalanceTable = "WhiteBalanceTable"
|
||||
LensModel = "LensModel"
|
||||
InternalSerialNumber = "InternalSerialNumber"
|
||||
DustRemovalData = "DustRemovalData"
|
||||
ProcessingInfo = "ProcessingInfo"
|
||||
MeasuredColor = "MeasuredColor"
|
||||
VRDOffset = "VRDOffset"
|
||||
SensorInfo = "SensorInfo"
|
||||
ColorData = "ColorData"
|
||||
|
||||
// Nikon-specific fields
|
||||
Nikon_Version = "Nikon.Version"
|
||||
Nikon_WhiteBalance = "Nikon.WhiteBalance"
|
||||
Nikon_ColorSpace = "Nikon.ColorSpace"
|
||||
Nikon_LightSource = "Nikon.LightSource"
|
||||
Nikon_Saturation = "Nikon_Saturation"
|
||||
Nikon_ShotInfo = "Nikon.ShotInfo" // A sub-IFD
|
||||
Nikon_VRInfo = "Nikon.VRInfo" // A sub-IFD
|
||||
Nikon_PictureControl = "Nikon.PictureControl" // A sub-IFD
|
||||
Nikon_WorldTime = "Nikon.WorldTime" // A sub-IFD
|
||||
Nikon_ISOInfo = "Nikon.ISOInfo" // A sub-IFD
|
||||
Nikon_AFInfo = "Nikon.AFInfo" // A sub-IFD
|
||||
Nikon_ColorBalance = "Nikon.ColorBalance" // A sub-IFD
|
||||
Nikon_LensData = "Nikon.LensData" // A sub-IFD
|
||||
Nikon_SerialNO = "Nikon.SerialNO" // usually starts with "NO="
|
||||
Nikon_FlashInfo = "Nikon.FlashInfo" // A sub-IFD
|
||||
Nikon_MultiExposure = "Nikon.MultiExposure" // A sub-IFD
|
||||
Nikon_AFInfo2 = "Nikon.AFInfo2" // A sub-IFD
|
||||
Nikon_FileInfo = "Nikon.FileInfo" // A sub-IFD
|
||||
Nikon_AFTune = "Nikon.AFTune" // A sub-IFD
|
||||
Nikon3_0x000a = "Nikon3.0x000a"
|
||||
Nikon3_0x009b = "Nikon3.0x009b"
|
||||
Nikon3_0x009f = "Nikon3.0x009f"
|
||||
Nikon3_0x00a3 = "Nikon3.0x00a3"
|
||||
|
||||
// Canon-specific fiends
|
||||
Canon_CameraSettings = "Canon.CameraSettings" // A sub-IFD
|
||||
Canon_ShotInfo = "Canon.ShotInfo" // A sub-IFD
|
||||
Canon_AFInfo = "Canon.AFInfo"
|
||||
Canon_0x0000 = "Canon.0x0000"
|
||||
Canon_0x0003 = "Canon.0x0003"
|
||||
Canon_0x00b5 = "Canon.0x00b5"
|
||||
Canon_0x00c0 = "Canon.0x00c0"
|
||||
Canon_0x00c1 = "Canon.0x00c1"
|
||||
)
|
||||
|
||||
var makerNoteCanonFields = map[uint16]exif.FieldName{
|
||||
0x0000: Canon_0x0000,
|
||||
0x0001: Canon_CameraSettings,
|
||||
0x0002: exif.FocalLength,
|
||||
0x0003: Canon_0x0003,
|
||||
0x0004: Canon_ShotInfo,
|
||||
0x0005: Panorama,
|
||||
0x0006: ImageType,
|
||||
0x0007: FirmwareVersion,
|
||||
0x0008: FileNumber,
|
||||
0x0009: OwnerName,
|
||||
0x000c: SerialNumber,
|
||||
0x000d: CameraInfo,
|
||||
0x000f: CustomFunctions,
|
||||
0x0010: ModelID,
|
||||
0x0012: PictureInfo,
|
||||
0x0013: ThumbnailImageValidArea,
|
||||
0x0015: SerialNumberFormat,
|
||||
0x001a: SuperMacro,
|
||||
0x0026: Canon_AFInfo,
|
||||
0x0083: OriginalDecisionDataOffset,
|
||||
0x00a4: WhiteBalanceTable,
|
||||
0x0095: LensModel,
|
||||
0x0096: InternalSerialNumber,
|
||||
0x0097: DustRemovalData,
|
||||
0x0099: CustomFunctions,
|
||||
0x00a0: ProcessingInfo,
|
||||
0x00aa: MeasuredColor,
|
||||
0x00b4: exif.ColorSpace,
|
||||
0x00b5: Canon_0x00b5,
|
||||
0x00c0: Canon_0x00c0,
|
||||
0x00c1: Canon_0x00c1,
|
||||
0x00d0: VRDOffset,
|
||||
0x00e0: SensorInfo,
|
||||
0x4001: ColorData,
|
||||
}
|
||||
|
||||
// Nikon version 3 Maker Notes fields (used by E5400, SQ, D2H, D70, and newer)
|
||||
var makerNoteNikon3Fields = map[uint16]exif.FieldName{
|
||||
0x0001: Nikon_Version,
|
||||
0x0002: ISOSpeed,
|
||||
0x0003: ColorMode,
|
||||
0x0004: Quality,
|
||||
0x0005: Nikon_WhiteBalance,
|
||||
0x0006: Sharpening,
|
||||
0x0007: Focus,
|
||||
0x0008: FlashSetting,
|
||||
0x0009: FlashDevice,
|
||||
0x000a: Nikon3_0x000a,
|
||||
0x000b: WhiteBalanceBias,
|
||||
0x000c: WB_RBLevels,
|
||||
0x000d: ProgramShift,
|
||||
0x000e: ExposureDiff,
|
||||
0x000f: ISOSelection,
|
||||
0x0010: DataDump,
|
||||
0x0011: Preview,
|
||||
0x0012: FlashComp,
|
||||
0x0013: ISOSettings,
|
||||
0x0016: ImageBoundary,
|
||||
0x0017: FlashExposureComp,
|
||||
0x0018: FlashBracketComp,
|
||||
0x0019: ExposureBracketComp,
|
||||
0x001a: ImageProcessing,
|
||||
0x001b: CropHiSpeed,
|
||||
0x001c: ExposureTuning,
|
||||
0x001d: SerialNumber,
|
||||
0x001e: Nikon_ColorSpace,
|
||||
0x001f: Nikon_VRInfo,
|
||||
0x0020: ImageAuthentication,
|
||||
0x0022: ActiveDLighting,
|
||||
0x0023: Nikon_PictureControl,
|
||||
0x0024: Nikon_WorldTime,
|
||||
0x0025: Nikon_ISOInfo,
|
||||
0x002a: VignetteControl,
|
||||
0x0080: ImageAdjustment,
|
||||
0x0081: ToneComp,
|
||||
0x0082: AuxiliaryLens,
|
||||
0x0083: LensType,
|
||||
0x0084: Lens,
|
||||
0x0085: FocusDistance,
|
||||
0x0086: DigitalZoom,
|
||||
0x0087: FlashMode,
|
||||
0x0088: Nikon_AFInfo,
|
||||
0x0089: ShootingMode,
|
||||
0x008a: AutoBracketRelease,
|
||||
0x008b: LensFStops,
|
||||
0x008c: ContrastCurve,
|
||||
0x008d: ColorHue,
|
||||
0x008f: SceneMode,
|
||||
0x0090: Nikon_LightSource,
|
||||
0x0091: Nikon_ShotInfo,
|
||||
0x0092: HueAdjustment,
|
||||
0x0093: NEFCompression,
|
||||
0x0094: Nikon_Saturation,
|
||||
0x0095: NoiseReduction,
|
||||
0x0096: LinearizationTable,
|
||||
0x0097: Nikon_ColorBalance,
|
||||
0x0098: Nikon_LensData,
|
||||
0x0099: RawImageCenter,
|
||||
0x009a: SensorPixelSize,
|
||||
0x009b: Nikon3_0x009b,
|
||||
0x009c: SceneAssist,
|
||||
0x009e: RetouchHistory,
|
||||
0x009f: Nikon3_0x009f,
|
||||
0x00a0: Nikon_SerialNO,
|
||||
0x00a2: ImageDataSize,
|
||||
0x00a3: Nikon3_0x00a3,
|
||||
0x00a5: ImageCount,
|
||||
0x00a6: DeletedImageCount,
|
||||
0x00a7: ShutterCount,
|
||||
0x00a8: Nikon_FlashInfo,
|
||||
0x00a9: ImageOptimization,
|
||||
0x00aa: SaturationText,
|
||||
0x00ab: VariProgram,
|
||||
0x00ac: ImageStabilization,
|
||||
0x00ad: AFResponse,
|
||||
0x00b0: Nikon_MultiExposure,
|
||||
0x00b1: HighISONoiseReduction,
|
||||
0x00b3: ToningEffect,
|
||||
0x00b7: Nikon_AFInfo2,
|
||||
0x00b8: Nikon_FileInfo,
|
||||
0x00b9: Nikon_AFTune,
|
||||
0x0e00: PrintIM,
|
||||
0x0e01: CaptureData,
|
||||
0x0e09: CaptureVersion,
|
||||
0x0e0e: CaptureOffsets,
|
||||
0x0e10: ScanIFD,
|
||||
0x0e1d: ICCProfile,
|
||||
0x0e1e: CaptureOutput,
|
||||
}
|
||||
70
vendor/github.com/rwcarlsen/goexif/mknote/mknote.go
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,70 @@
|
||||
// Package mknote provides makernote parsers that can be used with goexif/exif.
|
||||
package mknote
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
"github.com/rwcarlsen/goexif/exif"
|
||||
"github.com/rwcarlsen/goexif/tiff"
|
||||
)
|
||||
|
||||
var (
|
||||
// Canon is an exif.Parser for canon makernote data.
|
||||
Canon = &canon{}
|
||||
// NikonV3 is an exif.Parser for nikon makernote data.
|
||||
NikonV3 = &nikonV3{}
|
||||
// All is a list of all available makernote parsers
|
||||
All = []exif.Parser{Canon, NikonV3}
|
||||
)
|
||||
|
||||
type canon struct{}
|
||||
|
||||
// Parse decodes all Canon makernote data found in x and adds it to x.
|
||||
func (_ *canon) Parse(x *exif.Exif) error {
|
||||
m, err := x.Get(exif.MakerNote)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
mk, err := x.Get(exif.Make)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if val, err := mk.StringVal(); err != nil || val != "Canon" {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Canon notes are a single IFD directory with no header.
|
||||
// Reader offsets need to be w.r.t. the original tiff structure.
|
||||
buf := bytes.NewReader(append(make([]byte, m.ValOffset), m.Val...))
|
||||
buf.Seek(int64(m.ValOffset), 0)
|
||||
|
||||
mkNotesDir, _, err := tiff.DecodeDir(buf, x.Tiff.Order)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
x.LoadTags(mkNotesDir, makerNoteCanonFields, false)
|
||||
return nil
|
||||
}
|
||||
|
||||
type nikonV3 struct{}
|
||||
|
||||
// Parse decodes all Nikon makernote data found in x and adds it to x.
|
||||
func (_ *nikonV3) Parse(x *exif.Exif) error {
|
||||
m, err := x.Get(exif.MakerNote)
|
||||
if err != nil {
|
||||
return nil
|
||||
} else if bytes.Compare(m.Val[:6], []byte("Nikon\000")) != 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Nikon v3 maker note is a self-contained IFD (offsets are relative
|
||||
// to the start of the maker note)
|
||||
mkNotes, err := tiff.Decode(bytes.NewReader(m.Val[10:]))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
x.LoadTags(mkNotes.Dirs[0], makerNoteNikon3Fields, false)
|
||||
return nil
|
||||
}
|
||||
235
vendor/github.com/rwcarlsen/goexif/tiff/tiff_test.go
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,235 @@
|
||||
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}},
|
||||
},
|
||||
//////////// 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 !bytes.Equal(tg.Val, out.val) {
|
||||
t.Errorf("(%v) tag %v value decode: expected %v, got %v", 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
|
||||
}
|
||||