Sign in

    moon-pdf417-core

    Pure MoonBit PDF417 encoder: Text / Byte / Numeric compaction, the annex P mode selector, GF(929) Reed-Solomon parity with error repair, symbol layout, the annex A module patterns and SVG or ASCII rendering.

    pdf417
    barcode
    codewords
    reed-solomon
    encoding
    rendering
    svg
    gs1
    Download zip
    Author
    Version
    0.2.1
    License
    MIT
    Last updated
    25 days ago
    Downloads
    15

    No dependencies

    #Moon PDF417 Core

    A dependency-free MoonBit library for the codeword layer of PDF417: the part between "the user has a message" and "a renderer has codewords".

    It implements high level encoding (Text, Byte and Numeric compaction plus the automatic mode selector), GF(929) Reed-Solomon error correction, symbol layout planning, row indicators, and the inverse decoders that make every generated symbol verifiable.

    let codes : Array[Int] = []
    for character in "HELLO WORLD 1234567890123".iter() {
    codes.push(character.to_int())
    }
    let high = @pdf417.encode_high_level(codes) // data codewords
    let symbol = @pdf417.finalize(high.codewords, 2, 4) // + descriptor, pad, parity
    @pdf417.verify_symbol(symbol) // true

    #What it does

    AreaAPI
    Text Compactionencode_text, encode_text_segment, decode_text, text_automaton
    Numeric Compactionencode_numeric, decimal_chunk_to_base900, base900_to_decimal, decode_numeric
    Byte Compactionencode_byte, bytes_to_base900, base900_to_bytes, decode_byte
    Automatic mode selectionencode_high_level, consecutive_digits, consecutive_text, consecutive_binary
    Error correctionerror_correction, generator_polynomial, syndromes, correct_errors
    Layoutfinalize, rows_for, pad_codewords, plan_columns
    Planning queriesdata_capacity, recommended_level, smallest_symbol, geometry_of, symbol_modules
    Structurestart_pattern, stop_pattern, left_row_indicator, right_row_indicator, symbol_rows
    Low levelcluster_pattern, symbol_row_modules, symbol_matrix, verify_matrix, column_box, module_is_bar
    Renderingmatrix_to_ascii, matrix_to_svg
    Verificationverify_symbol, verify_matrix, is_error_free, round_trip_matches, decode_high_level

    #Scope

    This is a codeword layer library with the low level structure on top of it. It carries the ISO/IEC 15438 annex A symbol character tables (929 patterns per bar-space cluster) and turns codewords into modules, so symbol_matrix gives you one row of modules per symbol row and matrix_to_svg writes a black and white document. Every bar or space is drawn as a rectangle, so the output is a legible symbol rather than a rounded or scaled picture.

    What is still out of scope:

    • a decoder that reads a picture back into codewords, so a scanner cannot be round tripped here;
    • ECI, so input is an array of code units in 0..255. utf8_bytes converts a MoonBit string to UTF-8 byte values for callers that want non-Latin-1 payloads.

    #Install

    The library has no dependencies; add it to a module with:

    moon add fan-ere/moon-pdf417-core

    The current release is 0.2.1, published at https://mooncakes.io/docs/fan-ere/moon-pdf417-core.

    Then import the package from a moon.pkg:

    import { "fan-ere/moon-pdf417-core" @pdf417, }

    To work on the library itself, install the MoonBit toolchain, confirm that moon version --all works, and build from a checkout of this repository.

    #Reproduce

    From the repository root:

    moon check --deny-warn --target all moon build --target all moon test --deny-warn --target wasm moon test --deny-warn --target wasm-gc moon test --deny-warn --target js moon run examples/quickstart --target wasm

    examples/quickstart walks the whole pipeline: it encodes a message, lays out the symbol, prints the data codewords and the verification result, checks the module matrix and draws it as ASCII plus an SVG summary. A successful run is the shortest reproducibility check.

    #Command line

    moon run cmd/main --target native -- encode --data "HELLO WORLD 1234567890123" --level 2 --columns 4 moon run cmd/main --target native -- inspect --data "HELLO WORLD" moon run cmd/main --target native -- capacity --level 2 moon run cmd/main --target native -- structure --columns 4 --rows 6 --level 2 moon run cmd/main --target native -- render --data "HELLO 1234" --format svg > symbol.svg moon run cmd/main --target native -- render --data "HELLO 1234" --format ascii --scale 1

    --codes 72,69,76,76,79 feeds raw code units instead of text. The CLI works on every target; the examples above use native because it needs no runtime.

    #Correctness evidence

    • Text Compaction vectors: "AB" -> [1], "ABCD" -> [1, 63], "HELLO" -> [214, 341, 449], "]_" -> [876, 877].
    • Numeric Compaction vector: "1234" -> [12, 434] with the leading 1 prefix kept, so leading zeros survive.
    • Reed-Solomon reference vectors: level 0 over [3, 1, 2] gives [335, 565]; level 2 gives [791, 65, 893, 586, 381, 161, 381, 304]; the generator polynomials equal annex F.
    • Error correction is tested end to end: two corrupted codewords in a level 3 symbol are located with Berlekamp-Massey and repaired, and erasures double the repair budget.
    • The suite then covers the three compactions, the mode selector, the decoder, the parity block, the layout rules, the row indicator formulas and the module matrix.
    • The symbol character table is checked by property, not by spot values: all 2787 entries cover 17 modules with eight alternating elements of 1..6 modules, and every pattern is unique inside and across clusters. scripts/audit_pattern_tables.py --reference compares the storage form with the reference table entry by entry and reports them identical.

    The tests show that the encoder, decoder and module matrix agree with the reference vectors above. They do not prove that a scanner reads these symbols: this project has no image decoder, so the read-back direction is out of scope. See docs/SOURCES.md for what was compared against which reference.

    #Continuous integration

    .github/workflows/ci.yml runs on every push and pull request:

    JobWhat it covers
    lintmoon fmt and moon info leave no diff
    test (matrix)moon check --deny-warn, moon build, moon test --deny-warn on wasm, wasm-gc, js and native
    cliruns examples/quickstart, the five cmd/main commands and checks the rendered SVG and ASCII output
    tablesthe generated tables match their generators, and the symbol character table matches the reference table

    #Documentation

    #License

    MIT, see LICENSE.

    EncodeError

    pub suberror EncodeError {
    EmptyInput
    UnrepresentableChar(Int)
    TooManyCodewords(Int)
    InvalidErrorCorrectionLevel(Int)
    InvalidColumnCount(Int)
    LayoutImpossible(Int, Int)
    TooManyErasures(Int, Int)
    } derive(
    Debug
    )

    Everything that can go wrong while encoding.

    EncodeError is a MoonBit error type, so it can be raised with raise and caught with catch. Every fallible entry point also has an _opt companion that returns Option instead.

    EncodeError::to_repr

    Keep the derived Debug implementation available through to_repr without promoting it to a regular method (which the compiler deprecates).

    Compaction

    pub(all) enum Compaction {
    Text
    Numeric
    Byte
    Auto
    }

    Compaction (high level encoding) mode.

    Text uses the packed Text Compaction sub-modes, Numeric the base 900 decimal compaction, Byte the raw byte compaction and Auto lets the encoder pick a mode per segment.
    impl Eq for Compaction

    Compaction::equal

    fn Compaction::equal(self : Compaction, other : Compaction) -> Bool

    Keep Eq usable by callers without promoting its methods.

    Compaction::not_equal

    fn Compaction::not_equal(x : Compaction, y : Compaction) -> Bool

    Keep Eq usable by callers without promoting its methods.

    Geometry

    pub(all) struct Geometry {
    width_modules : Int
    height_rows : Int
    data_columns : Int
    data_rows : Int
    ec_level : Int
    }

    Geometry of a symbol in modules.

    HighLevel

    pub(all) struct HighLevel {
    codewords : Array[Int]
    modes : Array[Compaction]
    segments : Array[Int]
    }

    Result of a high level encoding pass.

    Symbol

    pub(all) struct Symbol {
    codewords : Array[Int]
    columns : Int
    rows : Int
    ec_level : Int
    data_count : Int
    pad_count : Int
    }

    A complete PDF417 codeword sequence with the layout that produced it.

    codewords is the full sequence that a low level encoder consumes: the symbol length descriptor, the high level data codewords, the pad codewords and finally the error correction codewords.

    TextSubmode

    pub(all) enum TextSubmode {
    Alpha
    Lower
    Mixed
    Punctuation
    }

    Text Compaction sub-mode, as defined by ISO/IEC 15438 4.4.2.
    impl Eq for TextSubmode

    TextSubmode::equal

    fn TextSubmode::equal(self : TextSubmode, other : TextSubmode) -> Bool

    TextSubmode::name

    fn TextSubmode::name(self : TextSubmode) -> String

    Debug rendering of a text sub-mode, used by tests and diagnostics.

    TextSubmode::not_equal

    fn TextSubmode::not_equal(x : TextSubmode, y : TextSubmode) -> Bool

    base900_to_bytes

    fn base900_to_bytes(words : Array[Int]) -> Array[Int] raise EncodeError

    Convert five base 900 codewords back to six bytes.

    base900_to_decimal

    fn base900_to_decimal(base900 : Array[Int]) -> Array[Int]

    Convert base 900 digits back to decimal digits. base900 is most significant first; the result has no leading zeros except for the value 0.

    berlekamp_massey

    fn berlekamp_massey(sequence : Array[Int]) -> Array[Int]

    Berlekamp-Massey: shortest linear feedback shift register generating the syndrome sequence. Coefficients are returned constant term first, with a leading 1.

    byte_capacity

    fn byte_capacity(count : Int) -> Int

    Number of base 900 codewords needed to describe a byte run of count bytes, including the length count that 901 mode carries.

    byte_count_codewords

    fn byte_count_codewords(count : Int) -> Int

    Number of codewords needed for an explicit byte length count: one codeword while the count is below 900, otherwise two.

    byte_group_codewords

    let byte_group_codewords : Int

    Number of codewords a full byte group produces.

    byte_group_size

    let byte_group_size : Int

    Number of bytes compressed into five codewords per group.

    bytes_to_base900

    fn bytes_to_base900(bytes : Array[Int]) -> Array[Int] raise EncodeError

    Convert six bytes to five base 900 codewords.

    cluster0_patterns

    let cluster0_patterns : Array[Int]

    Symbol character patterns of cluster 0.

    cluster1_patterns

    let cluster1_patterns : Array[Int]

    Symbol character patterns of cluster 1.

    cluster2_patterns

    let cluster2_patterns : Array[Int]

    Symbol character patterns of cluster 2.

    cluster_pattern

    fn cluster_pattern(cluster : Int, codeword : Int) -> Int?

    Symbol character for codeword in cluster, or None when the codeword or the cluster is out of range.

    column_box

    fn column_box(column : Int, columns : Int, rows : Int, scale : Int, quiet : Int) -> (Int, Int, Int, Int)

    Bounding box of the 17 module block that holds column column, in user units: (left, top, width, height) with the quiet zone included.

    This is what a scanner samples for that column, and what a highlight or annotation layer would draw around it.

    consecutive_binary

    fn consecutive_binary(input : Array[Int], start : Int) -> Int

    Number of consecutive characters that should go through byte compaction starting at start, following annex P: the run stops before a sequence of 13 or more digits so that Numeric Compaction can take over. A run that begins on such a digit sequence is therefore empty.

    consecutive_digits

    fn consecutive_digits(input : Array[Int], start : Int) -> Int

    Number of consecutive digits starting at start.

    consecutive_text

    fn consecutive_text(input : Array[Int], start : Int) -> Int

    Number of consecutive characters that Text Compaction can carry starting at start. The run stops before a sequence of 13 or more digits, which is the point where Numeric Compaction becomes worth a mode latch; a run that begins on such a digit sequence is therefore empty.

    correct_errors

    fn correct_errors(words : Array[Int], parity_count : Int, erasures : Array[Int]) -> (Array[Int], Array[Int]) raise EncodeError

    Repair a codeword sequence.

    erasures lists positions that are known to be damaged; the decoder can then fix up to parity_count - erasures.length() further errors, and parity_count / 2 unknown errors when no erasures are supplied.

    Returns the repaired sequence together with the positions that changed. Raises TooManyErasures when the sequence cannot be repaired.

    correct_errors_opt

    fn correct_errors_opt(words : Array[Int], parity_count : Int, erasures : Array[Int]) -> (Array[Int], Array[Int])?

    Repair without error handling: None when the sequence cannot be repaired.

    data_capacity

    fn data_capacity(columns : Int, level : Int) -> Int

    Largest number of data codewords that still fits a symbol with columns columns at level.

    decimal_chunk_to_base900

    fn decimal_chunk_to_base900(digits : Array[Int]) -> Array[Int]

    Convert one digit chunk to base 900 digits: the chunk gets a leading "1" and is then repeatedly divided by 900.

    decode_byte

    fn decode_byte(words : Array[Int]) -> Array[Int] raise EncodeError

    Decode Byte Compaction codewords (without latch and length count) back to bytes. Trailing incomplete groups are returned literally.

    decode_high_level

    fn decode_high_level(words : Array[Int]) -> Array[Int] raise EncodeError

    Decode a high level data codeword sequence (without the symbol length descriptor) back to characters.

    Text and byte segments are decoded exactly. Numeric segments are decoded greedily from the latch up to the next mode latch, which is how the encoder emits them in the common single-segment case.

    decode_high_level_opt

    fn decode_high_level_opt(words : Array[Int]) -> Array[Int]?

    Decoding without error handling.

    decode_numeric

    fn decode_numeric(words : Array[Int]) -> Array[Int] raise EncodeError

    Decode Numeric Compaction codewords back to decimal digits.

    The caller passes exactly the codewords that belong to the numeric segment, without the latch codeword.

    decode_text

    fn decode_text(words : Array[Int]) -> Array[Int] raise EncodeError

    Decode a Text Compaction codeword run back to characters.

    decode_text_values

    fn decode_text_values(values : Array[Int]) -> Array[Int] raise EncodeError

    Reverse the Text Compaction sub-mode automaton. values is a sequence of values 0..29 without the trailing pad heuristic applied.

    encode_byte

    fn encode_byte(input : Array[Int]) -> Array[Int] raise EncodeError

    Encode a byte run with Byte Compaction. Neither the 901/924 latch nor the length count is included; encode_high_level adds those.

    encode_byte_segment

    fn encode_byte_segment(input : Array[Int], start : Int, count : Int) -> Array[Int] raise EncodeError

    Encode input[start..start+count) as six byte groups plus a literal tail.

    encode_bytes_only

    fn encode_bytes_only(input : Array[Int]) -> Array[Int] raise EncodeError

    Encode bytes with Byte Compaction only, including the 901/924 latch and the explicit length count.

    encode_high_level

    fn encode_high_level(input : Array[Int]) -> HighLevel raise EncodeError

    Run the automatic mode selector over input.

    Throws EmptyInput for an empty input and UnrepresentableChar for a code unit outside 0..255.

    encode_high_level_opt

    fn encode_high_level_opt(input : Array[Int]) -> HighLevel?

    High level encoding without error handling.

    encode_numeric

    fn encode_numeric(input : Array[Int]) -> Array[Int] raise EncodeError

    Encode decimal digits with Numeric Compaction. The latch codeword is not included; encode_high_level adds it.

    input must be non-empty and contain only ASCII digits.

    encode_numeric_only

    fn encode_numeric_only(input : Array[Int]) -> Array[Int] raise EncodeError

    Encode digits with Numeric Compaction only, including the 902 latch.

    encode_numeric_opt

    fn encode_numeric_opt(input : Array[Int]) -> Array[Int]?

    Numeric encoding without error handling: returns None on failure.

    encode_numeric_segment

    fn encode_numeric_segment(input : Array[Int], start : Int, count : Int) -> Array[Int] raise EncodeError

    Encode input[start..start+count) with Numeric Compaction.

    encode_text

    fn encode_text(input : Array[Int]) -> Array[Int] raise EncodeError

    Encode a whole input in Text Compaction, starting in the Alpha sub-mode.

    Every code unit must be representable by one of the four sub-modes; otherwise UnrepresentableChar is raised.

    encode_text_from

    fn encode_text_from(input : Array[Int], initial : TextSubmode) -> Array[Int] raise EncodeError

    Like encode_text, but lets the caller choose the sub-mode the encoder starts in. Useful when several text segments are concatenated after a single mode latch.

    encode_text_only

    fn encode_text_only(input : Array[Int]) -> Array[Int] raise EncodeError

    Encode text with the packed Text Compaction sub-modes only. The latch codeword is not emitted, matching a symbol whose first data codeword is already in text mode.

    encode_text_opt

    fn encode_text_opt(input : Array[Int]) -> Array[Int]?

    Encode text with no error handling: returns None instead of raising.

    encode_text_segment

    fn encode_text_segment(input : Array[Int], start : Int, count : Int, initial : TextSubmode) -> (Array[Int], TextSubmode) raise EncodeError

    Encode input[start..start+count) in Text Compaction and report both the codewords and the sub-mode the encoder finished in.

    error_correction

    fn error_correction(data : Array[Int], level : Int) -> Array[Int] raise EncodeError

    Compute the parity codewords for data at the given error correction level.

    data is the full data codeword sequence, including the symbol length descriptor. The result holds 2^(level + 1) codewords in storage order.

    error_correction_codeword_count

    fn error_correction_codeword_count(level : Int) -> Int

    Number of Reed-Solomon parity codewords for an error correction level. ISO/IEC 15438 defines this as 2^(level + 1).

    error_locator_of

    fn error_locator_of(position : Int, length : Int) -> Int

    Field element attached to codeword position of a sequence of length codewords: X = 3^(length - 1 - position).

    finalize

    fn finalize(data : Array[Int], level : Int, columns : Int) -> Symbol raise EncodeError

    Finalize a high level encoding into a complete codeword sequence.

    data are the high level data codewords (without the length descriptor), level is the error correction level and columns the requested column count. The returned Symbol carries the full sequence a low level encoder consumes, plus the layout that produced it.

    finalize_opt

    fn finalize_opt(data : Array[Int], level : Int, columns : Int) -> Symbol?

    finalize without error handling.

    generator_polynomial

    fn generator_polynomial(degree : Int) -> Array[Int] raise EncodeError

    Generator polynomial coefficients for degree parity codewords, most significant first. The leading coefficient is always 1.

    geometry_of

    fn geometry_of(symbol : Symbol) -> Geometry

    Geometry of a finalized symbol.

    inverse929

    fn inverse929(value : Int) -> Int

    Multiplicative inverse modulo 929; 929 is prime, so every non-zero value has an inverse.

    is_alpha_lower

    fn is_alpha_lower(code : Int) -> Bool

    true if code is a lower case letter or a space, i.e. the Lower sub-mode.

    is_alpha_upper

    fn is_alpha_upper(code : Int) -> Bool

    true if code is a capital letter or a space, i.e. the Alpha sub-mode.

    is_byte_group_multiple

    fn is_byte_group_multiple(count : Int) -> Bool

    true if count bytes form complete six byte groups, which is the condition for the 924 latch instead of the 901 latch.

    is_digit

    fn is_digit(code : Int) -> Bool

    true if code is an ASCII decimal digit.

    is_error_free

    fn is_error_free(words : Array[Int], parity_count : Int) -> Bool

    true if every syndrome of words is zero.

    is_mixed

    fn is_mixed(code : Int) -> Bool

    true if the Mixed sub-mode can represent code.

    is_numeric_input

    fn is_numeric_input(input : Array[Int]) -> Bool

    true if every code unit of input is a decimal digit.

    is_punctuation

    fn is_punctuation(code : Int) -> Bool

    true if the Punctuation sub-mode can represent code.

    is_structurally_valid

    fn is_structurally_valid(codewords : Array[Int]) -> Bool

    true if the codeword sequence respects the structural rules of a symbol: length descriptor first, pad codewords 900 in the data area and no value outside 0..928.

    is_text_byte

    fn is_text_byte(code : Int) -> Bool

    true if code is a byte that Text Compaction can carry, following the "printable ASCII plus tab, newline and carriage return" rule of annex P.

    is_text_code

    fn is_text_code(code : Int) -> Bool

    true if Text Compaction can represent code at all.

    is_text_input

    fn is_text_input(input : Array[Int]) -> Bool

    true if every code unit of input is text encodable.

    is_valid_layout

    fn is_valid_layout(columns : Int, rows : Int) -> Bool

    true if columns and rows describe a legal data area.

    is_valid_pattern

    fn is_valid_pattern(pattern : Int, modules : Int) -> Bool

    true if a pattern describes exactly modules modules and alternates between bars and spaces with every width in 1..8. PDF417 patterns are 17 modules wide except the stop pattern, which is 18 modules and starts with an eight module bar (the start pattern).

    latch_byte

    let latch_byte : Int

    Mode latch to Byte Compaction for multiples of six bytes.

    latch_byte_padded

    let latch_byte_padded : Int

    Mode latch to Byte Compaction with an explicit length count.

    latch_numeric

    let latch_numeric : Int

    Mode latch to Numeric Compaction.

    latch_text

    let latch_text : Int

    Mode latch to Text Compaction.

    left_row_indicator

    fn left_row_indicator(row : Int, rows : Int, columns : Int, ec_level : Int) -> Int

    Left row indicator codeword for a row, from annex Q.

    The three clusters carry different information: cluster 0 puts the row count in the low position, cluster 1 the error correction level and the row count modulo three, cluster 2 the column count.

    matrix_row_width

    fn matrix_row_width(matrix : Array[Array[Int]]) -> Int

    Module width of one row, i.e. 35 + 17 * columns.

    matrix_to_ascii

    fn matrix_to_ascii(matrix : Array[Array[Int]], scale : Int, quiet : Int) -> String

    Render a matrix as text: X per bar, space per space, scale repeats. A quiet zone of quiet modules is added on both sides so the result can be eyeballed as a symbol.

    matrix_to_svg

    fn matrix_to_svg(matrix : Array[Array[Int]], scale : Int, quiet : Int) -> String

    Render a matrix as a black and white SVG document.

    scale is the width of one module in user units and quiet the quiet zone in modules. The output uses one path per row, so the document stays small even for a thirty column symbol.

    max_byte_value

    let max_byte_value : Int

    Highest byte value that byte compaction can carry.

    max_codewords

    let max_codewords : Int

    max_columns

    let max_columns : Int

    max_error_correction_level

    let max_error_correction_level : Int

    max_rows

    let max_rows : Int

    min_columns

    let min_columns : Int

    min_rows

    let min_rows : Int

    mixed_char

    let mixed_char : Array[Int]

    Inverse of mixed_value: value 0..29 -> character code, -1 if unused.

    mixed_value

    let mixed_value : Array[Int]

    Text Compaction Mixed sub-mode: value of each character, -1 if absent.

    module_is_bar

    fn module_is_bar(pattern : Int, modules : Int, index : Int) -> Bool

    true when the module is a bar. Bits below the pattern's most significant bit do not exist and are always spaces.

    numeric_chunk_size

    let numeric_chunk_size : Int

    Number of decimal digits converted per numeric codeword block.

    pad_codeword

    let pad_codeword : Int

    Pad codeword used to fill a symbol up to rows * columns.

    pad_codewords

    fn pad_codewords(source_codewords : Int, ec_codewords : Int, columns : Int, rows : Int) -> Int?

    Number of pad codewords needed so that data, padding, descriptor and error correction exactly fill rows * columns codewords. Returns None when the data area is smaller than the data.

    pattern_widths

    fn pattern_widths(pattern : Int, modules : Int) -> Array[Int]

    Expand a pattern into its bar widths, starting with a bar and alternating. A pattern whose leading bit is 0 starts with a zero width bar, which is how the caller detects the leading space.

    plan_columns

    fn plan_columns(source_codewords : Int, ec_codewords : Int, min_cols : Int, max_cols : Int, min_r : Int, max_r : Int) -> (Int, Int)?

    Choose the column count that gets closest to the 3:1 width/height ratio the standard recommends, searching min_cols..max_cols and accepting a row count inside min_r..max_r.

    Returns None when no column count fits.

    plan_rows

    fn plan_rows(source_codewords : Int, ec_codewords : Int, columns : Int, min_rows : Int) -> Int

    Rows required for source_codewords data codewords, ec_codewords error correction codewords and columns columns, with at least min_rows rows.

    pow_mod929

    fn pow_mod929(base : Int, exponent : Int) -> Int

    base^exponent mod 929.

    punctuation_char

    let punctuation_char : Array[Int]

    Inverse of punctuation_value: value 0..29 -> character code, -1 if unused.

    punctuation_value

    let punctuation_value : Array[Int]

    Text Compaction Punctuation sub-mode: value of each character, -1 if absent.
    fn recommended_level(n : Int) -> Int?

    Recommended minimum error correction level for n data codewords, from annex E of ISO/IEC 15438. Returns None when the standard gives no recommendation.

    right_row_indicator

    fn right_row_indicator(row : Int, rows : Int, columns : Int, ec_level : Int) -> Int

    Right row indicator codeword for a row, from annex Q.

    round_trip_matches

    fn round_trip_matches(input : Array[Int], words : Array[Int]) -> Bool

    true when the high level decoding of words reproduces input.

    row_cluster

    fn row_cluster(row : Int) -> Int

    Bar and space cluster of row row, i.e. row mod 3.

    row_codeword_count

    fn row_codeword_count(columns : Int) -> Int

    Number of data codewords in one row: one left indicator, columns data codewords and one right indicator.

    row_codewords

    fn row_codewords(codewords : Array[Int], row : Int, columns : Int, rows : Int, ec_level : Int) -> Array[Int]

    Codewords of one row in stored order: left indicator, data codewords, right indicator.

    rows_for

    fn rows_for(source_codewords : Int, ec_codewords : Int, columns : Int) -> Int

    Rows required with the default three row minimum.

    shift_byte

    let shift_byte : Int

    Mode shift to Byte Compaction for a single byte.

    smallest_symbol

    fn smallest_symbol(codewords : Int, ec_level : Int) -> (Int, Int)?

    Smallest legal symbol that holds codewords codewords, searching column counts from one to thirty and preferring the geometry closest to the standard's 3:1 ratio.

    start_modules

    let start_modules : Int

    Modules of the start pattern.

    start_pattern

    let start_pattern : Int

    Start pattern, 17 modules, most significant bit first (0 = space).

    start_pattern_modules

    let start_pattern_modules : Int

    Width of the start pattern in modules.

    stop_modules

    let stop_modules : Int

    Modules of the stop pattern.

    stop_pattern

    let stop_pattern : Int

    Stop pattern, 18 modules, most significant bit first.

    stop_pattern_modules

    let stop_pattern_modules : Int

    Width of the stop pattern in modules.

    symbol_codeword_capacity

    fn symbol_codeword_capacity(columns : Int, rows : Int) -> Int

    Total codeword capacity of a columns by rows data area, including the row indicators of every row.

    symbol_matrix

    fn symbol_matrix(symbol : Symbol) -> Array[Array[Int]] raise EncodeError

    Every module of a symbol, one array per row, without a quiet zone.

    symbol_modules

    fn symbol_modules(columns : Int) -> Int

    Total module width of a symbol with columns columns.

    One row is the start pattern (17 modules), the left row indicator, one symbol character per data column, the right row indicator (17 modules each) and the stop pattern (18 modules):

    17 + 17 * (columns + 2) + 18 = 69 + 17 * columns

    symbol_row_modules

    fn symbol_row_modules(codewords : Array[Int], row : Int, columns : Int, rows : Int, ec_level : Int) -> Array[Int] raise EncodeError

    Module row of one symbol row, without a quiet zone.

    row is zero based, codewords are the symbol codewords in storage order (row major) and ec_level is the error correction level the indicators report. The row indicator codewords are computed from the layout, exactly as symbol_rows does.

    symbol_rows

    fn symbol_rows(symbol : Symbol) -> Array[Array[Int]]?

    Split a symbol's codewords into rows. Returns None when the symbol is inconsistent with its layout.

    syndrome_weight

    fn syndrome_weight(words : Array[Int], parity_count : Int) -> Int

    Number of non-zero syndromes: a cheap measure of how damaged a sequence is.

    syndromes

    fn syndromes(words : Array[Int], parity_count : Int) -> Array[Int]

    Reed-Solomon syndromes of a complete codeword sequence.

    S[j] is c(3^(j+1)). A sequence without errors yields all-zero syndromes.

    tc_alpha_to_lower

    let tc_alpha_to_lower : Int

    Text Compaction shift/latch codes.

    tc_alpha_to_mixed

    let tc_alpha_to_mixed : Int

    tc_alpha_to_punct

    let tc_alpha_to_punct : Int

    tc_lower_to_alpha

    let tc_lower_to_alpha : Int

    tc_lower_to_mixed

    let tc_lower_to_mixed : Int

    tc_lower_to_punct

    let tc_lower_to_punct : Int

    tc_mixed_to_alpha

    let tc_mixed_to_alpha : Int

    tc_mixed_to_lower

    let tc_mixed_to_lower : Int

    tc_mixed_to_punct_latch

    let tc_mixed_to_punct_latch : Int

    tc_mixed_to_punct_shift

    let tc_mixed_to_punct_shift : Int

    tc_punct_to_alpha

    let tc_punct_to_alpha : Int

    tc_text_pad

    let tc_text_pad : Int

    Value substituted for a trailing space in Text Compaction.

    text_automaton

    fn text_automaton(input : Array[Int], start : Int, count : Int, initial : TextSubmode) -> (Array[Int], TextSubmode) raise EncodeError

    Run the Text Compaction sub-mode automaton over input[start..start+count) starting in initial, and return the resulting values together with the sub-mode the encoder ends in.

    unpack_text_values

    fn unpack_text_values(words : Array[Int]) -> Array[Int]

    Unpack codewords into Text Compaction values, dropping a trailing punctuation-shift pad when the resulting stream still decodes cleanly.

    utf8_bytes

    fn utf8_bytes(text : String) -> Array[Int]

    Convert a string to its UTF-8 byte values. Handy for callers that want non-Latin-1 payloads, since the library itself works on 0..255 code units.

    verify_matrix

    fn verify_matrix(matrix : Array[Array[Int]], columns : Int) -> Bool

    Check that a matrix is rectangular, that every row starts with the start pattern and ends with the stop pattern, and that the width matches the column count.

    verify_symbol

    fn verify_symbol(symbol : Symbol) -> Bool

    true if the sequence can be laid out and the trailing codewords are a valid Reed-Solomon parity block.