mirror of
https://github.com/zint/zint
synced 2024-11-16 20:57:25 +13:00
231 lines
11 KiB
C
231 lines
11 KiB
C
/*
|
|
libzint - the open source barcode library
|
|
Copyright (C) 2020 - 2021 Robin Stuart <rstuart114@gmail.com>
|
|
|
|
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;
|
|
}
|