aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcirakg <cirakg@cirakg.xyz>2026-10-20 12:16:59 +0200
committercirakg <cirakg@cirakg.xyz>2026-10-20 12:16:59 +0200
commit1ebc828f30698c1661055e17483e8d50a139ed45 (patch)
tree247763070cc90100b7cbb0cda12f0abbc38dce06
parentdfb8e358c20cf1f5f5eae365feca78ce4aa4176d (diff)
test(codes): compare Aztec with aztec_code_generator, decode it and its screenshot
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
-rw-r--r--source/app/AppInfo.mc2
-rw-r--r--source/app/Fixtures.mc1
-rw-r--r--test/codes/AztecTest.mc73
-rw-r--r--test/data/CodeVectors.mc28
-rw-r--r--test/golden/fenix7/about.pngbin4031 -> 4028 bytes
-rw-r--r--test/golden/fenix7/code_aztec.pngbin0 -> 3268 bytes
-rw-r--r--test/golden/fr255s/about.pngbin2383 -> 2374 bytes
-rw-r--r--test/golden/fr255s/code_aztec.pngbin0 -> 2144 bytes
-rw-r--r--test/golden/fr70/about.pngbin15292 -> 15478 bytes
-rw-r--r--test/golden/fr70/code_aztec.pngbin0 -> 11382 bytes
-rw-r--r--test/golden/fr965/about.pngbin15947 -> 16053 bytes
-rw-r--r--test/golden/fr965/code_aztec.pngbin0 -> 10679 bytes
-rw-r--r--test/golden/instinct3amoled45mm/about.pngbin13605 -> 13647 bytes
-rw-r--r--test/golden/instinct3amoled45mm/code_aztec.pngbin0 -> 11078 bytes
-rw-r--r--test/golden/venusq2/code_aztec.pngbin0 -> 2751 bytes
-rw-r--r--test/golden/venux1/code_aztec.pngbin0 -> 9514 bytes
-rw-r--r--tools/gen_code_vectors.py45
-rw-r--r--tools/tests/test_barcode_tools.py8
-rw-r--r--tools/ui_flow.py9
19 files changed, 161 insertions, 5 deletions
diff --git a/source/app/AppInfo.mc b/source/app/AppInfo.mc
index 1f40fee..497414e 100644
--- a/source/app/AppInfo.mc
+++ b/source/app/AppInfo.mc
@@ -12,5 +12,5 @@ import Toybox.Lang;
module AppInfo {
// Semantic version of the app: MAJOR.MINOR.PATCH.
- const VERSION = "0.5.0";
+ const VERSION = "0.6.0";
}
diff --git a/source/app/Fixtures.mc b/source/app/Fixtures.mc
index 0d6b683..31d4021 100644
--- a/source/app/Fixtures.mc
+++ b/source/app/Fixtures.mc
@@ -63,6 +63,7 @@ module Fixtures {
vault.add(qr);
vault.add(code("Parcel", Codes.DATAMATRIX, "PARCEL-FAKE-0042-7731"));
vault.add(code("Ticket", Codes.PDF417, "Boarding pass FAKE 0042 seat 12A"));
+ vault.add(code("Rail pass", Codes.AZTEC, "RAIL-FAKE-0042 Zone 1-3"));
vault.lock();
if (TestMode.ON) {
startImport();
diff --git a/test/codes/AztecTest.mc b/test/codes/AztecTest.mc
new file mode 100644
index 0000000..6ebc2bb
--- /dev/null
+++ b/test/codes/AztecTest.mc
@@ -0,0 +1,73 @@
+// Author: cirakg & claude ai
+// Summary: Tests for the Aztec encoder: aztec_code_generator references, decoding dumps (mixed text, UTF-8), limits and stuffing.
+
+import Toybox.Lang;
+import Toybox.Test;
+
+// README 12.4 check 1 where comparable: single-class payloads give the same
+// bits as the reference's optimal sequence, so the symbols must match,
+// compact and full range (with reference grids), at all four EC levels.
+(:test)
+function aztecMatchesReference(logger as Test.Logger) as Boolean {
+ var rows = CodeVectors.AZTEC;
+ for (var i = 0; i < rows.size(); i++) {
+ var row = rows[i] as Array;
+ var payload = row[0] as String;
+ var result = Aztec.encode(payload, row[1] as Number);
+ if (result instanceof Codes.CodeError) {
+ logger.error("row " + i + ": " + result.message);
+ return false;
+ }
+ var expectedSize = row[2] as Number;
+ var expected = row[3] as String;
+ if (result.width != expectedSize || !MatrixFixtures.packedHex(result).equals(expected)) {
+ logger.error("row " + i + " '" + Text.clip(payload, 20) + "': size " + result.width + ", reference " + expectedSize);
+ return false;
+ }
+ }
+ logger.debug("CODES aztec reference rows=" + rows.size());
+ return true;
+}
+
+// README 12.4 check 2: mixed content (Binary Shift, mode latches), UTF-8
+// and long payloads, decoded by tools/check_codes.py.
+(:test)
+function aztecDumpForDecoding(logger as Test.Logger) as Boolean {
+ var payloads = ["Boarding pass FAKE 0042, seat 12A", "Zürich ✓ Ünïcödé", "https://example.com/m/fake?id=0042",
+ "abcDEF123 xyz", "!@#$%^&*()", "a", "MiXeD 12 cAsE 34 ."];
+ var long = "";
+ for (var i = 0; i < 40; i++) {
+ long += "Fake-Ticket/" + i + " ";
+ }
+ payloads.add(long);
+ for (var i = 0; i < payloads.size(); i++) {
+ var text = payloads[i] as String;
+ var result = Aztec.encode(text, i % 4);
+ if (result instanceof Codes.CodeError) {
+ logger.error("'" + text + "': " + result.message);
+ return false;
+ }
+ MatrixFixtures.dump(logger, Codes.AZTEC, text, result);
+ }
+ return true;
+}
+
+(:test)
+function aztecStuffingAndLimits(logger as Test.Logger) as Boolean {
+ // Six zero bits in 6-bit codewords: 00000 gets a stuffed 1, then the
+ // last 0 is padded with ones (and its all-ones last bit cleared).
+ var words = Aztec.stuff([0, 0, 0, 0, 0, 0]b, 6);
+ if (words.size() != 2 || words[0] != 1 || words[1] != 0x1F) {
+ logger.error("stuffing gave " + words.toString());
+ return false;
+ }
+ if (!(Aztec.encode("", 1) instanceof Codes.CodeError)) {
+ logger.error("empty text accepted");
+ return false;
+ }
+ var big = "";
+ for (var i = 0; i < 400; i++) {
+ big += "~~~~~~~~~~";
+ }
+ return Aztec.encode(big, 3) instanceof Codes.CodeError;
+}
diff --git a/test/data/CodeVectors.mc b/test/data/CodeVectors.mc
index 578a177..50c51c6 100644
--- a/test/data/CodeVectors.mc
+++ b/test/data/CodeVectors.mc
@@ -326,4 +326,32 @@ module CodeVectors {
["é\\I,p|z€dNV4€rQu€0ZS%Jü€\\é>5?Y2Wo(%Bf7MCg", 8, 3, 11, 205, "ff5475383a2e10422e49c65cf218c91dc8ed3059cc3a8e1fd14ffaa3d41190e2e2e35edf27d1de73adfae79663a341f530fe8a7fd51d47eed3e63e4a3c85074cdccf4f9db3f65b278a83c7f453fea8afbe504425ef10c64c36c4771331411b4082117d2fbfa29ff546b813cb31d1a0e8625fac3e3b53cbcf114661eb5c41fd14ffaa3afa18a3ecfd97e4d36cf9b278caf8769f31f25ebe6fe8a7fd514e708ee4769820845c938cb9e431923b91d19ea7bc7f453fea8fa4c70cebe7353eb8f0cd6fa7b82693cbc8df46bf7bfa29ff54530fa3c157ee2871677e4a3c29a2f8f93963e4a9df9fd14ffaa28c19da0cf7944ce1b8b79c7428881677337321a39efe8a7fd51a704d0e278ccbe44de8c6fa8c621cb08e5fb26d3907f452"],
["&IO$u(WFü{ß(TAWéß)|8a>\"JLH2KJ(üaéü0eLq\"H,eüR414/P9ü>€ßeTDL1:üü{)üCßZß", 12, 2, 10, 273, "ff5475383420d8ed0e3a16ed0261a1c25cc61267b93b4c10422e49c6d042a041fd14ffaa3ea317eb09e5e705db7eb9d062a3e65fac279791be8f33442f9b7eb9f530fe8a7fd51fad0fc9a7b5fbf269cbe8c7c940d3af9cd8f94c85f7d712f8c5869ed47c7f453fea8afbe59f7b6441a338b182477239c850422e49c6d04218c90504821169183fa29ff546b843a0c5e86ce8317a0a2fd61f1da82f25f67bd985f126fded5f0bb5c41fd14ffaa3af893e349f6167ecbf269b67cc7c96723ba1f5283cbf3a6fcd33f65ebc2fe8a7fd514e70e49c6d04218c91dc8e8cf4108b6f3d411097bc724e32ce10c64d1607f453fea8f4a041792fb3df776e468579037eb9d062f4147418bd0517eb09e5e6bf7bfa29ff547d3933e859fb2fc9a6d9f31f2544f0cfd97e4d397d18f92876767eca98f9fd14ffaa28c19c938cb384319218c9d4e082ee6c5028211d11cb0614110acfbdd0b8fe8a40"]
];
+
+ // [payload, EC option, aztec_code_generator size, its matrix as hex of row-major bits]
+ const AZTEC = [
+ ["A", 1, 15, "0c7a7261c023ffe9015afa35154aa894572fa44054ffc8003b0b114b00"],
+ ["HELLO WORLD", 1, 15, "38f6ceb8c235fff701d2fbd516daabb455afad405cfff0624616868a80"],
+ ["hello world", 0, 15, "3185b64ec231ffdb018afbc5167aa93451afa14052ffe862308561a300"],
+ ["0042 7731", 2, 15, "0e89a01fc1a1ffd50106fb1d170aaed4582fbac058ffd0f61430abb180"],
+ ["FAKE TICKET FAKE TICKET FAKE TICKET FAKE TICKET FAKE TICKET FAKE TICKET FAKE TICKET FAKE TICKET FAKE TICKET FAKE TICKET ", 1, 37, "2ac7a804ae22822be22aaaaaaaab13c8024aa3412bf122c060e8f1619f2be6f8b3921b88b3284efad322632a4b32aad5fec39819b202da920dfffff6e564004645952ffa00a923405eaa703afaa5a2395457086aaaaaaaaa16151575273dafa9e2094d014849c9effa36923d001632224ffffdb24630a12ea8f948628d3a7f20a83b0c1fd19641cca1d340c0a2a3e0a9f1a8904a247d6414a692009e326aaaaaaaaa123e920a2b49024f1a80"],
+ ["abc def abc def abc def abc def abc def abc def abc def abc def abc def abc def abc def abc def abc def abc def abc def abc def abc def abc def abc def abc def abc def abc def abc def abc def abc def abc def abc def abc def abc def abc def abc def abc def abc def abc def abc def abc def abc def abc def abc def abc def ", 3, 67, "021289108a4882522aaaaaaaaaaaaaaaa830a0358481ac140cae4432923094a884a06b09035828196149d252a212c910ca49a620658501ac240d4a272ad5fb52377182006120b91334b5081a8b5842afd168b768001c4a3ae60c77da399aafaab7cba618384c635831c40b0638d57684b2b0b4d780840e06c5ae9fe62e8a4ec331df3f13d6b200629fa6b18f34392aaaaaaaaaaaaaaaaa13a49bfc421220c031d52f1d65ece37a2321401aea25a31c0a90adf61ef1e2838dabd6225ac933a50c4200ab0a3fef768f173b00ab082f37100c1cc01a2dbb78cc8f38220e97d612c408022c91e5bfffe72f96b848d061001ed98a008041aa6ffa03f8b0a500835501592722c201a607afa8261836337fb43515560f802aaaaaaaaaaaaaaaaa13e2afd4554a9e8e3562f5eafae8f2a82101b0f1405b0036a29359f72ffa2ebb0c8008ef640060e3364e252f0efffe4e0c02239a0801b82b1fd40e454adf8ac789281c20f085545066af1a778bf45f67d072b8a001eaae23cec1462af6fbf2e5bb42c918a999c3bb695a85fe6245fe4f33ff961606194f13f829a69d6d2aaaaaaaaaaaaaaaaa1290cbba03beff8020143a947061a94c294460ad435df974b08063bdf6cb2c920d8cc2cc77465105400e2593f52ff9c63f1e2a8f9390ba0695d00a003f0b09494a054c2580a1ac050cb0182092a844aa42324cb83580a1aa050ab000c892c844ca4292488b580a1ac050cb022a892a844aa423253698141ac090d602860aaaaaaaaaaaaaaaaa252089288448a42280"],
+ ["123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", 1, 67, "0376111b9888aec42aaaaaaaaaaaaaaaa82d04bd6815eaa0aeac46f6223bb128dda0fad02bd3415b5a09dac4a376911bd88caa856d6825eb40af2a884776231bb288972bfaa82bab412f5918886f6229bb188e5e36ac82bcb414f538a8cc776231bb28ff3942aa82bab412f131899dd0bcb29099b8ed9287f080c00b918a8c9b5582ade602a6becb2b9f3b27a7130aaaaaaaaaaaaaaaaa9b146664c9b29d9e2c75baa264af3a2233b138aaeb61cb7ab881ecbc3bd6f18a23ab99a63f6db6a46a63148bcc969fd203273b318a49190999a90d63fad9080f9cb73a319627d61b926a28359ce5bfffe3e2767113b33d001edae02ad748d82ffb659b72a1132d650148ac8cae6d0230afab337673119a9175155abafe2aaaaaaaaaaaaaaaaa50a2f254544adc4c6266615afaf7e06e3b64f0e14051e2e462a32def2ffb29c8a9afb3874c006d8bc4c736120afffd3e3b3e18eaba0ca20a04442f62bf2dafc0a9757803cc85ccac6e74467732ee757b772ad4e229615de0bfd0064af66fd999bb128b528ac7e34aa99ba56e66630eb93252dbd4522b3a238ebebb14ecaaaaaaaaaaaaaaaaa844e807d04f50980ab5d26c127e00e6dca844cbcdeb2743a32b9b46960d83e7bd9cc467a416aea0aabf8ea18a6ec62377189a8482abd40b5e90dc3ecddc446f6229a8cc47a816bca0b4f5527f88eec463763109aa57a816baa0b2f578b888eec4a3769108cd7a816bca0b4f50e2888eec46376311aeba82abd40b5e905a8aaaaaaaaaaaaaaaaa11ba888cec44376280"],
+ ["ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ", 0, 79, "eebdeebdeebdeebdeebcfbef7bef7bef7bef7befb9ef79ef79ef79ef79fddf7bdf7bdf7bdf7bdf7feef7aef7aef7aef7af3af7bdf7bdf7bdf7bdf7df3ef79ef79ef79ef7972aaaaaaaaaaaaaaaaaaaeaef7aef7aef7aef7aef7e7bdf7bdf7bdf7bdffffbdef3def3def3defacebeef7def7def7def2ff7cefbcf7bcf7bcf7beddd7fbbef7bef7bef7f6def8ddebbdebbdebbdfbffffffdf7bdf7bdf7cfd9d6daeebdeebdeebdf4fefbdf7ef7bef7bef5dfbbabf5ebbdebbdebbde9bdf9be7def7def7dffffffefffcf7bcf7bcfd9eb3afb5eeac66f1cbafebfdf3beeb899b3423fbbb72aaaaaaaaaaaaaaaaaaaeafd7e790c12a42b7a6f7e6f9a4bcffb9b7ffffffbfff9488b99f0f67acebed7bc2d3f9eccbfaff7cefbafc549ac67eeeddd7fafe6cd3c27356f6def8df30e42a936bfffbffffffff626d022becfd9d6daf6c8dc3a44d7f4fefbdf760bffff8f7ddfbbabf5fbeb00116bade9bdf9be6b76ffa24fffffffefffedf50140a7d9eb3afb5ef17afabafafebfdf3beeb1351575afbbb72aaaaaaaaaaaaaaaaaaaeafd7e49d457bceb7a6f7e6f9b11afa943fffffffbfff9fd405ed9f67acebed7bcc6ffa0cebfaff7cefbae9400734beeeddd7fafe16fffe57d6f6def8df31f87807d3fffbfffffffd1769116becfd9d6daf6fc02278cd7f4fefbdf7742c6a0577ddfbbabf5fb8242202bade9bdf9be681c0bc84fffffffefffe7e70ee1a7d9eb3afb5ee0143c6d7afebfdf3beebf79297d2fbbb72aaaaaaaaaaaaaaaaaaaeafd7cf7bcf7bceb7a6f7e6f9fbdefbdeffffffffbffdb7bdb7bdbf67acebed7fbdefbdefabfaff7cefeebdeebdeebeeeddd7fa7bef7bef7bf6f6def8dfbaf7baf7bafffbfffffdefbdefbdefacfd9d6def6def6def6def4fefbd7bef7bef7bef7dfbbabdef3def3def3dee9bdf9f7bef7bef7bef7ffffedef6def6def6defeb3aff7bef7bef7bef7abfdfaf7baf7baf7baf7bb72aaaaaaaaaaaaaaaaaaae8f7bcf7bcf7bcf7be6f7f7bdf7bdf7bdf7bdffff3def3def3def3def2cfbef7bef7bef7bef7bef5e7bde7bde7bde7bde7d7bef7bef7bef7bef7befdb7bdb7bdb7bdb7bdb780"],
+ ["0316810313 97933695146549885 513", 2, 23, "d7ebefdf6328a41962549053c20277ffff29001732ffb6c501446afaed351592aaaaa7d45447afacdf405edeffa75c00684fffc20416741ad67630d921da2dbaabc680"],
+ ["zeafyevetqifrldvqopuourlolthkfklrlsdeqpwfkphrrmjxwbqd rhbqcseyzdmyeyxibyiz htsnkhvcwixxgfwqmlj wo frfzzkxnhvcyqyojzeaigcjlzv c yno", 3, 45, "f3986aa063656a150d350dd2c8978189eb4018ab39d2bef2ed7eb3629ae02875f03aaaaaaaaaaabd0c87163b193ec80396fbd8c770eb498923d07a9967f6308842740a4eedd3a7c9657c73fe50167a4b845cdd6892ab7302938e220fffff3e4eccc40044af94c42ffba8fea015405538ac7b5afaa4ea0614545424e2aaaaaaaaaabeac3515d9277241afaed672e94d017022138b6ffb23ad5245001182263f2fffc0389a2634187ac65a5d7fa8e855b3ee3f5a990f9f674eaf8eefdda92f2b36d612b1c7b0105d6197592f3d39ed122baa823e4a10a6aaaaaaaaaab217459b7c1aaf627e16e2da68aa0ace8f1bab93d831a6c158d92f229ee18cb8c33d00"],
+ ["khgbkqwizxjnruzfrlcoschmhohdgcjpsirqjwxs jfhixashweirmbbrq zvrmkzhiaoyxrffeizplufauzhqdedblnuxajxwtxdjabashwm", 1, 37, "e575f2836430083b84aaaaaaaaaa1ad98105bf05fb6b538571ac88c5acc7f2f381e699314aa4c23c51acdd0c6e7ccbcd7f86a833f202e0262ffffc1f41c400584befaffac480fd40529aa85afad67aec54556c2aaaaaaaaa85b5152d9ba8afac87897d016405adeffa55888d001179610fffe4646e18d0e43e6e7af8ab95a7aa6913dd47be46c4608956c2e0cba171daea7051b9755839d526759c09562aaaaaaaab2d6c860e1bdb5a829700"],
+ ["65518223274087507999447277887133315395420221 97894936369234 855 18 6 26389 698", 1, 27, "d5285efb90a2b1d766f388574bd1d11cf5b2cbaa6bc4030f9ffffd9700182a2ffad79d014cb7afac93f515d4aaaaaaa25456682afae4a9405e472ffbca34004d4cffff6989004ed51c180b962e1c26b1c0dc9b51cf2dfd640e256880"],
+ ["IORVBBNVUJNBVWZYXHAYOJISXTXXNAYZKZROHADTCFINERAEQNLAWGMXYDSCMYRPRGNXOHTGBIMEPPHDINRXUIHQXHKHBPGSLRYRDTSBGPSUUBFCFVACPVCFBWBSU DWGNZU VGZZZHVCPBCYVFRUQTPMWJIVXHYMBEDMYTZ", 2, 45, "4bd0c3526ecb61d1adc20e9b92a89634f22ac712f2a262272dfe853450dd6a0fa8daaaaaaaaaaaa884f831c694dfbdda2ebedba69cea180c3cadccf4539453f2a1db9a35fe1d3366b450dd723b3e7c0ab78f544e788c330290b0621ffffe06b6c0e40075a5bb9aaffa75b6d159405801ae361afa93f65284d455f096aaaaaaaaaab82755150e000334afa89ef4e21d017ea8bb86affb00f6dacd0016aa9e7d0fffe9b64eab0a491834dfdffc9d0e191d3282679d939a4b92bea70803a32e46bb973b8cc7810bd9e8a6ea83f4fefd4c7de2ef30be004aaaaaaaaaaaaa9edc957db9d3dcaa122e5c6db50a4624648edb96ca9d1303e9eb8b5b27306966e700"],
+ ["POZLDPWYGYBFIMDULTATWFNXMUUAWQZQVLOWBSCCESYWCVRYMINTATGVBWVJUFSAQTSNARCEZN LZOI T S", 3, 37, "bb5da92228e33687722aaaaaaaab9a50227802e43ef72601ee43500ba5258423e99d29c6aaa92967666645a2ef441a59ac1cda0df200e0aa95fffe6a67d4007384efaffbbdc8cf4051ebe8eafabc68e054575ceaaaaaaaaaa87515ea1a58afab32cb45014ec1e72ffabae223001d2272afffee3cca20d13e6c9e89d8a834b385eba64c0264aa44734dc0edf5c89101ba9b1013e060f1ba2d22986c14deeaaaaaaaaa86bbb3ef976b028b9280"],
+ ["WGQMIKUUZZMSNYCSQNHYUGB D SRFEQMGEILZTBFQTJECXCGSTUVBTOJRDZCZETNAYHNIFW AJFGNWCCHNFBPKTWHYQCBZO UDRYTHLAFMZGGGIWOUDWYRJGXGZVHTXKRK", 3, 45, "ffa94bc9271982d7a43de702d917a28499223b90c38211b3a4a909b45005d8e09836aaaaaaaaaaadb88695ae84171f021c26f66fc2c5592569cb19c18bbcf923e18c821773f9b5c8ea08206eea2c877bec1bd7bcc0acb302df3596cfffff6bd7ee24005e669cebaffbafec93c140565868fc9afa966360b354542a5aaaaaaaaaaaab1b35158195e76fafad463c411d0160c7bbe26ffbdbd2a2b50016f26df0efffda2436733419d0296cc64cee384612e3aa5c0f5a0babaeef3603b3acc4caf1dfeccccf957260da06b33b3bde602e681e2e7aeba28aaaaaaaaaaab1234b0b589e46c4fec7e7cb03b6cf1e0381a691894598b910904aa289afa23996e700"],
+ ["NXARYIBKQZTJKZHLVSE GOWCAPRZPIECIHHHZPGEAHWROPRKFZPLWJYSMHIWSMIDDQBQUEKTWCLQZMWLKTSTMIJPYEOYGIU FDWLNNDCQDNCHGIYWINW YZVJWXA", 0, 37, "77cd2628a6165495922aaaaaaaabb1e318932ac8262ee32c3aa816609a86d526e887e845f2738362a3b8dbe8744cbfac0cff1b907202ea9685ffff4a07240047ca886ffa72d167405ca93edafad7a226d45594aaaaaaaaab2c3515ddaef1afaa7204dd01650ab3effb3f89ab0010cb73efffdfe40e38092a7d198bb36b278f0def9a0ef6a5c64d06e10006dd43c873f930c1cda976463579bc06969440aaaaaaaaab33723493173712040300"],
+ ["ZTSSADYVFRKKI FKYGNZZIMUTYHNYJLEPGZLO TLHWWLBBOVWSMEUWAAFJGGPSBXEFCQUJYDHUASICJYYWFMHBEZYZGVEU", 1, 31, "c4b0f0b4d92f10dbb278002a239eb717f5491515357ec361c50220a830e3da58c6035261fffc64f1001c9212ffbfb1c50171aaaafa93125515ab2aaaaaaadc545446f9afaa3d13405fbaaaffb25ebc007205cffff6bd40b03ae888a8d12506135f9baa54e514f9d70d0988cdd05e250c5655a771a03a27dd80"],
+ ["nwlslpuecektj uqguapgpnf nlitgfbjochdbnnvmqabzlvqdrgudpfkmjzjwunqrpwxesivi r ituixtbb", 1, 27, "f840f216b2896440492d7fbab62fd1d11da8b0338d61015081fd26f2fd2f6affffe62101a9d36faee0bd17bda4aac1113450ac36fb4b3540619eaffffd5c2e7bd291a113a6f0f9b174ce4ae8588385b15d35a162aa0990815f2cb280"],
+ ["OSJNRKHGDYITHEIWXRR MFDXEBQPMWWWOLYUGMLSAX", 0, 23, "92a06414fb49a92272119610c202efffff5700185effa3dd0155bafa8275159aaaaaa6545652afa8b3405a06ffb57400644fffd6440e3ccae9830cfa64fe5c1e014580"],
+ ["ord mwmfmrxf ktpas mhfwcwmgdyczbzye vddydpajlqypzyeaoeetnvkrqi pfrpycaharikmcotoquzaccqdzfxwigjkfl u lbtnhvvjbdpatmuacnukk wvaldwikc", 0, 37, "e7b972a13c743660de2aaaaaaaaa9436908a830cbbe903818b235dcaad21e447e99260ef08a6bce29ca2016012c45855ce8bec3ff202f88251ffff13473400550fc9affb47f2294056c9f0bafaaf78b5545718aaaaaaaaaa347515f40fdbafaa4bc8c5017524e46ffa40dabb001b49bfcfffc8e6180a30286c0d5c569b1509942537f3db92b6e12eef8f22dcbf92b9893ba2b0513256a8086602367492eaaaaaaaaa370039612a4572539600"],
+ ["hd ierfntgkbqfcp ehpcvn dnwnpuokywcllhfejvrzyvvuobewnjgnkxsnhtgjdukhrftgblwsgwpvcokfnoabrafwdhzgbx hpmljwnfwfbpzpdfddrnrpcvpwduoa", 0, 37, "f077f6fab446f0f6962aaaaaaaaa1e060a47ab573b581b2d95e8d9ec82cf8184b02849a601b87b6795f0fab21f981be8db168c91b202dc8751fffd52085c005c4d8c6ffbe9b16d405119b90afa9772b6d455b46aaaaaaaab301515c22622afaeba6dc5014f8198affbd7db31001a43ee2fffc16a1d1c70709aa869f198b522a4cab37a5f7ad38a7063e22badcdde8f82362251c921b56af8bae2685606eaaaaaaaab0a0a2258ab6516a7cb00"],
+ ["dkwfvxadzmmybfavxcnmxzgzaxrxm b wlqgdvcivcbasstsbujlqlgmp", 3, 31, "c940705950fb5928453b514a91fdc83450845e0d13fcf42a2aa3fdaed882f094c6020a39fffde085001f877effa71c3d014169aafadb7ff5157c2aaaaaaaeb54551665afa9be0d405ee13affa47b0c0057034fffc7e80c3e70f8f4fe348118353bcb6f28f973f9bc9e1dfede0391c3803650e8fb78b7a5ab00"],
+ ["NLBKD SSXPUIAVNZQRAPPZDNPWGOL AGRFG BWVVLURRWABIZXOMGRZ TNEAYXFBV RAXSDSDSRMLHRBBUTQLJFNVXEJAY FXEUGXKLEEFHWFPGFKEEVUKWOLBS MRXXNOJEPIVICR JXVTEHXXLJXS BMXNVPPOZDPJZMMFUEMJVVSPEFJRNNP UAIQT", 2, 45, "6e4cbf2c336f25c584ea85e9c15cd281cbe12aba4e6a16fea7377a6e84a6acd70ccaaaaaaaaaaaab34c8a1fa88a29bf230fe6e8df80d99ce09c0aaad45800a260af739caee596fb771da09aa79641c0a522e53af0f88b3028b379fb9fffe96b403f400742e53b4effbd8e2d35b4056b9e3685afaf023ea4554572cc6aaaaaaaaaaa1b95515521ece5cafa9e7990d450172459caa2ffa41c72b0d001880fc76affffdf294c838713c125ee80c8ef9352c512a19973a6fa70e629309974bbf0b169936a697bcd1c3785c9b8ea8e1e40a7234c87eef6882aaaaaaaaaabb0286b15622efa4f6f4d7bd271225b525b597afbfcb92d34a31291228a177ec062480"],
+ ["iawnuqjlcsuspmbrelfququnozxbufjpikjvuby", 1, 23, "f7d469049d70bcdb5cde11ba5cad404c8c5be62539ffdead012c6afb35cd15cecaa86e3457c8afa2a44044d8ffe768282c482cf6cca28e11c2e511aca462e5b3384c80"]
+ ];
}
diff --git a/test/golden/fenix7/about.png b/test/golden/fenix7/about.png
index eb34e4e..9df582a 100644
--- a/test/golden/fenix7/about.png
+++ b/test/golden/fenix7/about.png
Binary files differ
diff --git a/test/golden/fenix7/code_aztec.png b/test/golden/fenix7/code_aztec.png
new file mode 100644
index 0000000..7571fcd
--- /dev/null
+++ b/test/golden/fenix7/code_aztec.png
Binary files differ
diff --git a/test/golden/fr255s/about.png b/test/golden/fr255s/about.png
index b4aebeb..0198345 100644
--- a/test/golden/fr255s/about.png
+++ b/test/golden/fr255s/about.png
Binary files differ
diff --git a/test/golden/fr255s/code_aztec.png b/test/golden/fr255s/code_aztec.png
new file mode 100644
index 0000000..ed99901
--- /dev/null
+++ b/test/golden/fr255s/code_aztec.png
Binary files differ
diff --git a/test/golden/fr70/about.png b/test/golden/fr70/about.png
index 758268c..7d0b222 100644
--- a/test/golden/fr70/about.png
+++ b/test/golden/fr70/about.png
Binary files differ
diff --git a/test/golden/fr70/code_aztec.png b/test/golden/fr70/code_aztec.png
new file mode 100644
index 0000000..67888b9
--- /dev/null
+++ b/test/golden/fr70/code_aztec.png
Binary files differ
diff --git a/test/golden/fr965/about.png b/test/golden/fr965/about.png
index fe21a67..211487d 100644
--- a/test/golden/fr965/about.png
+++ b/test/golden/fr965/about.png
Binary files differ
diff --git a/test/golden/fr965/code_aztec.png b/test/golden/fr965/code_aztec.png
new file mode 100644
index 0000000..108f864
--- /dev/null
+++ b/test/golden/fr965/code_aztec.png
Binary files differ
diff --git a/test/golden/instinct3amoled45mm/about.png b/test/golden/instinct3amoled45mm/about.png
index b896bc8..72fde99 100644
--- a/test/golden/instinct3amoled45mm/about.png
+++ b/test/golden/instinct3amoled45mm/about.png
Binary files differ
diff --git a/test/golden/instinct3amoled45mm/code_aztec.png b/test/golden/instinct3amoled45mm/code_aztec.png
new file mode 100644
index 0000000..8797d3b
--- /dev/null
+++ b/test/golden/instinct3amoled45mm/code_aztec.png
Binary files differ
diff --git a/test/golden/venusq2/code_aztec.png b/test/golden/venusq2/code_aztec.png
new file mode 100644
index 0000000..57f716f
--- /dev/null
+++ b/test/golden/venusq2/code_aztec.png
Binary files differ
diff --git a/test/golden/venux1/code_aztec.png b/test/golden/venux1/code_aztec.png
new file mode 100644
index 0000000..053390d
--- /dev/null
+++ b/test/golden/venux1/code_aztec.png
Binary files differ
diff --git a/tools/gen_code_vectors.py b/tools/gen_code_vectors.py
index 5ce2611..1472bb7 100644
--- a/tools/gen_code_vectors.py
+++ b/tools/gen_code_vectors.py
@@ -23,6 +23,7 @@ from typing import Any, cast
import barcode_ref as ref
import ppf.datamatrix.codec_ascii # noqa: F401 (registers the datamatrix.ascii codec)
import segno
+from aztec_code_generator import AztecCode
from pdf417gen import encode as pdf417_encode
from ppf.datamatrix import DataMatrix
@@ -287,6 +288,42 @@ def pdf417_reference(payload: str, columns: int, level: int) -> tuple[int, int,
return len(rows), len(rows[0]), packed.hex()
+AZTEC_EC = [10, 23, 36, 50]
+
+
+def aztec_cases(rng: random.Random, count: int) -> list[tuple[str, int]]:
+ """(payload, EC option 0-3) with one character class each (capitals, small
+ letters or digits, plus spaces): for these the reference's optimal mode
+ sequence and the watch's encodation give the same bits, so the symbols
+ must match exactly. Sizes reach full range with reference grids."""
+ fixed = [
+ ("A", 1),
+ ("HELLO WORLD", 1),
+ ("hello world", 0),
+ ("0042 7731", 2),
+ ("FAKE TICKET " * 10, 1),
+ ("abc def " * 40, 3),
+ ("1234567890" * 60, 1),
+ ("Z" * 900, 0),
+ ]
+ out = list(fixed)
+ for _ in range(count):
+ alphabet = rng.choice([string.ascii_uppercase + " ", string.ascii_lowercase + " ", string.digits + " "])
+ n = rng.randint(1, 200)
+ payload = "".join(rng.choice(alphabet) for _ in range(n)).strip() or "X"
+ out.append((payload, rng.randrange(4)))
+ return out
+
+
+def aztec_reference(payload: str, option: int) -> tuple[int, str]:
+ """aztec_code_generator's (size, matrix as hex of row-major bits)."""
+ code = AztecCode(payload, ec_percent=AZTEC_EC[option])
+ bits = "".join(str(b) for row in code.matrix for b in row)
+ bits += "0" * (-len(bits) % 8)
+ packed = bytes(int(bits[i : i + 8], 2) for i in range(0, len(bits), 8))
+ return code.size, packed.hex()
+
+
def mc_string(text: str) -> str:
"""A Monkey C string literal body for text (quotes, backslashes, controls escaped)."""
out = []
@@ -342,6 +379,11 @@ def render(rows: list[tuple[int, str, int, str]], seed: int) -> str:
n_rows, width, hexbits = reference
pdf_lines.append(f' ["{mc_string(payload)}", {columns}, {level}, {n_rows}, {width}, "{hexbits}"]')
pdf_body = ",\n".join(pdf_lines)
+ aztec_lines = []
+ for payload, option in aztec_cases(random.Random(seed + 4), 16):
+ size, hexbits = aztec_reference(payload, option)
+ aztec_lines.append(f' ["{payload}", {option}, {size}, "{hexbits}"]')
+ aztec_body = ",\n".join(aztec_lines)
return (
"// Author: cirakg & claude ai\n"
"// Summary: zxing-cpp reference module rows for the linear barcode encoders (generated; do not edit).\n"
@@ -358,6 +400,9 @@ def render(rows: list[tuple[int, str, int, str]], seed: int) -> str:
+ "\n ];\n\n // [payload, columns, level, pdf417gen rows, width, one module row per PDF417 row as hex]\n"
+ " const PDF417 = [\n"
+ pdf_body
+ + "\n ];\n\n // [payload, EC option, aztec_code_generator size, its matrix as hex of row-major bits]\n"
+ + " const AZTEC = [\n"
+ + aztec_body
+ "\n ];\n}\n"
)
diff --git a/tools/tests/test_barcode_tools.py b/tools/tests/test_barcode_tools.py
index 5a2e999..f63b3fe 100644
--- a/tools/tests/test_barcode_tools.py
+++ b/tools/tests/test_barcode_tools.py
@@ -109,3 +109,11 @@ def test_pdf417_reference_rows() -> None:
reference = gen_code_vectors.pdf417_reference("Hello, World!", 3, 2)
assert reference is not None and reference[0] == 7 and reference[1] == 17 * (3 + 4) + 1
assert gen_code_vectors.pdf417_reference("ab", 30, 0) is None # one row: below the minimum of 3
+
+
+def test_aztec_reference_is_compact_for_short_text() -> None:
+ size, hexbits = gen_code_vectors.aztec_reference("HELLO WORLD", 1)
+ assert size == 15 # compact, one layer
+ assert len(bytes.fromhex(hexbits)) == (15 * 15 + 7) // 8
+ image = ref.render_matrix(bytes.fromhex(hexbits), (15, 15), 3, quiet=2)
+ assert ref.decode(image, ref.AZTEC) == ["HELLO WORLD"]
diff --git a/tools/ui_flow.py b/tools/ui_flow.py
index eea3e17..e54b530 100644
--- a/tools/ui_flow.py
+++ b/tools/ui_flow.py
@@ -65,6 +65,7 @@ MEMBER_QR = ( # source/app/Fixtures.mc: a version 6 QR
)
PARCEL_DM = "PARCEL-FAKE-0042-7731" # source/app/Fixtures.mc: Data Matrix
TICKET_PDF417 = "Boarding pass FAKE 0042 seat 12A" # source/app/Fixtures.mc: PDF417
+RAIL_AZTEC = "RAIL-FAKE-0042 Zone 1-3" # source/app/Fixtures.mc: Aztec
QR_TIMEOUT_S = 30.0 # the QR is encoded in timer steps the first time
@@ -432,8 +433,8 @@ def flow_lockout(f: Flow) -> None:
def flow_code(f: Flow) -> None:
- """The EAN-13 gym card (index 6), the QR (7), Data Matrix (8) and PDF417 (9)
- cards: their screenshots must decode."""
+ """The EAN-13 gym card (index 6), the QR (7), Data Matrix (8), PDF417 (9)
+ and Aztec (10) cards: their screenshots must decode."""
f.act()
f.back() # leave the waiting PIN screen
f.expect("list")
@@ -455,8 +456,8 @@ def flow_code(f: Flow) -> None:
if encoded is not None:
print(f"[{f.sim.device_dir.name}] QR {encoded.group(1)} encoded in {encoded.group(2)} ms")
f.shot("code_qr", expect_code=MEMBER_QR)
- # Data Matrix (8) and PDF417 (9), also encoded as jobs the first time.
- for name, expected in (("code_datamatrix", PARCEL_DM), ("code_pdf417", TICKET_PDF417)):
+ # Data Matrix (8), PDF417 (9) and Aztec (10), also encoded as jobs.
+ for name, expected in (("code_datamatrix", PARCEL_DM), ("code_pdf417", TICKET_PDF417), ("code_aztec", RAIL_AZTEC)):
f.act()
f.back()
f.expect("list")