codec

package
v0.19.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 30, 2026 License: BSD-3-Clause Imports: 17 Imported by: 0

Documentation

Overview

Package codec is go-gfx's unified image-decoding registry: one Decode entry point that sniffs a byte slice's container format and dispatches to the appropriate REFERENCE decoder, returning the shared raster.Image substrate the rest of go-gfx consumes.

It writes as well as reads, through Encode, and the two are not symmetric: a reference DECODER exists in pure Go for every format below, a reference encoder for five of them. CanEncode says which.

It reimplements NO decoder. Every format is handed to a battle-tested pure-Go (CGO-free) reference library, and this package only sniffs the format, delegates, and converts the reference's image.Image into a straight-alpha raster.Image:

format  reference decoder                          module
------  ----------------------------------------   ------------------------------------
PNG     image/png                                  standard library
JPEG    image/jpeg                                 standard library
GIF     image/gif                                  standard library
WEBP    golang.org/x/image/webp                    golang.org/x/image
TIFF    golang.org/x/image/tiff                    golang.org/x/image
BMP     golang.org/x/image/bmp                     golang.org/x/image
ICO     github.com/sergeymakinen/go-ico            github.com/sergeymakinen/go-ico
ICNS    image/png (per embedded PNG representation)  standard library  [see icns.go]
JP2     github.com/ajroetker/go-jpeg2000           github.com/ajroetker/go-jpeg2000
JBIG2   github.com/tannevaled/gobig2 [fork]         github.com/tannevaled/gobig2

ICNS is the single format with no clean pure-Go decode reference (see the verdict in icns.go): its container is demuxed here by a bounds-checked TLV walk and each embedded PNG representation is decoded by the standard library — so no image decoder is reimplemented, only the container is unpacked, exactly as go-ico unpacks the .ico container around the standard BMP/PNG decoders.

Decode returns the primary (largest, most detailed) image of a container. DecodeBest additionally lets a caller target a pixel size for the multi-representation formats (ICO, ICNS), picking the smallest representation at least as large as the target, or the largest available when none reaches it. All decoders are pure-Go; the package never shells out and never needs CGO.

Index

Constants

This section is empty.

Variables

View Source
var ErrCannotEncode = fmt.Errorf("codec: no reference encoder for this format")

ErrCannotEncode is returned for a format this can read but not write.

Reading and writing are not symmetric and the gap is not an oversight. A reference decoder exists in pure Go for every format Sniff names; a reference ENCODER does not, and this package writes none of its own. Saying which way a format goes is part of its contract.

View Source
var ErrUnknownFormat = fmt.Errorf("codec: unrecognised image format")

ErrUnknownFormat is returned by Decode and DecodeBest when the input's leading bytes match no format the registry knows how to decode.

Functions

func CanEncode added in v0.16.0

func CanEncode(f Format) bool

CanEncode says whether Encode can write a format, so a caller can offer what is possible rather than find out by failing.

func Decode

func Decode(data []byte) (*raster.Image, error)

Decode sniffs data's format, delegates to the matching reference decoder, and returns the image as a straight-alpha raster.Image. For multi-representation containers (ICO, ICNS) it returns the largest, most detailed representation; use DecodeBest to target a size. It returns ErrUnknownFormat for an unrecognised input and the reference decoder's own error for a corrupt one.

func DecodeBest

func DecodeBest(data []byte, targetSize int) (*raster.Image, error)

DecodeBest is Decode with a target pixel size for the multi-representation formats. For ICO and ICNS it selects the representation whose larger side is the smallest that is still >= targetSize, falling back to the largest representation when none reaches the target; a targetSize <= 0 always selects the largest. targetSize is ignored for single-image formats, whose sole image is returned regardless.

func DecodeEmbeddedJBIG2 added in v0.14.0

func DecodeEmbeddedJBIG2(data, globals []byte) (*raster.Image, error)

DecodeEmbeddedJBIG2 decodes the headerless form of JBIG2 — segments and nothing else, with the shared ones handed in separately — which is what a container embeds when its own metadata already says what the bytes are.

It sits outside Decode's contract deliberately. Every other format here is found by sniffing, and this one cannot be: the embedded form carries no signature, and the globals cannot be guessed from the stream at all. Passing it through Sniff would mean pretending to recognise something.

It is here rather than in each container's own reader so that one package names the JBIG2 decoder. That matters more than usual for this format: the reference decoder's resource limits are process-global rather than per-decode, so the day it is swapped should be a change in one place.

The decoder is a fork, which is not the usual arrangement here and is meant to end. Upstream's per-symbol pixel cap defaults below what real scanned documents contain: it refuses 7 of 403 JBIG2 streams taken from public scans, and a library cannot raise it, because the limits are those process-global variables. The fix is offered as dkrisman/gobig2#2 and the fork exists to carry it, tagged, until it lands.

globals may be nil, which is the common case: an encoder that puts a page's symbol dictionary in the page's own stream needs no shared segments.

func Encode added in v0.16.0

func Encode(w io.Writer, img *raster.Image, f Format) error

Encode writes an image in the named format.

The formats that can be written are PNG, JPEG, GIF, TIFF and BMP, each through the same reference library that reads it. WEBP, ICO, ICNS, PNM, QOI, JP2 and JBIG2 can be read here and not written: they return ErrCannotEncode rather than something in another format under the asked-for name.

TIFF is written with Deflate compression and BMP is not written with any, because BMP has none to write: of the five, BMP is the one whose files are large and stay large. A page-sized picture comes to 471 kB as a PNG, 415 kB as a TIFF and 5.8 MB as a BMP.

Alpha survives into PNG and TIFF, which carry it. JPEG, GIF and BMP do not, and what they are given is the image composited onto white — chosen rather than left to the encoder, because an encoder that drops the alpha channel puts the colour that was UNDER the transparency on the page, and for a page drawn on transparent ground that is black.

Types

type Format

type Format int

Format identifies a decodable image-container format recognised by Sniff.

const (
	Unknown Format = iota
	PNG
	JPEG
	GIF
	WEBP
	TIFF
	BMP
	ICO
	ICNS
	PNM   // Netpbm: PBM/PGM/PPM, ASCII (P1–P3) and binary (P4–P6)
	QOI   // Quite OK Image
	JP2   // JPEG 2000: the JP2 container and the bare codestream alike
	JBIG2 // JBIG2: the bitonal ink layer of a scanned page
)

The container formats codec can decode. Unknown is the zero value returned when a byte slice matches no known signature.

func Sniff

func Sniff(data []byte) Format

Sniff identifies the container format of data from its magic bytes, without decoding it. It returns Unknown when the input is too short or matches no known signature.

func (Format) String

func (f Format) String() string

String returns the format's short uppercase name (e.g. "PNG"), or "unknown".

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL