Documentation
¶
Overview ¶
Package decoder defines the public Decoder interface and registry for opentile-go's pluggable codec layer. Codec-specific subpackages (decoder/jpeg, decoder/jpeg2000, decoder/lzw, etc.) register themselves into this package's registry at init() time.
Most consumers wanting "all codecs available" should blank-import the decoder/all subpackage:
import _ "github.com/wsilabs/opentile-go/decoder/all"
Smaller-footprint consumers can blank-import only the codec subpackages they need.
The decoder layer backs the Level / Pyramid read methods (DecodedTile / ReadRegion / ReadRegionScaled / ScaledStrips). It is also usable standalone for third-party Go pathology code that wants decoded tile bytes from opentile-go-readable WSI files.
Design spec: docs/superpowers/specs/2026-05-23-opentile-go-v22-decoder-resample-lift-design.md.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ( // subpackage that was excluded from this build (via -tags // no<codec> or -tags nocgo). The wrapping error message names the // codec and the build tag to remove. ErrCodecUnavailable = errors.New("decoder: codec not available in this build") // ErrUnsupportedScale is returned by Decode when DecodeOptions.Scale // is not a value the decoder supports. JPEG decoders accept 1, 2, // 4, 8; other decoders accept only 1. ErrUnsupportedScale = errors.New("decoder: scale factor not supported by this codec") // ErrUnsupportedFormat is returned by Decode when DecodeOptions.Format // is not producible by the decoder. ErrUnsupportedFormat = errors.New("decoder: pixel format not supported by this codec") // ErrDestinationSize is returned by Decode when DecodeOptions.Dst // is non-nil but its dimensions don't match the decoded size. ErrDestinationSize = errors.New("decoder: dst Image dimensions don't match decoded size") // ErrCorruptInput is returned by Decode when the compressed bytes // can't be parsed. ErrCorruptInput = errors.New("decoder: corrupt input data") )
Sentinel errors used by Decode implementations. Wrap with fmt.Errorf("...: %w", ErrXxx) for codec-specific context; callers detect via errors.Is.
Functions ¶
func Register ¶
func Register(f Factory)
Register adds a factory to the global decoder registry. Called from each codec subpackage's init(). Last-in-wins on name or tag collision (intentional — lets consumers shadow a default decoder with a custom impl).
func Registered ¶
func Registered() []string
Registered returns the canonical names of every registered decoder. Order is unspecified.
Types ¶
type ChromaSubsampling ¶ added in v0.43.0
type ChromaSubsampling uint8
ChromaSubsampling is the chroma subsampling of a codestream's samples, expressed in the conventional J:a:b notation. SubsamplingNone is a single-channel (grayscale) codestream with no chroma to subsample.
const ( SubsamplingUnknown ChromaSubsampling = iota SubsamplingNone // grayscale / no chroma channels Subsampling444 // no chroma subsampling Subsampling422 // 2:1 horizontal Subsampling420 // 2:1 horizontal + vertical Subsampling440 // 2:1 vertical Subsampling411 // 4:1 horizontal )
func (ChromaSubsampling) String ¶ added in v0.43.0
func (s ChromaSubsampling) String() string
type CodestreamInfo ¶ added in v0.42.0
type CodestreamInfo struct {
// Components is the sample/channel count (1 = grayscale, 3 = color,
// 4 = e.g. CMYK or color+alpha).
Components int
// BitDepth is the bits per component (typically 8; J2K/JXL may be higher).
BitDepth int
// Lossless reports whether the codestream is reversible/lossless. It is a
// tri-state because not every codec exposes a header-only reversibility
// signal: JPEG 2000 / HTJ2K report it from the COD transform and JPEG
// baseline is always lossy, but JPEG XL's JxlBasicInfo carries no lossless
// flag, so JXL reports LosslessUnknown.
Lossless Lossless
// ColorEncoding is the codec-domain color encoding of the samples.
ColorEncoding ColorEncoding
// ChromaSubsampling is the chroma subsampling of the samples. It matters to
// frame-copy consumers that must distinguish, e.g., DICOM YBR_FULL_422
// (4:2:2) from YBR_FULL (4:4:4) — a conformance distinction. JPEG reports it
// from the SOF component sampling factors; JPEG 2000 / HTJ2K from the SIZ
// per-component XRsiz/YRsiz. Grayscale codestreams report SubsamplingNone;
// codecs that don't expose it (e.g. JPEG XL) report SubsamplingUnknown.
ChromaSubsampling ChromaSubsampling
// Boxed reports whether src is a boxed container (JP2 / JPH / JXL container)
// rather than a raw codestream (J2K / raw JXL). Targets such as DICOM
// require a specific encapsulated form (e.g. HTJ2K wants the raw .j2c
// codestream, not the .jph box), so consumers need this before frame-copy.
Boxed bool
}
CodestreamInfo is header-only metadata about an encoded tile/frame, obtained without a full decode (GH #41). It carries the codec-domain facts a consumer needs to frame-copy a tile verbatim into a target container (e.g. a DICOM TransferSyntax + PhotometricInterpretation) without re-decoding.
Mapping the codec-domain fields to a target container's vocabulary (e.g. DICOM PhotometricInterpretation) is the consumer's job; this struct is codec-domain only.
type CodestreamInspector ¶ added in v0.42.1
type CodestreamInspector interface {
// Inspect parses src's codestream header and returns codec-domain metadata
// without decoding the pixels. Returns ErrCorruptInput if the header can't
// be parsed. Header-only is the contract: it must not decode the full frame.
Inspect(src []byte) (CodestreamInfo, error)
}
CodestreamInspector is implemented by codec Factories that can return codec-domain metadata about an encoded codestream from its header alone — without fully decoding the frame (GH #41). Not every Factory implements it; consumers type-assert:
f, _ := decoder.GetByCompressionTag(tag)
if p, ok := f.(decoder.CodestreamInspector); ok {
info, err := p.Inspect(compressed)
}
Implemented by jpeg, jpeg2000, htj2k, and jpegxl. Codecs without a meaningful codestream header (none / lzw / deflate / webp / avif) do not implement it, so the type assertion reports ok == false.
type ColorEncoding ¶ added in v0.42.0
type ColorEncoding uint8
ColorEncoding is the codec-domain color encoding of a codestream. The YBR_ICT / YBR_RCT values are the JPEG 2000 multiple-component transforms (irreversible / reversible); the String() forms match the DICOM PhotometricInterpretation spelling for convenience.
const ( ColorUnknown ColorEncoding = iota ColorGrayscale // single luminance channel ColorRGB // RGB components, no decorrelating transform ColorYCbCr // JPEG (JFIF) luma/chroma ColorYBRICT // JPEG 2000 irreversible MCT (lossy) ColorYBRRCT // JPEG 2000 reversible MCT (lossless) )
func (ColorEncoding) String ¶ added in v0.42.0
func (c ColorEncoding) String() string
type DecodeOptions ¶
type DecodeOptions struct {
// Scale is the in-codec downscale factor. Valid values: 1, 2, 4, 8;
// other values return ErrUnsupportedScale. The zero value (0) is
// treated as 1 (no scaling). Decode produces ceil(srcDim/Scale).
// Supported by: jpeg (libjpeg IDCT fast-scale), jpeg2000 and htj2k
// (DWT resolution-level decode, 1/2^log2(Scale), box-finishing any
// residual when the codestream has too few levels). Other decoders
// return ErrUnsupportedScale if Scale != 1.
Scale int
// Format is the requested output pixel format. Decoders return
// ErrUnsupportedFormat if they can't produce the requested format.
// Today: PixelFormatRGB and PixelFormatRGBA are universal.
Format PixelFormat
// Dst is an optional caller-supplied destination Image. If nil, the
// decoder allocates. If non-nil and its dimensions match the
// decoded size, the decoder writes into Dst.Pix and returns Dst.
// Mismatched dimensions return ErrDestinationSize.
Dst *Image
}
DecodeOptions configures a single Decode call. The zero value is valid (Scale=1, Format=PixelFormatRGB, Dst=nil → allocate fresh RGB).
type Decoder ¶
type Decoder interface {
// Decode the compressed bytes per opts. If opts.Dst is non-nil and
// matches the decoded dimensions, writes into Dst and returns it;
// otherwise allocates a fresh Image.
Decode(compressed []byte, opts DecodeOptions) (*Image, error)
// Close releases the decoder's internal state. Safe to call
// multiple times. After Close, further Decode calls return an
// error.
Close() error
}
Decoder turns compressed tile bytes into a decoded Image. Decoders are NOT safe for concurrent use; callers running concurrent decodes on the same slide should construct one Decoder per goroutine via Factory.New().
type Factory ¶
type Factory interface {
// Name is the canonical codec identifier (e.g., "jpeg",
// "jpeg2000", "lzw"). Lowercase.
Name() string
// TIFFCompressionTags lists the TIFF Compression tag values this
// factory's decoder handles. Multiple tags allowed (e.g., JPEG
// 2000 is both 33003 (Aperio) and 34712 (libtiff)). Empty for
// non-TIFF-associated codecs.
TIFFCompressionTags() []uint16
// New returns a fresh Decoder instance. Each call returns a new
// instance with its own state. Decoders are NOT safe for
// concurrent use across goroutines.
New() Decoder
}
Factory constructs decoders for a specific codec. Codec subpackages register a Factory in their init() function.
func Get ¶
Get returns the factory registered for the given codec name, or (nil, false) if none is registered.
func GetByCompressionTag ¶
GetByCompressionTag returns the factory registered for the given TIFF Compression tag value, or (nil, false) if none is registered.
type Image ¶
type Image struct {
Width, Height int
Stride int // bytes per row; may over-allocate for SIMD alignment
Format PixelFormat
Pix []byte // len(Pix) == Stride * Height
}
Image is a decoded raster bitmap.
func NewImage ¶
NewImage returns a freshly-allocated Image with PixelFormatRGB and Stride = w * 3. The Pix slice is zero-filled.
func NewImageFormat ¶
func NewImageFormat(w, h int, fmt PixelFormat) *Image
NewImageFormat returns a freshly-allocated Image with the requested format. Stride is set to the format's bytes-per-pixel times w.
type Lossless ¶ added in v0.42.0
type Lossless uint8
Lossless is the tri-state reversibility of a codestream.
const ( // LosslessUnknown means the codec exposes no header-only reversibility // signal (JPEG XL). LosslessUnknown Lossless = iota // LosslessYes means the codestream is reversible/lossless (J2K 5/3, // HTJ2K reversible). LosslessYes // LosslessNo means the codestream is lossy (J2K 9/7, JPEG baseline). LosslessNo )
type PixelFormat ¶
type PixelFormat int
PixelFormat selects the in-memory pixel layout of a decoded Image.
const ( // PixelFormatRGB is 3 bytes per pixel, no alpha channel. // The default — WSI imagery is opaque so alpha is wasted memory. PixelFormatRGB PixelFormat = iota // PixelFormatRGBA is 4 bytes per pixel with alpha = 0xFF. // Use when interop with Go stdlib image.NRGBA matters. PixelFormatRGBA )
Directories
¶
| Path | Synopsis |
|---|---|
|
Package all blank-imports every decoder subpackage so all codecs register at init() time.
|
Package all blank-imports every decoder subpackage so all codecs register at init() time. |
|
Package avif implements the AVIF decoder via libavif.
|
Package avif implements the AVIF decoder via libavif. |
|
Package deflate implements the decoder for TIFF Compression=8 (Deflate/Zip).
|
Package deflate implements the decoder for TIFF Compression=8 (Deflate/Zip). |
|
Package htj2k implements the HTJ2K (High-Throughput JPEG 2000) decoder via OpenJPH (https://github.com/aous72/OpenJPH).
|
Package htj2k implements the HTJ2K (High-Throughput JPEG 2000) decoder via OpenJPH (https://github.com/aous72/OpenJPH). |
|
Package jpeg implements the JPEG decoder via libjpeg-turbo.
|
Package jpeg implements the JPEG decoder via libjpeg-turbo. |
|
Package jpeg2000 implements the JPEG 2000 decoder via openjp2.
|
Package jpeg2000 implements the JPEG 2000 decoder via openjp2. |
|
Package jpegxl implements the JPEG-XL decoder via libjxl.
|
Package jpegxl implements the JPEG-XL decoder via libjxl. |
|
Package lzw implements the decoder for TIFF Compression=5 (LZW).
|
Package lzw implements the decoder for TIFF Compression=5 (LZW). |
|
Package none implements the trivial "no-compression" decoder for TIFF Compression=1 tiles, where the on-disk bytes ARE the decoded pixels.
|
Package none implements the trivial "no-compression" decoder for TIFF Compression=1 tiles, where the on-disk bytes ARE the decoded pixels. |
|
Package webp implements the WebP decoder via libwebp.
|
Package webp implements the WebP decoder via libwebp. |