README

Build Status codecov Go Report Card GoDoc

Overview

This package provides native Go functionality to parse an existing EXIF block, update an existing EXIF block, or add a new EXIF block.

Getting

To get the project and dependencies:

$ go get -t github.com/dsoprea/go-exif/v3

Scope

This project is concerned only with parsing and encoding raw EXIF data. It does not understand specific file-formats. This package assumes you know how to extract the raw EXIF data from a file, such as a JPEG, and, if you want to update it, know how to write it back. File-specific formats are not the concern of go-exif, though we provide exif.SearchAndExtractExif and exif.SearchFileAndExtractExif as brute-force search mechanisms that will help you explore the EXIF information for newer formats that you might not yet have any way to parse.

That said, the author also provides the following projects to support the efficient processing of the corresponding image formats:

See the SetExif example in go-jpeg-image-structure for practical information on getting started with JPEG files.

Usage

The package provides a set of working examples and is covered by unit-tests. Please look to these for getting familiar with how to read and write EXIF.

Create an instance of the Exif type and call Scan() with a byte-slice, where the first byte is the beginning of the raw EXIF data. You may pass a callback that will be invoked for every tag or nil if you do not want one. If no callback is given, you are effectively just validating the structure or parsing of the image.

Obviously, it is most efficient to properly parse the media file and then provide the specific EXIF data to be parsed, but there is also a heuristic for finding the EXIF data within the media blob, directly. This means that, at least for testing or curiosity, you do not have to parse or even understand the format of image or audio file in order to find and decode the EXIF information inside of it. See the usage of the SearchAndExtractExif method in the example.

The library often refers to an IFD with an "IFD path" (e.g. IFD/Exif, IFD/GPSInfo). A "fully-qualified" IFD-path is one that includes an index describing which specific sibling IFD is being referred to if not the first one (e.g. IFD1, the IFD where the thumbnail is expressed per the TIFF standard).

There is an "IFD mapping" and a "tag index" that must be created and passed to the library from the top. These contain all of the knowledge of the IFD hierarchies and their tag-IDs (the IFD mapping) and the tags that they are allowed to host (the tag index). There are convenience functions to load them with the standard TIFF information, but you, alternatively, may choose something totally different (to support parsing any kind of EXIF data that does not follow or is not relevant to TIFF at all).

Standards and Customization

This project is configuration driven. By default, it has no knowledge of tags and IDs until you load them prior to using (which is incorporated in the examples). You are just as easily able to add additional custom IFDs and custom tags for them. If desired, you could completely ignore the standard information and load totally non-standard IFDs and tags.

This would be useful for divergent implementations that add non-standard information to images. It would also be useful if there is some need to just store a flat list of tags in an image for simplified, proprietary usage.

Reader Tool

There is a runnable reading/dumping tool included:

$ go get github.com/dsoprea/go-exif/v3/command/exif-read-tool
$ exif-read-tool -filepath "<media file-path>"

Example output:

IFD-PATH=[IFD] ID=(0x010f) NAME=[Make] COUNT=(6) TYPE=[ASCII] VALUE=[Canon]
IFD-PATH=[IFD] ID=(0x0110) NAME=[Model] COUNT=(22) TYPE=[ASCII] VALUE=[Canon EOS 5D Mark III]
IFD-PATH=[IFD] ID=(0x0112) NAME=[Orientation] COUNT=(1) TYPE=[SHORT] VALUE=[1]
IFD-PATH=[IFD] ID=(0x011a) NAME=[XResolution] COUNT=(1) TYPE=[RATIONAL] VALUE=[72/1]
IFD-PATH=[IFD] ID=(0x011b) NAME=[YResolution] COUNT=(1) TYPE=[RATIONAL] VALUE=[72/1]
IFD-PATH=[IFD] ID=(0x0128) NAME=[ResolutionUnit] COUNT=(1) TYPE=[SHORT] VALUE=[2]
IFD-PATH=[IFD] ID=(0x0132) NAME=[DateTime] COUNT=(20) TYPE=[ASCII] VALUE=[2017:12:02 08:18:50]
...

You can also print the raw, parsed data as JSON:

$ exif-read-tool -filepath "<media file-path>" -json

Example output:

[
    {
        "ifd_path": "IFD",
        "fq_ifd_path": "IFD",
        "ifd_index": 0,
        "tag_id": 271,
        "tag_name": "Make",
        "tag_type_id": 2,
        "tag_type_name": "ASCII",
        "unit_count": 6,
        "value": "Canon",
        "value_string": "Canon"
    },
    {
        "ifd_path": "IFD",
...

Testing

The traditional method:

$ go test github.com/dsoprea/go-exif/v3/...

Release Notes

v3 Release

This release primarily introduces an interchangeable data-layer, where any io.ReadSeeker can be used to read EXIF data rather than necessarily loading the EXIF blob into memory first.

Several backwards-incompatible clean-ups were also included in this release. See releases for more information.

v2 Release

Features a heavily reflowed interface that makes usage much simpler. The undefined-type tag-processing (which affects most photographic images) has also been overhauled and streamlined. It is now complete and stable. Adoption is strongly encouraged.

Contributing

EXIF has an excellently-documented structure but there are a lot of devices and manufacturers out there. There are only so many files that we can personally find to test against, and most of these are images that have been generated only in the past few years. JPEG, being the largest implementor of EXIF, has been around for even longer (but not much). Therefore, there is a lot of compatibility to test for.

If you are able to help by running the included reader-tool against all of the EXIF-compatible files you have, it would be deeply appreciated. This is mostly going to be JPEG files (but not all variations). If you are able to test a large number of files (thousands or millions) then please post an issue mentioning how many files you have processed. If you had failures, then please share them and try to support efforts to understand them.

If you are able to test 100K+ files, I will give you credit on the project. The further back in time your images reach, the higher in the list your name/company will go.

Contributors/Testing

Thank you to the following users for solving non-trivial issues, supporting the project with solving edge-case problems in specific images, or otherwise providing their non-trivial time or image corpus to test go-exif:

In addition to these, it has been tested on my own collection, north of 478K images.

Expand ▾ Collapse ▴

Documentation

Overview

    exif parses raw EXIF information given a block of raw EXIF data.

    v1 of go-exif is now deprecated. Please use v2.

    Index

    Examples

    Constants

    View Source
    const (
    	// ExifAddressableAreaStart is the absolute offset in the file that all
    	// offsets are relative to.
    	ExifAddressableAreaStart = uint32(0x0)
    
    	// ExifDefaultFirstIfdOffset is essentially the number of bytes in addition
    	// to `ExifAddressableAreaStart` that you have to move in order to escape
    	// the rest of the header and get to the earliest point where we can put
    	// stuff (which has to be the first IFD). This is the size of the header
    	// sequence containing the two-character byte-order, two-character fixed-
    	// bytes, and the four bytes describing the first-IFD offset.
    	ExifDefaultFirstIfdOffset = uint32(2 + 2 + 4)
    )
    View Source
    const (
    	IfdStandard = "IFD"
    	IfdExif     = "Exif"
    	IfdGps      = "GPSInfo"
    	IfdIop      = "Iop"
    
    	IfdExifId = 0x8769
    	IfdGpsId  = 0x8825
    	IfdIopId  = 0xA005
    
    	IfdRootId = 0x0000
    
    	IfdPathStandard        = "IFD"
    	IfdPathStandardExif    = "IFD/Exif"
    	IfdPathStandardExifIop = "IFD/Exif/Iop"
    	IfdPathStandardGps     = "IFD/GPSInfo"
    )
    View Source
    const (
    	ThumbnailOffsetTagId = 0x0201
    	ThumbnailSizeTagId   = 0x0202
    
    	TagVersionId = 0x0000
    
    	TagLatitudeId     = 0x0002
    	TagLatitudeRefId  = 0x0001
    	TagLongitudeId    = 0x0004
    	TagLongitudeRefId = 0x0003
    
    	TagTimestampId = 0x0007
    	TagDatestampId = 0x001d
    
    	TagAltitudeId    = 0x0006
    	TagAltitudeRefId = 0x0005
    )
    View Source
    const (
    	TagUnknownType_9298_UserComment_Encoding_ASCII     = iota
    	TagUnknownType_9298_UserComment_Encoding_JIS       = iota
    	TagUnknownType_9298_UserComment_Encoding_UNICODE   = iota
    	TagUnknownType_9298_UserComment_Encoding_UNDEFINED = iota
    )
    View Source
    const (
    	TagUnknownType_9101_ComponentsConfiguration_Channel_Y  = 0x1
    	TagUnknownType_9101_ComponentsConfiguration_Channel_Cb = 0x2
    	TagUnknownType_9101_ComponentsConfiguration_Channel_Cr = 0x3
    	TagUnknownType_9101_ComponentsConfiguration_Channel_R  = 0x4
    	TagUnknownType_9101_ComponentsConfiguration_Channel_G  = 0x5
    	TagUnknownType_9101_ComponentsConfiguration_Channel_B  = 0x6
    )
    View Source
    const (
    	TagUnknownType_9101_ComponentsConfiguration_OTHER = iota
    	TagUnknownType_9101_ComponentsConfiguration_RGB   = iota
    	TagUnknownType_9101_ComponentsConfiguration_YCBCR = iota
    )
    View Source
    const (
    	// Tag-ID + Tag-Type + Unit-Count + Value/Offset.
    	IfdTagEntrySize = uint32(2 + 2 + 4 + 4)
    )
    View Source
    const (
    	UnparseableUnknownTagValuePlaceholder = "!UNKNOWN"
    )

    Variables

    View Source
    var (
    	ErrTagNotFound    = errors.New("tag not found")
    	ErrTagNotStandard = errors.New("tag not a standard tag")
    )
    View Source
    var (
    
    	// EncodeDefaultByteOrder is the default byte-order for encoding operations.
    	EncodeDefaultByteOrder = binary.BigEndian
    
    	// Default byte order for tests.
    	TestDefaultByteOrder = binary.BigEndian
    
    	BigEndianBoBytes    = [2]byte{'M', 'M'}
    	LittleEndianBoBytes = [2]byte{'I', 'I'}
    
    	ByteOrderLookup = map[[2]byte]binary.ByteOrder{
    		BigEndianBoBytes:    binary.BigEndian,
    		LittleEndianBoBytes: binary.LittleEndian,
    	}
    
    	ByteOrderLookupR = map[binary.ByteOrder][2]byte{
    		binary.BigEndian:    BigEndianBoBytes,
    		binary.LittleEndian: LittleEndianBoBytes,
    	}
    
    	ExifFixedBytesLookup = map[binary.ByteOrder][2]byte{
    		binary.LittleEndian: {0x2a, 0x00},
    		binary.BigEndian:    {0x00, 0x2a},
    	}
    )
    View Source
    var (
    	ErrNoExif          = errors.New("no exif data")
    	ErrExifHeaderError = errors.New("exif header error")
    )
    View Source
    var (
    	ErrTagEntryNotFound = errors.New("tag entry not found")
    	ErrChildIbNotFound  = errors.New("child IB not found")
    )
    View Source
    var (
    	ErrNoThumbnail     = errors.New("no thumbnail")
    	ErrNoGpsTags       = errors.New("no gps tags")
    	ErrTagTypeNotValid = errors.New("tag type invalid")
    )
    View Source
    var (
    	// TODO(dustin): Rename TypeNames() to typeNames() and add getter.
    	TypeNames = map[TagTypePrimitive]string{
    		TypeByte:           "BYTE",
    		TypeAscii:          "ASCII",
    		TypeShort:          "SHORT",
    		TypeLong:           "LONG",
    		TypeRational:       "RATIONAL",
    		TypeUndefined:      "UNDEFINED",
    		TypeSignedLong:     "SLONG",
    		TypeSignedRational: "SRATIONAL",
    
    		TypeAsciiNoNul: "_ASCII_NO_NUL",
    	}
    
    	TypeNamesR = map[string]TagTypePrimitive{}
    )
    View Source
    var (
    	// ErrNotEnoughData is used when there isn't enough data to accomodate what
    	// we're trying to parse (sizeof(type) * unit_count).
    	ErrNotEnoughData = errors.New("not enough data for type")
    
    	// ErrWrongType is used when we try to parse anything other than the
    	// current type.
    	ErrWrongType = errors.New("wrong type, can not parse")
    
    	// ErrUnhandledUnknownTag is used when we try to parse a tag that's
    	// recorded as an "unknown" type but not a documented tag (therefore
    	// leaving us not knowning how to read it).
    	ErrUnhandledUnknownTypedTag = errors.New("not a standard unknown-typed tag")
    )
    View Source
    var (
    	ErrChildIfdNotMapped = errors.New("no child-IFD for that tag-ID under parent")
    )
    View Source
    var (
    	ErrGpsCoordinatesNotValid = errors.New("GPS coordinates not valid")
    )
    View Source
    var (
    	ValidGpsVersions = [][4]byte{
    		{2, 2, 0, 0},
    
    		{2, 3, 0, 0},
    	}
    )

    Functions

    func BuildExifHeader

    func BuildExifHeader(byteOrder binary.ByteOrder, firstIfdOffset uint32) (headerBytes []byte, err error)

      BuildExifHeader constructs the bytes that go in the very beginning.

      Example
      Output:
      
      ExifHeader<BYTE-ORDER=[BigEndian] FIRST-IFD-OFFSET=(0x11223344)>
      

      func Collect

      func Collect(ifdMapping *IfdMapping, tagIndex *TagIndex, exifData []byte) (eh ExifHeader, index IfdIndex, err error)

        Collect recursively builds a static structure of all IFDs and tags.

        func DumpBytes

        func DumpBytes(data []byte)

        func DumpBytesClause

        func DumpBytesClause(data []byte)

        func DumpBytesClauseToString

        func DumpBytesClauseToString(data []byte) string

        func DumpBytesToString

        func DumpBytesToString(data []byte) string

        func EncodeStringToBytes

        func EncodeStringToBytes(tagType TagTypePrimitive, valueString string) (value interface{}, err error)

        func EncodeUnknown_9286

        func EncodeUnknown_9286(uc TagUnknownType_9298_UserComment) (encoded []byte, err error)

        func ExifFullTimestampString

        func ExifFullTimestampString(t time.Time) (fullTimestampPhrase string)

          ExifFullTimestampString produces a string like "2018:11:30 13:01:49" from a `time.Time` struct. It will attempt to convert to UTC first.

          Example
          Output:
          
          To EXIF timestamp: [2018:11:30 13:01:49]
          

          func Format

          func Format(rawBytes []byte, tagType TagTypePrimitive, justFirst bool, byteOrder binary.ByteOrder) (value string, err error)

            Format returns a stringified value for the given bytes. Automatically calculates count based on type size.

            func LoadStandardIfds

            func LoadStandardIfds(im *IfdMapping) (err error)

            func LoadStandardTags

            func LoadStandardTags(ti *TagIndex) (err error)

              LoadStandardTags registers the tags that all devices/applications should support.

              func ParseExifFullTimestamp

              func ParseExifFullTimestamp(fullTimestampPhrase string) (timestamp time.Time, err error)

                ParseExifFullTimestamp parses dates like "2018:11:30 13:01:49" into a UTC `time.Time` struct.

                Example
                Output:
                
                To Go timestamp: [2018-11-30T13:01:49Z]
                

                func SearchAndExtractExif

                func SearchAndExtractExif(data []byte) (rawExif []byte, err error)

                  SearchAndExtractExif returns a slice from the beginning of the EXIF data to end of the file (it's not practical to try and calculate where the data actually ends; it needs to be formally parsed).

                  func SearchFileAndExtractExif

                  func SearchFileAndExtractExif(filepath string) (rawExif []byte, err error)

                    SearchFileAndExtractExif returns a slice from the beginning of the EXIF data to the end of the file (it's not practical to try and calculate where the data actually ends).

                    func TagTypeSize

                    func TagTypeSize(tagType TagTypePrimitive) int

                    func UndefinedValue

                    func UndefinedValue(ifdPath string, tagId uint16, valueContext interface{}, byteOrder binary.ByteOrder) (value interface{}, err error)

                      UndefinedValue knows how to resolve the value for most unknown-type tags.

                      Types

                      type BuilderTag

                      type BuilderTag struct {
                      	// contains filtered or unexported fields
                      }

                      func NewBuilderTag

                      func NewBuilderTag(ifdPath string, tagId uint16, typeId TagTypePrimitive, value *IfdBuilderTagValue, byteOrder binary.ByteOrder) *BuilderTag

                      func NewChildIfdBuilderTag

                      func NewChildIfdBuilderTag(ifdPath string, tagId uint16, value *IfdBuilderTagValue) *BuilderTag

                      func NewStandardBuilderTag

                      func NewStandardBuilderTag(ifdPath string, it *IndexedTag, byteOrder binary.ByteOrder, value interface{}) *BuilderTag

                        NewStandardBuilderTag constructs a `BuilderTag` instance. The type is looked up. `ii` is the type of IFD that owns this tag.

                        func (*BuilderTag) SetValue

                        func (bt *BuilderTag) SetValue(byteOrder binary.ByteOrder, value interface{}) (err error)
                        Example
                        Output:
                        
                        

                        func (*BuilderTag) String

                        func (bt *BuilderTag) String() string

                        func (*BuilderTag) Value

                        func (bt *BuilderTag) Value() (value *IfdBuilderTagValue)

                        type ByteWriter

                        type ByteWriter struct {
                        	// contains filtered or unexported fields
                        }

                        func NewByteWriter

                        func NewByteWriter(b *bytes.Buffer, byteOrder binary.ByteOrder) (bw *ByteWriter)

                        func (ByteWriter) WriteFourBytes

                        func (bw ByteWriter) WriteFourBytes(value []byte) (err error)

                        func (ByteWriter) WriteUint16

                        func (bw ByteWriter) WriteUint16(value uint16) (err error)

                        func (ByteWriter) WriteUint32

                        func (bw ByteWriter) WriteUint32(value uint32) (err error)

                        type EncodeableUndefinedValue

                        type EncodeableUndefinedValue struct {
                        	IfdPath    string
                        	TagId      uint16
                        	Parameters interface{}
                        }

                        type EncodedData

                        type EncodedData struct {
                        	Type    TagTypePrimitive
                        	Encoded []byte
                        
                        	// TODO(dustin): Is this really necessary? We might have this just to correlate to the incoming stream format (raw bytes and a unit-count both for incoming and outgoing).
                        	UnitCount uint32
                        }

                          EncodedData encapsulates the compound output of an encoding operation.

                          func EncodeUndefined

                          func EncodeUndefined(ifdPath string, tagId uint16, value interface{}) (ed EncodedData, err error)

                          type ExifHeader

                          type ExifHeader struct {
                          	ByteOrder      binary.ByteOrder
                          	FirstIfdOffset uint32
                          }

                          func ParseExifHeader

                          func ParseExifHeader(data []byte) (eh ExifHeader, err error)

                            ParseExifHeader parses the bytes at the very top of the header.

                            This will panic with ErrNoExif on any data errors so that we can double as an EXIF-detection routine.

                            func Visit

                            func Visit(rootIfdName string, ifdMapping *IfdMapping, tagIndex *TagIndex, exifData []byte, visitor RawTagVisitor) (eh ExifHeader, err error)

                              Visit recursively invokes a callback for every tag.

                              func (ExifHeader) String

                              func (eh ExifHeader) String() string

                              type ExifTag

                              type ExifTag struct {
                              	IfdPath string `json:"ifd_path"`
                              
                              	TagId   uint16 `json:"id"`
                              	TagName string `json:"name"`
                              
                              	TagTypeId   TagTypePrimitive `json:"type_id"`
                              	TagTypeName string           `json:"type_name"`
                              	Value       interface{}      `json:"value"`
                              	ValueBytes  []byte           `json:"value_bytes"`
                              
                              	ChildIfdPath string `json:"child_ifd_path"`
                              }

                                ExifTag is one simple representation of a tag in a flat list of all of them.

                                func GetFlatExifData

                                func GetFlatExifData(exifData []byte) (exifTags []ExifTag, err error)

                                  GetFlatExifData returns a simple, flat representation of all tags.

                                  func (ExifTag) String

                                  func (et ExifTag) String() string

                                    String returns a string representation.

                                    type GpsDegrees

                                    type GpsDegrees struct {
                                    	Orientation               byte
                                    	Degrees, Minutes, Seconds float64
                                    }

                                    func (GpsDegrees) Decimal

                                    func (d GpsDegrees) Decimal() float64

                                    func (GpsDegrees) String

                                    func (d GpsDegrees) String() string

                                    type GpsInfo

                                    type GpsInfo struct {
                                    	Latitude, Longitude GpsDegrees
                                    	Altitude            int
                                    	Timestamp           time.Time
                                    }

                                    func (*GpsInfo) S2CellId

                                    func (gi *GpsInfo) S2CellId() s2.CellID

                                    func (*GpsInfo) String

                                    func (gi *GpsInfo) String() string

                                    type Ifd

                                    type Ifd struct {
                                    	ByteOrder binary.ByteOrder
                                    
                                    	// Name is the name of the IFD (the rightmost name in the path, sans any
                                    	// indices).
                                    	Name string
                                    
                                    	// IfdPath is a simple IFD path (e.g. IFD/GPSInfo). No indices.
                                    	IfdPath string
                                    
                                    	// FqIfdPath is a fully-qualified IFD path (e.g. IFD0/GPSInfo0). With
                                    	// indices.
                                    	FqIfdPath string
                                    
                                    	TagId uint16
                                    
                                    	Id int
                                    
                                    	ParentIfd *Ifd
                                    
                                    	// ParentTagIndex is our tag position in the parent IFD, if we had a parent
                                    	// (if `ParentIfd` is not nil and we weren't an IFD referenced as a sibling
                                    	// instead of as a child).
                                    	ParentTagIndex int
                                    
                                    	// Name   string
                                    	Index  int
                                    	Offset uint32
                                    
                                    	Entries        []*IfdTagEntry
                                    	EntriesByTagId map[uint16][]*IfdTagEntry
                                    
                                    	Children []*Ifd
                                    
                                    	ChildIfdIndex map[string]*Ifd
                                    
                                    	NextIfdOffset uint32
                                    	NextIfd       *Ifd
                                    	// contains filtered or unexported fields
                                    }

                                      Ifd represents a single parsed IFD.

                                      func FindIfdFromRootIfd

                                      func FindIfdFromRootIfd(rootIfd *Ifd, ifdPath string) (ifd *Ifd, err error)

                                      func (*Ifd) ChildWithIfdPath

                                      func (ifd *Ifd) ChildWithIfdPath(ifdPath string) (childIfd *Ifd, err error)

                                      func (*Ifd) DumpTags

                                      func (ifd *Ifd) DumpTags() []*IfdTagEntry

                                        DumpTags prints the IFD hierarchy.

                                        func (*Ifd) DumpTree

                                        func (ifd *Ifd) DumpTree() []string

                                          DumpTree returns a list of strings describing the IFD hierarchy.

                                          func (*Ifd) EnumerateTagsRecursively

                                          func (ifd *Ifd) EnumerateTagsRecursively(visitor ParsedTagVisitor) (err error)
                                          Example
                                          Output:
                                          
                                          

                                          func (*Ifd) FindTagWithId

                                          func (ifd *Ifd) FindTagWithId(tagId uint16) (results []*IfdTagEntry, err error)

                                            FindTagWithId returns a list of tags (usually just zero or one) that match the given tag ID. This is efficient.

                                            func (*Ifd) FindTagWithName

                                            func (ifd *Ifd) FindTagWithName(tagName string) (results []*IfdTagEntry, err error)

                                              FindTagWithName returns a list of tags (usually just zero or one) that match the given tag name. This is not efficient (though the labor is trivial).

                                              Example
                                              Output:
                                              
                                              Canon EOS 5D Mark III
                                              

                                              func (*Ifd) GetValueContext

                                              func (ifd *Ifd) GetValueContext(ite *IfdTagEntry) *ValueContext

                                              func (*Ifd) GpsInfo

                                              func (ifd *Ifd) GpsInfo() (gi *GpsInfo, err error)

                                                GpsInfo parses and consolidates the GPS info. This can only be called on the GPS IFD.

                                                Example
                                                Output:
                                                
                                                GpsInfo<LAT=(26.58667) LON=(-80.05361) ALT=(0) TIME=[2018-04-29 01:22:57 +0000 UTC]>
                                                

                                                func (*Ifd) PrintIfdTree

                                                func (ifd *Ifd) PrintIfdTree()

                                                  PrintIfdTree prints the IFD hierarchy.

                                                  func (*Ifd) PrintTagTree

                                                  func (ifd *Ifd) PrintTagTree(populateValues bool)

                                                    PrintTagTree prints the IFD hierarchy.

                                                    func (Ifd) String

                                                    func (ifd Ifd) String() string

                                                    func (*Ifd) TagValue

                                                    func (ifd *Ifd) TagValue(ite *IfdTagEntry) (value interface{}, err error)

                                                    func (*Ifd) TagValueBytes

                                                    func (ifd *Ifd) TagValueBytes(ite *IfdTagEntry) (value []byte, err error)

                                                    func (*Ifd) Thumbnail

                                                    func (ifd *Ifd) Thumbnail() (data []byte, err error)
                                                    Example
                                                    Output:
                                                    
                                                    

                                                    type IfdBuilder

                                                    type IfdBuilder struct {
                                                    	// contains filtered or unexported fields
                                                    }

                                                    func GetOrCreateIbFromRootIb

                                                    func GetOrCreateIbFromRootIb(rootIb *IfdBuilder, fqIfdPath string) (ib *IfdBuilder, err error)

                                                      GetOrCreateIbFromRootIb returns an IB representing the requested IFD, even if an IB doesn't already exist for it. This function may call itself recursively.

                                                      func NewIfdBuilder

                                                      func NewIfdBuilder(ifdMapping *IfdMapping, tagIndex *TagIndex, fqIfdPath string, byteOrder binary.ByteOrder) (ib *IfdBuilder)

                                                      func NewIfdBuilderFromExistingChain

                                                      func NewIfdBuilderFromExistingChain(rootIfd *Ifd, itevr *IfdTagEntryValueResolver) (firstIb *IfdBuilder)

                                                        NewIfdBuilderFromExistingChain creates a chain of IB instances from an IFD chain generated from real data.

                                                        func NewIfdBuilderWithExistingIfd

                                                        func NewIfdBuilderWithExistingIfd(ifd *Ifd) (ib *IfdBuilder)

                                                          NewIfdBuilderWithExistingIfd creates a new IB using the same header type information as the given IFD.

                                                          func (*IfdBuilder) Add

                                                          func (ib *IfdBuilder) Add(bt *BuilderTag) (err error)

                                                          func (*IfdBuilder) AddChildIb

                                                          func (ib *IfdBuilder) AddChildIb(childIb *IfdBuilder) (err error)

                                                            AddChildIb adds a tag that branches to a new IFD.

                                                            func (*IfdBuilder) AddStandard

                                                            func (ib *IfdBuilder) AddStandard(tagId uint16, value interface{}) (err error)

                                                              AddStandard quickly and easily composes and adds the tag using the information already known about a tag. Only works with standard tags.

                                                              func (*IfdBuilder) AddStandardWithName

                                                              func (ib *IfdBuilder) AddStandardWithName(tagName string, value interface{}) (err error)

                                                                AddStandardWithName quickly and easily composes and adds the tag using the information already known about a tag (using the name). Only works with standard tags.

                                                                func (*IfdBuilder) AddTagsFromExisting

                                                                func (ib *IfdBuilder) AddTagsFromExisting(ifd *Ifd, itevr *IfdTagEntryValueResolver, includeTagIds []uint16, excludeTagIds []uint16) (err error)

                                                                  AddTagsFromExisting does a verbatim copy of the entries in `ifd` to this builder. It excludes child IFDs. These must be added explicitly via `AddChildIb()`.

                                                                  func (*IfdBuilder) ChildWithTagId

                                                                  func (ib *IfdBuilder) ChildWithTagId(childIfdTagId uint16) (childIb *IfdBuilder, err error)

                                                                  func (*IfdBuilder) DeleteAll

                                                                  func (ib *IfdBuilder) DeleteAll(tagId uint16) (n int, err error)

                                                                  func (*IfdBuilder) DeleteFirst

                                                                  func (ib *IfdBuilder) DeleteFirst(tagId uint16) (err error)

                                                                  func (*IfdBuilder) DeleteN

                                                                  func (ib *IfdBuilder) DeleteN(tagId uint16, n int) (err error)

                                                                  func (*IfdBuilder) DumpToStrings

                                                                  func (ib *IfdBuilder) DumpToStrings() (lines []string)

                                                                  func (*IfdBuilder) Find

                                                                  func (ib *IfdBuilder) Find(tagId uint16) (position int, err error)

                                                                  func (*IfdBuilder) FindN

                                                                  func (ib *IfdBuilder) FindN(tagId uint16, maxFound int) (found []int, err error)

                                                                  func (*IfdBuilder) FindTag

                                                                  func (ib *IfdBuilder) FindTag(tagId uint16) (bt *BuilderTag, err error)

                                                                  func (*IfdBuilder) FindTagWithName

                                                                  func (ib *IfdBuilder) FindTagWithName(tagName string) (bt *BuilderTag, err error)

                                                                  func (*IfdBuilder) NewBuilderTagFromBuilder

                                                                  func (ib *IfdBuilder) NewBuilderTagFromBuilder(childIb *IfdBuilder) (bt *BuilderTag)

                                                                  func (*IfdBuilder) NextIb

                                                                  func (ib *IfdBuilder) NextIb() (nextIb *IfdBuilder, err error)

                                                                  func (*IfdBuilder) PrintIfdTree

                                                                  func (ib *IfdBuilder) PrintIfdTree()

                                                                  func (*IfdBuilder) PrintTagTree

                                                                  func (ib *IfdBuilder) PrintTagTree()

                                                                  func (*IfdBuilder) Replace

                                                                  func (ib *IfdBuilder) Replace(tagId uint16, bt *BuilderTag) (err error)

                                                                  func (*IfdBuilder) ReplaceAt

                                                                  func (ib *IfdBuilder) ReplaceAt(position int, bt *BuilderTag) (err error)

                                                                  func (*IfdBuilder) Set

                                                                  func (ib *IfdBuilder) Set(bt *BuilderTag) (err error)

                                                                    Set will add a new entry or update an existing entry.

                                                                    func (*IfdBuilder) SetNextIb

                                                                    func (ib *IfdBuilder) SetNextIb(nextIb *IfdBuilder) (err error)

                                                                    func (*IfdBuilder) SetStandard

                                                                    func (ib *IfdBuilder) SetStandard(tagId uint16, value interface{}) (err error)

                                                                      SetStandard quickly and easily composes and adds or replaces the tag using the information already known about a tag. Only works with standard tags.

                                                                      func (*IfdBuilder) SetStandardWithName

                                                                      func (ib *IfdBuilder) SetStandardWithName(tagName string, value interface{}) (err error)

                                                                        SetStandardWithName quickly and easily composes and adds or replaces the tag using the information already known about a tag (using the name). Only works with standard tags.

                                                                        Example

                                                                          ExampleIfdBuilder_SetStandardWithName establishes a chain of `IfdBuilder` structs from an existing chain of `Ifd` structs, navigates to the IB representing IFD0, updates the ProcessingSoftware tag to a different value, encodes down to a new EXIF block, reparses, and validates that the value for that tag is what we set it to.

                                                                          Output:
                                                                          
                                                                          alternative software
                                                                          

                                                                          func (*IfdBuilder) SetThumbnail

                                                                          func (ib *IfdBuilder) SetThumbnail(data []byte) (err error)

                                                                            SetThumbnail sets thumbnail data.

                                                                            NOTES:

                                                                            - We don't manage any facet of the thumbnail data. This is the

                                                                            responsibility of the user/developer.
                                                                            

                                                                            - This method will fail unless the thumbnail is set on a the root IFD.

                                                                            However, in order to be valid, it must be set on the second one, linked to
                                                                            by the first, as per the EXIF/TIFF specification.
                                                                            

                                                                            - We set the offset to (0) now but will allocate the data and properly assign

                                                                            the offset when the IB is encoded (later).
                                                                            

                                                                            func (*IfdBuilder) String

                                                                            func (ib *IfdBuilder) String() string

                                                                            func (*IfdBuilder) Tags

                                                                            func (ib *IfdBuilder) Tags() (tags []*BuilderTag)

                                                                            func (*IfdBuilder) Thumbnail

                                                                            func (ib *IfdBuilder) Thumbnail() []byte

                                                                            type IfdBuilderTagValue

                                                                            type IfdBuilderTagValue struct {
                                                                            	// contains filtered or unexported fields
                                                                            }

                                                                            func NewIfdBuilderTagValueFromBytes

                                                                            func NewIfdBuilderTagValueFromBytes(valueBytes []byte) *IfdBuilderTagValue

                                                                            func NewIfdBuilderTagValueFromIfdBuilder

                                                                            func NewIfdBuilderTagValueFromIfdBuilder(ib *IfdBuilder) *IfdBuilderTagValue

                                                                            func (IfdBuilderTagValue) Bytes

                                                                            func (ibtv IfdBuilderTagValue) Bytes() []byte

                                                                            func (IfdBuilderTagValue) Ib

                                                                            func (ibtv IfdBuilderTagValue) Ib() *IfdBuilder

                                                                            func (IfdBuilderTagValue) IsBytes

                                                                            func (ibtv IfdBuilderTagValue) IsBytes() bool

                                                                              IsBytes returns true if the bytes are populated. This is always the case when we're loaded from a tag in an existing IFD.

                                                                              func (IfdBuilderTagValue) IsIb

                                                                              func (ibtv IfdBuilderTagValue) IsIb() bool

                                                                              func (IfdBuilderTagValue) String

                                                                              func (ibtv IfdBuilderTagValue) String() string

                                                                              type IfdByteEncoder

                                                                              type IfdByteEncoder struct {
                                                                              	// contains filtered or unexported fields
                                                                              }

                                                                                IfdByteEncoder converts an IB to raw bytes (for writing) while also figuring out all of the allocations and indirection that is required for extended data.

                                                                                func NewIfdByteEncoder

                                                                                func NewIfdByteEncoder() (ibe *IfdByteEncoder)

                                                                                func (*IfdByteEncoder) EncodeToExif

                                                                                func (ibe *IfdByteEncoder) EncodeToExif(ib *IfdBuilder) (data []byte, err error)

                                                                                  EncodeToExif calls EncodeToExifPayload and then packages the result into a complete EXIF block.

                                                                                  Example
                                                                                  Output:
                                                                                  
                                                                                  
                                                                                  0: IfdTagEntry<TAG-IFD-PATH=[IFD] TAG-ID=(0x000b) TAG-TYPE=[ASCII] UNIT-COUNT=(11)> [asciivalue]
                                                                                  1: IfdTagEntry<TAG-IFD-PATH=[IFD] TAG-ID=(0x0150) TAG-TYPE=[BYTE] UNIT-COUNT=(1)> [[17]]
                                                                                  2: IfdTagEntry<TAG-IFD-PATH=[IFD] TAG-ID=(0x00ff) TAG-TYPE=[SHORT] UNIT-COUNT=(1)> [[8755]]
                                                                                  3: IfdTagEntry<TAG-IFD-PATH=[IFD] TAG-ID=(0x0100) TAG-TYPE=[LONG] UNIT-COUNT=(1)> [[1146447479]]
                                                                                  4: IfdTagEntry<TAG-IFD-PATH=[IFD] TAG-ID=(0x013e) TAG-TYPE=[RATIONAL] UNIT-COUNT=(1)> [[{286335522 858997828}]]
                                                                                  5: IfdTagEntry<TAG-IFD-PATH=[IFD] TAG-ID=(0x9201) TAG-TYPE=[SRATIONAL] UNIT-COUNT=(1)> [[{286335522 858997828}]]
                                                                                  

                                                                                  func (*IfdByteEncoder) EncodeToExifPayload

                                                                                  func (ibe *IfdByteEncoder) EncodeToExifPayload(ib *IfdBuilder) (data []byte, err error)

                                                                                    EncodeToExifPayload is the base encoding step that transcribes the entire IB structure to its on-disk layout.

                                                                                    func (*IfdByteEncoder) Journal

                                                                                    func (ibe *IfdByteEncoder) Journal() [][3]string

                                                                                    func (*IfdByteEncoder) PrintJournal

                                                                                    func (ibe *IfdByteEncoder) PrintJournal()

                                                                                      PrintJournal prints a hierarchical representation of the steps taken during encoding.

                                                                                      func (*IfdByteEncoder) TableSize

                                                                                      func (ibe *IfdByteEncoder) TableSize(entryCount int) uint32

                                                                                      type IfdEnumerate

                                                                                      type IfdEnumerate struct {
                                                                                      	// contains filtered or unexported fields
                                                                                      }

                                                                                      func NewIfdEnumerate

                                                                                      func NewIfdEnumerate(ifdMapping *IfdMapping, tagIndex *TagIndex, exifData []byte, byteOrder binary.ByteOrder) *IfdEnumerate

                                                                                      func (*IfdEnumerate) Collect

                                                                                      func (ie *IfdEnumerate) Collect(rootIfdOffset uint32, resolveValues bool) (index IfdIndex, err error)

                                                                                        Scan enumerates the different EXIF blocks (called IFDs).

                                                                                        func (*IfdEnumerate) GetValueContext

                                                                                        func (ie *IfdEnumerate) GetValueContext(ite *IfdTagEntry) *ValueContext

                                                                                        func (*IfdEnumerate) ParseIfd

                                                                                        func (ie *IfdEnumerate) ParseIfd(fqIfdPath string, ifdIndex int, ite *IfdTagEnumerator, visitor interface{}, doDescend bool, resolveValues bool) (nextIfdOffset uint32, entries []*IfdTagEntry, thumbnailData []byte, err error)

                                                                                          ParseIfd decodes the IFD block that we're currently sitting on the first byte of.

                                                                                          func (*IfdEnumerate) Scan

                                                                                          func (ie *IfdEnumerate) Scan(rootIfdName string, ifdOffset uint32, visitor RawTagVisitor, resolveValue bool) (err error)

                                                                                            Scan enumerates the different EXIF blocks (called IFDs). `rootIfdName` will be "IFD" in the TIFF standard.

                                                                                            type IfdIndex

                                                                                            type IfdIndex struct {
                                                                                            	RootIfd *Ifd
                                                                                            	Ifds    []*Ifd
                                                                                            	Tree    map[int]*Ifd
                                                                                            	Lookup  map[string][]*Ifd
                                                                                            }

                                                                                            type IfdMapping

                                                                                            type IfdMapping struct {
                                                                                            	// contains filtered or unexported fields
                                                                                            }

                                                                                              IfdMapping describes all of the IFDs that we currently recognize.

                                                                                              func NewIfdMapping

                                                                                              func NewIfdMapping() (ifdMapping *IfdMapping)

                                                                                              func NewIfdMappingWithStandard

                                                                                              func NewIfdMappingWithStandard() (ifdMapping *IfdMapping)

                                                                                              func (*IfdMapping) Add

                                                                                              func (im *IfdMapping) Add(parentPlacement []uint16, tagId uint16, name string) (err error)

                                                                                                Add puts the given IFD at the given position of the tree. The position of the tree is referred to as the placement and is represented by a set of tag-IDs, where the leftmost is the root tag and the tags going to the right are progressive descendants.

                                                                                                func (*IfdMapping) DumpLineages

                                                                                                func (im *IfdMapping) DumpLineages() (output []string, err error)

                                                                                                func (*IfdMapping) FqPathPhraseFromLineage

                                                                                                func (im *IfdMapping) FqPathPhraseFromLineage(lineage []IfdTagIdAndIndex) (fqPathPhrase string)

                                                                                                func (*IfdMapping) Get

                                                                                                func (im *IfdMapping) Get(parentPlacement []uint16) (childIfd *MappedIfd, err error)

                                                                                                func (*IfdMapping) GetChild

                                                                                                func (im *IfdMapping) GetChild(parentPathPhrase string, tagId uint16) (mi *MappedIfd, err error)

                                                                                                  GetChild is a convenience function to get the child path for a given parent placement and child tag-ID.

                                                                                                  func (*IfdMapping) GetWithPath

                                                                                                  func (im *IfdMapping) GetWithPath(pathPhrase string) (mi *MappedIfd, err error)

                                                                                                  func (*IfdMapping) PathPhraseFromLineage

                                                                                                  func (im *IfdMapping) PathPhraseFromLineage(lineage []IfdTagIdAndIndex) (pathPhrase string)

                                                                                                  func (*IfdMapping) ResolvePath

                                                                                                  func (im *IfdMapping) ResolvePath(pathPhrase string) (lineage []IfdTagIdAndIndex, err error)

                                                                                                    ResolvePath takes a list of names, which can also be suffixed with indices (to identify the second, third, etc.. sibling IFD) and returns a list of tag-IDs and those indices.

                                                                                                    Example:

                                                                                                    - IFD/Exif/Iop - IFD0/Exif/Iop

                                                                                                    This is the only call that supports adding the numeric indices.

                                                                                                    func (*IfdMapping) StripPathPhraseIndices

                                                                                                    func (im *IfdMapping) StripPathPhraseIndices(pathPhrase string) (strippedPathPhrase string, err error)

                                                                                                      StripPathPhraseIndices returns a non-fully-qualified path-phrase (no indices).

                                                                                                      type IfdTagEntry

                                                                                                      type IfdTagEntry struct {
                                                                                                      	TagId          uint16
                                                                                                      	TagIndex       int
                                                                                                      	TagType        TagTypePrimitive
                                                                                                      	UnitCount      uint32
                                                                                                      	ValueOffset    uint32
                                                                                                      	RawValueOffset []byte
                                                                                                      
                                                                                                      	// ChildIfdName is the right most atom in the IFD-path. We need this to
                                                                                                      	// construct the fully-qualified IFD-path.
                                                                                                      	ChildIfdName string
                                                                                                      
                                                                                                      	// ChildIfdPath is the IFD-path of the child if this tag represents a child
                                                                                                      	// IFD.
                                                                                                      	ChildIfdPath string
                                                                                                      
                                                                                                      	// ChildFqIfdPath is the IFD-path of the child if this tag represents a
                                                                                                      	// child IFD. Includes indices.
                                                                                                      	ChildFqIfdPath string
                                                                                                      
                                                                                                      	// IfdPath is the IFD that this tag belongs to.
                                                                                                      	IfdPath string
                                                                                                      	// contains filtered or unexported fields
                                                                                                      }

                                                                                                      func ParseOneIfd

                                                                                                      func ParseOneIfd(ifdMapping *IfdMapping, tagIndex *TagIndex, fqIfdPath, ifdPath string, byteOrder binary.ByteOrder, ifdBlock []byte, visitor RawTagVisitor, resolveValues bool) (nextIfdOffset uint32, entries []*IfdTagEntry, err error)

                                                                                                        ParseOneIfd is a hack to use an IE to parse a raw IFD block. Can be used for testing.

                                                                                                        func ParseOneTag

                                                                                                        func ParseOneTag(ifdMapping *IfdMapping, tagIndex *TagIndex, fqIfdPath, ifdPath string, byteOrder binary.ByteOrder, tagBlock []byte, resolveValue bool) (tag *IfdTagEntry, err error)

                                                                                                          ParseOneTag is a hack to use an IE to parse a raw tag block.

                                                                                                          func (*IfdTagEntry) String

                                                                                                          func (ite *IfdTagEntry) String() string

                                                                                                          func (*IfdTagEntry) Value

                                                                                                          func (ite *IfdTagEntry) Value(addressableData []byte, byteOrder binary.ByteOrder) (value interface{}, err error)

                                                                                                            Value returns the specific, parsed, typed value from the tag.

                                                                                                            func (*IfdTagEntry) ValueBytes

                                                                                                            func (ite *IfdTagEntry) ValueBytes(addressableData []byte, byteOrder binary.ByteOrder) (value []byte, err error)

                                                                                                              ValueBytes renders a specific list of bytes from the value in this tag.

                                                                                                              func (*IfdTagEntry) ValueString

                                                                                                              func (ite *IfdTagEntry) ValueString(addressableData []byte, byteOrder binary.ByteOrder) (value string, err error)

                                                                                                                ValueString renders a string from whatever the value in this tag is.

                                                                                                                type IfdTagEntryValueResolver

                                                                                                                type IfdTagEntryValueResolver struct {
                                                                                                                	// contains filtered or unexported fields
                                                                                                                }

                                                                                                                  IfdTagEntryValueResolver instances know how to resolve the values for any tag for a particular EXIF block.

                                                                                                                  func NewIfdTagEntryValueResolver

                                                                                                                  func NewIfdTagEntryValueResolver(exifData []byte, byteOrder binary.ByteOrder) (itevr *IfdTagEntryValueResolver)

                                                                                                                  func (*IfdTagEntryValueResolver) Value

                                                                                                                  func (itevr *IfdTagEntryValueResolver) Value(ite *IfdTagEntry) (value interface{}, err error)

                                                                                                                  func (*IfdTagEntryValueResolver) ValueBytes

                                                                                                                  func (itevr *IfdTagEntryValueResolver) ValueBytes(ite *IfdTagEntry) (value []byte, err error)

                                                                                                                    ValueBytes will resolve embedded or allocated data from the tag and return the raw bytes.

                                                                                                                    type IfdTagEnumerator

                                                                                                                    type IfdTagEnumerator struct {
                                                                                                                    	// contains filtered or unexported fields
                                                                                                                    }

                                                                                                                      IfdTagEnumerator knows how to decode an IFD and all of the tags it describes.

                                                                                                                      The IFDs and the actual values can float throughout the EXIF block, but the IFD itself is just a minor header followed by a set of repeating, statically-sized records. So, the tags (though notnecessarily their values) are fairly simple to enumerate.

                                                                                                                      func NewIfdTagEnumerator

                                                                                                                      func NewIfdTagEnumerator(addressableData []byte, byteOrder binary.ByteOrder, ifdOffset uint32) (ite *IfdTagEnumerator)

                                                                                                                      type IfdTagIdAndIndex

                                                                                                                      type IfdTagIdAndIndex struct {
                                                                                                                      	Name  string
                                                                                                                      	TagId uint16
                                                                                                                      	Index int
                                                                                                                      }

                                                                                                                      func (IfdTagIdAndIndex) String

                                                                                                                      func (itii IfdTagIdAndIndex) String() string

                                                                                                                      type IndexedTag

                                                                                                                      type IndexedTag struct {
                                                                                                                      	Id      uint16
                                                                                                                      	Name    string
                                                                                                                      	IfdPath string
                                                                                                                      	Type    TagTypePrimitive
                                                                                                                      }

                                                                                                                      func (*IndexedTag) Is

                                                                                                                      func (it *IndexedTag) Is(ifdPath string, id uint16) bool

                                                                                                                      func (*IndexedTag) IsName

                                                                                                                      func (it *IndexedTag) IsName(ifdPath, name string) bool

                                                                                                                      func (*IndexedTag) String

                                                                                                                      func (it *IndexedTag) String() string

                                                                                                                      type MappedIfd

                                                                                                                      type MappedIfd struct {
                                                                                                                      	ParentTagId uint16
                                                                                                                      	Placement   []uint16
                                                                                                                      	Path        []string
                                                                                                                      
                                                                                                                      	Name     string
                                                                                                                      	TagId    uint16
                                                                                                                      	Children map[uint16]*MappedIfd
                                                                                                                      }

                                                                                                                      func (*MappedIfd) PathPhrase

                                                                                                                      func (mi *MappedIfd) PathPhrase() string

                                                                                                                      func (*MappedIfd) String

                                                                                                                      func (mi *MappedIfd) String() string

                                                                                                                      type ParsedTagVisitor

                                                                                                                      type ParsedTagVisitor func(*Ifd, *IfdTagEntry) error

                                                                                                                      type Parser

                                                                                                                      type Parser struct {
                                                                                                                      }

                                                                                                                      func (*Parser) ParseAscii

                                                                                                                      func (p *Parser) ParseAscii(data []byte, unitCount uint32) (value string, err error)

                                                                                                                        ParseAscii returns a string and auto-strips the trailing NUL character.

                                                                                                                        func (*Parser) ParseAsciiNoNul

                                                                                                                        func (p *Parser) ParseAsciiNoNul(data []byte, unitCount uint32) (value string, err error)

                                                                                                                          ParseAsciiNoNul returns a string without any consideration for a trailing NUL character.

                                                                                                                          func (*Parser) ParseBytes

                                                                                                                          func (p *Parser) ParseBytes(data []byte, unitCount uint32) (value []uint8, err error)

                                                                                                                          func (*Parser) ParseLongs

                                                                                                                          func (p *Parser) ParseLongs(data []byte, unitCount uint32, byteOrder binary.ByteOrder) (value []uint32, err error)

                                                                                                                          func (*Parser) ParseRationals

                                                                                                                          func (p *Parser) ParseRationals(data []byte, unitCount uint32, byteOrder binary.ByteOrder) (value []Rational, err error)

                                                                                                                          func (*Parser) ParseShorts

                                                                                                                          func (p *Parser) ParseShorts(data []byte, unitCount uint32, byteOrder binary.ByteOrder) (value []uint16, err error)

                                                                                                                          func (*Parser) ParseSignedLongs

                                                                                                                          func (p *Parser) ParseSignedLongs(data []byte, unitCount uint32, byteOrder binary.ByteOrder) (value []int32, err error)

                                                                                                                          func (*Parser) ParseSignedRationals

                                                                                                                          func (p *Parser) ParseSignedRationals(data []byte, unitCount uint32, byteOrder binary.ByteOrder) (value []SignedRational, err error)

                                                                                                                          type QueuedIfd

                                                                                                                          type QueuedIfd struct {
                                                                                                                          	Name      string
                                                                                                                          	IfdPath   string
                                                                                                                          	FqIfdPath string
                                                                                                                          
                                                                                                                          	TagId uint16
                                                                                                                          
                                                                                                                          	Index  int
                                                                                                                          	Offset uint32
                                                                                                                          	Parent *Ifd
                                                                                                                          
                                                                                                                          	// ParentTagIndex is our tag position in the parent IFD, if we had a parent
                                                                                                                          	// (if `ParentIfd` is not nil and we weren't an IFD referenced as a sibling
                                                                                                                          	// instead of as a child).
                                                                                                                          	ParentTagIndex int
                                                                                                                          }

                                                                                                                          type Rational

                                                                                                                          type Rational struct {
                                                                                                                          	Numerator   uint32
                                                                                                                          	Denominator uint32
                                                                                                                          }

                                                                                                                          type RawTagVisitor

                                                                                                                          type RawTagVisitor func(fqIfdPath string, ifdIndex int, tagId uint16, tagType TagType, valueContext ValueContext) (err error)

                                                                                                                            RawTagVisitor is an optional callback that can get hit for every tag we parse through. `addressableData` is the byte array startign after the EXIF header (where the offsets of all IFDs and values are calculated from).

                                                                                                                            DEPRECATED(dustin): Use a RawTagWalk instead.

                                                                                                                            type RawTagWalk

                                                                                                                            type RawTagWalk interface {
                                                                                                                            	Visit(fqIfdPath string, ifdIndex int, tagId uint16, tagType TagType, valueContext *ValueContext) (err error)
                                                                                                                            }

                                                                                                                              RawTagVisitorPtr is an optional callback that can get hit for every tag we parse through. `addressableData` is the byte array startign after the EXIF header (where the offsets of all IFDs and values are calculated from).

                                                                                                                              This was reimplemented as an interface to allow for simpler change management in the future.

                                                                                                                              type RawTagWalkLegacyWrapper

                                                                                                                              type RawTagWalkLegacyWrapper struct {
                                                                                                                              	// contains filtered or unexported fields
                                                                                                                              }

                                                                                                                              func (RawTagWalkLegacyWrapper) Visit

                                                                                                                              func (rtwlw RawTagWalkLegacyWrapper) Visit(fqIfdPath string, ifdIndex int, tagId uint16, tagType TagType, valueContext *ValueContext) (err error)

                                                                                                                              type SignedRational

                                                                                                                              type SignedRational struct {
                                                                                                                              	Numerator   int32
                                                                                                                              	Denominator int32
                                                                                                                              }

                                                                                                                              type TagIndex

                                                                                                                              type TagIndex struct {
                                                                                                                              	// contains filtered or unexported fields
                                                                                                                              }

                                                                                                                              func NewTagIndex

                                                                                                                              func NewTagIndex() *TagIndex

                                                                                                                              func (*TagIndex) Add

                                                                                                                              func (ti *TagIndex) Add(it *IndexedTag) (err error)

                                                                                                                              func (*TagIndex) Get

                                                                                                                              func (ti *TagIndex) Get(ifdPath string, id uint16) (it *IndexedTag, err error)

                                                                                                                                Get returns information about the non-IFD tag.

                                                                                                                                func (*TagIndex) GetWithName

                                                                                                                                func (ti *TagIndex) GetWithName(ifdPath string, name string) (it *IndexedTag, err error)

                                                                                                                                  Get returns information about the non-IFD tag.

                                                                                                                                  type TagType

                                                                                                                                  type TagType struct {
                                                                                                                                  	// contains filtered or unexported fields
                                                                                                                                  }

                                                                                                                                  func NewTagType

                                                                                                                                  func NewTagType(tagType TagTypePrimitive, byteOrder binary.ByteOrder) TagType

                                                                                                                                  func (TagType) ByteOrder

                                                                                                                                  func (tt TagType) ByteOrder() binary.ByteOrder

                                                                                                                                  func (TagType) Encode

                                                                                                                                  func (tt TagType) Encode(value interface{}) (encoded []byte, err error)

                                                                                                                                    Encode knows how to encode the given value to a byte slice.

                                                                                                                                    func (TagType) FromString

                                                                                                                                    func (tt TagType) FromString(valueString string) (value interface{}, err error)

                                                                                                                                    func (TagType) Name

                                                                                                                                    func (tt TagType) Name() string

                                                                                                                                    func (TagType) ParseAscii

                                                                                                                                    func (tt TagType) ParseAscii(data []byte, unitCount uint32) (value string, err error)

                                                                                                                                      ParseAscii returns a string and auto-strips the trailing NUL character.

                                                                                                                                      func (TagType) ParseAsciiNoNul

                                                                                                                                      func (tt TagType) ParseAsciiNoNul(data []byte, unitCount uint32) (value string, err error)

                                                                                                                                        ParseAsciiNoNul returns a string without any consideration for a trailing NUL character.

                                                                                                                                        func (TagType) ParseBytes

                                                                                                                                        func (tt TagType) ParseBytes(data []byte, unitCount uint32) (value []uint8, err error)

                                                                                                                                        func (TagType) ParseLongs

                                                                                                                                        func (tt TagType) ParseLongs(data []byte, unitCount uint32) (value []uint32, err error)

                                                                                                                                        func (TagType) ParseRationals

                                                                                                                                        func (tt TagType) ParseRationals(data []byte, unitCount uint32) (value []Rational, err error)

                                                                                                                                        func (TagType) ParseShorts

                                                                                                                                        func (tt TagType) ParseShorts(data []byte, unitCount uint32) (value []uint16, err error)

                                                                                                                                        func (TagType) ParseSignedLongs

                                                                                                                                        func (tt TagType) ParseSignedLongs(data []byte, unitCount uint32) (value []int32, err error)

                                                                                                                                        func (TagType) ParseSignedRationals

                                                                                                                                        func (tt TagType) ParseSignedRationals(data []byte, unitCount uint32) (value []SignedRational, err error)

                                                                                                                                        func (TagType) ReadAsciiNoNulValue

                                                                                                                                        func (tt TagType) ReadAsciiNoNulValue(valueContext ValueContext) (value string, err error)

                                                                                                                                        func (TagType) ReadAsciiValue

                                                                                                                                        func (tt TagType) ReadAsciiValue(valueContext ValueContext) (value string, err error)

                                                                                                                                        func (TagType) ReadByteValues

                                                                                                                                        func (tt TagType) ReadByteValues(valueContext ValueContext) (value []byte, err error)

                                                                                                                                        func (TagType) ReadLongValues

                                                                                                                                        func (tt TagType) ReadLongValues(valueContext ValueContext) (value []uint32, err error)

                                                                                                                                        func (TagType) ReadRationalValues

                                                                                                                                        func (tt TagType) ReadRationalValues(valueContext ValueContext) (value []Rational, err error)

                                                                                                                                        func (TagType) ReadShortValues

                                                                                                                                        func (tt TagType) ReadShortValues(valueContext ValueContext) (value []uint16, err error)

                                                                                                                                        func (TagType) ReadSignedLongValues

                                                                                                                                        func (tt TagType) ReadSignedLongValues(valueContext ValueContext) (value []int32, err error)

                                                                                                                                        func (TagType) ReadSignedRationalValues

                                                                                                                                        func (tt TagType) ReadSignedRationalValues(valueContext ValueContext) (value []SignedRational, err error)

                                                                                                                                        func (TagType) Resolve

                                                                                                                                        func (tt TagType) Resolve(valueContext *ValueContext) (values interface{}, err error)

                                                                                                                                          Resolve knows how to resolve the given value.

                                                                                                                                          Since this method lacks the information to process unknown-type tags (e.g. byte-order, tag-ID, IFD type), it will return an error if attempted. See `Undefined()`.

                                                                                                                                          func (TagType) ResolveAsString

                                                                                                                                          func (tt TagType) ResolveAsString(valueContext ValueContext, justFirst bool) (value string, err error)

                                                                                                                                            ResolveAsString resolves the given value and returns a flat string.

                                                                                                                                            Where the type is not ASCII, `justFirst` indicates whether to just stringify the first item in the slice (or return an empty string if the slice is empty).

                                                                                                                                            Since this method lacks the information to process unknown-type tags (e.g. byte-order, tag-ID, IFD type), it will return an error if attempted. See `Undefined()`.

                                                                                                                                            func (TagType) Size

                                                                                                                                            func (tt TagType) Size() int

                                                                                                                                            func (TagType) String

                                                                                                                                            func (tt TagType) String() string

                                                                                                                                            func (TagType) Type

                                                                                                                                            func (tt TagType) Type() TagTypePrimitive

                                                                                                                                            type TagTypePrimitive

                                                                                                                                            type TagTypePrimitive uint16
                                                                                                                                            const (
                                                                                                                                            	TypeByte           TagTypePrimitive = 1
                                                                                                                                            	TypeAscii          TagTypePrimitive = 2
                                                                                                                                            	TypeShort          TagTypePrimitive = 3
                                                                                                                                            	TypeLong           TagTypePrimitive = 4
                                                                                                                                            	TypeRational       TagTypePrimitive = 5
                                                                                                                                            	TypeUndefined      TagTypePrimitive = 7
                                                                                                                                            	TypeSignedLong     TagTypePrimitive = 9
                                                                                                                                            	TypeSignedRational TagTypePrimitive = 10
                                                                                                                                            
                                                                                                                                            	// TypeAsciiNoNul is just a pseudo-type, for our own purposes.
                                                                                                                                            	TypeAsciiNoNul TagTypePrimitive = 0xf0
                                                                                                                                            )

                                                                                                                                            func (TagTypePrimitive) Size

                                                                                                                                            func (tagType TagTypePrimitive) Size() int

                                                                                                                                            func (TagTypePrimitive) String

                                                                                                                                            func (typeType TagTypePrimitive) String() string

                                                                                                                                            type TagUnknownType_9101_ComponentsConfiguration

                                                                                                                                            type TagUnknownType_9101_ComponentsConfiguration struct {
                                                                                                                                            	ConfigurationId    int
                                                                                                                                            	ConfigurationBytes []byte
                                                                                                                                            }

                                                                                                                                            func (TagUnknownType_9101_ComponentsConfiguration) String

                                                                                                                                            func (TagUnknownType_9101_ComponentsConfiguration) ValueBytes

                                                                                                                                            func (uc TagUnknownType_9101_ComponentsConfiguration) ValueBytes() (value []byte, err error)

                                                                                                                                            type TagUnknownType_927C_MakerNote

                                                                                                                                            type TagUnknownType_927C_MakerNote struct {
                                                                                                                                            	MakerNoteType  []byte
                                                                                                                                            	MakerNoteBytes []byte
                                                                                                                                            }

                                                                                                                                            func (TagUnknownType_927C_MakerNote) String

                                                                                                                                            func (TagUnknownType_927C_MakerNote) ValueBytes

                                                                                                                                            func (uc TagUnknownType_927C_MakerNote) ValueBytes() (value []byte, err error)

                                                                                                                                            type TagUnknownType_9298_UserComment

                                                                                                                                            type TagUnknownType_9298_UserComment struct {
                                                                                                                                            	EncodingType  int
                                                                                                                                            	EncodingBytes []byte
                                                                                                                                            }

                                                                                                                                            func (TagUnknownType_9298_UserComment) String

                                                                                                                                            func (TagUnknownType_9298_UserComment) ValueBytes

                                                                                                                                            func (uc TagUnknownType_9298_UserComment) ValueBytes() (value []byte, err error)

                                                                                                                                            type TagUnknownType_GeneralString

                                                                                                                                            type TagUnknownType_GeneralString string

                                                                                                                                            func (TagUnknownType_GeneralString) ValueBytes

                                                                                                                                            func (gs TagUnknownType_GeneralString) ValueBytes() (value []byte, err error)

                                                                                                                                            type TagUnknownType_UnknownValue

                                                                                                                                            type TagUnknownType_UnknownValue []byte

                                                                                                                                            func (TagUnknownType_UnknownValue) String

                                                                                                                                            func (tutuv TagUnknownType_UnknownValue) String() string

                                                                                                                                            type UnknownTagValue

                                                                                                                                            type UnknownTagValue interface {
                                                                                                                                            	ValueBytes() ([]byte, error)
                                                                                                                                            }

                                                                                                                                            type ValueContext

                                                                                                                                            type ValueContext struct {
                                                                                                                                            	// contains filtered or unexported fields
                                                                                                                                            }

                                                                                                                                              ValueContext describes all of the parameters required to find and extract the actual tag value.

                                                                                                                                              func (*ValueContext) AddressableData

                                                                                                                                              func (vc *ValueContext) AddressableData() []byte

                                                                                                                                              func (*ValueContext) Format

                                                                                                                                              func (vc *ValueContext) Format() (value string, err error)

                                                                                                                                                Format returns a string representation for the value.

                                                                                                                                                Where the type is not ASCII, `justFirst` indicates whether to just stringify the first item in the slice (or return an empty string if the slice is empty).

                                                                                                                                                Since this method lacks the information to process undefined-type tags (e.g. byte-order, tag-ID, IFD type), it will return an error if attempted. See `Undefined()`.

                                                                                                                                                func (*ValueContext) FormatFirst

                                                                                                                                                func (vc *ValueContext) FormatFirst() (value string, err error)

                                                                                                                                                  FormatOne is similar to `Format` but only gets and stringifies the first item.

                                                                                                                                                  func (*ValueContext) RawValueOffset

                                                                                                                                                  func (vc *ValueContext) RawValueOffset() []byte

                                                                                                                                                  func (*ValueContext) ReadAscii

                                                                                                                                                  func (vc *ValueContext) ReadAscii() (value string, err error)

                                                                                                                                                  func (*ValueContext) ReadAsciiNoNul

                                                                                                                                                  func (vc *ValueContext) ReadAsciiNoNul() (value string, err error)

                                                                                                                                                  func (*ValueContext) ReadBytes

                                                                                                                                                  func (vc *ValueContext) ReadBytes() (value []byte, err error)

                                                                                                                                                  func (*ValueContext) ReadLongs

                                                                                                                                                  func (vc *ValueContext) ReadLongs() (value []uint32, err error)

                                                                                                                                                  func (*ValueContext) ReadRationals

                                                                                                                                                  func (vc *ValueContext) ReadRationals() (value []Rational, err error)

                                                                                                                                                  func (*ValueContext) ReadShorts

                                                                                                                                                  func (vc *ValueContext) ReadShorts() (value []uint16, err error)

                                                                                                                                                  func (*ValueContext) ReadSignedLongs

                                                                                                                                                  func (vc *ValueContext) ReadSignedLongs() (value []int32, err error)

                                                                                                                                                  func (*ValueContext) ReadSignedRationals

                                                                                                                                                  func (vc *ValueContext) ReadSignedRationals() (value []SignedRational, err error)

                                                                                                                                                  func (*ValueContext) SetUnknownValueType

                                                                                                                                                  func (vc *ValueContext) SetUnknownValueType(tagType TagTypePrimitive)

                                                                                                                                                  func (*ValueContext) Undefined

                                                                                                                                                  func (vc *ValueContext) Undefined() (value interface{}, err error)

                                                                                                                                                    Undefined attempts to identify and decode supported undefined-type fields. This is the primary, preferred interface to reading undefined values.

                                                                                                                                                    func (*ValueContext) UnitCount

                                                                                                                                                    func (vc *ValueContext) UnitCount() uint32

                                                                                                                                                    func (*ValueContext) ValueOffset

                                                                                                                                                    func (vc *ValueContext) ValueOffset() uint32

                                                                                                                                                    func (*ValueContext) Values

                                                                                                                                                    func (vc *ValueContext) Values() (values interface{}, err error)

                                                                                                                                                      Values knows how to resolve the given value. This value is always a list (undefined-values aside), so we're named accordingly.

                                                                                                                                                      Since this method lacks the information to process unknown-type tags (e.g. byte-order, tag-ID, IFD type), it will return an error if attempted. See `Undefined()`.

                                                                                                                                                      type ValueEncoder

                                                                                                                                                      type ValueEncoder struct {
                                                                                                                                                      	// contains filtered or unexported fields
                                                                                                                                                      }

                                                                                                                                                      func NewValueEncoder

                                                                                                                                                      func NewValueEncoder(byteOrder binary.ByteOrder) *ValueEncoder

                                                                                                                                                      func (*ValueEncoder) Encode

                                                                                                                                                      func (ve *ValueEncoder) Encode(value interface{}) (ed EncodedData, err error)

                                                                                                                                                        Encode returns bytes for the given value, infering type from the actual value. This does not support `TypeAsciiNoNull` (all strings are encoded as `TypeAscii`).

                                                                                                                                                        func (*ValueEncoder) EncodeWithType

                                                                                                                                                        func (ve *ValueEncoder) EncodeWithType(tt TagType, value interface{}) (ed EncodedData, err error)

                                                                                                                                                          EncodeWithType returns bytes for the given value, using the given `TagType` value to determine how to encode. This supports `TypeAsciiNoNul`.

                                                                                                                                                          Directories

                                                                                                                                                          Path Synopsis
                                                                                                                                                          This tool dumps EXIF information from images.
                                                                                                                                                          This tool dumps EXIF information from images.