core

package
v0.0.0-...-b4425be Latest Latest
Warning

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

Go to latest
Published: Aug 22, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package core holds the types shared by the detection and decoding stages: the pixel Bitmap, floating-point geometry (PointF, Perspective), the decoded-symbol result types, the shared status codes, and small per-pixel colour statistics. It is the dependency leaf under detect, decode, read and diag, and imports none of them.

Index

Constants

View Source
const (
	Failure    = 0
	Success    = 1
	FatalError = -2
)

Status values shared by the detection and decoding stages.

Variables

This section is empty.

Functions

func AvgVar

func AvgVar(rgb []byte) (avg, variance float64)

AvgVar returns the mean and variance of a pixel's RGB values.

func BoolColor

func BoolColor(b bool) int

BoolColor maps a binary channel test to the 0/255 color value used for type classification.

func Majority5Columns

func Majority5Columns(src, dst []byte, width, height int)

Majority5Columns writes the interior pixels of a vertical five-pixel majority pass. Edge pixels remain untouched.

func Majority5Row

func Majority5Row(src, dst []byte, width int)

Majority5Row writes the interior pixels of a horizontal five-pixel majority pass. src must contain only 0 or 255 bytes: the SIMD implementation relies on those values being boolean masks. Edge pixels are deliberately untouched because the filter's full-kernel contract leaves them unchanged.

func MinMax

func MinMax(rgb []byte) (min, mid, max byte, iMin, iMid, iMax int)

MinMax orders a pixel's three channels, returning the values and their original channel indices.

func ParallelChunks

func ParallelChunks(n, minPerChunk int, fn func(lo, hi int))

ParallelChunks is ParallelRows with an explicit minimum chunk size, for loops whose iterations are much heavier than one pixel row (e.g. block rows). The same disjoint-writes contract applies.

func ParallelRows

func ParallelRows(rows int, fn func(lo, hi int))

ParallelRows splits the half-open row range [0, rows) into contiguous bands and runs fn on each band, concurrently when the range is large enough to pay for the goroutines. Each band's writes must stay inside its own rows; bands are disjoint, so the combined result is identical to the sequential loop regardless of scheduling.

func RGBBlockStats

func RGBBlockStats(pix []byte, width, channels, sx, ex, sy, ey int) (lo, hi [3]int, sum [3]float64, n int)

RGBBlockStats returns per-channel extrema and sums for a rectangular RGB region.

Types

type Bitmap

type Bitmap struct {
	Width, Height int
	Channels      int
	Pix           []byte // row-major, Width*Height*Channels bytes
	// contains filtered or unexported fields
}

Bitmap is a raw 8-bit-per-channel pixel buffer used by the detector and decoder. Channels is 4 (RGBA) for input images, or 1 for grayscale/binary intermediates.

func BitmapFromImage

func BitmapFromImage(img image.Image) *Bitmap

BitmapFromImage converts any image.Image into a 4-channel RGBA bitmap. Reading a JAB Code from a file is therefore just stdlib decoding (e.g. png.Decode) followed by this conversion.

func NewBitmap

func NewBitmap(width, height, channels int) *Bitmap

func (*Bitmap) Gray

func (b *Bitmap) Gray() *image.Gray

Gray returns a zero-copy image view of a materialized single-channel bitmap. Bitmap owns the backing bytes and the returned image aliases them; callers must not retain the view after the bitmap's pixels are replaced.

func (*Bitmap) HasPixels

func (b *Bitmap) HasPixels() bool

HasPixels reports whether the row-major buffer is present. A bitmap may carry only its shape while the pixels stay resident on a device, so every consumer that indexes Pix directly has to ask first and fail closed; indexing a shape-only bitmap is an out-of-range panic, and Decode must never panic.

func (*Bitmap) NRGBA

func (b *Bitmap) NRGBA() *image.NRGBA

NRGBA returns a zero-copy image view of a 4-channel bitmap, valid because the buffer is always tightly packed with a zero origin. The view aliases Pix, so writes through either side are visible in both. Returns nil for other channel counts or for a shape-only deferred bitmap.

func (*Bitmap) Offset

func (b *Bitmap) Offset(x, y int) int

Offset returns the index into Pix of pixel (x, y).

func (*Bitmap) Pixel

func (b *Bitmap) Pixel(x, y int) byte

Pixel returns a single-channel pixel without requiring a deferred mask to expand into a full image. Ordinary bitmaps take the direct row-major path; sparse readers are used only by downstream consumers that need bounded windows of a packed detector result.

func (*Bitmap) SetPixelReader

func (b *Bitmap) SetPixelReader(read func(x, y int) byte)

SetPixelReader installs a deferred reader for a shape-only single-channel bitmap. It is an internal handoff for packed detector masks, not a general replacement for Bitmap.Pix.

type DecodedSymbol

type DecodedSymbol struct {
	WireVariant      wire.Variant
	Index            int
	HostIndex        int
	HostPosition     int
	SideSize         image.Point
	ModuleSize       float64
	PatternPositions [4]PointF
	MetadataModules  int
	Meta             Metadata
	SecondaryMeta    [4]Metadata
	Palette          []byte
	Data             []byte
}

DecodedSymbol holds a decoded symbol.

type GridDevice

type GridDevice interface {
	MaterializeGrid(matrix *Bitmap, reason GridReason) bool
}

GridDevice fills a sampled grid's module data from the device that produced it, for the host stages that have to read modules.

A device-route sample is a shape-only bitmap until something asks, so that a read which never leaves the device never pays for the grid. Materializing is deliberately a call and not a side effect of reading Pix: the stages that need modules are all fallbacks, and they should be countable.

It reports false when the grid can no longer be produced - the device has moved on to another sample, or the route context is gone - and the caller then fails the way it fails for any matrix it cannot read.

type GridReason

type GridReason string

GridReason names the host stage that wants the modules. One function performs every grid download, so without the caller's name a census can say how much module traffic a read costs but not which stage to move onto the device to remove it, which is the only question worth asking of the number.

const (
	GridReasonFixedPattern      GridReason = "fixed_pattern"
	GridReasonPayloadFallback   GridReason = "payload_fallback"
	GridReasonPaletteRetry      GridReason = "palette_retry"
	GridReasonMetadataDecline   GridReason = "metadata_decline"
	GridReasonAlignmentResample GridReason = "alignment_resample"
	GridReasonStreamObservation GridReason = "stream_observation"
	GridReasonHistoricalFamily  GridReason = "historical_family"
	GridReasonCrossFrame        GridReason = "cross_frame"
	GridReasonModuleCosts       GridReason = "module_costs"
	GridReasonDiagnosticSample  GridReason = "diagnostic_sample"
)

type Metadata

type Metadata struct {
	DefaultMode    bool
	NC             int // colour mode Nc; colour count = 2^(NC+1)
	MaskType       int
	DockedPosition int
	SideVersion    image.Point
	ECL            image.Point // error-correction (wc, wr)
}

Metadata holds a decoded symbol's parameters.

type MetadataDevice

type MetadataDevice interface {
	WalkPrimaryMetadata(matrix *Bitmap, symbol *DecodedSymbol) (PrimaryMetadata, error)
}

MetadataDevice interprets a primary symbol's metadata where its module grid already is: part I and its correction, the embedded palette, part II and the fields it declares.

As with PayloadDevice, Matrix identifies the sample rather than supplying it, because a device walk is only usable on the grid the device itself produced. A device that cannot answer - a grid it no longer owns, a colour mode outside what it implements, a walk that left the symbol - returns an error, which is a decline the host answers by walking the metadata itself.

type PayloadDevice

type PayloadDevice interface {
	// SupportsFixedPatternAdmission reports whether CorrectSymbolPayload can
	// gate correction on the format-fixed modules without materializing the
	// sampled grid.
	SupportsFixedPatternAdmission() bool
	CorrectSymbolPayload(request PayloadRequest) (dec []byte, ok bool, err error)
}

PayloadDevice corrects a symbol's payload where its module grid already is: classification, unmasking, deinterleaving, hard error correction, and its soft-decision retry, with the corrected message bits as the only result that crosses back.

ok reports the post-retry syndrome; a false ok means the device answered but both correction stages gave up and the bits are unreliable. A corrector that cannot answer - an unsupported symbol shape, or a grid it no longer owns - returns an error, which is a decline rather than a failed read.

type PayloadRequest

type PayloadRequest struct {
	Matrix *Bitmap
	Symbol *DecodedSymbol

	// MetadataModules is how many modules the metadata walk consumed, which is
	// all a device stage needs to replay that walk and reserve the same modules
	// the host reserved.
	MetadataModules int

	// DataModules is how many modules carry payload, so the caller and the
	// device agree on the codeword length before either builds it.
	DataModules int

	// RequireFixedPatternAgreement defers the module-grid half of admission to
	// the resident correction submission. The host has already accepted the
	// palette-coherence half before setting it.
	RequireFixedPatternAgreement bool

	NormalizedPalette []float64
	PaletteThresholds []float64
}

PayloadRequest describes one symbol's payload correction in the terms a device stage can answer: which sampled grid, the metadata already interpreted from it, and how much of the grid that interpretation consumed.

It carries no module data. A device corrector is only usable when the grid it would read is still the one it produced, which is why Matrix identifies the sample rather than supplying it.

type Perspective

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

Perspective is a 3x3 projective transform matrix.

func PerspectiveTransform

func PerspectiveTransform(p0, p1, p2, p3 PointF, side image.Point) Perspective

PerspectiveTransform returns the transform mapping a symbol's module grid (corners at 3.5 inside each finder/alignment pattern) to the four detected pattern centers.

func QuadToQuad

func QuadToQuad(s, d [4]PointF) Perspective

QuadToQuad returns the transform mapping source quadrilateral s to destination quadrilateral d.

func (Perspective) Coefficients

func (m Perspective) Coefficients() [9]float64

Coefficients returns the matrix in the row-major order Warp consumes it, so a device stage can be handed the same transform the host derived rather than re-deriving it from corners it would also have to be given.

func (Perspective) Warp

func (m Perspective) Warp(p PointF) PointF

Warp maps a point through the transform.

func (Perspective) WarpRow

func (m Perspective) WarpRow(xs []float64, y float64, out []PointF)

WarpRow warps the points (xs[i], y) into out, which must be at least len(xs) long. It hoists the a2k*y products that Warp would otherwise recompute for every point sharing a row. The result is bit-identical to Warp(Pt(xs[i], y)): Warp sums a1k*x + a2k*y + a3k left to right, and precomputing a2k*y then adding it to a1k*x in that same order changes no rounding.

type PointF

type PointF struct{ X, Y float64 }

PointF is a 2D point with floating-point coordinates. The stdlib image.Point is integer-only, so detection geometry uses this.

func Pt

func Pt(x, y float64) PointF

Pt returns a PointF with the given coordinates, mirroring image.Pt.

type PrimaryDevice

type PrimaryDevice interface {
	DecodePrimary(matrix *Bitmap, symbol *DecodedSymbol) (PrimaryDeviceResult, error)
}

PrimaryDevice decodes one primary symbol from a module grid that already resides on the device. An error is a decline, so the host may materialize the same grid and run its full path. PayloadOK false is an answered decode failure and must not repeat correction on the host.

type PrimaryDeviceResult

type PrimaryDeviceResult struct {
	Metadata  PrimaryMetadata
	Payload   []byte
	PayloadOK bool
	Evidence  PrimaryEvidence
}

PrimaryDeviceResult is the only host-visible output of a resident primary decode: interpreted metadata and corrected message bits. Locate, sampling, classification and correction workspaces remain device-owned.

type PrimaryEvidence

type PrimaryEvidence struct {
	Available        bool
	MetadataExplicit bool
	FixedPatternUsed bool
	SoftFallbackUsed bool

	MetadataPartIInitial      uint32
	MetadataPartIResidual     uint32
	MetadataPartICorrections  uint32
	MetadataPartIIInitial     uint32
	MetadataPartIIResidual    uint32
	MetadataPartIICorrections uint32

	PaletteSeparation   float32
	PaletteDisagreement float32
	FixedAgreements     uint32
	FixedChecks         uint32

	PayloadInitial        uint32
	PayloadHardResidual   uint32
	PayloadCorrections    uint32
	PayloadSoftResidual   uint32
	PayloadSoftIterations uint32
}

PrimaryEvidence is the compact quantitative record behind one corrected primary interpretation. A successful parser is deliberately absent: syntax is an admission gate applied after this physical and correction evidence, never evidence that can break a tie between disagreeing payloads.

func (PrimaryEvidence) Admitted

func (e PrimaryEvidence) Admitted() bool

Admitted reports whether the evidence itself permits final message parsing. Explicit metadata needs clean parity. A default or weak-metadata route must instead carry the fixed-pattern evidence that admitted it. Payload correction always ends at zero residual, including a soft retry when one was used.

func (PrimaryEvidence) Dominates

func (a PrimaryEvidence) Dominates(b PrimaryEvidence) bool

Dominates reports whether a is no worse on every comparable signal and strictly better on at least one. Incomparable admission mechanisms and any conflict return false, so neither compile order nor completion order can become an implicit winner rule.

type PrimaryMetadata

type PrimaryMetadata struct {
	// Defaulted reports that part I did not resolve a colour mode and the
	// symbol is to be read under default metadata, which is a ladder the host
	// owns rather than a failure.
	Defaulted bool

	// Rejected reports that the symbol declared a shape its own sample
	// contradicts: a side version that is not the sampled side, or ECC weights
	// out of order. The fields below still carry what was read, because a
	// caller's alignment-pattern retry uses the declared version.
	Rejected bool

	NC          int
	Colors      int
	SideVersion image.Point
	ECL         image.Point
	MaskType    int
	Palette     []byte

	// MetadataModules is how many modules the walk consumed, which is what lets
	// the host reserve exactly the modules the walk reserved.
	MetadataModules int

	PartISyndromeOK  bool
	PartIISyndromeOK bool
}

PrimaryMetadata is a primary symbol's metadata as a device stage resolves it: the colour mode, the embedded palette and the shape the symbol declares.

It stops where geometry takes over. The reserved-module map and the normalized palette are both derivable from these fields alone - the first from the walk length, the second from the palette bytes - so a device that already holds them has no reason to ship them, and a host that rederives them gets the values its own arithmetic would have produced rather than a narrower float's.

Jump to

Keyboard shortcuts

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