/* libzint - the open source barcode library Copyright (C) 2020 - 2021 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the project nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* vim: set ts=4 sw=4 et : */ #include "testcommon.h" #include "../reedsol.h" // Print out the log/alog tables for "backend/reedsol_logs.h" static void print_logs(const char *name, int logmod, unsigned int *logt, unsigned int *alog, int u16, int last) { int i; const char *type = u16 ? "short" : "char"; const char *format = u16 ? " 0x%04X," : " 0x%02X,"; printf("static const unsigned %s logt_%s[%d] = {", type, name, logmod + 1); for (i = 0; i < logmod + 1; i++) { if (i % 16 == 0) printf("\n "); printf(format, i ? logt[i] : 0); } printf("\n};\n"); printf("static const unsigned %s alog_%s[%d] = {", type, name, logmod * 2); for (i = 0; i < logmod; i++) { if (i % 16 == 0) printf("\n "); printf(format, alog[i]); } // Double antilog table for (i = 0; i < logmod; i++) { if (i % 16 == 0) printf("\n "); printf(format, alog[i]); } printf("\n};\n"); if (!last) { printf("\n"); } } static void gen_logs(const unsigned int prime_poly, int logmod, unsigned int *logt, unsigned int *alog) { int b, p, v; b = logmod + 1; // Calculate the log/alog tables for (p = 1, v = 0; v < logmod; v++) { alog[v] = p; logt[p] = v; p <<= 1; if (p & b) p ^= prime_poly; } } // Dummy to generate static log/antilog tables for "backend/reedsol_logs.h" static void test_generate(int generate) { struct item { const char *name; int logmod; unsigned int prime_poly; int u16; }; struct item data[] = { { "0x13", 15, 0x13, 0 }, { "0x25", 31, 0x25, 0 }, { "0x43", 63, 0x43, 0 }, { "0x89", 127, 0x89, 0 }, { "0x11d", 255, 0x11d, 0 }, { "0x12d", 255, 0x12d, 0 }, { "0x163", 255, 0x163, 0 }, }; int data_size = ARRAY_SIZE(data); int i; unsigned int logt[4096]; unsigned int alog[8192]; if (!generate) { return; } for (i = 0; i < data_size; i++) { gen_logs(data[i].prime_poly, data[i].logmod, logt, alog); print_logs(data[i].name, data[i].logmod, logt, alog, data[i].u16, i + 1 == data_size); } } static void test_encoding(int index) { struct item { unsigned int prime_poly; int nsym; int index; int datalen; unsigned char data[256]; unsigned char expected[256]; }; // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<")) struct item data[] = { /* 0*/ { 0x43, 4, 1, 7, { 4, 20, 49, 37, 49, 38, 23 }, { 54, 17, 53, 58 } }, // AUSPOST Australia Post Customer Barcoding Technical Specifications Diagram 10 /* 1*/ { 0x43, 7, 1, 10, { 9, 50, 1, 41, 47, 2, 39, 37, 1, 27 }, { 38, 50, 8, 16, 10, 20, 40 } }, // AZTEC ISO/IEC 24778:2008 Section G.4 /* 2*/ { 0x13, 5, 1, 2, { 0, 9 }, { 12, 2, 3, 1, 9 } }, // AZTEC ISO/IEC 24778:2008 Section G.4 Mode Message /* 3*/ { 0x12d, 5, 1, 3, { 142, 164, 186 }, { 114, 25, 5, 88, 102 } }, // DATAMATRIX ISO/IEC 16022:2006 Annex O /* 4*/ { 0x89, 25, 1, 25, { 42, 13, 54, 39, 124, 91, 121, 65, 28, 40, 95, 48, 0, 126, 0, 126, 0, 126, 0, 126, 0, 126, 0, 126, 0 }, { 123, 47, 2, 20, 54, 112, 35, 23, 100, 89, 55, 17, 101, 4, 14, 33, 48, 62, 98, 52, 2, 79, 92, 70, 102 } }, // GRIDMATRIX AIMD014 Section 6.8 /* 5*/ { 0x163, 4, 1, 21, { 0x11, 0xED, 0xC8, 0xC5, 0x40, 0x0F, 0xF4 }, { 0xEB, 0xB4, 0x68, 0x1D } }, // HANXIN ISO/IEC DIS 20830:2019 Annex K.1 /* 6*/ { 0x163, 24, 1, 27, { 0x11, 0xED, 0xC8, 0xC5, 0x40, 0x0F, 0xF4, 0x8A, 0x2C, 0xC3, 0x4E, 0x3D, 0x09, 0x25, 0x9A, 0x7A, 0x29, 0xAB, 0xEA, 0x3E, 0x46, 0x4C, 0x7E, 0x73, 0xE8, 0x6C, 0xC7 }, { 0x08, 0x57, 0x0C, 0xE0, 0x7A, 0xA5, 0xDD, 0xA2, 0x99, 0xCF, 0xA4, 0x82, 0xAD, 0x11, 0xB0, 0x84, 0x74, 0x5D, 0x9A, 0x99, 0x0B, 0xCD, 0x49, 0x77 } }, // HANXIN ISO/IEC DIS 20830:2019 Annex K.2 1st block /* 7*/ { 0x163, 24, 1, 27, { 0xE7, 0x3E, 0x33, 0x29, 0xE8, 0xFC, }, { 0xA2, 0xA7, 0x68, 0x8A, 0x5F, 0xE6, 0xAA, 0x11, 0xA6, 0x69, 0x4A, 0xCF, 0xCF, 0x20, 0x5D, 0x00, 0x1B, 0x79, 0xA1, 0xFE, 0xB7, 0x94, 0x03, 0x9B } }, // HANXIN ISO/IEC DIS 20830:2019 Annex K.2 2nd block /* 8*/ { 0x163, 24, 1, 29, { 0x00 }, { 0x00 } }, // HANXIN ISO/IEC DIS 20830:2019 Annex K.2 3rd block /* 9*/ { 0x25, 6, 1, 16, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4 }, { 14, 7, 23, 3, 23, 15 } }, // MAILMARK Royal Mail Mailmark barcode C encoding and decoding Example 2.3.1 /* 10*/ { 0x25, 6, 1, 16, { 15, 22, 3, 25, 23, 26, 7, 3, 20, 14, 1, 4, 16, 3, 9, 28 }, { 27, 22, 24, 16, 6, 24 } }, // MAILMARK Royal Mail Mailmark barcode C encoding and decoding Example 2.3.2 /* 11*/ { 0x25, 7, 1, 19, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4 }, { 20, 1, 20, 7, 14, 11, 18 } }, // MAILMARK Royal Mail Mailmark barcode L encoding and decoding Example 2.3.1 /* 12*/ { 0x25, 7, 1, 19, { 0, 8, 21, 10, 29, 1, 29, 21, 2, 24, 15, 2, 19, 1, 4, 15, 11, 4, 16 }, { 19, 7, 9, 8, 6, 16, 16 } }, // MAILMARK Royal Mail Mailmark barcode L encoding and decoding Example 2.3.2 /* 13*/ { 0x43, 10, 1, 10, { 4, 13, 63, 1, 24, 9, 59, 3, 15, 4 }, { 50, 2, 42, 51, 53, 34, 22, 20, 5, 16 } }, // MAXICODE Annex H Primary /* 14*/ { 0x43, 20, 1, 42, { 5, 57, 49, 47, 8, 18, 59, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33 }, { 31, 2, 58, 6, 6, 39, 13, 63, 2, 30, 19, 19, 14, 19, 23, 17, 62, 8, 2, 23 } }, // MAXICODE Annex H Secondary odd /* 15*/ { 0x43, 20, 1, 42, { 47, 40, 57, 3, 1, 19, 41, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33 }, { 1, 15, 22, 28, 39, 17, 60, 5, 35, 35, 4, 8, 0, 32, 51, 45, 63, 53, 61, 14 } }, // MAXICODE Annex H Secondary even /* 16*/ { 0x11d, 10, 0, 16, { 0x10, 0x20, 0x0C, 0x56, 0x61, 0x80, 0xEC, 0x11, 0xEC, 0x11, 0xEC, 0x11, 0xEC, 0x11, 0xEC, 0x11 }, { 0xA5, 0x24, 0xD4, 0xC1, 0xED, 0x36, 0xC7, 0x87, 0x2C, 0x55 } }, // QRCODE Annex I.2 /* 17*/ { 0x11d, 5, 0, 5, { 0x40, 0x18, 0xAC, 0xC3, 0x00 }, { 0x86, 0x0D, 0x22, 0xAE, 0x30 } }, // QRCODE Annex I.3 }; int data_size = ARRAY_SIZE(data); int i; testStart("test_encoding"); for (i = 0; i < data_size; i++) { int j; rs_t rs; unsigned char res[1024]; if (index != -1 && i != index) continue; rs_init_gf(&rs, data[i].prime_poly); rs_init_code(&rs, data[i].nsym, data[i].index); rs_encode(&rs, data[i].datalen, data[i].data, res); //fprintf(stderr, "res "); for (j = data[i].nsym - 1; j >= 0; j--) fprintf(stderr, "%d ", res[j]); fprintf(stderr, "\n"); //fprintf(stderr, "exp "); for (j = 0; j < data[i].nsym; j++) fprintf(stderr, "%d ", data[i].expected[j]); fprintf(stderr, "\n"); for (j = 0; j < data[i].nsym; j++) { int k = data[i].nsym - 1 - j; assert_equal(res[k], data[i].expected[j], "i:%d res[%d] %d != expected[%d] %d\n", i, k, res[k], j, data[i].expected[j]); } } testFinish(); } static void test_encoding_uint(int index) { struct item { unsigned int prime_poly; int logmod; int nsym; int index; int datalen; unsigned int data[256]; unsigned int expected[256]; }; // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<")) struct item data[] = { /* 0*/ { 0x409, 1023, 4, 1, 7, { 0x3FF, 0x000, 0x100, 0x1FF, 0x3FF, 0x000, 0x123 }, { 229, 153, 993, 674 } }, /* 1*/ { 0x1069, 4095, 4, 1, 7, { 0xFFF, 0x000, 0x700, 0x7FF, 0xFFF, 0x000, 0x123 }, { 3472, 2350, 3494, 575 } }, }; int data_size = ARRAY_SIZE(data); int i; testStart("test_encoding_uint"); for (i = 0; i < data_size; i++) { int j; rs_uint_t rs_uint; unsigned int res[1024]; if (index != -1 && i != index) continue; rs_uint_init_gf(&rs_uint, data[i].prime_poly, data[i].logmod); rs_uint_init_code(&rs_uint, data[i].nsym, data[i].index); rs_uint_encode(&rs_uint, data[i].datalen, data[i].data, res); rs_uint_free(&rs_uint); //fprintf(stderr, "res "); for (j = data[i].nsym - 1; j >= 0; j--) fprintf(stderr, "%d ", res[j]); fprintf(stderr, "\n"); //fprintf(stderr, "exp "); for (j = 0; j < data[i].nsym; j++) fprintf(stderr, "%d ", data[i].expected[j]); fprintf(stderr, "\n"); for (j = 0; j < data[i].nsym; j++) { int k = data[i].nsym - 1 - j; assert_equal(res[k], data[i].expected[j], "i:%d res[%d] %d != expected[%d] %d\n", i, k, (int) res[k], j, (int) data[i].expected[j]); } } testFinish(); } int main(int argc, char *argv[]) { testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */ { "test_generate", test_generate, 0, 1, 0 }, { "test_encoding", test_encoding, 1, 0, 0 }, { "test_encoding_uint", test_encoding_uint, 1, 0, 0 }, }; testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); testReport(); return 0; }