Documentation
¶
Overview ¶
Package read coordinates detection and decoding into the full JAB Code reading pipeline: it owns the orientation and region-of-interest retries, the detect-then-decode handoff for the primary symbol (including the alignment-pattern fallback that needs the decoded side version), and the docked-secondary walk that derives each secondary's geometry from its decoded host metadata.
Index ¶
- func CompiledCapabilities() wire.Capabilities
- func Decode(img image.Image) ([]byte, error)
- func DecodeCapabilities(img image.Image, capabilities wire.Capabilities) ([]byte, error)
- func DecodeImage(img image.Image) (data []byte, ok, evidence bool)
- func DecodeOnly(img image.Image, variant wire.Variant) ([]byte, error)
- func ProbeDegrees() []float64
- func WarmGPUForFrame(width, height int)
- type DiagnosticAttempt
- type DiagnosticROIs
- type DiagnosticRoute
- type DiagnosticSecondary
- type DiagnosticTrace
- type Message
- type RouteKinds
- type RouteReport
- type RouteStages
- type Stream
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CompiledCapabilities ¶
func CompiledCapabilities() wire.Capabilities
CompiledCapabilities reports the decoder variants included in this build. It is internal API for the CLI's oracle-only selector and capability tests; normal callers use Decode and automatically receive the whole set.
func Decode ¶
Decode decodes the data of a JAB Code from img: the primary symbol and any docked secondary symbols. Reading a JAB Code from a file is stdlib decoding (e.g. png.Decode) followed by Decode.
A large capture rarely needs its full resolution - only small-module symbols do - so Decode searches a resolution pyramid: box-halved levels of the frame decode concurrently and the coarsest success wins (see decodePyramid). Small images run the single full-resolution search directly and behave exactly as before.
Orientation is not searched. The finder scan turns its own scan lines rather than the frame, so one whole-frame read of a level covers every orientation that level can present and no route resamples pixels to try an angle.
What a level's whole-frame read can still miss is a symbol competing with the rest of a large cluttered frame, so as a last resort the read repeats per proposed region of interest. A crop carries no more resolution than the level it came from; what it changes is that binarization and the finder scan work against the region's own statistics.
func DecodeCapabilities ¶
DecodeCapabilities is Decode with every wire format enabled by capabilities. The mask is additive: one physical locate and sample can be interpreted by each compatible wire decoder before the route escalates.
func DecodeImage ¶
DecodeImage attempts one full read of img as given: binarize, locate and decode the primary symbol, then its docked secondaries, then assemble the message. It runs the entire session on one image so the primary, the alignment-pattern fallback and the secondaries share a single coherent coordinate frame. evidence reports whether the finder search saw any finder structure at all, so Decode can skip the region search outright on blank or near-uniform input.
func DecodeOnly ¶
DecodeOnly is Decode under one selected internal wire variant.
func ProbeDegrees ¶
func ProbeDegrees() []float64
ProbeDegrees are the scan directions a whole-frame pass sweeps when its row walk does not settle. RouteReport.Deg is always one of them, or -1.
func WarmGPUForFrame ¶
func WarmGPUForFrame(width, height int)
WarmGPUForFrame prepares the device decode route for a frame of this size without needing its pixels. The route's own acquisition otherwise creates the device, the kernel set, the finder chain compilation and the size-matched workspace after the image has been decoded, all of it on the critical path of a single-shot read. Everything there depends on geometry alone; only the pixel upload does not, and that stays where it was. A caller that knows the frame size before it decodes the image - which the header gives for free - can overlap the whole of it.
Types ¶
type DiagnosticAttempt ¶
type DiagnosticAttempt struct {
Route DiagnosticRoute
Stage string
Balanced *core.Bitmap
InitialChannels [3]*core.Bitmap
FinalChannels [3]*core.Bitmap
Detector detect.DetectorStats
DetectorTrace detect.DetectorTrace
Finders []detect.FinderPattern
// FindersFamily is the signature Finders came from. The two families have
// different finder geometry, so a quad drawn or read against the wrong one
// describes a symbol that was never there.
FindersFamily detect.FinderFamily
// FinderCorner identifies the retained quad's weakest-corner evidence.
// FinderHypotheses counts the image-backed and constructed quads sampled for
// this route. AmbiguousFinders reports that more than one decoded and their
// interpreted messages disagreed, so no payload was returned.
FinderCorner detect.CornerSource
FinderHypotheses int
AmbiguousFinders bool
PrintDetected bool
Side image.Point
Transform core.Perspective
HasTransform bool
ChannelOffsets [3]core.PointF
Sampled *core.Bitmap
Primary []decode.PrimaryTrace
Alignments []*detect.AlignmentTrace
Secondaries []DiagnosticSecondary
Payload []byte
}
DiagnosticAttempt owns the intermediate state of one actual decode route. It is populated only for DecodeWithTrace; the normal Decode path passes nil and allocates none of this diagnostic state.
type DiagnosticROIs ¶
type DiagnosticROIs struct {
Level int
Image image.Image
TileMap detect.ROITileMap
Candidates []detect.ROICandidate
}
DiagnosticROIs records the actual ROI analysis used by one search route.
type DiagnosticRoute ¶
type DiagnosticRoute struct {
Kind string
Level int
ROI int
// Deg is the scan direction this attempt's quad came from, -1 when it
// located nothing. Kind names the rung and nothing about scan geometry, so
// without this an attempt line cannot say whether the search turned. An
// attempt reaches this trace only through finishAttempt, which always
// stamps it, so there is no unset state to default.
Deg float64
}
DiagnosticRoute identifies one concrete decode attempt.
type DiagnosticSecondary ¶
type DiagnosticSecondary struct {
HostIndex int
DockedPosition int
Side image.Point
Transform core.Perspective
HasTransform bool
Patterns []detect.FinderPattern
Matrix *core.Bitmap
MetadataMatrix *core.Bitmap
Symbol core.DecodedSymbol
Classification decode.ModuleClassificationTrace
Result int
}
DiagnosticSecondary records one docked-secondary sample and decode result.
type DiagnosticTrace ¶
type DiagnosticTrace struct {
Input image.Image
Pyramid []image.Point
PyramidImages []image.Image
ROIs []DiagnosticROIs
Attempts []DiagnosticAttempt
}
DiagnosticTrace is the observation-only record of one authoritative Decode session. Attempts are ordered by the same deterministic route priority used to commit a decode result. ROI proposals are the actual search inputs used by those routes, not diagnostic recomputations.
func DecodeWithTrace ¶
func DecodeWithTrace(img image.Image) ([]byte, *DiagnosticTrace, error)
DecodeWithTrace runs the same decoder as Decode exactly once and returns its detailed observation trace. The trace cannot influence route selection or payload decisions.
func DecodeWithTraceCapabilities ¶
func DecodeWithTraceCapabilities(img image.Image, capabilities wire.Capabilities) ([]byte, *DiagnosticTrace, error)
DecodeWithTraceCapabilities is DecodeWithTrace with an additive decoder mask.
func DecodeWithTraceOnly ¶
DecodeWithTraceOnly is DecodeWithTrace under one selected internal variant.
type Message ¶
Message is the mode decoder's paired raw-data and reader-transmission result.
func DecodeMessage ¶
DecodeMessage decodes img once and returns both raw application data and the standards-facing reader transmission produced from the same corrected bits.
func DecodeMessageCapabilities ¶
DecodeMessageCapabilities is DecodeMessage with an explicit additive capability set for internal oracle and CLI use.
type RouteKinds ¶
type RouteKinds struct {
Frame, Seeded, ROI int
}
RouteKinds counts attempted routes per ladder rung.
type RouteReport ¶
type RouteReport struct {
// Decoded reports whether Kind names a winning route or only the best
// failed one.
Decoded bool
// Kind is the ladder rung: frame, roi or seeded. It names where the pixels
// came from - the whole frame at some pyramid level, a region crop, or a
// coarse level's finding - and says nothing about scan geometry. Read Deg
// for that. Empty when no route was
// attempted at all.
Kind string
// Level is the pyramid level, -1 for the single-scale search and -2 for
// the enlarged detection scale.
Level int
// ROI is the proposed region index, -1 for a whole-frame route.
ROI int
// Deg is the scan direction that produced the quad of the attempt this
// report names - the winner when Decoded, otherwise the furthest failed
// attempt, which may well have located one. It is -1 when that attempt
// located nothing, which zero cannot stand in for: zero is the row walk and
// a real answer. Every whole-frame pass sweeps the probe directions when its
// row walk does not settle, so Kind cannot tell a row-settled read from a
// turned one and this is what does.
Deg float64
// Stage is how far the route got, in pipeline order.
Stage string
// Side is the finder-based grid estimate, zero when the route never
// located.
Side image.Point
// Attempts counts the routes collected when the read returned. A failed
// read runs the ladder out, so this is its full route count; a successful
// one returns as soon as its winner commits and leaves concurrent losing
// routes unjoined, so there it counts the routes committed up to the
// winner rather than every route the process ran.
Attempts int
// Kinds splits Attempts by rung, which is what says where a read's route
// budget went rather than only how large it was.
Kinds RouteKinds
// Stages splits Attempts by how far each route got. Stage alone reports the
// furthest route, which on a failed read says only that *something*
// sampled; the split says how many routes paid for a sample and how many
// stopped at the finder walk, which is what distinguishes a read that is
// expensive because it keeps sampling from one that is expensive because it
// keeps searching.
Stages RouteStages
// Levels is the pyramid depth, 1 for the single-scale search. Level alone
// does not say how coarse a route ran: level 1 is the finest of two and
// the second coarsest of four.
Levels int
}
RouteReport attributes one read to a single rung of the decode ladder: the route that produced the payload, or - when nothing decoded - the furthest an attempted route got. It is the cheap counterpart of DiagnosticTrace, which answers the same question only by retaining every attempt's intermediate bitmaps: a route census over a whole capture pool needs the attribution without the megabytes.
func DecodeWithRouteCapabilities ¶
func DecodeWithRouteCapabilities(img image.Image, capabilities wire.Capabilities) ([]byte, RouteReport, error)
DecodeWithRouteCapabilities runs the same decode as DecodeCapabilities and additionally reports which ladder rung answered. The report is observation only; collecting it changes no decode decision.
func (RouteReport) String ¶
func (r RouteReport) String() string
type RouteStages ¶
type RouteStages struct {
Aborted, NoFinders, NoSideSize, NoSample, Sampled, Decoded int
}
RouteStages counts attempted routes per furthest stage reached.
type Stream ¶
type Stream struct {
// contains filtered or unexported fields
}
Stream decodes one ordered, coherent frame sequence under a fixed per-frame work quota. Unlike the single-image Decode, which escalates through regions of interest and an alignment-pattern fallback until everything failed, a Stream frame spends at most one replay of a remembered hypothesis, one whole-frame scan, one queued scale attempt and one admission-gated payload correction, then returns and waits for the next frame: in a coherent sequence the next frame is usually cheaper than searching this one harder. Hypotheses the budget could not try carry over to the following frames in deterministic order, so a hard first lock (rotated, or small in the frame) is found across a few frames instead of inside one. The zero value is ready to use; a Stream is not safe for concurrent use (frames are supplied in sequence order).
Each frame's result is deterministic given the frames decoded before it: the ring and the hypothesis queue are pure functions of the sequence, and every attempt is deterministic.
Emission is per frame. DecodeMessage returns the payload currently on screen for every frame that yields one, and an error for a frame that does not, including a transition frame showing two codes at once, which never decodes. A frame that re-shows an already-returned code returns it again (cheaply, without a correction, when the frame's own evidence still confirms it), and a code that reappears later in the sequence is decoded afresh: the Stream never withholds a payload because it emitted those bytes before. Cross-frame deduplication, loop-occurrence identity and whole-message reassembly are the caller's responsibility, above this decoder. Frame order is the caller's supply order, which the Stream neither reorders nor tags, so a caller correlates payloads to frames by the order it supplied them.
func NewStreamOnly ¶
NewStreamOnly returns an empty stream restricted to variant for internal oracle tests. The zero Stream uses every decoder compiled into this build.
func (*Stream) Close ¶
Close releases the optional resident GPU workspace. The zero Stream remains usable after Close and will reopen a session when a later frame qualifies.
func (*Stream) Decode ¶
Decode reads one frame within the per-frame quota. On success the winning hypothesis moves to the ring's front; on failure the ring is kept - a single blurred or occluded frame should not throw away a working lock - and the frame's unspent hypotheses wait in the queue for the next frame.
func (*Stream) DecodeMessage ¶
DecodeMessage reads one frame and returns paired raw data and reader transmission from the winning correction.
Source Files
¶
- alignment_observation.go
- bsi_disabled.go
- current_family_variants_iso.go
- diagnostic.go
- docked.go
- docked_bsi_disabled.go
- docked_variant_default.go
- evidencegroup.go
- high_color_disabled.go
- historical_disabled.go
- legacy_capabilities_disabled.go
- message.go
- primary_correction.go
- pyramid.go
- read.go
- routereport.go
- seeded.go
- stream.go
- stream_historical_disabled.go
- trace.go