Checkpoint implementation at user-requested stop; document known failures and incomplete release qualification. Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: GPT-6 Codex <noreply@openai.com>
26 KiB
Barcode catalog: qqq-barcodes-9
Version 9 adds worker-owned physical barcode fitting for 13 explicit default encoder profiles; the catalog remains 71 IDs, not 71 distinct standards. All other profiles explicitly report fit unsupported. See BARCODE-FIT.md for geometry, dynamic scene types, scanner-mode requirements and current evidence limits. This candidate requires its own full/image qualification before adoption.
Fit profile qqq-barcode-fit/1: code128, code39, code93, itf, gs1-128, qr, ean13, ean8, upca, upce, datamatrix, pdf417, aztec, default options only. Actual encoder bounds include quiet zones once; physical boxes round inward using immutable stock DPI. The worker re-encodes at the greatest whole-module scale 1..16 within both box dimensions and existing raster budgets. It never stretches/clips. Other 58 IDs, binary fit and option-dependent profiles are unsupported. Canonical GS1 remains explicit; ambiguous scanned GS1 is refused.
PDF: <qqq-barcode type="${barcode.type}" value="${barcode.value}" fit="box" widthMicrons="90000" heightMicrons="50000" quiet="10"></qqq-barcode>. Do not specify scale. PDF uses stock DPI; layout still determines placement. ZPL: {"type":"barcode","symbologyPath":"/barcode/type","allowedSymbologies":["code128","qr"],"valuePath":"/barcode/value","x":0,"y":0,"quiet":10,"fit":{"widthMicrons":90000,"heightMicrons":50000}} inside the existing scene. Dynamic types must belong to that template-owned list. Static symbology remains valid.
For verified plain scanner inputs, PDF additionally uses scannerSymbology + aimIdentifier; ZPL uses paired scannerSymbologyPath + aimIdentifierPath. These do not attest device settings. A trusted scanner service must preserve and verify original text/raw data, exact label, AIM/GS1 modifiers and decoder configuration. Initial profiles require unmodified printable ASCII: CODE128/]C0, CODE39/]A0, CODE93/]G0, I2OF5/]I0, QRCODE/]Q1, DATAMATRIX/]d1, PDF417/]L0, AZTEC/]z0, EAN13/]E0, EAN8/]E4, UPCA/]E0, UPCE0/]E0 (optional exact LABEL-TYPE- label prefix). EAN/UPC require complete valid check digits; no prefix/suffix stripping, Code39 expansion/check removal, UPC conversion or GS1 inference. Missing/ambiguous modes refuse. Full contract and scanner-owner prerequisites are in BARCODE-FIT.md.
Version 8 added a distinct MIT-attributed Java Code93i encoder from pinned BWIPP source, for 71 explicit IDs. It preserves catalog 7's four-family bounded BASE64 mode, catalog 6's COOP Java port and the earlier typed append/color capabilities. It adds no executable, interpreter or dependency. Catalog 8 source is a new candidate: prior sealed catalog 7 images and results remain unchanged, and catalog 8 requires its own gates before adoption. IDs include aliases and profiles, not 71 distinct standards. Only documented typed options are accepted; CATALOG is the machine-readable contract. Software known answers and pixel checks are not physical-reader or hostile-runtime qualification.
Code93i
code93i is distinct from code93 and Code93 Extended. Its finite Java port
preserves the pinned BWIPP base/numeric/byte compaction, group shifts, checksum,
ordinary-Code93 compatibility preference and optional six-symbol GF(53) error
correction. No other family is substituted as an approximation.
Input is nonempty text converted to literal UTF-8 bytes, at most 500 bytes;
malformed surrogate input is refused. This does not insert an ECI or promise
that a reader interprets those bytes as Unicode. The initial public profile does
not accept BASE64, GS1/HIBC, ECI, raw codewords, FNC/escape parsing or automatic
splitting. Escape-looking strings remain literal data. Options are exactly
barHeight (integer 1..1000) and errorCorrection (boolean, default false).
Error correction has the additional upstream limit of 44 encoded data symbol
characters, not 44 input bytes. Upstream capacity and unencodable refusals are
preserved; notably a single space without error correction is unencodable.
Both PDF and ZPL retain integer modules using scale 1..16 and quiet 10..64. Existing 4096-axis/four-million-pixel bounds still apply before raster allocation: a legal 500-byte message need not fit the selected geometry. No enlargement of common budgets, automatic rescaling or provider fallback occurs.
<qqq-barcode type="code93i" value="${record.reference}" scale="2" quiet="10" options='{"errorCorrection":true}'></qqq-barcode>
{"type":"barcode","symbology":"code93i","valuePath":"/record/reference","x":20,"y":20,"scale":2,"quiet":10,"options":{"errorCorrection":true}}
The first staged corpus retains 20 upstream literal codeword answers and two upstream bar/space answers, plus PDF/ZPL pixel preservation. These expectations were authored upstream, not generated from this Java port. The upstream PostScript oracle has not been executed here, and no independent Code93i software decoder or physical reader is qualified. Exact hashes, MIT notice, unsupported source branches and maintenance policy are in src/test/resources/barcodes/code93i/README.md.
Opaque binary payloads
payloadEncoding is exactly UTF8 (default) or BASE64. Text mode retains
all existing provider and option behavior. BASE64 is available only for
qr, datamatrix, pdf417 and aztec, using the already isolated pinned
Zint provider; its absence is an error, never a Java text-encoder fallback.
Catalog metadata reports that binary provider's availability separately.
BASE64 must be canonical standard padded Base64, at most 684 characters,
decoding to 1–512 bytes. Whitespace, URL alphabet, data-URI prefixes, missing
padding when required, noncanonical trailing bits and empty content fail.
Decoded bytes are sent unchanged to fixed --binary --input=- arguments;
NUL, CR/LF, invalid UTF-8 and escape-looking data remain ordinary bytes.
No newline is added. The binary branch initially requires an empty options
object: ECI, GS1/HIBC, structured append, PDF417 macro, version/ECC and all
other text options are unsupported here. Authors must choose text mode to
use existing text options; they are never silently translated or ignored.
PDF uses the payloadEncoding attribute (HTML attribute names are
case-insensitive; its value is case-sensitive). ZPL uses a string property
with the same spelling; both literal value and valuePath results must
be strings for BASE64, with no numeric/boolean coercion.
<qqq-barcode type="qr" payloadEncoding="BASE64" value="${record.payloadBase64}" scale="4" quiet="10"></qqq-barcode>
{"type":"barcode","symbology":"datamatrix","payloadEncoding":"BASE64","valuePath":"/record/payloadBase64","x":20,"y":20,"scale":4,"quiet":10,"options":{}}
Scale 1–16 and quiet zone 4–64 modules, 4096-pixel axes, four-million-pixel
bitmap bounds, native output/time limits and document placement limits remain
unchanged. A legal512-byte input may still exceed the requested geometry;
there is no automatic shrinking, format change or splitting. Publication
validation does not evaluate future PDF contexts or promise future capacity.
The executable catalog describes payloadEncodings, defaultPayloadEncoding,
and binary-specific bounds/provider/options under payloadEncodingDetails;
the ordinary options map on these four IDs applies to UTF8 only.
The independent36-case byte oracle includes all256 values, numeric compaction, invalid UTF-8 and two512-byte boundary patterns per family. Final candidate qualification must also recover exact bytes from the produced PDF and ZPL rasters. This fixed no-ECI/no-GS1 profile does not qualify arbitrary byte interpretations on a physical reader.
COOP 2 of 5
coop2of5 is a distinct COOP encoder, not an alias for Industrial, Matrix or
Interleaved 2 of 5. It accepts 1–500 supplied ASCII digits, fixed wide:narrow
ratio 3:1, and checkDigit of NONE (default), ADD or VALIDATE.
ADD appends a modulo-ten check digit with weights 3/1 from the rightmost data
digit. VALIDATE requires at least two supplied digits, validates the final
check and emits it once. Leading zeros remain data. Spaces, separators, Unicode
digits, alternate ratios, GS1/HIBC/ECI and extra options are refused.
barHeight is an integer 1–1000; scale 1–16 and quiet zone 10–64 use the existing
bitmap bounds. The encoder's 500-digit limit does not guarantee a renderable
bitmap: with n encoded digits the width is (10*n + 15 + 2*quiet)*scale.
At quiet10 and scale1, 406 encoded digits fit (4095 pixels) and 407 refuse before
raster allocation. ADD counts the new check digit toward that width. Height,
the 4096-pixel side bound and four-million-pixel bound also apply. Both PDF and
ZPL use the same exact monochrome modules; captions remain template text.
<qqq-barcode type="coop2of5" value="${record.id}" scale="2" quiet="10" options='{"checkDigit":"ADD","barHeight":40}'></qqq-barcode>
{"type":"barcode","symbology":"coop2of5","x":20,"y":20,"scale":2,"quiet":10,"valuePath":"/record/id","options":{"checkDigit":"NONE"}}
The encoder is derived
from BWIPP commit 11fa6d6.
Pinned source/test hashes and the exact external run vector are retained under
src/test/resources/barcodes/coop2of5; the MIT notice ships in the renderer JAR.
Reference comparisons cover the upstream pattern and checksum cases; no
independent COOP decoder or physical scanner is qualified by these tests.
Template context
The selected record is available under record: PDF source uses ${record.id}
and a ZPL scene uses "valuePath":"/record/id". Replace id with an available
field from the configured source table; it is not every table's primary-key name.
A published context script may add other objects and paths. Use the script's
actual returned structure when referencing those additions. The native
Barcode catalog and template examples action supplies both starter sources.
Publication profiles
| ID | Accepted payload and options |
|---|---|
issn |
Exactly seven ASCII digits plus one digit or uppercase X; original modulus-11 check digit is mandatory and validated. variant is an exact two-digit string, default "00". Produces GTIN13 977 + first seven ISSN digits + variant + new modulo-10 carrier check digit. |
ismn |
Exactly 13 ASCII digits beginning 9790, including a valid GTIN13 check digit. |
Both render through the existing Okapi EAN13 encoder in PDF and ZPL. barHeight
may be an integer 1–1000; scale 1–16 and quiet zone 10–64 modules retain existing
bitmap bounds. Other options, hyphens, spaces, lowercase x, legacy ISMN M
notation, and inline supplements are refused. ISSN variation digits are not the
2/5-digit issue-number supplement; integrated supplements remain unsupported.
Templates can place explicit human-readable text separately. Checksum validation
does not establish agency assignment, ownership, or retail/print approval.
Rules: ISSN Centre GTIN mapping,
US ISSN Centre checksum,
International ISMN Agency structure.
The GS1 ISSN example
contains an inconsistent original check digit (0174736X; weighted sum 118 requires
3). We reject that typo. The fixture explicitly labels 01747363 as locally
corrected; its GTIN remains 9770174736005. Other derived/synthetic fixture
provenance is recorded in publication-vectors.json.
Additional isolated Zint provider
All 15 Zint IDs render monochrome pixels in both PDF and ZPL. Every new ID requires
/usr/local/bin/zint version 2.16.0 and the exact zint-2.16.0-qqq-p1 patchset
identity with the packaged build configuration (see vendor/PATCHES.md); absence,
wrong version, warnings, malformed data or provider failure refuses generation.
There is no substitute encoder. providerInstalled means executable presence,
not that the image or sandbox is qualified. These IDs do not inherit Okapi options.
| ID | Standard / bounded options |
|---|---|
rmqr |
Rectangular Micro QR; version 1–32, ecc 2 (M) or 4 (H) |
han-xin |
Han Xin Code; version 1–84, ecc 1–4 |
dotcode |
DotCode; optional columns 5–200 |
gs1-dotcode |
DotCode with mandatory GS1 validation; bracketed AIs; optional columns 5–200 |
datamatrix-dmre |
Data Matrix Rectangular Extension; exact version 31–48, default 31 (8×48); ordinary rectangular Data Matrix is not silently substituted |
mailmark-2d |
Royal Mail 2D Mailmark; version 8 (24×24), 10 (32×32), or 30 (16×48), otherwise encoder chooses a valid size; 45–90 characters, complete uppercase 45-character header beginning JGB |
mailmark-4state |
Royal Mail Mailmark C/L; exactly 22 or 26 uppercase/digit/space characters, including required padding |
upu-s10 |
UPU S10; two uppercase service letters, nine digits including supplied check digit, two uppercase country letters |
isbn |
ISBN-10 or ISBN-13 with supplied checksum; supplement/profile composition is not exposed in this tranche |
fim |
Facing Identification Mark, exactly one uppercase letter A–E; no extra options |
cepnet |
Brazilian CEPNet, exactly 8 digits; native check digit generation; no extra options |
bc412 |
SEMI T1-95 BC412, 7–18 uppercase alphanumerics excluding O; native check generation; no extra options |
dx-film-edge |
Canonical part1-part2[/frame[A]]: part1 is 1–127, part2 is 0–15, optional numeric frame is 0–63 followed optionally by uppercase A. Examples 79-7, 79-7/23A, 127-15/63A. No leading-zero numbers, special frame aliases, DX-extract/full shorthand or extra options. Clock and data tracks are preserved. |
daft |
Exact four-state bar pattern, 1–576 uppercase A/D/F/T characters; a pattern facility, not independent validation of a carrier business profile; no extra options |
flattermarken |
1–128 digits including at least one nonzero digit. Zero encodes a blank nine-module position; leading/trailing zeros retain their positions. Zero-only input is explicitly unsupported because it produces no visible mark and the renderer refuses blank barcodes. No extra options. |
New payloads are UTF-8 text, at most 4000 UTF-16 code units, with control characters
and malformed surrogate pairs rejected. Specialized postal/business fields and
checksums also pass Zint validation; no missing padding/check digits are repaired
by the host. For rmqr, han-xin, dotcode and datamatrix-dmre, optional eci is exactly
3 (Latin-1) or 26 (UTF-8). Use explicit ECI 26 for nondefault Unicode: auto-ECI
selection warnings are deliberately refused by --werror. GS1/postal/ISBN IDs
do not accept this option. No GS1 validation bypass, arbitrary ECI flag, binary data, user file
path, output path or shell command is accepted.
Quiet zones are 10–64 modules for these IDs. Scale is 1–16 integer pixels per module, except DotCode requires 2–16. Zint draws the dots at the final requested scale; the host does not resize them into squares. Both formats preserve that raster at stock DPI. The fixed BMP parser accepts only an exact uncompressed 1-bit black/white envelope, dimensions ≤4096, area ≤4 million pixels, complete whitespace margins and square module geometry where applicable. Physical print grading and carrier acceptance remain separate from module/reference correctness. The six v3 types use the pinned encoder's default bar/track heights; arbitrary height, ECI, segment, dot-size and file-path switches are not exposed for these types.
The additional capability is finite. Ultracode in ZPL, unlisted symbologies, arbitrary structured append, binary families/options beyond the explicit four-family profile, and unsupported application profiles remain open requirements; this is not a claim to encode every standard.
PDF-only Ultracode (catalog 5)
ultracode uses Zint 2.16.0 + QQQ p1, symbology 144, fixed revision 1. Its colors
carry data. PDF preserves exact RGB pixels; ZPL validation and rendering reject
the family before looking up or launching the encoder. There is no monochrome
threshold, printer-command fallback, or custom color option.
Accepted options are ecc integer 1–6 (default 3) and optional eci exactly 3
(Latin-1) or 26 (UTF-8). Payloads are text, at most 252 UTF-8 bytes, with the native
provider also enforcing symbol capacity at the chosen ECC/ECI. Controls, malformed
Unicode, raw binary, GS1, compression, revision 2, structured append and arbitrary
native switches are refused. The provider treats warnings as failures; explicitly
select ECI 26 for nondefault Unicode rather than relying on automatic ECI warnings.
Scale is 1–16; white quiet zones are 10–64 modules. Existing process deadline,
output-byte and 4096-dimension/4-million-pixel bounds still apply.
Only the pinned 4-bit uncompressed BMP envelope and native fixed palette are
accepted. The separate color parser checks the entire raster, palette, dimensions,
padding, module geometry and whitespace; the existing monochrome parser is unchanged.
CATALOG reports formats:["PDF"], colorRequired:true, revision:1 and the byte
limit. The explicit format-aware Java dispatch is required; generic monochrome
render calls refuse this ID.
<qqq-barcode type="ultracode" value="${record.id}" scale="4" quiet="10" options='{"ecc":3}'></qqq-barcode>
The twelve retained pinned upstream module vectors, strict parser refusal tests and exact embedded-PDF pixel checks are software evidence. The new exact-image gate is pending; independent color decoding and physical color printer/scanner grading remain separate acceptance gates. Source: pinned Ultracode tests, BMP palette contract, pinned manual.
Preserved Okapi provider
Explicit structured-append segments (catalog 5)
Each element renders one symbol in either PDF or ZPL. The template supplies the segments and their order; the renderer does not split payloads, calculate a whole-message parity, check a collection for missing/duplicate positions, or add pages/labels. All ordinary payload, pixel, output and deadline limits still apply.
| Exact ID | Complete tuple when enabled | Optional identity | ZPL | |
|---|---|---|---|---|
qr |
structuredAppendPosition 1–total, structuredAppendTotal 2–16, structuredAppendParity 0–255 |
None; parity is the common XOR of all original message bytes, using the intended encoding | One monochrome symbol | Same raster |
datamatrix |
structuredAppendPosition 1–total, structuredAppendTotal 2–16, structuredAppendFileId integer 1–64516 |
None; use the same Okapi file ID across the sequence (not Zint's decimal two-part ID syntax) | One monochrome symbol | Same raster |
aztec |
structuredAppendPosition 1–total, structuredAppendTotal 2–26 |
structuredAppendMessageId, 1–32 ASCII characters in ! through ~ (33–126), no spaces or controls; omitted means no message ID |
One monochrome symbol | Same raster |
Any structured-append option activates validation of the complete tuple. Unknown
keys, wrong JSON types, explicit nulls, total 1, position exceeding total and
family-inappropriate identifiers are refused. These options are not inherited by
Swiss QR, UPN QR, Micro QR or Aztec Rune. Forced one-symbol append is not exposed.
Existing PDF417 Macro options retain their previous separate contract.
The CATALOG entry includes structuredAppend.requiredOptionsWhenUsed and the
single-symbol/position constraint alongside individual option bounds.
Example first and second QR segments for FIRSTSECOND (ASCII parity 74):
<qqq-barcode type="qr" value="FIRST" scale="2" quiet="10" options='{"structuredAppendPosition":1,"structuredAppendTotal":2,"structuredAppendParity":74}'></qqq-barcode>
<qqq-barcode type="qr" value="SECOND" scale="2" quiet="10" options='{"structuredAppendPosition":2,"structuredAppendTotal":2,"structuredAppendParity":74}'></qqq-barcode>
{"schema":"qqq-zpl-scene/1","elements":[
{"type":"barcode","symbology":"datamatrix","x":20,"y":20,"scale":3,"quiet":4,"valuePath":"/record/firstSegment","options":{"structuredAppendPosition":1,"structuredAppendTotal":2,"structuredAppendFileId":64516}},
{"type":"barcode","symbology":"aztec","x":20,"y":300,"scale":3,"quiet":4,"valuePath":"/record/secondSegment","options":{"structuredAppendPosition":2,"structuredAppendTotal":2,"structuredAppendMessageId":"SHIP-42"}}
]}
The latter example shows two different sequence types, not one interoperable
sequence. Production templates should supply every segment of their chosen family.
Ten unmodified Okapi 0.5.7 upstream fixtures and SHA-256 provenance are retained in
src/test/resources/barcodes/structured-append/ under the existing Apache license.
Tests compare exact codewords/patterns for all three families, independently decode
QR sequence/parity headers and reassemble explicit QR parts, and verify exact
PDF/ZPL embedded pixels. They do not assert independent Data Matrix/Aztec sequence
reassembly, physical scanner support, or collection-wide validation.
Provider contracts: QR, Data Matrix, Aztec.
| Family | IDs |
|---|---|
| Linear / retail | code11, code128, gs1-128, code2of5, itf, code39, code39-extended, code93, codabar, ean8, ean13, ean-upc-addon, upca, upce, msi-plessey, plessey, telepen, channel-code |
| Stacked / matrix | aztec, aztec-rune, codablock-f, code16k, code49, code-one, datamatrix, grid-matrix, maxicode, micro-qr, pdf417, qr |
| GS1 | gs1-composite, gs1-databar, gs1-databar-expanded, gs1-databar-limited (plus GS1 options on supporting encoders) |
| Postal / logistics | australia-post, dpd, japan-post, kix, korea-post, logmars, nve18, postnet, royal-mail, usps-onecode, usps-package |
| Pharmaceutical / payment | code32, pharmacode, pharmacode-two-track, pzn, swiss-qr, upn-qr |
Payloads use each encoder's documented alphabet, length, checksums and application format. Library validation errors fail generation; the renderer does not truncate values or substitute another symbology. GS1 input uses Okapi's bracketed AI syntax, for example [01]09501101530003. GS1 syntax validation is not proof that a business identifier or carrier-specific label is authorized or operationally valid.
Common options are barHeight (1–1000), dataType (ECI/HIBC and GS1 where supported), and eciMode only on supporting encoders. The configured integer scale is 1–16; quiet zones are 4–64 modules for QR/Data Matrix/Aztec/PDF417 and conservatively 10–64 for other families. These conservative defaults are not a replacement for application-specific standards or physical barcode grading.
| ID / family | Additional typed options |
|---|---|
australia-post |
mode: POST, REPLY, ROUTE, REDIRECT |
aztec |
mode: ANY, NORMAL, COMPACT |
code2of5, itf |
mode: MATRIX, INDUSTRIAL, IATA, DATA_LOGIC, INTERLEAVED, INTERLEAVED_WITH_CHECK_DIGIT, ITF14, DP_LEITCODE, DP_IDENTCODE |
gs1-databar |
mode: LINEAR, OMNI, STACKED |
gs1-databar-expanded |
stacked: boolean |
gs1-composite |
linearContent; symbology: UPCA, UPCE, EAN, CODE_128, DATABAR_14, DATABAR_14_STACK, DATABAR_14_STACK_OMNI, DATABAR_LIMITED, DATABAR_EXPANDED, DATABAR_EXPANDED_STACK; preferredMode: CC_A, CC_B, CC_C |
maxicode |
mode: integer 2–6; primary: at most 32 characters, with library-defined primary message validation |
micro-qr |
preferredVersion: 1–4; eccMode: L, M, Q |
msi-plessey |
checkDigit: explicit enum values returned by CATALOG |
pdf417 |
mode: NORMAL, TRUNCATED, MICRO; dataColumns: 1–30; structuredAppendPosition/Total: 1–99999; structuredAppendFileId: at most 96 characters (library restrictions also apply). These fields enable Macro PDF417 segments. |
postnet |
mode: POSTNET, PLANET |
telepen |
mode: NORMAL, NUMERIC |
| QR-derived encoders | preferredVersion: 1–40; preferredEccLevel: L, M, Q, H, subject to the specialized format's fixed restrictions |
Options outside these lists are rejected. The underlying library has additional configuration that is not yet exposed; adding it requires explicit typed validation, metadata and representative tests. Automatic multi-symbol splitting, arbitrary binary payloads, every structured-append facility and carrier-specific composites are not silently inferred.
Reference coverage consists of 47 pinned upstream known codeword/pattern vectors and per-family raster/invalid-input tests. Independent ZXing round trips cover Code128, GS1-128, Code39, Code93, Codabar, ITF, EAN8/13, UPC-A/E, QR, Data Matrix, Aztec and PDF417. The renderer also decodes a PDF QR label after rasterizing at its declared 203 DPI. These are software checks; all printer resolutions, materials, scanner models and postal/carrier acceptance rules still require physical qualification.
Only the IDs and profiles listed in this catalog are offered. Han Xin, rMQR and DotCode use the documented pinned Zint provider; they are not supplied by Okapi. Ultracode has a separate strict color contract for PDF only; it cannot pass through the monochrome ZPL provider. To add an unlisted family, supply an approved open-source encoder, an explicit stable ID and options, geometry/payload/resource bounds, reference vectors and independent decoding where available, PDF/ZPL raster checks, and physical qualification. Update the catalog version and image provenance. No future or proprietary format is implied by the word “all.”