summaryrefslogtreecommitdiff
path: root/source/codes/Codes.mc
diff options
context:
space:
mode:
authorcirakg <cirakg@cirakg.xyz>2026-10-20 06:56:58 +0200
committercirakg <cirakg@cirakg.xyz>2026-10-20 06:56:58 +0200
commit3548312586aeafbfca0d0b87db90f9bdd972c831 (patch)
treeb657f5b2884ffc506c2d9dd080407e5c6218edee /source/codes/Codes.mc
parente3cc458d3b9aadb9459b51ef0120621408093f38 (diff)
feat(codes): add a QR Code encoder (versions 1-40, levels L-H) as a resumable job
Optimal numeric/alphanumeric/byte segmentation, Reed-Solomon over GF(256), all eight masks scored like segno, steps sized for the 120,000-bytecode watchdog; block tables generated from segno; a generic Matrix type with a compact form for caching. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'source/codes/Codes.mc')
-rw-r--r--source/codes/Codes.mc54
1 files changed, 54 insertions, 0 deletions
diff --git a/source/codes/Codes.mc b/source/codes/Codes.mc
index 70c6c2d..2d307ef 100644
--- a/source/codes/Codes.mc
+++ b/source/codes/Codes.mc
@@ -53,6 +53,60 @@ module Codes {
}
}
+ // A 2D code ready to draw: width x height modules, row-major, 1 = dark,
+ // plus the quiet zone its symbology needs (QR 4, Data Matrix 1, ...).
+ class Matrix {
+ var width as Number;
+ var height as Number;
+ var quiet as Number;
+ var modules as ByteArray;
+
+ function initialize(w as Number, h as Number, quietModules as Number, bits as ByteArray) {
+ width = w;
+ height = h;
+ quiet = quietModules;
+ modules = bits;
+ }
+
+ // Compact form for the encrypted cache: width, height, quiet (one byte
+ // each), then the modules packed 8 per byte.
+ function toBytes() as ByteArray {
+ var out = [width, height, quiet]b;
+ var packed = new [(modules.size() + 7) / 8]b;
+ for (var i = 0; i < modules.size(); i++) {
+ if (modules[i] == 1) {
+ packed[i / 8] = packed[i / 8] | (0x80 >> (i % 8));
+ }
+ }
+ out.addAll(packed);
+ return out;
+ }
+
+ static function fromBytes(data as ByteArray) as Matrix? {
+ if (data.size() < 3) {
+ return null;
+ }
+ var w = data[0];
+ var h = data[1];
+ if (w == 0 || h == 0 || data.size() != 3 + (w * h + 7) / 8) {
+ return null;
+ }
+ var bits = new [w * h]b;
+ for (var i = 0; i < w * h; i++) {
+ bits[i] = (data[3 + i / 8] >> (7 - i % 8)) & 1;
+ }
+ return new Matrix(w, h, data[2], bits);
+ }
+ }
+
+ function isMatrix(symbology as Number) as Boolean {
+ return symbology == QR || symbology == DATAMATRIX || symbology == PDF417 || symbology == AZTEC;
+ }
+
+ function ecLevel(options as Number) as Number {
+ return options & OPT_EC_MASK;
+ }
+
// Why a payload can't be encoded, in words for the user.
class CodeError {
var message as String;