mirror of
https://github.com/zint/zint
synced 2024-11-16 20:57:25 +13:00
test suite: zxing-cpp: adjust for returnCodabarStartEnd
no-op;
allow for old "libpng" (`png_set_scale_16()` not available) general: Solaris compat library: use proper function ptr instead of `void *` for function table; warning suppression "-Wpedantic" -> "-Wstrict-prototypes" GRIDMATRIX/HANXIN/QRCODE: `xx_define_mode()`: multi-dim `char_modes`
This commit is contained in:
parent
7b41dfbee2
commit
e167f5b534
@ -54,7 +54,8 @@ extern "C" {
|
|||||||
# include <malloc.h>
|
# include <malloc.h>
|
||||||
# define z_alloca(nmemb) _alloca(nmemb)
|
# define z_alloca(nmemb) _alloca(nmemb)
|
||||||
#else
|
#else
|
||||||
# if defined(ZINT_IS_C89) || defined(ZINT_IS_C99) || defined(__NuttX__) || defined(_AIX)
|
# if defined(ZINT_IS_C89) || defined(ZINT_IS_C99) || defined(__NuttX__) || defined(_AIX) \
|
||||||
|
|| (defined(__sun) && defined(__SVR4) /*Solaris*/)
|
||||||
# include <alloca.h>
|
# include <alloca.h>
|
||||||
# endif
|
# endif
|
||||||
# define z_alloca(nmemb) alloca(nmemb)
|
# define z_alloca(nmemb) alloca(nmemb)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* gridmtx.c - Grid Matrix */
|
/* gridmtx.c - Grid Matrix */
|
||||||
/*
|
/*
|
||||||
libzint - the open source barcode library
|
libzint - the open source barcode library
|
||||||
Copyright (C) 2009-2023 Robin Stuart <rstuart114@gmail.com>
|
Copyright (C) 2009-2024 Robin Stuart <rstuart114@gmail.com>
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions
|
modification, are permitted provided that the following conditions
|
||||||
@ -156,15 +156,15 @@ static void gm_define_mode(char *mode, const unsigned int ddata[], const int len
|
|||||||
unsigned int numeral_end = 0, numeral_cost = 0, byte_count = 0; /* State */
|
unsigned int numeral_end = 0, numeral_cost = 0, byte_count = 0; /* State */
|
||||||
int double_byte, space, numeric, lower, upper, control, double_digit, eol;
|
int double_byte, space, numeric, lower, upper, control, double_digit, eol;
|
||||||
|
|
||||||
int i, j, k, cm_i;
|
int i, j, k;
|
||||||
unsigned int min_cost;
|
unsigned int min_cost;
|
||||||
char cur_mode;
|
char cur_mode;
|
||||||
unsigned int prev_costs[GM_NUM_MODES];
|
unsigned int prev_costs[GM_NUM_MODES];
|
||||||
unsigned int cur_costs[GM_NUM_MODES];
|
unsigned int cur_costs[GM_NUM_MODES];
|
||||||
char *char_modes = (char *) z_alloca(length * GM_NUM_MODES);
|
char (*char_modes)[GM_NUM_MODES] = (char (*)[GM_NUM_MODES]) z_alloca(GM_NUM_MODES * length);
|
||||||
|
|
||||||
/* char_modes[i * GM_NUM_MODES + j] represents the mode to encode the code point at index i such that the final
|
/* char_modes[i][j] represents the mode to encode the code point at index i such that the final segment
|
||||||
* segment ends in mode_types[j] and the total number of bits is minimized over all possible choices */
|
ends in mode_types[j] and the total number of bits is minimized over all possible choices */
|
||||||
memset(char_modes, 0, length * GM_NUM_MODES);
|
memset(char_modes, 0, length * GM_NUM_MODES);
|
||||||
|
|
||||||
/* At the beginning of each iteration of the loop below, prev_costs[j] is the minimum number of 1/6 (1/XX_MULT)
|
/* At the beginning of each iteration of the loop below, prev_costs[j] is the minimum number of 1/6 (1/XX_MULT)
|
||||||
@ -172,7 +172,7 @@ static void gm_define_mode(char *mode, const unsigned int ddata[], const int len
|
|||||||
memcpy(prev_costs, head_costs, GM_NUM_MODES * sizeof(unsigned int));
|
memcpy(prev_costs, head_costs, GM_NUM_MODES * sizeof(unsigned int));
|
||||||
|
|
||||||
/* Calculate costs using dynamic programming */
|
/* Calculate costs using dynamic programming */
|
||||||
for (i = 0, cm_i = 0; i < length; i++, cm_i += GM_NUM_MODES) {
|
for (i = 0; i < length; i++) {
|
||||||
memset(cur_costs, 0, GM_NUM_MODES * sizeof(unsigned int));
|
memset(cur_costs, 0, GM_NUM_MODES * sizeof(unsigned int));
|
||||||
|
|
||||||
space = numeric = lower = upper = control = double_digit = eol = 0;
|
space = numeric = lower = upper = control = double_digit = eol = 0;
|
||||||
@ -201,7 +201,7 @@ static void gm_define_mode(char *mode, const unsigned int ddata[], const int len
|
|||||||
|
|
||||||
/* Hanzi mode can encode anything */
|
/* Hanzi mode can encode anything */
|
||||||
cur_costs[GM_H] = prev_costs[GM_H] + (double_digit || eol ? 39 : 78); /* (6.5 : 13) * GM_MULT */
|
cur_costs[GM_H] = prev_costs[GM_H] + (double_digit || eol ? 39 : 78); /* (6.5 : 13) * GM_MULT */
|
||||||
char_modes[cm_i + GM_H] = GM_CHINESE;
|
char_modes[i][GM_H] = GM_CHINESE;
|
||||||
|
|
||||||
/* Byte mode can encode anything */
|
/* Byte mode can encode anything */
|
||||||
if (byte_count == 512 || (double_byte && byte_count == 511)) {
|
if (byte_count == 512 || (double_byte && byte_count == 511)) {
|
||||||
@ -213,39 +213,39 @@ static void gm_define_mode(char *mode, const unsigned int ddata[], const int len
|
|||||||
byte_count = 0;
|
byte_count = 0;
|
||||||
}
|
}
|
||||||
cur_costs[GM_B] += prev_costs[GM_B] + (double_byte ? 96 : 48); /* (16 : 8) * GM_MULT */
|
cur_costs[GM_B] += prev_costs[GM_B] + (double_byte ? 96 : 48); /* (16 : 8) * GM_MULT */
|
||||||
char_modes[cm_i + GM_B] = GM_BYTE;
|
char_modes[i][GM_B] = GM_BYTE;
|
||||||
byte_count += double_byte ? 2 : 1;
|
byte_count += double_byte ? 2 : 1;
|
||||||
|
|
||||||
if (gm_in_numeral(ddata, length, i, &numeral_end, &numeral_cost)) {
|
if (gm_in_numeral(ddata, length, i, &numeral_end, &numeral_cost)) {
|
||||||
cur_costs[GM_N] = prev_costs[GM_N] + numeral_cost;
|
cur_costs[GM_N] = prev_costs[GM_N] + numeral_cost;
|
||||||
char_modes[cm_i + GM_N] = GM_NUMBER;
|
char_modes[i][GM_N] = GM_NUMBER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (control) {
|
if (control) {
|
||||||
cur_costs[GM_L] = prev_costs[GM_L] + 78; /* (7 + 6) * GM_MULT */
|
cur_costs[GM_L] = prev_costs[GM_L] + 78; /* (7 + 6) * GM_MULT */
|
||||||
char_modes[cm_i + GM_L] = GM_LOWER;
|
char_modes[i][GM_L] = GM_LOWER;
|
||||||
cur_costs[GM_U] = prev_costs[GM_U] + 78; /* (7 + 6) * GM_MULT */
|
cur_costs[GM_U] = prev_costs[GM_U] + 78; /* (7 + 6) * GM_MULT */
|
||||||
char_modes[cm_i + GM_U] = GM_UPPER;
|
char_modes[i][GM_U] = GM_UPPER;
|
||||||
cur_costs[GM_M] = prev_costs[GM_M] + 96; /* (10 + 6) * GM_MULT */
|
cur_costs[GM_M] = prev_costs[GM_M] + 96; /* (10 + 6) * GM_MULT */
|
||||||
char_modes[cm_i + GM_M] = GM_MIXED;
|
char_modes[i][GM_M] = GM_MIXED;
|
||||||
} else {
|
} else {
|
||||||
if (lower || space) {
|
if (lower || space) {
|
||||||
cur_costs[GM_L] = prev_costs[GM_L] + 30; /* 5 * GM_MULT */
|
cur_costs[GM_L] = prev_costs[GM_L] + 30; /* 5 * GM_MULT */
|
||||||
char_modes[cm_i + GM_L] = GM_LOWER;
|
char_modes[i][GM_L] = GM_LOWER;
|
||||||
}
|
}
|
||||||
if (upper || space) {
|
if (upper || space) {
|
||||||
cur_costs[GM_U] = prev_costs[GM_U] + 30; /* 5 * GM_MULT */
|
cur_costs[GM_U] = prev_costs[GM_U] + 30; /* 5 * GM_MULT */
|
||||||
char_modes[cm_i + GM_U] = GM_UPPER;
|
char_modes[i][GM_U] = GM_UPPER;
|
||||||
}
|
}
|
||||||
if (numeric || lower || upper || space) {
|
if (numeric || lower || upper || space) {
|
||||||
cur_costs[GM_M] = prev_costs[GM_M] + 36; /* 6 * GM_MULT */
|
cur_costs[GM_M] = prev_costs[GM_M] + 36; /* 6 * GM_MULT */
|
||||||
char_modes[cm_i + GM_M] = GM_MIXED;
|
char_modes[i][GM_M] = GM_MIXED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == length - 1) { /* Add end of data costs if last character */
|
if (i == length - 1) { /* Add end of data costs if last character */
|
||||||
for (j = 0; j < GM_NUM_MODES; j++) {
|
for (j = 0; j < GM_NUM_MODES; j++) {
|
||||||
if (char_modes[cm_i + j]) {
|
if (char_modes[i][j]) {
|
||||||
cur_costs[j] += eod_costs[j];
|
cur_costs[j] += eod_costs[j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -254,11 +254,11 @@ static void gm_define_mode(char *mode, const unsigned int ddata[], const int len
|
|||||||
/* Start new segment at the end to switch modes */
|
/* Start new segment at the end to switch modes */
|
||||||
for (j = 0; j < GM_NUM_MODES; j++) { /* To mode */
|
for (j = 0; j < GM_NUM_MODES; j++) { /* To mode */
|
||||||
for (k = 0; k < GM_NUM_MODES; k++) { /* From mode */
|
for (k = 0; k < GM_NUM_MODES; k++) { /* From mode */
|
||||||
if (j != k && char_modes[cm_i + k]) {
|
if (j != k && char_modes[i][k]) {
|
||||||
const unsigned int new_cost = cur_costs[k] + switch_costs[k][j];
|
const unsigned int new_cost = cur_costs[k] + switch_costs[k][j];
|
||||||
if (!char_modes[cm_i + j] || new_cost < cur_costs[j]) {
|
if (!char_modes[i][j] || new_cost < cur_costs[j]) {
|
||||||
cur_costs[j] = new_cost;
|
cur_costs[j] = new_cost;
|
||||||
char_modes[cm_i + j] = mode_types[k];
|
char_modes[i][j] = mode_types[k];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -278,9 +278,9 @@ static void gm_define_mode(char *mode, const unsigned int ddata[], const int len
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Get optimal mode for each code point by tracing backwards */
|
/* Get optimal mode for each code point by tracing backwards */
|
||||||
for (i = length - 1, cm_i = i * GM_NUM_MODES; i >= 0; i--, cm_i -= GM_NUM_MODES) {
|
for (i = length - 1; i >= 0; i--) {
|
||||||
j = posn(mode_types, cur_mode);
|
j = posn(mode_types, cur_mode);
|
||||||
cur_mode = char_modes[cm_i + j];
|
cur_mode = char_modes[i][j];
|
||||||
mode[i] = cur_mode;
|
mode[i] = cur_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* hanxin.c - Han Xin Code */
|
/* hanxin.c - Han Xin Code */
|
||||||
/*
|
/*
|
||||||
libzint - the open source barcode library
|
libzint - the open source barcode library
|
||||||
Copyright (C) 2009-2023 Robin Stuart <rstuart114@gmail.com>
|
Copyright (C) 2009-2024 Robin Stuart <rstuart114@gmail.com>
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions
|
modification, are permitted provided that the following conditions
|
||||||
@ -384,28 +384,28 @@ static void hx_define_mode(char *mode, const unsigned int ddata[], const int len
|
|||||||
unsigned int numeric_end = 0, numeric_cost = 0, text_submode = 1, fourbyte_end = 0, fourbyte_cost = 0; /* State */
|
unsigned int numeric_end = 0, numeric_cost = 0, text_submode = 1, fourbyte_end = 0, fourbyte_cost = 0; /* State */
|
||||||
int text1, text2;
|
int text1, text2;
|
||||||
|
|
||||||
int i, j, k, cm_i;
|
int i, j, k;
|
||||||
unsigned int min_cost;
|
unsigned int min_cost;
|
||||||
char cur_mode;
|
char cur_mode;
|
||||||
unsigned int prev_costs[HX_NUM_MODES];
|
unsigned int prev_costs[HX_NUM_MODES];
|
||||||
unsigned int cur_costs[HX_NUM_MODES];
|
unsigned int cur_costs[HX_NUM_MODES];
|
||||||
char *char_modes = (char *) z_alloca(length * HX_NUM_MODES);
|
char (*char_modes)[HX_NUM_MODES] = (char (*)[HX_NUM_MODES]) z_alloca(HX_NUM_MODES * length);
|
||||||
|
|
||||||
/* char_modes[i * HX_NUM_MODES + j] represents the mode to encode the code point at index i such that the final
|
/* char_modes[i][j] represents the mode to encode the code point at index i such that the final segment
|
||||||
* segment ends in mode_types[j] and the total number of bits is minimized over all possible choices */
|
ends in mode_types[j] and the total number of bits is minimized over all possible choices */
|
||||||
memset(char_modes, 0, length * HX_NUM_MODES);
|
memset(char_modes, 0, HX_NUM_MODES * length);
|
||||||
|
|
||||||
/* At the beginning of each iteration of the loop below, prev_costs[j] is the minimum number of 1/6 (1/XX_MULT)
|
/* At the beginning of each iteration of the loop below, prev_costs[j] is the minimum number of 1/6 (1/XX_MULT)
|
||||||
* bits needed to encode the entire string prefix of length i, and end in mode_types[j] */
|
* bits needed to encode the entire string prefix of length i, and end in mode_types[j] */
|
||||||
memcpy(prev_costs, head_costs, HX_NUM_MODES * sizeof(unsigned int));
|
memcpy(prev_costs, head_costs, HX_NUM_MODES * sizeof(unsigned int));
|
||||||
|
|
||||||
/* Calculate costs using dynamic programming */
|
/* Calculate costs using dynamic programming */
|
||||||
for (i = 0, cm_i = 0; i < length; i++, cm_i += HX_NUM_MODES) {
|
for (i = 0; i < length; i++) {
|
||||||
memset(cur_costs, 0, HX_NUM_MODES * sizeof(unsigned int));
|
memset(cur_costs, 0, HX_NUM_MODES * sizeof(unsigned int));
|
||||||
|
|
||||||
if (hx_in_numeric(ddata, length, i, &numeric_end, &numeric_cost)) {
|
if (hx_in_numeric(ddata, length, i, &numeric_end, &numeric_cost)) {
|
||||||
cur_costs[HX_N] = prev_costs[HX_N] + numeric_cost;
|
cur_costs[HX_N] = prev_costs[HX_N] + numeric_cost;
|
||||||
char_modes[cm_i + HX_N] = 'n';
|
char_modes[i][HX_N] = 'n';
|
||||||
text1 = 1;
|
text1 = 1;
|
||||||
text2 = 0;
|
text2 = 0;
|
||||||
} else {
|
} else {
|
||||||
@ -420,35 +420,35 @@ static void hx_define_mode(char *mode, const unsigned int ddata[], const int len
|
|||||||
} else {
|
} else {
|
||||||
cur_costs[HX_T] = prev_costs[HX_T] + 36; /* 6 * HX_MULT */
|
cur_costs[HX_T] = prev_costs[HX_T] + 36; /* 6 * HX_MULT */
|
||||||
}
|
}
|
||||||
char_modes[cm_i + HX_T] = 't';
|
char_modes[i][HX_T] = 't';
|
||||||
} else {
|
} else {
|
||||||
text_submode = 1;
|
text_submode = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Binary mode can encode anything */
|
/* Binary mode can encode anything */
|
||||||
cur_costs[HX_B] = prev_costs[HX_B] + (ddata[i] > 0xFF ? 96 : 48); /* (16 : 8) * HX_MULT */
|
cur_costs[HX_B] = prev_costs[HX_B] + (ddata[i] > 0xFF ? 96 : 48); /* (16 : 8) * HX_MULT */
|
||||||
char_modes[cm_i + HX_B] = 'b';
|
char_modes[i][HX_B] = 'b';
|
||||||
|
|
||||||
if (hx_in_fourbyte(ddata, length, i, &fourbyte_end, &fourbyte_cost)) {
|
if (hx_in_fourbyte(ddata, length, i, &fourbyte_end, &fourbyte_cost)) {
|
||||||
cur_costs[HX_F] = prev_costs[HX_F] + fourbyte_cost;
|
cur_costs[HX_F] = prev_costs[HX_F] + fourbyte_cost;
|
||||||
char_modes[cm_i + HX_F] = 'f';
|
char_modes[i][HX_F] = 'f';
|
||||||
} else {
|
} else {
|
||||||
if (hx_isDoubleByte(ddata[i])) {
|
if (hx_isDoubleByte(ddata[i])) {
|
||||||
cur_costs[HX_D] = prev_costs[HX_D] + 90; /* 15 * HX_MULT */
|
cur_costs[HX_D] = prev_costs[HX_D] + 90; /* 15 * HX_MULT */
|
||||||
char_modes[cm_i + HX_D] = 'd';
|
char_modes[i][HX_D] = 'd';
|
||||||
if (hx_isRegion1(ddata[i])) { /* Subset */
|
if (hx_isRegion1(ddata[i])) { /* Subset */
|
||||||
cur_costs[HX_1] = prev_costs[HX_1] + 72; /* 12 * HX_MULT */
|
cur_costs[HX_1] = prev_costs[HX_1] + 72; /* 12 * HX_MULT */
|
||||||
char_modes[cm_i + HX_1] = '1';
|
char_modes[i][HX_1] = '1';
|
||||||
} else if (hx_isRegion2(ddata[i])) { /* Subset */
|
} else if (hx_isRegion2(ddata[i])) { /* Subset */
|
||||||
cur_costs[HX_2] = prev_costs[HX_2] + 72; /* 12 * HX_MULT */
|
cur_costs[HX_2] = prev_costs[HX_2] + 72; /* 12 * HX_MULT */
|
||||||
char_modes[cm_i + HX_2] = '2';
|
char_modes[i][HX_2] = '2';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == length - 1) { /* Add end of data costs if last character */
|
if (i == length - 1) { /* Add end of data costs if last character */
|
||||||
for (j = 0; j < HX_NUM_MODES; j++) {
|
for (j = 0; j < HX_NUM_MODES; j++) {
|
||||||
if (char_modes[cm_i + j]) {
|
if (char_modes[i][j]) {
|
||||||
cur_costs[j] += eod_costs[j];
|
cur_costs[j] += eod_costs[j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -457,11 +457,11 @@ static void hx_define_mode(char *mode, const unsigned int ddata[], const int len
|
|||||||
/* Start new segment at the end to switch modes */
|
/* Start new segment at the end to switch modes */
|
||||||
for (j = 0; j < HX_NUM_MODES; j++) { /* To mode */
|
for (j = 0; j < HX_NUM_MODES; j++) { /* To mode */
|
||||||
for (k = 0; k < HX_NUM_MODES; k++) { /* From mode */
|
for (k = 0; k < HX_NUM_MODES; k++) { /* From mode */
|
||||||
if (j != k && char_modes[cm_i + k]) {
|
if (j != k && char_modes[i][k]) {
|
||||||
const unsigned int new_cost = cur_costs[k] + switch_costs[k][j];
|
const unsigned int new_cost = cur_costs[k] + switch_costs[k][j];
|
||||||
if (!char_modes[cm_i + j] || new_cost < cur_costs[j]) {
|
if (!char_modes[i][j] || new_cost < cur_costs[j]) {
|
||||||
cur_costs[j] = new_cost;
|
cur_costs[j] = new_cost;
|
||||||
char_modes[cm_i + j] = mode_types[k];
|
char_modes[i][j] = mode_types[k];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -481,9 +481,9 @@ static void hx_define_mode(char *mode, const unsigned int ddata[], const int len
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Get optimal mode for each code point by tracing backwards */
|
/* Get optimal mode for each code point by tracing backwards */
|
||||||
for (i = length - 1, cm_i = i * HX_NUM_MODES; i >= 0; i--, cm_i -= HX_NUM_MODES) {
|
for (i = length - 1; i >= 0; i--) {
|
||||||
j = posn(mode_types, cur_mode);
|
j = posn(mode_types, cur_mode);
|
||||||
cur_mode = char_modes[cm_i + j];
|
cur_mode = char_modes[i][j];
|
||||||
mode[i] = cur_mode;
|
mode[i] = cur_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -568,16 +568,15 @@ static int has_hrt(const int symbology) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Suppress warning ISO C forbids initialization between function pointer and ‘void *’ */
|
/* Suppress clang warning: a function declaration without a prototype is deprecated in all versions of C
|
||||||
#if defined(__GNUC__) || defined(__clang__)
|
(not included in gcc's "-wpedantic") */
|
||||||
|
#if defined(__clang__)
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#pragma GCC diagnostic ignored "-Wpedantic"
|
#pragma GCC diagnostic ignored "-Wstrict-prototypes"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Used for dispatching barcodes and for whether symbol id valid */
|
/* Used for dispatching barcodes and for whether symbol id valid */
|
||||||
typedef int (*barcode_segs_func_t)(struct zint_symbol *, struct zint_seg[], const int);
|
static int (*const barcode_funcs[BARCODE_LAST + 1])() = {
|
||||||
typedef int (*barcode_func_t)(struct zint_symbol *, unsigned char[], int);
|
|
||||||
static const void *barcode_funcs[BARCODE_LAST + 1] = {
|
|
||||||
NULL, code11, c25standard, c25inter, c25iata, /*0-4*/
|
NULL, code11, c25standard, c25inter, c25iata, /*0-4*/
|
||||||
NULL, c25logic, c25ind, code39, excode39, /*5-9*/
|
NULL, c25logic, c25ind, code39, excode39, /*5-9*/
|
||||||
NULL, NULL, NULL, eanx, eanx, /*10-14*/
|
NULL, NULL, NULL, eanx, eanx, /*10-14*/
|
||||||
@ -610,6 +609,12 @@ static const void *barcode_funcs[BARCODE_LAST + 1] = {
|
|||||||
rmqr, bc412,
|
rmqr, bc412,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if defined(__clang__)
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef int (*barcode_segs_func_t)(struct zint_symbol *, struct zint_seg[], const int);
|
||||||
|
typedef int (*barcode_func_t)(struct zint_symbol *, unsigned char[], int);
|
||||||
static int reduced_charset(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count);
|
static int reduced_charset(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count);
|
||||||
|
|
||||||
/* Main dispatch, checking for barcodes which handle ECIs/character sets themselves, otherwise calling
|
/* Main dispatch, checking for barcodes which handle ECIs/character sets themselves, otherwise calling
|
||||||
@ -688,10 +693,6 @@ static int reduced_charset(struct zint_symbol *symbol, struct zint_seg segs[], c
|
|||||||
return error_number;
|
return error_number;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__GNUC__) || defined(__clang__)
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Remove Unicode BOM at start of data */
|
/* Remove Unicode BOM at start of data */
|
||||||
static void strip_bom(unsigned char *source, int *input_length) {
|
static void strip_bom(unsigned char *source, int *input_length) {
|
||||||
int i;
|
int i;
|
||||||
|
40
backend/qr.c
40
backend/qr.c
@ -1,7 +1,7 @@
|
|||||||
/* qr.c Handles QR Code, Micro QR Code, UPNQR and rMQR */
|
/* qr.c Handles QR Code, Micro QR Code, UPNQR and rMQR */
|
||||||
/*
|
/*
|
||||||
libzint - the open source barcode library
|
libzint - the open source barcode library
|
||||||
Copyright (C) 2009-2023 Robin Stuart <rstuart114@gmail.com>
|
Copyright (C) 2009-2024 Robin Stuart <rstuart114@gmail.com>
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions
|
modification, are permitted provided that the following conditions
|
||||||
@ -237,18 +237,18 @@ static void qr_define_mode(char mode[], const unsigned int ddata[], const int le
|
|||||||
};
|
};
|
||||||
int m1, m2;
|
int m1, m2;
|
||||||
|
|
||||||
int i, j, k, cm_i;
|
int i, j, k;
|
||||||
unsigned int min_cost;
|
unsigned int min_cost;
|
||||||
char cur_mode;
|
char cur_mode;
|
||||||
unsigned int prev_costs[QR_NUM_MODES];
|
unsigned int prev_costs[QR_NUM_MODES];
|
||||||
unsigned int cur_costs[QR_NUM_MODES];
|
unsigned int cur_costs[QR_NUM_MODES];
|
||||||
char *char_modes = (char *) z_alloca(length * QR_NUM_MODES);
|
char (*char_modes)[QR_NUM_MODES] = (char (*)[QR_NUM_MODES]) z_alloca(QR_NUM_MODES * length);
|
||||||
|
|
||||||
state[QR_VER] = (unsigned int) version;
|
state[QR_VER] = (unsigned int) version;
|
||||||
|
|
||||||
/* char_modes[i * QR_NUM_MODES + j] represents the mode to encode the code point at index i such that the final
|
/* char_modes[i][j] represents the mode to encode the code point at index i such that the final segment
|
||||||
* segment ends in qr_mode_types[j] and the total number of bits is minimized over all possible choices */
|
ends in qr_mode_types[j] and the total number of bits is minimized over all possible choices */
|
||||||
memset(char_modes, 0, length * QR_NUM_MODES);
|
memset(char_modes, 0, QR_NUM_MODES * length);
|
||||||
|
|
||||||
/* At the beginning of each iteration of the loop below, prev_costs[j] is the minimum number of 1/6 (1/QR_MULT)
|
/* At the beginning of each iteration of the loop below, prev_costs[j] is the minimum number of 1/6 (1/QR_MULT)
|
||||||
* bits needed to encode the entire string prefix of length i, and end in qr_mode_types[j] */
|
* bits needed to encode the entire string prefix of length i, and end in qr_mode_types[j] */
|
||||||
@ -257,13 +257,13 @@ static void qr_define_mode(char mode[], const unsigned int ddata[], const int le
|
|||||||
#ifdef QR_DEBUG_DEFINE_MODE
|
#ifdef QR_DEBUG_DEFINE_MODE
|
||||||
printf(" head");
|
printf(" head");
|
||||||
for (j = 0; j < QR_NUM_MODES; j++) {
|
for (j = 0; j < QR_NUM_MODES; j++) {
|
||||||
printf(" %c(%c)=%d", qr_mode_types[j], char_modes[j], prev_costs[j]);
|
printf(" %c(%c)=%d", qr_mode_types[j], char_modes[0][j], prev_costs[j]);
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Calculate costs using dynamic programming */
|
/* Calculate costs using dynamic programming */
|
||||||
for (i = 0, cm_i = 0; i < length; i++, cm_i += QR_NUM_MODES) {
|
for (i = 0; i < length; i++) {
|
||||||
memset(cur_costs, 0, QR_NUM_MODES * sizeof(unsigned int));
|
memset(cur_costs, 0, QR_NUM_MODES * sizeof(unsigned int));
|
||||||
|
|
||||||
m1 = version == MICROQR_VERSION;
|
m1 = version == MICROQR_VERSION;
|
||||||
@ -271,31 +271,31 @@ static void qr_define_mode(char mode[], const unsigned int ddata[], const int le
|
|||||||
|
|
||||||
if (ddata[i] > 0xFF) {
|
if (ddata[i] > 0xFF) {
|
||||||
cur_costs[QR_B] = prev_costs[QR_B] + ((m1 || m2) ? QR_MICROQR_MAX : 96); /* 16 * QR_MULT */
|
cur_costs[QR_B] = prev_costs[QR_B] + ((m1 || m2) ? QR_MICROQR_MAX : 96); /* 16 * QR_MULT */
|
||||||
char_modes[cm_i + QR_B] = 'B';
|
char_modes[i][QR_B] = 'B';
|
||||||
cur_costs[QR_K] = prev_costs[QR_K] + ((m1 || m2) ? QR_MICROQR_MAX : 78); /* 13 * QR_MULT */
|
cur_costs[QR_K] = prev_costs[QR_K] + ((m1 || m2) ? QR_MICROQR_MAX : 78); /* 13 * QR_MULT */
|
||||||
char_modes[cm_i + QR_K] = 'K';
|
char_modes[i][QR_K] = 'K';
|
||||||
} else {
|
} else {
|
||||||
if (qr_in_numeric(ddata, length, i, &state[QR_N_END], &state[QR_N_COST])) {
|
if (qr_in_numeric(ddata, length, i, &state[QR_N_END], &state[QR_N_COST])) {
|
||||||
cur_costs[QR_N] = prev_costs[QR_N] + state[QR_N_COST];
|
cur_costs[QR_N] = prev_costs[QR_N] + state[QR_N_COST];
|
||||||
char_modes[cm_i + QR_N] = 'N';
|
char_modes[i][QR_N] = 'N';
|
||||||
}
|
}
|
||||||
if (qr_in_alpha(ddata, length, i, &state[QR_A_END], &state[QR_A_COST], &state[QR_A_PCENT],
|
if (qr_in_alpha(ddata, length, i, &state[QR_A_END], &state[QR_A_COST], &state[QR_A_PCENT],
|
||||||
&state[QR_A_PCCNT], gs1)) {
|
&state[QR_A_PCCNT], gs1)) {
|
||||||
cur_costs[QR_A] = prev_costs[QR_A] + (m1 ? QR_MICROQR_MAX : state[QR_A_COST]);
|
cur_costs[QR_A] = prev_costs[QR_A] + (m1 ? QR_MICROQR_MAX : state[QR_A_COST]);
|
||||||
char_modes[cm_i + QR_A] = 'A';
|
char_modes[i][QR_A] = 'A';
|
||||||
}
|
}
|
||||||
cur_costs[QR_B] = prev_costs[QR_B] + ((m1 || m2) ? QR_MICROQR_MAX : 48); /* 8 * QR_MULT */
|
cur_costs[QR_B] = prev_costs[QR_B] + ((m1 || m2) ? QR_MICROQR_MAX : 48); /* 8 * QR_MULT */
|
||||||
char_modes[cm_i + QR_B] = 'B';
|
char_modes[i][QR_B] = 'B';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Start new segment at the end to switch modes */
|
/* Start new segment at the end to switch modes */
|
||||||
for (j = 0; j < QR_NUM_MODES; j++) { /* To mode */
|
for (j = 0; j < QR_NUM_MODES; j++) { /* To mode */
|
||||||
for (k = 0; k < QR_NUM_MODES; k++) { /* From mode */
|
for (k = 0; k < QR_NUM_MODES; k++) { /* From mode */
|
||||||
if (j != k && char_modes[cm_i + k]) {
|
if (j != k && char_modes[i][k]) {
|
||||||
const unsigned int new_cost = cur_costs[k] + state[j]; /* Switch costs same as head costs */
|
const unsigned int new_cost = cur_costs[k] + state[j]; /* Switch costs same as head costs */
|
||||||
if (!char_modes[cm_i + j] || new_cost < cur_costs[j]) {
|
if (!char_modes[i][j] || new_cost < cur_costs[j]) {
|
||||||
cur_costs[j] = new_cost;
|
cur_costs[j] = new_cost;
|
||||||
char_modes[cm_i + j] = qr_mode_types[k];
|
char_modes[i][j] = qr_mode_types[k];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -306,10 +306,10 @@ static void qr_define_mode(char mode[], const unsigned int ddata[], const int le
|
|||||||
int min_j = 0;
|
int min_j = 0;
|
||||||
printf(" % 4d: curr", i);
|
printf(" % 4d: curr", i);
|
||||||
for (j = 0; j < QR_NUM_MODES; j++) {
|
for (j = 0; j < QR_NUM_MODES; j++) {
|
||||||
printf(" %c(%c)=%d", qr_mode_types[j], char_modes[cm_i + j], cur_costs[j]);
|
printf(" %c(%c)=%d", qr_mode_types[j], char_modes[i][j], cur_costs[j]);
|
||||||
if (cur_costs[j] < cur_costs[min_j]) min_j = j;
|
if (cur_costs[j] < cur_costs[min_j]) min_j = j;
|
||||||
}
|
}
|
||||||
printf(" min %c(%c)=%d\n", qr_mode_types[min_j], char_modes[cm_i + min_j], cur_costs[min_j]);
|
printf(" min %c(%c)=%d\n", qr_mode_types[min_j], char_modes[i][min_j], cur_costs[min_j]);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
memcpy(prev_costs, cur_costs, QR_NUM_MODES * sizeof(unsigned int));
|
memcpy(prev_costs, cur_costs, QR_NUM_MODES * sizeof(unsigned int));
|
||||||
@ -326,9 +326,9 @@ static void qr_define_mode(char mode[], const unsigned int ddata[], const int le
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Get optimal mode for each code point by tracing backwards */
|
/* Get optimal mode for each code point by tracing backwards */
|
||||||
for (i = length - 1, cm_i = i * QR_NUM_MODES; i >= 0; i--, cm_i -= QR_NUM_MODES) {
|
for (i = length - 1; i >= 0; i--) {
|
||||||
j = posn(qr_mode_types, cur_mode);
|
j = posn(qr_mode_types, cur_mode);
|
||||||
cur_mode = char_modes[cm_i + j];
|
cur_mode = char_modes[i][j];
|
||||||
mode[i] = cur_mode;
|
mode[i] = cur_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
libzint - the open source barcode library
|
libzint - the open source barcode library
|
||||||
Copyright (C) 2023 Robin Stuart <rstuart114@gmail.com>
|
Copyright (C) 2023-2024 Robin Stuart <rstuart114@gmail.com>
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions
|
modification, are permitted provided that the following conditions
|
||||||
@ -109,7 +109,11 @@ static void test_svg(const testCtx *const p_ctx) {
|
|||||||
testFinish();
|
testFinish();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _WIN32
|
#if defined(_WIN32) || (defined(__sun) && defined(__SVR4))
|
||||||
|
#define ZINT_TEST_NO_FMEMOPEN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ZINT_TEST_NO_FMEMOPEN
|
||||||
extern FILE *fmemopen(void *buf, size_t size, const char *mode);
|
extern FILE *fmemopen(void *buf, size_t size, const char *mode);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -145,7 +149,7 @@ static void test_putsf(const testCtx *const p_ctx) {
|
|||||||
struct zint_symbol *const symbol = &symbol_data;
|
struct zint_symbol *const symbol = &symbol_data;
|
||||||
struct filemem fm;
|
struct filemem fm;
|
||||||
struct filemem *const fmp = &fm;
|
struct filemem *const fmp = &fm;
|
||||||
#ifndef _WIN32
|
#ifndef ZINT_TEST_NO_FMEMOPEN
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char buf[512] = {0}; /* Suppress clang-16/17 run-time exception MemorySanitizer: use-of-uninitialized-value */
|
char buf[512] = {0}; /* Suppress clang-16/17 run-time exception MemorySanitizer: use-of-uninitialized-value */
|
||||||
#endif
|
#endif
|
||||||
@ -153,8 +157,8 @@ static void test_putsf(const testCtx *const p_ctx) {
|
|||||||
testStart("test_putsf");
|
testStart("test_putsf");
|
||||||
|
|
||||||
for (j = 0; j < 2; j++) { /* 1st `memfile`, then file */
|
for (j = 0; j < 2; j++) { /* 1st `memfile`, then file */
|
||||||
#ifdef _WIN32
|
#ifdef ZINT_TEST_NO_FMEMOPEN
|
||||||
if (j == 1) break; /* Skip file test on Windows */
|
if (j == 1) break; /* Skip file test on Windows/Solaris */
|
||||||
#endif
|
#endif
|
||||||
for (i = 0; i < data_size; i++) {
|
for (i = 0; i < data_size; i++) {
|
||||||
const char *locale = NULL;
|
const char *locale = NULL;
|
||||||
@ -164,7 +168,7 @@ static void test_putsf(const testCtx *const p_ctx) {
|
|||||||
|
|
||||||
ZBarcode_Reset(symbol);
|
ZBarcode_Reset(symbol);
|
||||||
if (j == 1) {
|
if (j == 1) {
|
||||||
#ifndef _WIN32
|
#ifndef ZINT_TEST_NO_FMEMOPEN
|
||||||
buf[0] = '\0';
|
buf[0] = '\0';
|
||||||
fp = fmemopen(buf, sizeof(buf), "w");
|
fp = fmemopen(buf, sizeof(buf), "w");
|
||||||
assert_nonnull(fp, "%d: fmemopen fail (%d, %s)\n", i, errno, strerror(errno));
|
assert_nonnull(fp, "%d: fmemopen fail (%d, %s)\n", i, errno, strerror(errno));
|
||||||
@ -174,7 +178,7 @@ static void test_putsf(const testCtx *const p_ctx) {
|
|||||||
}
|
}
|
||||||
assert_nonzero(fm_open(fmp, symbol, "w"), "i:%d: fm_open fail (%d, %s)\n", i, fmp->err, strerror(fmp->err));
|
assert_nonzero(fm_open(fmp, symbol, "w"), "i:%d: fm_open fail (%d, %s)\n", i, fmp->err, strerror(fmp->err));
|
||||||
if (j == 1) {
|
if (j == 1) {
|
||||||
#ifndef _WIN32
|
#ifndef ZINT_TEST_NO_FMEMOPEN
|
||||||
/* Hack in `fmemopen()` fp */
|
/* Hack in `fmemopen()` fp */
|
||||||
assert_zero(fclose(fmp->fp), "i:%d fclose(fmp->fp) fail (%d, %s)\n", i, errno, strerror(errno));
|
assert_zero(fclose(fmp->fp), "i:%d fclose(fmp->fp) fail (%d, %s)\n", i, errno, strerror(errno));
|
||||||
fmp->fp = fp;
|
fmp->fp = fp;
|
||||||
@ -200,7 +204,7 @@ static void test_putsf(const testCtx *const p_ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (j == 1) {
|
if (j == 1) {
|
||||||
#ifndef _WIN32
|
#ifndef ZINT_TEST_NO_FMEMOPEN
|
||||||
assert_zero(strcmp(buf, data[i].expected), "%d: strcmp(%s, %s) != 0\n", i, buf, data[i].expected);
|
assert_zero(strcmp(buf, data[i].expected), "%d: strcmp(%s, %s) != 0\n", i, buf, data[i].expected);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
@ -1685,7 +1685,11 @@ int testUtilCmpPngs(const char *png1, const char *png2) {
|
|||||||
color_type1 = png_get_color_type(png_ptr1, info_ptr1);
|
color_type1 = png_get_color_type(png_ptr1, info_ptr1);
|
||||||
bit_depth1 = png_get_bit_depth(png_ptr1, info_ptr1);
|
bit_depth1 = png_get_bit_depth(png_ptr1, info_ptr1);
|
||||||
if (bit_depth1 == 16) {
|
if (bit_depth1 == 16) {
|
||||||
|
#if defined(PNG_LIBPNG_VER) && PNG_LIBPNG_VER >= 10504
|
||||||
png_set_scale_16(png_ptr1);
|
png_set_scale_16(png_ptr1);
|
||||||
|
#else
|
||||||
|
png_set_strip_16(png_ptr1);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
if (color_type1 == PNG_COLOR_TYPE_PALETTE) {
|
if (color_type1 == PNG_COLOR_TYPE_PALETTE) {
|
||||||
png_set_palette_to_rgb(png_ptr1);
|
png_set_palette_to_rgb(png_ptr1);
|
||||||
@ -1707,7 +1711,11 @@ int testUtilCmpPngs(const char *png1, const char *png2) {
|
|||||||
color_type2 = png_get_color_type(png_ptr2, info_ptr2);
|
color_type2 = png_get_color_type(png_ptr2, info_ptr2);
|
||||||
bit_depth2 = png_get_bit_depth(png_ptr2, info_ptr2);
|
bit_depth2 = png_get_bit_depth(png_ptr2, info_ptr2);
|
||||||
if (bit_depth2 == 16) {
|
if (bit_depth2 == 16) {
|
||||||
|
#if defined(PNG_LIBPNG_VER) && PNG_LIBPNG_VER >= 10504
|
||||||
png_set_scale_16(png_ptr2);
|
png_set_scale_16(png_ptr2);
|
||||||
|
#else
|
||||||
|
png_set_strip_16(png_ptr2);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
if (color_type2 == PNG_COLOR_TYPE_PALETTE) {
|
if (color_type2 == PNG_COLOR_TYPE_PALETTE) {
|
||||||
png_set_palette_to_rgb(png_ptr2);
|
png_set_palette_to_rgb(png_ptr2);
|
||||||
@ -4036,7 +4044,9 @@ int testUtilZXingCPPCmp(struct zint_symbol *symbol, char *msg, char *cmp_buf, in
|
|||||||
expected_len += maxi_len;
|
expected_len += maxi_len;
|
||||||
}
|
}
|
||||||
} else if (symbology == BARCODE_CODABAR) {
|
} else if (symbology == BARCODE_CODABAR) {
|
||||||
/* Start A/B/C/D and stop A/B/C/D chars not returned by ZXing-C++ */
|
/* Ignore start A/B/C/D and stop A/B/C/D chars to avoid upper/lowercase issues */
|
||||||
|
cmp_buf++;
|
||||||
|
cmp_len -= 2;
|
||||||
expected++;
|
expected++;
|
||||||
expected_len -= 2;
|
expected_len -= 2;
|
||||||
if (symbol->option_2 == 1 || symbol->option_2 == 2) {
|
if (symbol->option_2 == 1 || symbol->option_2 == 2) {
|
||||||
|
@ -65,7 +65,8 @@ typedef char static_assert_int_at_least_32bits[sizeof(int) * CHAR_BIT < 32 ? -1
|
|||||||
# include <malloc.h>
|
# include <malloc.h>
|
||||||
# define z_alloca(nmemb) _alloca(nmemb)
|
# define z_alloca(nmemb) _alloca(nmemb)
|
||||||
#else
|
#else
|
||||||
# if defined(ZINT_IS_C89) || defined(ZINT_IS_C99) || defined(__NuttX__) || defined(_AIX)
|
# if defined(ZINT_IS_C89) || defined(ZINT_IS_C99) || defined(__NuttX__) || defined(_AIX) \
|
||||||
|
|| (defined(__sun) && defined(__SVR4) /*Solaris*/)
|
||||||
# include <alloca.h>
|
# include <alloca.h>
|
||||||
# endif
|
# endif
|
||||||
# define z_alloca(nmemb) alloca(nmemb)
|
# define z_alloca(nmemb) alloca(nmemb)
|
||||||
|
Loading…
Reference in New Issue
Block a user