Depenancy upgrades and movign to dep. (#8630)
23
vendor/github.com/rwcarlsen/goexif/.gitignore
сгенерированный
поставляемый
@@ -1,23 +0,0 @@
|
||||
# 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
сгенерированный
поставляемый
@@ -1,71 +0,0 @@
|
||||
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 Cash tips welcome: 1DrU5V37nTXuv4vnRLVpahJEjhdATNgoBh
|
||||
|
||||
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
сгенерированный
поставляемый
@@ -1,42 +0,0 @@
|
||||
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)
|
||||
}
|
||||
69
vendor/github.com/rwcarlsen/goexif/exif/exif.go
сгенерированный
поставляемый
@@ -201,14 +201,16 @@ type Exif struct {
|
||||
Raw []byte
|
||||
}
|
||||
|
||||
// Decode parses EXIF-encoded data from r and returns a queryable Exif
|
||||
// object. After the exif data section is called and the tiff structure
|
||||
// decoded, each registered parser is called (in order of registration). If
|
||||
// one parser returns an error, decoding terminates and the remaining
|
||||
// parsers are not called.
|
||||
// The error can be inspected with functions such as IsCriticalError to
|
||||
// determine whether the returned object might still be usable.
|
||||
// Decode parses EXIF data from r (a TIFF, JPEG, or raw EXIF block)
|
||||
// and returns a queryable Exif object. After the EXIF data section is
|
||||
// called and the TIFF structure is decoded, each registered parser is
|
||||
// called (in order of registration). If one parser returns an error,
|
||||
// decoding terminates and the remaining parsers are not called.
|
||||
//
|
||||
// The error can be inspected with functions such as IsCriticalError
|
||||
// to determine whether the returned object might still be usable.
|
||||
func Decode(r io.Reader) (*Exif, error) {
|
||||
|
||||
// EXIF data in JPEG is stored in the APP1 marker. EXIF data uses the TIFF
|
||||
// format to store data.
|
||||
// If we're parsing a TIFF image, we don't need to strip away any data.
|
||||
@@ -216,15 +218,14 @@ func Decode(r io.Reader) (*Exif, error) {
|
||||
// marker and also the EXIF header.
|
||||
|
||||
header := make([]byte, 4)
|
||||
n, err := r.Read(header)
|
||||
n, err := io.ReadFull(r, header)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if n < len(header) {
|
||||
return nil, errors.New("exif: short read on header")
|
||||
return nil, fmt.Errorf("exif: error reading 4 byte header, got %d, %v", n, err)
|
||||
}
|
||||
|
||||
var isTiff bool
|
||||
var isRawExif bool
|
||||
var assumeJPEG bool
|
||||
switch string(header) {
|
||||
case "II*\x00":
|
||||
// TIFF - Little endian (Intel)
|
||||
@@ -232,8 +233,11 @@ func Decode(r io.Reader) (*Exif, error) {
|
||||
case "MM\x00*":
|
||||
// TIFF - Big endian (Motorola)
|
||||
isTiff = true
|
||||
case "Exif":
|
||||
isRawExif = true
|
||||
default:
|
||||
// Not TIFF, assume JPEG
|
||||
assumeJPEG = true
|
||||
}
|
||||
|
||||
// Put the header bytes back into the reader.
|
||||
@@ -241,9 +245,20 @@ func Decode(r io.Reader) (*Exif, error) {
|
||||
var (
|
||||
er *bytes.Reader
|
||||
tif *tiff.Tiff
|
||||
sec *appSec
|
||||
)
|
||||
|
||||
if isTiff {
|
||||
switch {
|
||||
case isRawExif:
|
||||
var header [6]byte
|
||||
if _, err := io.ReadFull(r, header[:]); err != nil {
|
||||
return nil, fmt.Errorf("exif: unexpected raw exif header read error")
|
||||
}
|
||||
if got, want := string(header[:]), "Exif\x00\x00"; got != want {
|
||||
return nil, fmt.Errorf("exif: unexpected raw exif header; got %q, want %q", got, want)
|
||||
}
|
||||
fallthrough
|
||||
case isTiff:
|
||||
// Functions below need the IFDs from the TIFF data to be stored in a
|
||||
// *bytes.Reader. We use TeeReader to get a copy of the bytes as a
|
||||
// side-effect of tiff.Decode() doing its work.
|
||||
@@ -251,9 +266,8 @@ func Decode(r io.Reader) (*Exif, error) {
|
||||
tr := io.TeeReader(r, b)
|
||||
tif, err = tiff.Decode(tr)
|
||||
er = bytes.NewReader(b.Bytes())
|
||||
} else {
|
||||
case assumeJPEG:
|
||||
// Locate the JPEG APP1 header.
|
||||
var sec *appSec
|
||||
sec, err = newAppSec(jpeg_APP1, r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -368,8 +382,27 @@ func (x *Exif) DateTime() (time.Time, error) {
|
||||
exifTimeLayout := "2006:01:02 15:04:05"
|
||||
dateStr := strings.TrimRight(string(tag.Val), "\x00")
|
||||
// TODO(bradfitz,mpl): look for timezone offset, GPS time, etc.
|
||||
// For now, just always return the time.Local timezone.
|
||||
return time.ParseInLocation(exifTimeLayout, dateStr, time.Local)
|
||||
timeZone := time.Local
|
||||
if tz, _ := x.TimeZone(); tz != nil {
|
||||
timeZone = tz
|
||||
}
|
||||
return time.ParseInLocation(exifTimeLayout, dateStr, timeZone)
|
||||
}
|
||||
|
||||
func (x *Exif) TimeZone() (*time.Location, error) {
|
||||
// TODO: parse more timezone fields (e.g. Nikon WorldTime).
|
||||
timeInfo, err := x.Get("Canon.TimeInfo")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if timeInfo.Count < 2 {
|
||||
return nil, errors.New("Canon.TimeInfo does not contain timezone")
|
||||
}
|
||||
offsetMinutes, err := timeInfo.Int(1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return time.FixedZone("", offsetMinutes*60), nil
|
||||
}
|
||||
|
||||
func ratFloat(num, dem int64) float64 {
|
||||
@@ -574,7 +607,7 @@ func newAppSec(marker byte, r io.Reader) (*appSec, error) {
|
||||
}
|
||||
|
||||
dataLenBytes := make([]byte, 2)
|
||||
for k,_ := range dataLenBytes {
|
||||
for k, _ := range dataLenBytes {
|
||||
c, err := br.ReadByte()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
202
vendor/github.com/rwcarlsen/goexif/exif/exif_test.go
сгенерированный
поставляемый
@@ -1,202 +0,0 @@
|
||||
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())
|
||||
}
|
||||
}
|
||||
224
vendor/github.com/rwcarlsen/goexif/exif/fields.go
сгенерированный
поставляемый
@@ -9,127 +9,127 @@ const UnknownPrefix = "UnknownTag_"
|
||||
// Primary EXIF fields
|
||||
const (
|
||||
ImageWidth FieldName = "ImageWidth"
|
||||
ImageLength = "ImageLength" // Image height called Length by EXIF spec
|
||||
BitsPerSample = "BitsPerSample"
|
||||
Compression = "Compression"
|
||||
PhotometricInterpretation = "PhotometricInterpretation"
|
||||
Orientation = "Orientation"
|
||||
SamplesPerPixel = "SamplesPerPixel"
|
||||
PlanarConfiguration = "PlanarConfiguration"
|
||||
YCbCrSubSampling = "YCbCrSubSampling"
|
||||
YCbCrPositioning = "YCbCrPositioning"
|
||||
XResolution = "XResolution"
|
||||
YResolution = "YResolution"
|
||||
ResolutionUnit = "ResolutionUnit"
|
||||
DateTime = "DateTime"
|
||||
ImageDescription = "ImageDescription"
|
||||
Make = "Make"
|
||||
Model = "Model"
|
||||
Software = "Software"
|
||||
Artist = "Artist"
|
||||
Copyright = "Copyright"
|
||||
ExifIFDPointer = "ExifIFDPointer"
|
||||
GPSInfoIFDPointer = "GPSInfoIFDPointer"
|
||||
InteroperabilityIFDPointer = "InteroperabilityIFDPointer"
|
||||
ExifVersion = "ExifVersion"
|
||||
FlashpixVersion = "FlashpixVersion"
|
||||
ColorSpace = "ColorSpace"
|
||||
ComponentsConfiguration = "ComponentsConfiguration"
|
||||
CompressedBitsPerPixel = "CompressedBitsPerPixel"
|
||||
PixelXDimension = "PixelXDimension"
|
||||
PixelYDimension = "PixelYDimension"
|
||||
MakerNote = "MakerNote"
|
||||
UserComment = "UserComment"
|
||||
RelatedSoundFile = "RelatedSoundFile"
|
||||
DateTimeOriginal = "DateTimeOriginal"
|
||||
DateTimeDigitized = "DateTimeDigitized"
|
||||
SubSecTime = "SubSecTime"
|
||||
SubSecTimeOriginal = "SubSecTimeOriginal"
|
||||
SubSecTimeDigitized = "SubSecTimeDigitized"
|
||||
ImageUniqueID = "ImageUniqueID"
|
||||
ExposureTime = "ExposureTime"
|
||||
FNumber = "FNumber"
|
||||
ExposureProgram = "ExposureProgram"
|
||||
SpectralSensitivity = "SpectralSensitivity"
|
||||
ISOSpeedRatings = "ISOSpeedRatings"
|
||||
OECF = "OECF"
|
||||
ShutterSpeedValue = "ShutterSpeedValue"
|
||||
ApertureValue = "ApertureValue"
|
||||
BrightnessValue = "BrightnessValue"
|
||||
ExposureBiasValue = "ExposureBiasValue"
|
||||
MaxApertureValue = "MaxApertureValue"
|
||||
SubjectDistance = "SubjectDistance"
|
||||
MeteringMode = "MeteringMode"
|
||||
LightSource = "LightSource"
|
||||
Flash = "Flash"
|
||||
FocalLength = "FocalLength"
|
||||
SubjectArea = "SubjectArea"
|
||||
FlashEnergy = "FlashEnergy"
|
||||
SpatialFrequencyResponse = "SpatialFrequencyResponse"
|
||||
FocalPlaneXResolution = "FocalPlaneXResolution"
|
||||
FocalPlaneYResolution = "FocalPlaneYResolution"
|
||||
FocalPlaneResolutionUnit = "FocalPlaneResolutionUnit"
|
||||
SubjectLocation = "SubjectLocation"
|
||||
ExposureIndex = "ExposureIndex"
|
||||
SensingMethod = "SensingMethod"
|
||||
FileSource = "FileSource"
|
||||
SceneType = "SceneType"
|
||||
CFAPattern = "CFAPattern"
|
||||
CustomRendered = "CustomRendered"
|
||||
ExposureMode = "ExposureMode"
|
||||
WhiteBalance = "WhiteBalance"
|
||||
DigitalZoomRatio = "DigitalZoomRatio"
|
||||
FocalLengthIn35mmFilm = "FocalLengthIn35mmFilm"
|
||||
SceneCaptureType = "SceneCaptureType"
|
||||
GainControl = "GainControl"
|
||||
Contrast = "Contrast"
|
||||
Saturation = "Saturation"
|
||||
Sharpness = "Sharpness"
|
||||
DeviceSettingDescription = "DeviceSettingDescription"
|
||||
SubjectDistanceRange = "SubjectDistanceRange"
|
||||
LensMake = "LensMake"
|
||||
LensModel = "LensModel"
|
||||
ImageLength FieldName = "ImageLength" // Image height called Length by EXIF spec
|
||||
BitsPerSample FieldName = "BitsPerSample"
|
||||
Compression FieldName = "Compression"
|
||||
PhotometricInterpretation FieldName = "PhotometricInterpretation"
|
||||
Orientation FieldName = "Orientation"
|
||||
SamplesPerPixel FieldName = "SamplesPerPixel"
|
||||
PlanarConfiguration FieldName = "PlanarConfiguration"
|
||||
YCbCrSubSampling FieldName = "YCbCrSubSampling"
|
||||
YCbCrPositioning FieldName = "YCbCrPositioning"
|
||||
XResolution FieldName = "XResolution"
|
||||
YResolution FieldName = "YResolution"
|
||||
ResolutionUnit FieldName = "ResolutionUnit"
|
||||
DateTime FieldName = "DateTime"
|
||||
ImageDescription FieldName = "ImageDescription"
|
||||
Make FieldName = "Make"
|
||||
Model FieldName = "Model"
|
||||
Software FieldName = "Software"
|
||||
Artist FieldName = "Artist"
|
||||
Copyright FieldName = "Copyright"
|
||||
ExifIFDPointer FieldName = "ExifIFDPointer"
|
||||
GPSInfoIFDPointer FieldName = "GPSInfoIFDPointer"
|
||||
InteroperabilityIFDPointer FieldName = "InteroperabilityIFDPointer"
|
||||
ExifVersion FieldName = "ExifVersion"
|
||||
FlashpixVersion FieldName = "FlashpixVersion"
|
||||
ColorSpace FieldName = "ColorSpace"
|
||||
ComponentsConfiguration FieldName = "ComponentsConfiguration"
|
||||
CompressedBitsPerPixel FieldName = "CompressedBitsPerPixel"
|
||||
PixelXDimension FieldName = "PixelXDimension"
|
||||
PixelYDimension FieldName = "PixelYDimension"
|
||||
MakerNote FieldName = "MakerNote"
|
||||
UserComment FieldName = "UserComment"
|
||||
RelatedSoundFile FieldName = "RelatedSoundFile"
|
||||
DateTimeOriginal FieldName = "DateTimeOriginal"
|
||||
DateTimeDigitized FieldName = "DateTimeDigitized"
|
||||
SubSecTime FieldName = "SubSecTime"
|
||||
SubSecTimeOriginal FieldName = "SubSecTimeOriginal"
|
||||
SubSecTimeDigitized FieldName = "SubSecTimeDigitized"
|
||||
ImageUniqueID FieldName = "ImageUniqueID"
|
||||
ExposureTime FieldName = "ExposureTime"
|
||||
FNumber FieldName = "FNumber"
|
||||
ExposureProgram FieldName = "ExposureProgram"
|
||||
SpectralSensitivity FieldName = "SpectralSensitivity"
|
||||
ISOSpeedRatings FieldName = "ISOSpeedRatings"
|
||||
OECF FieldName = "OECF"
|
||||
ShutterSpeedValue FieldName = "ShutterSpeedValue"
|
||||
ApertureValue FieldName = "ApertureValue"
|
||||
BrightnessValue FieldName = "BrightnessValue"
|
||||
ExposureBiasValue FieldName = "ExposureBiasValue"
|
||||
MaxApertureValue FieldName = "MaxApertureValue"
|
||||
SubjectDistance FieldName = "SubjectDistance"
|
||||
MeteringMode FieldName = "MeteringMode"
|
||||
LightSource FieldName = "LightSource"
|
||||
Flash FieldName = "Flash"
|
||||
FocalLength FieldName = "FocalLength"
|
||||
SubjectArea FieldName = "SubjectArea"
|
||||
FlashEnergy FieldName = "FlashEnergy"
|
||||
SpatialFrequencyResponse FieldName = "SpatialFrequencyResponse"
|
||||
FocalPlaneXResolution FieldName = "FocalPlaneXResolution"
|
||||
FocalPlaneYResolution FieldName = "FocalPlaneYResolution"
|
||||
FocalPlaneResolutionUnit FieldName = "FocalPlaneResolutionUnit"
|
||||
SubjectLocation FieldName = "SubjectLocation"
|
||||
ExposureIndex FieldName = "ExposureIndex"
|
||||
SensingMethod FieldName = "SensingMethod"
|
||||
FileSource FieldName = "FileSource"
|
||||
SceneType FieldName = "SceneType"
|
||||
CFAPattern FieldName = "CFAPattern"
|
||||
CustomRendered FieldName = "CustomRendered"
|
||||
ExposureMode FieldName = "ExposureMode"
|
||||
WhiteBalance FieldName = "WhiteBalance"
|
||||
DigitalZoomRatio FieldName = "DigitalZoomRatio"
|
||||
FocalLengthIn35mmFilm FieldName = "FocalLengthIn35mmFilm"
|
||||
SceneCaptureType FieldName = "SceneCaptureType"
|
||||
GainControl FieldName = "GainControl"
|
||||
Contrast FieldName = "Contrast"
|
||||
Saturation FieldName = "Saturation"
|
||||
Sharpness FieldName = "Sharpness"
|
||||
DeviceSettingDescription FieldName = "DeviceSettingDescription"
|
||||
SubjectDistanceRange FieldName = "SubjectDistanceRange"
|
||||
LensMake FieldName = "LensMake"
|
||||
LensModel FieldName = "LensModel"
|
||||
)
|
||||
|
||||
// thumbnail fields
|
||||
const (
|
||||
ThumbJPEGInterchangeFormat = "ThumbJPEGInterchangeFormat" // offset to thumb jpeg SOI
|
||||
ThumbJPEGInterchangeFormatLength = "ThumbJPEGInterchangeFormatLength" // byte length of thumb
|
||||
ThumbJPEGInterchangeFormat FieldName = "ThumbJPEGInterchangeFormat" // offset to thumb jpeg SOI
|
||||
ThumbJPEGInterchangeFormatLength FieldName = "ThumbJPEGInterchangeFormatLength" // byte length of thumb
|
||||
)
|
||||
|
||||
// GPS fields
|
||||
const (
|
||||
GPSVersionID FieldName = "GPSVersionID"
|
||||
GPSLatitudeRef = "GPSLatitudeRef"
|
||||
GPSLatitude = "GPSLatitude"
|
||||
GPSLongitudeRef = "GPSLongitudeRef"
|
||||
GPSLongitude = "GPSLongitude"
|
||||
GPSAltitudeRef = "GPSAltitudeRef"
|
||||
GPSAltitude = "GPSAltitude"
|
||||
GPSTimeStamp = "GPSTimeStamp"
|
||||
GPSSatelites = "GPSSatelites"
|
||||
GPSStatus = "GPSStatus"
|
||||
GPSMeasureMode = "GPSMeasureMode"
|
||||
GPSDOP = "GPSDOP"
|
||||
GPSSpeedRef = "GPSSpeedRef"
|
||||
GPSSpeed = "GPSSpeed"
|
||||
GPSTrackRef = "GPSTrackRef"
|
||||
GPSTrack = "GPSTrack"
|
||||
GPSImgDirectionRef = "GPSImgDirectionRef"
|
||||
GPSImgDirection = "GPSImgDirection"
|
||||
GPSMapDatum = "GPSMapDatum"
|
||||
GPSDestLatitudeRef = "GPSDestLatitudeRef"
|
||||
GPSDestLatitude = "GPSDestLatitude"
|
||||
GPSDestLongitudeRef = "GPSDestLongitudeRef"
|
||||
GPSDestLongitude = "GPSDestLongitude"
|
||||
GPSDestBearingRef = "GPSDestBearingRef"
|
||||
GPSDestBearing = "GPSDestBearing"
|
||||
GPSDestDistanceRef = "GPSDestDistanceRef"
|
||||
GPSDestDistance = "GPSDestDistance"
|
||||
GPSProcessingMethod = "GPSProcessingMethod"
|
||||
GPSAreaInformation = "GPSAreaInformation"
|
||||
GPSDateStamp = "GPSDateStamp"
|
||||
GPSDifferential = "GPSDifferential"
|
||||
GPSLatitudeRef FieldName = "GPSLatitudeRef"
|
||||
GPSLatitude FieldName = "GPSLatitude"
|
||||
GPSLongitudeRef FieldName = "GPSLongitudeRef"
|
||||
GPSLongitude FieldName = "GPSLongitude"
|
||||
GPSAltitudeRef FieldName = "GPSAltitudeRef"
|
||||
GPSAltitude FieldName = "GPSAltitude"
|
||||
GPSTimeStamp FieldName = "GPSTimeStamp"
|
||||
GPSSatelites FieldName = "GPSSatelites"
|
||||
GPSStatus FieldName = "GPSStatus"
|
||||
GPSMeasureMode FieldName = "GPSMeasureMode"
|
||||
GPSDOP FieldName = "GPSDOP"
|
||||
GPSSpeedRef FieldName = "GPSSpeedRef"
|
||||
GPSSpeed FieldName = "GPSSpeed"
|
||||
GPSTrackRef FieldName = "GPSTrackRef"
|
||||
GPSTrack FieldName = "GPSTrack"
|
||||
GPSImgDirectionRef FieldName = "GPSImgDirectionRef"
|
||||
GPSImgDirection FieldName = "GPSImgDirection"
|
||||
GPSMapDatum FieldName = "GPSMapDatum"
|
||||
GPSDestLatitudeRef FieldName = "GPSDestLatitudeRef"
|
||||
GPSDestLatitude FieldName = "GPSDestLatitude"
|
||||
GPSDestLongitudeRef FieldName = "GPSDestLongitudeRef"
|
||||
GPSDestLongitude FieldName = "GPSDestLongitude"
|
||||
GPSDestBearingRef FieldName = "GPSDestBearingRef"
|
||||
GPSDestBearing FieldName = "GPSDestBearing"
|
||||
GPSDestDistanceRef FieldName = "GPSDestDistanceRef"
|
||||
GPSDestDistance FieldName = "GPSDestDistance"
|
||||
GPSProcessingMethod FieldName = "GPSProcessingMethod"
|
||||
GPSAreaInformation FieldName = "GPSAreaInformation"
|
||||
GPSDateStamp FieldName = "GPSDateStamp"
|
||||
GPSDifferential FieldName = "GPSDifferential"
|
||||
)
|
||||
|
||||
// interoperability fields
|
||||
|
||||
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
сгенерированный
поставляемый
@@ -1,60 +0,0 @@
|
||||
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
сгенерированный
поставляемый
@@ -1,268 +0,0 @@
|
||||
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
сгенерированный
поставляемый
@@ -1,70 +0,0 @@
|
||||
// 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
|
||||
}
|
||||
22
vendor/github.com/rwcarlsen/goexif/tiff/tag.go
сгенерированный
поставляемый
@@ -41,17 +41,17 @@ type DataType uint16
|
||||
|
||||
const (
|
||||
DTByte DataType = 1
|
||||
DTAscii = 2
|
||||
DTShort = 3
|
||||
DTLong = 4
|
||||
DTRational = 5
|
||||
DTSByte = 6
|
||||
DTUndefined = 7
|
||||
DTSShort = 8
|
||||
DTSLong = 9
|
||||
DTSRational = 10
|
||||
DTFloat = 11
|
||||
DTDouble = 12
|
||||
DTAscii DataType = 2
|
||||
DTShort DataType = 3
|
||||
DTLong DataType = 4
|
||||
DTRational DataType = 5
|
||||
DTSByte DataType = 6
|
||||
DTUndefined DataType = 7
|
||||
DTSShort DataType = 8
|
||||
DTSLong DataType = 9
|
||||
DTSRational DataType = 10
|
||||
DTFloat DataType = 11
|
||||
DTDouble DataType = 12
|
||||
)
|
||||
|
||||
var typeNames = map[DataType]string{
|
||||
|
||||
235
vendor/github.com/rwcarlsen/goexif/tiff/tiff_test.go
сгенерированный
поставляемый
@@ -1,235 +0,0 @@
|
||||
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
|
||||
}
|
||||