summaryrefslogtreecommitdiff
path: root/vendor/github.com/dsoprea/go-iptc
diff options
context:
space:
mode:
authorLibravatar Tobi Smethurst <31960611+tsmethurst@users.noreply.github.com>2021-08-12 21:03:24 +0200
committerLibravatar GitHub <noreply@github.com>2021-08-12 21:03:24 +0200
commit98263a7de64269898a2f81207e38943b5c8e8653 (patch)
tree743c90f109a6c5d27832d1dcef2388d939f0f77a /vendor/github.com/dsoprea/go-iptc
parentText duplication fix (#137) (diff)
downloadgotosocial-98263a7de64269898a2f81207e38943b5c8e8653.tar.xz
Grand test fixup (#138)
* start fixing up tests * fix up tests + automate with drone * fiddle with linting * messing about with drone.yml * some more fiddling * hmmm * add cache * add vendor directory * verbose * ci updates * update some little things * update sig
Diffstat (limited to 'vendor/github.com/dsoprea/go-iptc')
-rw-r--r--vendor/github.com/dsoprea/go-iptc/.MODULE_ROOT0
-rw-r--r--vendor/github.com/dsoprea/go-iptc/.travis.yml14
-rw-r--r--vendor/github.com/dsoprea/go-iptc/LICENSE21
-rw-r--r--vendor/github.com/dsoprea/go-iptc/README.md8
-rw-r--r--vendor/github.com/dsoprea/go-iptc/go.mod5
-rw-r--r--vendor/github.com/dsoprea/go-iptc/go.sum10
-rw-r--r--vendor/github.com/dsoprea/go-iptc/standard.go101
-rw-r--r--vendor/github.com/dsoprea/go-iptc/tag.go277
-rw-r--r--vendor/github.com/dsoprea/go-iptc/testing_common.go73
-rw-r--r--vendor/github.com/dsoprea/go-iptc/utility.go25
10 files changed, 534 insertions, 0 deletions
diff --git a/vendor/github.com/dsoprea/go-iptc/.MODULE_ROOT b/vendor/github.com/dsoprea/go-iptc/.MODULE_ROOT
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/vendor/github.com/dsoprea/go-iptc/.MODULE_ROOT
diff --git a/vendor/github.com/dsoprea/go-iptc/.travis.yml b/vendor/github.com/dsoprea/go-iptc/.travis.yml
new file mode 100644
index 000000000..710e46b39
--- /dev/null
+++ b/vendor/github.com/dsoprea/go-iptc/.travis.yml
@@ -0,0 +1,14 @@
+language: go
+go:
+ - master
+ - stable
+ - "1.13"
+ - "1.12"
+env:
+ - GO111MODULE=on
+install:
+ - go get -t ./...
+ - go get github.com/mattn/goveralls
+script:
+ - go test -v ./...
+ - goveralls -v -service=travis-ci
diff --git a/vendor/github.com/dsoprea/go-iptc/LICENSE b/vendor/github.com/dsoprea/go-iptc/LICENSE
new file mode 100644
index 000000000..d92c04268
--- /dev/null
+++ b/vendor/github.com/dsoprea/go-iptc/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 Dustin Oprea
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/github.com/dsoprea/go-iptc/README.md b/vendor/github.com/dsoprea/go-iptc/README.md
new file mode 100644
index 000000000..8065d16e4
--- /dev/null
+++ b/vendor/github.com/dsoprea/go-iptc/README.md
@@ -0,0 +1,8 @@
+[![Build Status](https://travis-ci.org/dsoprea/go-iptc.svg?branch=master)](https://travis-ci.org/dsoprea/go-iptc)
+[![Coverage Status](https://coveralls.io/repos/github/dsoprea/go-iptc/badge.svg?branch=master)](https://coveralls.io/github/dsoprea/go-iptc?branch=master)
+[![Go Report Card](https://goreportcard.com/badge/github.com/dsoprea/go-iptc)](https://goreportcard.com/report/github.com/dsoprea/go-iptc)
+[![GoDoc](https://godoc.org/github.com/dsoprea/go-iptc?status.svg)](https://godoc.org/github.com/dsoprea/go-iptc)
+
+# Overview
+
+This project provides functionality to parse a series of IPTC records/datasets. It also provides name resolution, but other constraints/validation is not yet implemented (though there is structure present that can accommodate this when desired/required).
diff --git a/vendor/github.com/dsoprea/go-iptc/go.mod b/vendor/github.com/dsoprea/go-iptc/go.mod
new file mode 100644
index 000000000..45c02f432
--- /dev/null
+++ b/vendor/github.com/dsoprea/go-iptc/go.mod
@@ -0,0 +1,5 @@
+module github.com/dsoprea/go-iptc
+
+go 1.13
+
+require github.com/dsoprea/go-logging v0.0.0-20200517223158-a10564966e9d
diff --git a/vendor/github.com/dsoprea/go-iptc/go.sum b/vendor/github.com/dsoprea/go-iptc/go.sum
new file mode 100644
index 000000000..9d20e12fd
--- /dev/null
+++ b/vendor/github.com/dsoprea/go-iptc/go.sum
@@ -0,0 +1,10 @@
+github.com/dsoprea/go-logging v0.0.0-20200517223158-a10564966e9d h1:F/7L5wr/fP/SKeO5HuMlNEX9Ipyx2MbH2rV9G4zJRpk=
+github.com/dsoprea/go-logging v0.0.0-20200517223158-a10564966e9d/go.mod h1:7I+3Pe2o/YSU88W0hWlm9S22W7XI1JFNJ86U0zPKMf8=
+github.com/go-errors/errors v1.0.2 h1:xMxH9j2fNg/L4hLn/4y3M0IUsn0M6Wbu/Uh9QlOfBh4=
+github.com/go-errors/errors v1.0.2/go.mod h1:psDX2osz5VnTOnFWbDeWwS7yejl+uV3FEWEp4lssFEs=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5 h1:WQ8q63x+f/zpC8Ac1s9wLElVoHhm32p6tudrU72n1QA=
+golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
diff --git a/vendor/github.com/dsoprea/go-iptc/standard.go b/vendor/github.com/dsoprea/go-iptc/standard.go
new file mode 100644
index 000000000..307aa5a87
--- /dev/null
+++ b/vendor/github.com/dsoprea/go-iptc/standard.go
@@ -0,0 +1,101 @@
+package iptc
+
+import (
+ "errors"
+)
+
+// StreamTagInfo encapsulates the properties of each tag.
+type StreamTagInfo struct {
+ // Description is the human-readable description of the tag.
+ Description string
+}
+
+var (
+ standardTags = map[StreamTagKey]StreamTagInfo{
+ {1, 120}: {"ARM Identifier"},
+
+ {1, 122}: {"ARM Version"},
+ {2, 0}: {"Record Version"},
+ {2, 3}: {"Object Type Reference"},
+ {2, 4}: {"Object Attribute Reference"},
+ {2, 5}: {"Object Name"},
+ {2, 7}: {"Edit Status"},
+ {2, 8}: {"Editorial Update"},
+ {2, 10}: {"Urgency"},
+ {2, 12}: {"Subject Reference"},
+ {2, 15}: {"Category"},
+ {2, 20}: {"Supplemental Category"},
+ {2, 22}: {"Fixture Identifier"},
+ {2, 25}: {"Keywords"},
+ {2, 26}: {"Content Location Code"},
+ {2, 27}: {"Content Location Name"},
+ {2, 30}: {"Release Date"},
+ {2, 35}: {"Release Time"},
+ {2, 37}: {"Expiration Date"},
+ {2, 38}: {"Expiration Time"},
+ {2, 40}: {"Special Instructions"},
+ {2, 42}: {"Action Advised"},
+ {2, 45}: {"Reference Service"},
+ {2, 47}: {"Reference Date"},
+ {2, 50}: {"Reference Number"},
+ {2, 55}: {"Date Created"},
+ {2, 60}: {"Time Created"},
+ {2, 62}: {"Digital Creation Date"},
+ {2, 63}: {"Digital Creation Time"},
+ {2, 65}: {"Originating Program"},
+ {2, 70}: {"Program Version"},
+ {2, 75}: {"Object Cycle"},
+ {2, 80}: {"By-line"},
+ {2, 85}: {"By-line Title"},
+ {2, 90}: {"City"},
+ {2, 92}: {"Sublocation"},
+ {2, 95}: {"Province/State"},
+ {2, 100}: {"Country/Primary Location Code"},
+ {2, 101}: {"Country/Primary Location Name"},
+ {2, 103}: {"Original Transmission Reference"},
+ {2, 105}: {"Headline"},
+ {2, 110}: {"Credit"},
+ {2, 115}: {"Source"},
+ {2, 116}: {"Copyright Notice"},
+ {2, 118}: {"Contact"},
+ {2, 120}: {"Caption/Abstract"},
+ {2, 122}: {"Writer/Editor"},
+ {2, 125}: {"Rasterized Caption"},
+ {2, 130}: {"Image Type"},
+ {2, 131}: {"Image Orientation"},
+ {2, 135}: {"Language Identifier"},
+ {2, 150}: {"Audio Type"},
+ {2, 151}: {"Audio Sampling Rate"},
+ {2, 152}: {"Audio Sampling Resolution"},
+ {2, 153}: {"Audio Duration"},
+ {2, 154}: {"Audio Outcue"},
+ {2, 200}: {"ObjectData Preview File Format"},
+ {2, 201}: {"ObjectData Preview File Format Version"},
+ {2, 202}: {"ObjectData Preview Data"},
+ {7, 10}: {"Size Mode"},
+ {7, 20}: {"Max Subfile Size"},
+ {7, 90}: {"ObjectData Size Announced"},
+ {7, 95}: {"Maximum ObjectData Size"},
+ {8, 10}: {"Subfile"},
+ {9, 10}: {"Confirmed ObjectData Size"},
+ }
+)
+
+var (
+ // ErrTagNotStandard indicates that the given tag is not known among the
+ // documented standard set.
+ ErrTagNotStandard = errors.New("not a standard tag")
+)
+
+// GetTagInfo return the info for the given tag. Returns ErrTagNotStandard if
+// not known.
+func GetTagInfo(recordNumber, datasetNumber int) (sti StreamTagInfo, err error) {
+ stk := StreamTagKey{uint8(recordNumber), uint8(datasetNumber)}
+
+ sti, found := standardTags[stk]
+ if found == false {
+ return sti, ErrTagNotStandard
+ }
+
+ return sti, nil
+}
diff --git a/vendor/github.com/dsoprea/go-iptc/tag.go b/vendor/github.com/dsoprea/go-iptc/tag.go
new file mode 100644
index 000000000..4ceabf41d
--- /dev/null
+++ b/vendor/github.com/dsoprea/go-iptc/tag.go
@@ -0,0 +1,277 @@
+package iptc
+
+import (
+ "errors"
+ "fmt"
+ "io"
+ "strings"
+ "unicode"
+
+ "encoding/binary"
+
+ "github.com/dsoprea/go-logging"
+)
+
+var (
+ // TODO(dustin): We're still not sure if this is the right endianness. No search to IPTC or IIM seems to state one or the other.
+
+ // DefaultEncoding is the standard encoding for the IPTC format.
+ defaultEncoding = binary.BigEndian
+)
+
+var (
+ // ErrInvalidTagMarker indicates that the tag can not be parsed because the
+ // tag boundary marker is not the expected value.
+ ErrInvalidTagMarker = errors.New("invalid tag marker")
+)
+
+// Tag describes one tag read from the stream.
+type Tag struct {
+ recordNumber uint8
+ datasetNumber uint8
+ dataSize uint64
+}
+
+// String expresses state as a string.
+func (tag *Tag) String() string {
+ return fmt.Sprintf(
+ "Tag<DATASET=(%d:%d) DATA-SIZE=(%d)>",
+ tag.recordNumber, tag.datasetNumber, tag.dataSize)
+}
+
+// DecodeTag parses one tag from the stream.
+func DecodeTag(r io.Reader) (tag Tag, err error) {
+ defer func() {
+ if state := recover(); state != nil {
+ err = log.Wrap(state.(error))
+ }
+ }()
+
+ tagMarker := uint8(0)
+ err = binary.Read(r, defaultEncoding, &tagMarker)
+ if err != nil {
+ if err == io.EOF {
+ return tag, err
+ }
+
+ log.Panic(err)
+ }
+
+ if tagMarker != 0x1c {
+ return tag, ErrInvalidTagMarker
+ }
+
+ recordNumber := uint8(0)
+ err = binary.Read(r, defaultEncoding, &recordNumber)
+ log.PanicIf(err)
+
+ datasetNumber := uint8(0)
+ err = binary.Read(r, defaultEncoding, &datasetNumber)
+ log.PanicIf(err)
+
+ dataSize16Raw := uint16(0)
+ err = binary.Read(r, defaultEncoding, &dataSize16Raw)
+ log.PanicIf(err)
+
+ var dataSize uint64
+
+ if dataSize16Raw < 32768 {
+ // We only had 16-bits (has the MSB set to (0)).
+ dataSize = uint64(dataSize16Raw)
+ } else {
+ // This field is just the length of the length (has the MSB set to (1)).
+
+ // Clear the MSB.
+ lengthLength := dataSize16Raw & 32767
+
+ if lengthLength == 4 {
+ dataSize32Raw := uint32(0)
+ err := binary.Read(r, defaultEncoding, &dataSize32Raw)
+ log.PanicIf(err)
+
+ dataSize = uint64(dataSize32Raw)
+ } else if lengthLength == 8 {
+ err := binary.Read(r, defaultEncoding, &dataSize)
+ log.PanicIf(err)
+ } else {
+ // No specific sizes or limits are specified in the specification
+ // so we need to impose our own limits in order to implement.
+
+ log.Panicf("extended data-set tag size is not supported: (%d)", lengthLength)
+ }
+ }
+
+ tag = Tag{
+ recordNumber: recordNumber,
+ datasetNumber: datasetNumber,
+ dataSize: dataSize,
+ }
+
+ return tag, nil
+}
+
+// StreamTagKey is a convenience type that lets us key our index with a high-
+// level type.
+type StreamTagKey struct {
+ // RecordNumber is the major classification of the dataset.
+ RecordNumber uint8
+
+ // DatasetNumber is the minor classification of the dataset.
+ DatasetNumber uint8
+}
+
+// String returns a descriptive string.
+func (stk StreamTagKey) String() string {
+ return fmt.Sprintf("%d:%d", stk.RecordNumber, stk.DatasetNumber)
+}
+
+// TagData is a convenience wrapper around a byte-slice.
+type TagData []byte
+
+// IsPrintable returns true if all characters are printable.
+func (tg TagData) IsPrintable() bool {
+ for _, b := range tg {
+ r := rune(b)
+
+ // Newline characters aren't considered printable.
+ if r == 0x0d || r == 0x0a {
+ continue
+ }
+
+ if unicode.IsGraphic(r) == false || unicode.IsPrint(r) == false {
+ return false
+ }
+ }
+
+ return true
+}
+
+// String returns a descriptive string. If the data doesn't include any non-
+// printable characters, it will include the value itself.
+func (tg TagData) String() string {
+ if tg.IsPrintable() == true {
+ return string(tg)
+ }
+
+ return fmt.Sprintf("BINARY<(%d) bytes>", len(tg))
+}
+
+// ParsedTags is the complete, unordered set of tags parsed from the stream.
+type ParsedTags map[StreamTagKey][]TagData
+
+// ParseStream parses a serial sequence of tags and tag data out of the stream.
+func ParseStream(r io.Reader) (tags map[StreamTagKey][]TagData, err error) {
+ defer func() {
+ if state := recover(); state != nil {
+ err = log.Wrap(state.(error))
+ }
+ }()
+
+ tags = make(ParsedTags)
+
+ for {
+ tag, err := DecodeTag(r)
+ if err != nil {
+ if err == io.EOF {
+ break
+ }
+
+ log.Panic(err)
+ }
+
+ raw := make([]byte, tag.dataSize)
+
+ _, err = io.ReadFull(r, raw)
+ log.PanicIf(err)
+
+ data := TagData(raw)
+
+ stk := StreamTagKey{
+ RecordNumber: tag.recordNumber,
+ DatasetNumber: tag.datasetNumber,
+ }
+
+ if existing, found := tags[stk]; found == true {
+ tags[stk] = append(existing, data)
+ } else {
+ tags[stk] = []TagData{data}
+ }
+ }
+
+ return tags, nil
+}
+
+// GetSimpleDictionaryFromParsedTags returns a dictionary of tag names to tag
+// values, where all values are strings and any tag that had a non-printable
+// value is omitted. We will also only return the first value, therefore
+// dropping any follow-up values for repeatable tags. This will ignore non-
+// standard tags. This will trim whitespace from the ends of strings.
+//
+// This is a convenience function for quickly displaying only the summary IPTC
+// metadata that a user might actually be interested in at first glance.
+func GetSimpleDictionaryFromParsedTags(pt ParsedTags) (distilled map[string]string) {
+ distilled = make(map[string]string)
+
+ for stk, dataSlice := range pt {
+ sti, err := GetTagInfo(int(stk.RecordNumber), int(stk.DatasetNumber))
+ if err != nil {
+ if err == ErrTagNotStandard {
+ continue
+ } else {
+ log.Panic(err)
+ }
+ }
+
+ data := dataSlice[0]
+
+ if data.IsPrintable() == false {
+ continue
+ }
+
+ // TODO(dustin): Trim leading whitespace, too.
+ distilled[sti.Description] = strings.Trim(string(data), "\r\n")
+ }
+
+ return distilled
+}
+
+// GetDictionaryFromParsedTags returns all tags. It will keep non-printable
+// values, though will not print a placeholder instead. This will keep non-
+// standard tags (and print the fully-qualified dataset ID rather than the
+// name). It will keep repeated values (with the counter value appended to the
+// end).
+func GetDictionaryFromParsedTags(pt ParsedTags) (distilled map[string]string) {
+ distilled = make(map[string]string)
+ for stk, dataSlice := range pt {
+ var keyPhrase string
+
+ sti, err := GetTagInfo(int(stk.RecordNumber), int(stk.DatasetNumber))
+ if err != nil {
+ if err == ErrTagNotStandard {
+ keyPhrase = fmt.Sprintf("%s (not a standard tag)", stk.String())
+ } else {
+ log.Panic(err)
+ }
+ } else {
+ keyPhrase = sti.Description
+ }
+
+ for i, data := range dataSlice {
+ currentKeyPhrase := keyPhrase
+ if len(dataSlice) > 1 {
+ currentKeyPhrase = fmt.Sprintf("%s (%d)", currentKeyPhrase, i+1)
+ }
+
+ var presentable string
+ if data.IsPrintable() == false {
+ presentable = fmt.Sprintf("[BINARY] %s", DumpBytesToString(data))
+ } else {
+ presentable = string(data)
+ }
+
+ distilled[currentKeyPhrase] = presentable
+ }
+ }
+
+ return distilled
+}
diff --git a/vendor/github.com/dsoprea/go-iptc/testing_common.go b/vendor/github.com/dsoprea/go-iptc/testing_common.go
new file mode 100644
index 000000000..b54b9b8f3
--- /dev/null
+++ b/vendor/github.com/dsoprea/go-iptc/testing_common.go
@@ -0,0 +1,73 @@
+package iptc
+
+import (
+ "os"
+ "path"
+
+ "github.com/dsoprea/go-logging"
+)
+
+var (
+ testDataRelFilepath = "iptc.data"
+)
+
+var (
+ moduleRootPath = ""
+ assetsPath = ""
+)
+
+// GetModuleRootPath returns the root-path of the module.
+func GetModuleRootPath() string {
+ if moduleRootPath == "" {
+ moduleRootPath = os.Getenv("IPTC_MODULE_ROOT_PATH")
+ if moduleRootPath != "" {
+ return moduleRootPath
+ }
+
+ currentWd, err := os.Getwd()
+ log.PanicIf(err)
+
+ currentPath := currentWd
+ visited := make([]string, 0)
+
+ for {
+ tryStampFilepath := path.Join(currentPath, ".MODULE_ROOT")
+
+ _, err := os.Stat(tryStampFilepath)
+ if err != nil && os.IsNotExist(err) != true {
+ log.Panic(err)
+ } else if err == nil {
+ break
+ }
+
+ visited = append(visited, tryStampFilepath)
+
+ currentPath = path.Dir(currentPath)
+ if currentPath == "/" {
+ log.Panicf("could not find module-root: %v", visited)
+ }
+ }
+
+ moduleRootPath = currentPath
+ }
+
+ return moduleRootPath
+}
+
+// GetTestAssetsPath returns the path of the test-assets.
+func GetTestAssetsPath() string {
+ if assetsPath == "" {
+ moduleRootPath := GetModuleRootPath()
+ assetsPath = path.Join(moduleRootPath, "assets")
+ }
+
+ return assetsPath
+}
+
+// GetTestDataFilepath returns the file-path of the common test-data.
+func GetTestDataFilepath() string {
+ assetsPath := GetTestAssetsPath()
+ filepath := path.Join(assetsPath, testDataRelFilepath)
+
+ return filepath
+}
diff --git a/vendor/github.com/dsoprea/go-iptc/utility.go b/vendor/github.com/dsoprea/go-iptc/utility.go
new file mode 100644
index 000000000..5a4a10ad3
--- /dev/null
+++ b/vendor/github.com/dsoprea/go-iptc/utility.go
@@ -0,0 +1,25 @@
+package iptc
+
+import (
+ "bytes"
+ "fmt"
+
+ "github.com/dsoprea/go-logging"
+)
+
+// DumpBytesToString returns a stringified list of hex-encoded bytes.
+func DumpBytesToString(data []byte) string {
+ b := new(bytes.Buffer)
+
+ for i, x := range data {
+ _, err := b.WriteString(fmt.Sprintf("%02x", x))
+ log.PanicIf(err)
+
+ if i < len(data)-1 {
+ _, err := b.WriteRune(' ')
+ log.PanicIf(err)
+ }
+ }
+
+ return b.String()
+}