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
- func AvgVar(rgb []byte) (avg, variance float64)
- func BoolColor(b bool) int
- func Majority5Columns(src, dst []byte, width, height int)
- func Majority5Row(src, dst []byte, width int)
- func MinMax(rgb []byte) (min, mid, max byte, iMin, iMid, iMax int)
- func ParallelChunks(n, minPerChunk int, fn func(lo, hi int))
- func ParallelRows(rows int, fn func(lo, hi int))
- func RGBBlockStats(pix []byte, width, channels, sx, ex, sy, ey int) (lo, hi [3]int, sum [3]float64, n int)
- type Bitmap
- type DecodedSymbol
- type GridDevice
- type GridReason
- type Metadata
- type MetadataDevice
- type PayloadDevice
- type PayloadRequest
- type Perspective
- type PointF
- type PrimaryDevice
- type PrimaryDeviceResult
- type PrimaryEvidence
- type PrimaryMetadata
Constants ¶
const ( Failure = 0 Success = 1 FatalError = -2 )
Status values shared by the detection and decoding stages.
Variables ¶
This section is empty.
Functions ¶
func BoolColor ¶
BoolColor maps a binary channel test to the 0/255 color value used for type classification.
func Majority5Columns ¶
Majority5Columns writes the interior pixels of a vertical five-pixel majority pass. Edge pixels remain untouched.
func Majority5Row ¶
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 ¶
MinMax orders a pixel's three channels, returning the values and their original channel indices.
func ParallelChunks ¶
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 ¶
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.
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 ¶
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 (*Bitmap) 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 ¶
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 ¶
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) Pixel ¶
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 ¶
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.
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.