Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

github.com/imclaren/go-exif

Package Overview
Dependencies
Alerts
File Explorer
Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

github.com/imclaren/go-exif

  • v0.0.0-20210617020511-eecaf3691f5e
  • Source
  • Go
  • Socket score

Version published
Created
Source

Go Report Card GoDoc

Origin

This project is a fork of github.com/dsoprea/go-exif/v2. This fork extracts EXIF tags from files without needing to store all of the bytes (starting from the start of the EXIF block) in memory.

By default the go-exif scanner searches up to 5MB into the file for the EXIF header, and then scans up to 1MB of EXIF data. These defaults can be changed when creating a new scanner.

The initial search does not increase memory usage, it just takes a long time to search entire large files for exif headers. Most EXIF headers seem to be near the start of files.

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/imclaren/go-exif

Example

func getExifTags(filePath string) (OK bool, exifTags []exif.ExifTag, err error) {
	f, err := os.Open(filePath)
	if err != nil {
		return false, nil, err
	}
	defer f.Close()
	fi, err := f.Stat()
	if err != nil {
		return false, nil, err
 	}
	s, err := exif.NewScanner(f, fi.Size())
	if err != nil {
		if err == exif.ErrNoExif {
			return false, nil, nil
		}
		return false, nil, err
	}
	exifTags, err = s.GetFlatExifData()
	if err != nil {
		return false, nil, err
	}
	return true, exifTags, nil
}

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 original 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/imclaren/go-exif/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/imclaren/go-exif/...

FAQs

Package last updated on 17 Jun 2021

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc