...

Package pngstructure

import "github.com/dsoprea/go-png-image-structure/v2"
Overview
Index
Examples

Overview ▾

Index ▾

Variables
func DumpBytes(data []byte)
func DumpBytesClause(data []byte)
func DumpBytesClauseToString(data []byte) string
func DumpBytesToString(data []byte) string
type Chunk
    func (c *Chunk) Bytes() []byte
    func (c *Chunk) CheckCrc32() bool
    func (c *Chunk) String() string
    func (c *Chunk) UpdateCrc32()
    func (c *Chunk) WriteTo(w io.Writer) (count int, err error)
type ChunkDecoder
    func NewChunkDecoder() *ChunkDecoder
    func (cd *ChunkDecoder) Decode(c *Chunk) (decoded interface{}, err error)
type ChunkIHDR
    func (ihdr *ChunkIHDR) String() string
type ChunkSlice
    func NewChunkSlice(chunks []*Chunk) *ChunkSlice
    func NewPngChunkSlice() *ChunkSlice
    func (cs *ChunkSlice) Chunks() []*Chunk
    func (cs *ChunkSlice) ConstructExifBuilder() (rootIb *exif.IfdBuilder, err error)
    func (cs *ChunkSlice) Exif() (rootIfd *exif.Ifd, data []byte, err error)
    func (cs *ChunkSlice) FindExif() (chunk *Chunk, err error)
    func (cs *ChunkSlice) Index() (index map[string][]*Chunk)
    func (cs *ChunkSlice) SetExif(ib *exif.IfdBuilder) (err error)
    func (cs *ChunkSlice) String() string
    func (cs *ChunkSlice) WriteTo(w io.Writer) (err error)
type PngMediaParser
    func NewPngMediaParser() *PngMediaParser
    func (pmp *PngMediaParser) GetImage(r io.Reader) (img image.Image, err error)
    func (pmp *PngMediaParser) LooksLikeFormat(data []byte) bool
    func (pmp *PngMediaParser) Parse(rs io.ReadSeeker, size int) (mc riimage.MediaContext, err error)
    func (pmp *PngMediaParser) ParseBytes(data []byte) (mc riimage.MediaContext, err error)
    func (pmp *PngMediaParser) ParseFile(filepath string) (mc riimage.MediaContext, err error)
type PngSplitter
    func NewPngSplitter() *PngSplitter
    func (ps *PngSplitter) Chunks() *ChunkSlice
    func (ps *PngSplitter) CrcErrors() []string
    func (ps *PngSplitter) DoCheckCrc(doCheck bool)
    func (ps *PngSplitter) Split(data []byte, atEOF bool) (advance int, token []byte, err error)

Package files

chunk_decoder.go media_parser.go png.go testing_common.go utility.go

Variables

var (
    PngSignature  = [8]byte{137, 'P', 'N', 'G', '\r', '\n', 26, '\n'}
    EXifChunkType = "eXIf"
    IHDRChunkType = "IHDR"
)
var (
    ErrNotPng     = errors.New("not png data")
    ErrCrcFailure = errors.New("crc failure")
)

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

type Chunk

Chunk describes a single chunk.

type Chunk struct {
    Offset int
    Length uint32
    Type   string
    Data   []byte
    Crc    uint32
}

func (*Chunk) Bytes

func (c *Chunk) Bytes() []byte

Bytes encodes and returns the bytes for this chunk.

Example

Code:

c := Chunk{
    Offset: 0,
    Length: 5,
    Type:   "ABCD",
    Data:   []byte{0x11, 0x22, 0x33, 0x44, 0x55},
    Crc:    0x5678,
}

data := c.Bytes()
data = data

func (*Chunk) CheckCrc32

func (c *Chunk) CheckCrc32() bool

func (*Chunk) String

func (c *Chunk) String() string

func (*Chunk) UpdateCrc32

func (c *Chunk) UpdateCrc32()

func (*Chunk) WriteTo

func (c *Chunk) WriteTo(w io.Writer) (count int, err error)

Write encodes and writes the bytes for this chunk.

type ChunkDecoder

type ChunkDecoder struct {
}

func NewChunkDecoder

func NewChunkDecoder() *ChunkDecoder

func (*ChunkDecoder) Decode

func (cd *ChunkDecoder) Decode(c *Chunk) (decoded interface{}, err error)

Example

Code:

filepath := path.Join(assetsPath, "Selection_058.png")

pmp := NewPngMediaParser()

intfc, err := pmp.ParseFile(filepath)
log.PanicIf(err)

cs := intfc.(*ChunkSlice)

index := cs.Index()
ihdrRawSlice, found := index["IHDR"]

if found != true {
    log.Panicf("IHDR chunk not found")
}

cd := NewChunkDecoder()

ihdrRaw, err := cd.Decode(ihdrRawSlice[0])
log.PanicIf(err)

ihdr := ihdrRaw.(*ChunkIHDR)
ihdr = ihdr

type ChunkIHDR

type ChunkIHDR struct {
    Width             uint32
    Height            uint32
    BitDepth          uint8
    ColorType         uint8
    CompressionMethod uint8
    FilterMethod      uint8
    InterlaceMethod   uint8
}

func (*ChunkIHDR) String

func (ihdr *ChunkIHDR) String() string

type ChunkSlice

ChunkSlice encapsulates a slice of chunks.

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

func NewChunkSlice

func NewChunkSlice(chunks []*Chunk) *ChunkSlice

func NewPngChunkSlice

func NewPngChunkSlice() *ChunkSlice

func (*ChunkSlice) Chunks

func (cs *ChunkSlice) Chunks() []*Chunk

Chunks exposes the actual slice.

func (*ChunkSlice) ConstructExifBuilder

func (cs *ChunkSlice) ConstructExifBuilder() (rootIb *exif.IfdBuilder, err error)

ConstructExifBuilder returns an `exif.IfdBuilder` instance (needed for modifying) preloaded with all existing tags.

Example

Code:

testExifFilepath := getTestExifImageFilepath()

pmp := NewPngMediaParser()

intfc, err := pmp.ParseFile(testExifFilepath)
log.PanicIf(err)

cs := intfc.(*ChunkSlice)

// Add a new tag to the additional EXIF.

rootIb, err := cs.ConstructExifBuilder()
log.PanicIf(err)

err = rootIb.SetStandardWithName("ImageLength", []uint32{44})
log.PanicIf(err)

err = rootIb.AddStandardWithName("BitsPerSample", []uint16{33})
log.PanicIf(err)

// Update the image.

err = cs.SetExif(rootIb)
log.PanicIf(err)

b := new(bytes.Buffer)

err = cs.WriteTo(b)
log.PanicIf(err)

updatedImageData := b.Bytes()

// Re-parse.

pmp = NewPngMediaParser()

intfc, err = pmp.ParseBytes(updatedImageData)
log.PanicIf(err)

cs = intfc.(*ChunkSlice)

rootIfd, _, err := cs.Exif()
log.PanicIf(err)

for i, ite := range rootIfd.Entries() {
    value, err := ite.Value()
    log.PanicIf(err)

    fmt.Printf("%d: (0x%04x) %v\n", i, ite.TagId(), value)
}

Output:

0: (0x0100) [11]
1: (0x0101) [44]
2: (0x0102) [33]

func (*ChunkSlice) Exif

func (cs *ChunkSlice) Exif() (rootIfd *exif.Ifd, data []byte, err error)

Exif returns an `exif.Ifd` instance with the existing tags.

Example

Code:

testExifFilepath := getTestExifImageFilepath()

pmp := NewPngMediaParser()

intfc, err := pmp.ParseFile(testExifFilepath)
log.PanicIf(err)

cs := intfc.(*ChunkSlice)

rootIfd, _, err := cs.Exif()
log.PanicIf(err)

rootIfd = rootIfd

func (*ChunkSlice) FindExif

func (cs *ChunkSlice) FindExif() (chunk *Chunk, err error)

FindExif returns the the segment that hosts the EXIF data.

Example

Code:

testBasicFilepath := getTestBasicImageFilepath()

pmp := NewPngMediaParser()

intfc, err := pmp.ParseFile(testBasicFilepath)
log.PanicIf(err)

cs := intfc.(*ChunkSlice)

exifChunk, err := cs.FindExif()
log.PanicIf(err)

exifChunk = exifChunk

func (*ChunkSlice) Index

func (cs *ChunkSlice) Index() (index map[string][]*Chunk)

Index returns a map of chunk types to chunk slices, grouping all like chunks.

Example

Code:

filepath := path.Join(assetsPath, "Selection_058.png")

pmp := NewPngMediaParser()

intfc, err := pmp.ParseFile(filepath)
log.PanicIf(err)

cs := intfc.(*ChunkSlice)

index := cs.Index()
index = index

func (*ChunkSlice) SetExif

func (cs *ChunkSlice) SetExif(ib *exif.IfdBuilder) (err error)

SetExif encodes and sets EXIF data into this segment.

Example

Code:

// Build EXIF.

testBasicFilepath := getTestBasicImageFilepath()

im, err := exifcommon.NewIfdMappingWithStandard()
log.PanicIf(err)

ti := exif.NewTagIndex()

ib := exif.NewIfdBuilder(im, ti, exifcommon.IfdStandardIfdIdentity, exifcommon.TestDefaultByteOrder)

err = ib.AddStandardWithName("ImageWidth", []uint32{11})
log.PanicIf(err)

err = ib.AddStandardWithName("ImageLength", []uint32{22})
log.PanicIf(err)

// Add/replace EXIF into PNG (overwrite existing).

pmp := NewPngMediaParser()

intfc, err := pmp.ParseFile(testBasicFilepath)
log.PanicIf(err)

cs := intfc.(*ChunkSlice)

err = cs.SetExif(ib)
log.PanicIf(err)

b := new(bytes.Buffer)

// Write to a `bytes.Buffer`.
err = cs.WriteTo(b)
log.PanicIf(err)

func (*ChunkSlice) String

func (cs *ChunkSlice) String() string

func (*ChunkSlice) WriteTo

func (cs *ChunkSlice) WriteTo(w io.Writer) (err error)

Write encodes and writes all chunks.

type PngMediaParser

PngMediaParser knows how to parse a PNG stream.

type PngMediaParser struct {
}

func NewPngMediaParser

func NewPngMediaParser() *PngMediaParser

NewPngMediaParser returns a new `PngMediaParser` struct.

func (*PngMediaParser) GetImage

func (pmp *PngMediaParser) GetImage(r io.Reader) (img image.Image, err error)

GetImage returns an image.Image-compatible struct.

func (*PngMediaParser) LooksLikeFormat

func (pmp *PngMediaParser) LooksLikeFormat(data []byte) bool

LooksLikeFormat returns a boolean indicating whether the stream looks like a PNG image.

Example

Code:

filepath := path.Join(assetsPath, "libpng.png")

data, err := ioutil.ReadFile(filepath)
log.PanicIf(err)

pmp := NewPngMediaParser()

isPng := pmp.LooksLikeFormat(data)
fmt.Printf("%v\n", isPng)

Output:

true

func (*PngMediaParser) Parse

func (pmp *PngMediaParser) Parse(rs io.ReadSeeker, size int) (mc riimage.MediaContext, err error)

Parse parses a PNG stream given a `io.ReadSeeker`.

func (*PngMediaParser) ParseBytes

func (pmp *PngMediaParser) ParseBytes(data []byte) (mc riimage.MediaContext, err error)

ParseBytes parses a PNG stream given a byte-slice.

func (*PngMediaParser) ParseFile

func (pmp *PngMediaParser) ParseFile(filepath string) (mc riimage.MediaContext, err error)

ParseFile parses a PNG stream given a file-path.

type PngSplitter

PngSplitter hosts the princpal `Split()` method uses by `bufio.Scanner`.

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

func NewPngSplitter

func NewPngSplitter() *PngSplitter

func (*PngSplitter) Chunks

func (ps *PngSplitter) Chunks() *ChunkSlice

func (*PngSplitter) CrcErrors

func (ps *PngSplitter) CrcErrors() []string

func (*PngSplitter) DoCheckCrc

func (ps *PngSplitter) DoCheckCrc(doCheck bool)

func (*PngSplitter) Split

func (ps *PngSplitter) Split(data []byte, atEOF bool) (advance int, token []byte, err error)

Split fulfills the `bufio.SplitFunc` function definition for `bufio.Scanner`.