QRCODE: fix qr_in_alpha() uneven percent check to be gs1 only,

causing incorrect mode costings leading to version 40 `binlen`
  < lower version, triggering assert, ticket #300 (#15), props
  Andre Maute
This commit is contained in:
gitlost 2023-12-05 19:00:01 +00:00
parent ff992a4265
commit 885cf0610d
8 changed files with 39 additions and 29 deletions

View File

@ -109,7 +109,7 @@ static int qr_in_alpha(const unsigned int ddata[], const int length, const int i
*p_pcent = 0; *p_pcent = 0;
} else { } else {
/* As above, uneven percents means will fit in alpha pair */ /* As above, uneven percents means will fit in alpha pair */
*p_cost = !last || !(*p_pccnt & 1) ? 33 /* (11 / 2) * QR_MULT */ : 36 /* 6 * QR_MULT */; *p_cost = !last || (gs1 && !(*p_pccnt & 1)) ? 33 /* (11 / 2) * QR_MULT */ : 36 /* 6 * QR_MULT */;
} }
return 1; return 1;
} }
@ -136,11 +136,13 @@ static int qr_in_alpha(const unsigned int ddata[], const int length, const int i
*p_pcent = two_alphas && gs1 && ddata[in_posn + 1] == '%'; /* 2nd char is percent */ *p_pcent = two_alphas && gs1 && ddata[in_posn + 1] == '%'; /* 2nd char is percent */
*p_pccnt += *p_pcent; /* No-op unless `gs1` */ *p_pccnt += *p_pcent; /* No-op unless `gs1` */
/* Uneven percents means will fit in alpha pair */ /* Uneven percents means will fit in alpha pair */
*p_cost = two_alphas || !(*p_pccnt & 1) ? 33 /* (11 / 2) * QR_MULT */ : 36 /* 6 * QR_MULT */; *p_cost = two_alphas || (gs1 && !(*p_pccnt & 1)) ? 33 /* (11 / 2) * QR_MULT */ : 36 /* 6 * QR_MULT */;
return 1; return 1;
} }
/*#define QR_DEBUG_DEFINE_MODE*/ /* For debugging costings */ #if 0
#define QR_DEBUG_DEFINE_MODE /* For debugging costings */
#endif
/* Indexes into qr_mode_types array (and state array) */ /* Indexes into qr_mode_types array (and state array) */
#define QR_N 0 /* Numeric */ #define QR_N 0 /* Numeric */
@ -292,7 +294,7 @@ 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(" curr"); 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[cm_i + j], cur_costs[j]);
} }

View File

@ -5250,7 +5250,7 @@ static void test_microqr_optimize(const testCtx *const p_ctx) {
/* 5*/ { UNICODE_MODE, 1, 4, -1, "01a", 0, "43 30 31 61 00 00 EC 11 EC 11 EC 11 EC 11 EC 11", 1, 1, "B3" }, /* 5*/ { UNICODE_MODE, 1, 4, -1, "01a", 0, "43 30 31 61 00 00 EC 11 EC 11 EC 11 EC 11 EC 11", 1, 1, "B3" },
/* 6*/ { UNICODE_MODE, 1, -1, -1, "こんwa、αβ", 0, "46 82 B1 82 F1 77 61 66 00 10 FF 88 00 00 EC 11", 1, 1, "B6 K3" }, /* 6*/ { UNICODE_MODE, 1, -1, -1, "こんwa、αβ", 0, "46 82 B1 82 F1 77 61 66 00 10 FF 88 00 00 EC 11", 1, 1, "B6 K3" },
/* 7*/ { UNICODE_MODE, 1, -1, -1, "こんにwa、αβ", 0, "66 13 10 B8 85 25 09 DD 85 98 00 43 FE 20 00 00", 1, 1, "K3 B2 K3" }, /* 7*/ { UNICODE_MODE, 1, -1, -1, "こんにwa、αβ", 0, "66 13 10 B8 85 25 09 DD 85 98 00 43 FE 20 00 00", 1, 1, "K3 B2 K3" },
/* 8*/ { UNICODE_MODE, 1, 3, -1, "こんAB123\177", 0, "D0 4C 42 E2 A9 CD 05 E1 C2 FE 00", 1, 1, "K2 A5 B1" }, /* 8*/ { UNICODE_MODE, 1, 3, -1, "こんAB123\177", 0, "D0 4C 42 E2 91 CD 06 3D C2 FE 00", 0, 1, "K2 A2 N3 B1; BWIPP different encodation (K2 A5 B1)" },
/* 9*/ { UNICODE_MODE, 1, 4, -1, "こんAB123\177", 0, "64 13 10 B8 92 9C D0 5E 1A 0B F8 00 EC 11 EC 11", 1, 1, "K2 A5 B1" }, /* 9*/ { UNICODE_MODE, 1, 4, -1, "こんAB123\177", 0, "64 13 10 B8 92 9C D0 5E 1A 0B F8 00 EC 11 EC 11", 1, 1, "K2 A5 B1" },
/* 10*/ { DATA_MODE, 1, -1, -1, "\223\137", 0, "8A 4D 7C 00 EC 11 EC 11 EC 11 00", 0, 0, "B2; BWIPP uses Kanji (ZINT_FULL_MULTIBYTE) mode, see below); ZXing-C++ test can't handle DATA_MODE for certain inputs" }, /* 10*/ { DATA_MODE, 1, -1, -1, "\223\137", 0, "8A 4D 7C 00 EC 11 EC 11 EC 11 00", 0, 0, "B2; BWIPP uses Kanji (ZINT_FULL_MULTIBYTE) mode, see below); ZXing-C++ test can't handle DATA_MODE for certain inputs" },
/* 11*/ { DATA_MODE, 1, -1, ZINT_FULL_MULTIBYTE, "\223\137", 0, "CB 67 C0 00 EC 11 EC 11 EC 11 00", 1, 1, "K1" }, /* 11*/ { DATA_MODE, 1, -1, ZINT_FULL_MULTIBYTE, "\223\137", 0, "CB 67 C0 00 EC 11 EC 11 EC 11 00", 1, 1, "K1" },
@ -8121,7 +8121,7 @@ static void test_rmqr_optimize(const testCtx *const p_ctx) {
/* 7*/ { UNICODE_MODE, 4, 11, "0123A", 0, "28 06 1A 12 80", 1, "N4 A1 (nayuki.io - alpha/numeric)" }, /* 7*/ { UNICODE_MODE, 4, 11, "0123A", 0, "28 06 1A 12 80", 1, "N4 A1 (nayuki.io - alpha/numeric)" },
/* 8*/ { UNICODE_MODE, 4, 11, "0a", 0, "68 C1 84 00 EC", 1, "B2 (nayuki.io - numeric/byte)" }, /* 8*/ { UNICODE_MODE, 4, 11, "0a", 0, "68 C1 84 00 EC", 1, "B2 (nayuki.io - numeric/byte)" },
/* 9*/ { UNICODE_MODE, 4, 11, "01a", 0, "24 05 96 10 EC", 1, "N2 B1 (nayuki.io - numeric/byte)" }, /* 9*/ { UNICODE_MODE, 4, 11, "01a", 0, "24 05 96 10 EC", 1, "N2 B1 (nayuki.io - numeric/byte)" },
/* 10*/ { UNICODE_MODE, 4, 11, "ABCa", 0, "46 73 4C 65 84", 0, "A3 B1 (nayuki.io - alphanumeric/byte); BWIPP different encodation (B4)" }, /* 10*/ { UNICODE_MODE, 4, 11, "ABCa", 0, "71 05 09 0D 84", 1, "A4 (nayuki.io - alphanumeric/byte)" },
/* 11*/ { UNICODE_MODE, 2, 11, "ABCDa", 0, "48 73 51 4B 2C 20 EC", 1, "A4 B1 (same bits as B5)" }, /* 11*/ { UNICODE_MODE, 2, 11, "ABCDa", 0, "48 73 51 4B 2C 20 EC", 1, "A4 B1 (same bits as B5)" },
/* 12*/ { UNICODE_MODE, 2, 24, "THE SQUARE ROOT OF 2 IS 1.41421356237309504880168872420969807856967187537694807317667973799", 0, "(48) 46 A9 52 9A A0 D5 42 66 E6 F8 A1 4F 62 3E 56 CC D4 40 2B 98 2C F1 AB 19 2E A2 F8 61", 1, " A26 N65 (nayuki.io - alpha/numeric)" }, /* 12*/ { UNICODE_MODE, 2, 24, "THE SQUARE ROOT OF 2 IS 1.41421356237309504880168872420969807856967187537694807317667973799", 0, "(48) 46 A9 52 9A A0 D5 42 66 E6 F8 A1 4F 62 3E 56 CC D4 40 2B 98 2C F1 AB 19 2E A2 F8 61", 1, " A26 N65 (nayuki.io - alpha/numeric)" },
/* 13*/ { UNICODE_MODE, 2, 21, "Golden ratio φ = 1.6180339887498948482045868343656381177203091798057628621354486227052604628189024497072072041893911374......", ZINT_WARN_NONCOMPLIANT, "Warning (73) 65 11 DB DB 19 19 5B 88 1C 98 5D 1A 5B C8 20 F4 C8 0F 48 0C 4B 8B 24 D4 10 FB 97 6E", 1, "B20 N100 A6 (nayuki.io - alpha/numeric/byte)" }, /* 13*/ { UNICODE_MODE, 2, 21, "Golden ratio φ = 1.6180339887498948482045868343656381177203091798057628621354486227052604628189024497072072041893911374......", ZINT_WARN_NONCOMPLIANT, "Warning (73) 65 11 DB DB 19 19 5B 88 1C 98 5D 1A 5B C8 20 F4 C8 0F 48 0C 4B 8B 24 D4 10 FB 97 6E", 1, "B20 N100 A6 (nayuki.io - alpha/numeric/byte)" },
@ -8748,21 +8748,21 @@ static void test_rmqr_encode_segs(const testCtx *const p_ctx) {
}, },
/* 4*/ { UNICODE_MODE, 2, 32, -1, { { TU("Google Pixel 4a 128 GB Black;price:$439.97"), -1, 3 }, { TU("Google 谷歌 Pixel 4a 128 GB黑色;零售价:¥3149.79"), -1, 29 }, { TU("Google Pixel 4a 128 GB Schwarz;Preis:444,90 €"), -1, 17 } }, 0, 17, 139, 0, "AIM ITS/04-023:2022 Annex A example (shortened); BWIPP different encodation", /* 4*/ { UNICODE_MODE, 2, 32, -1, { { TU("Google Pixel 4a 128 GB Black;price:$439.97"), -1, 3 }, { TU("Google 谷歌 Pixel 4a 128 GB黑色;零售价:¥3149.79"), -1, 29 }, { TU("Google Pixel 4a 128 GB Schwarz;Preis:444,90 €"), -1, 17 } }, 0, 17, 139, 0, "AIM ITS/04-023:2022 Annex A example (shortened); BWIPP different encodation",
"1111111010101010101010101011101010101010101010101010101110101010101010101010101010111010101010101010101010101011101010101010101010101010111" "1111111010101010101010101011101010101010101010101010101110101010101010101010101010111010101010101010101010101011101010101010101010101010111"
"1000001001000010110111101110110000000110010001001010001010100010000110011100101000101101010100111001001101110110110010000011110000111000101" "1000001001000010100111001110100000111100110111111110001010100010000110011100101000101101010100111001001101110110110010000011110000101100101"
"1011101011100111011110110011110001010110001000110011111111110000100000111001000110111011000001100011000000100011101101100100110100110011011" "1011101011101011111110110011100101100111101000001011111111110000100000111001000110111011000011100011000000100011101101100100110100110011011"
"1011101001001010011100110110001011111110101111101101000001100101001111110100111010000000011000111101110100000100011001000010001010111100110" "1011101001001110000110100100001111011110111110111101000000100101001111110100111010000000011000101101110100000100011001000010001010101111110"
"1011101000001100010010010011011111000001100111100100011100111110001100101010001111111110111000000000101011100001101000001000111100110110111" "1011101000010000111010100101101000100010100100110100011110111110001100101010001111110110111000000000101011100001101000001000110000000110111"
"1000001000000011110001010010001001010011011010000100110000111111011101011110010000001100000110101110010111000010001001110111011101111000110" "1000001000001001100011001110100010110001011011011100110000111111011101011110010000000000000010001110010111000010001001110111010101011000110"
"1111111010000000010010011101001100101100001010000000000100011111111001000000110011111000111011111010000011011111100111011010000100011000001" "1111111010100010010100110101101010100010001110001000100100011111111001000000111011111000110011111010000011011111100111011001000000011010001"
"0000000010011100010100010000111011010000111011111011010010110001100100001000011110000000010001111100010001000000100101100101011000011011110" "0000000010010110010000100000000010101010110111110011010010110001100100001000010011000000110101111100010001000000100101100111011000011011110"
"1101110011110000010101110111110111001010010101001110011111101110010110101100100110110100101110100100111100000111111011110100100101011111001" "1101110011111001110010000111111111101100100101001110001111101110010110101100001110110110001110100100111100000111111011110100100101011111001"
"0101110111101001110110001110010101111100111101010111000011001111100011011100001001100111001100110101111010101100010101100100010010110101000" "0111111100100011001110011010010100110111101101010111000011001111100011011100001100100110011110110101111010101100010101100000010010110101000"
"1000011000101010000011100001100000010101000010001000001100010011011010010000101001110011000011010011011111110101101101101101000101100001001" "1011000010101000110000001001010011101001100001111011001100010011011010010000101101110011000011010011011111110101101101100101110101100001001"
"0000110000010010100101011100100001111010010001100100100000101010000111111001110010000101100100111001010001010010011010001110101101111011100" "0001110000010011000000110000010111111010010001010100100000101010000111111001110000000101100101110001010001010010011010001110101101111011100"
"1110010111111001100011110101010001100011101010001110101100101100110100100101001101110111101001100111001101111001111010001011111000110111111" "1000101101011001001010000001111011100111100000100110101100101100110100100101001101110111101001100111001101111001111010001011011000110111111"
"0100001101110100010111001110101111111010001111100000100010111011000010010110001010000001000001001111000010011100111110010011000111100110001" "0110100001110101010110010010100000111110011101011100100010111011000010010110001010000001001001001111000010011100111110010011000110100110001"
"1100011010000101111101101111111111010011001010111001011110010011101010100011101001111010100111010100110100011111110111100101000111010110101" "1001000001100110110011100011111101010111100110100101011110010011101010100011101001111010100111010100110100011111110111100101000101010110101"
"1010011110100110011111000010111010001000100111010111011011101000100101110000010011101110110100011010110111010110110011110110000001000110001" "1010011110111011011111000010111011001001010001011111011011101000100101110000010011101110110100011010110111010110110011110110000001000110001"
"1110101010101010101010101011101010101010101010101010101110101010101010101010101010111010101010101010101010101011101010101010101010101011111" "1110101010101010101010101011101010101010101010101010101110101010101010101010101010111010101010101010101010101011101010101010101010101011111"
}, },
/* 5*/ { DATA_MODE, 4, 3, -1, { { TU("\266"), 1, 0 }, { TU("\266"), 1, 7 }, { TU("\266"), 1, 0 } }, 0, 7, 77, 1, "Standard example + extra seg, data mode", /* 5*/ { DATA_MODE, 4, 3, -1, { { TU("\266"), 1, 0 }, { TU("\266"), 1, 7 }, { TU("\266"), 1, 0 } }, 0, 7, 77, 1, "Standard example + extra seg, data mode",
@ -8886,6 +8886,7 @@ static void test_fuzz(const testCtx *const p_ctx) {
int input_mode; int input_mode;
int option_1; int option_1;
int option_2; int option_2;
int option_3;
char *data; char *data;
int length; int length;
int ret; int ret;
@ -8894,7 +8895,8 @@ static void test_fuzz(const testCtx *const p_ctx) {
}; };
/* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */
struct item data[] = { struct item data[] = {
/* 0*/ { BARCODE_QRCODE, GS1_MODE | GS1NOCHECK_MODE, -1, -1, "[]CCCCCLLLLLLLLLLLLLLLLLLLLLCCCCCCCC@CCCCCCCCCCCCCCCCCCCCCCC%%C%C%%%%%%%%%%%%%%LLLCCCCCCCC%%C%C%%%%%%%%%%%%%%LLLLLLLLLLLLLLLLLLL000000032861710*383556LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL155816162LLLLLCC%%C%C%%%%%%%%%%%%%%LLLCCCCCCCC%%C%C%%%%%%%%%%%%%%LLLLLLLLLL)!1661055777[723]T5", -1, 0, 1, "" }, /* #300 (#14), Andre Maute */ /* 0*/ { BARCODE_QRCODE, GS1_MODE | GS1NOCHECK_MODE, -1, -1, -1, "[]CCCCCLLLLLLLLLLLLLLLLLLLLLCCCCCCCC@CCCCCCCCCCCCCCCCCCCCCCC%%C%C%%%%%%%%%%%%%%LLLCCCCCCCC%%C%C%%%%%%%%%%%%%%LLLLLLLLLLLLLLLLLLL000000032861710*383556LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL155816162LLLLLCC%%C%C%%%%%%%%%%%%%%LLLCCCCCCCC%%C%C%%%%%%%%%%%%%%LLLLLLLLLL)!1661055777[723]T5", -1, 0, 1, "" }, /* #300 (#14), Andre Maute */
/* 1*/ { BARCODE_QRCODE, DATA_MODE, -1, -1, ZINT_FULL_MULTIBYTE, "\215\215\350\2156750\215\215\215\215\215\215\000\000\000\025\215\215\215\215\215\232\215\232\232\001\361\215\215\215\215\215\221\215\215\215\215JJJJJJNJJJJJJ\215\215\215\2159999\215\215\215\215\215\215\215\215\215\235\215\215\215\215\215\035\004\000\000@\000\000\000\000\375\000\000\000\000\000\000\000\000\000\000\000\000\000\241\000\000\000\000\000\000\000\241\247^^^\377\377\377\000 \000\000\000\000\000\000\377\377u\000\000\000\000\000\000\000^\377\377^^\000:\000\177\377\377\377?\377\377\377\377\377\377\377\377\377\377\377\377\377\377\241\241\232\232\232\232\232\232\232\232\000\377\377\377\242\003\000\000\377\377/\000AA\000\000\000\000\000\000\000\000\000\000\000\000T\000\000\000\000\000\000\000\000WWW\237\250WWWWWW\377\377R30 \377\377\000\000\000", 231, 0, 1, "" }, /* #300 (#15), Andre Maute */
}; };
int data_size = ARRAY_SIZE(data); int data_size = ARRAY_SIZE(data);
int i, length, ret; int i, length, ret;
@ -8909,7 +8911,7 @@ static void test_fuzz(const testCtx *const p_ctx) {
symbol = ZBarcode_Create(); symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n"); assert_nonnull(symbol, "Symbol not created\n");
length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, data[i].option_1, data[i].option_2, -1, -1 /*output_options*/, data[i].data, data[i].length, debug); length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, data[i].option_1, data[i].option_2, data[i].option_3, -1 /*output_options*/, data[i].data, data[i].length, debug);
ret = ZBarcode_Encode(symbol, (unsigned char *) data[i].data, length); ret = ZBarcode_Encode(symbol, (unsigned char *) data[i].data, length);
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);

View File

@ -196,6 +196,9 @@
padding: 0.125em 0.5em 0.25em 0.5em; padding: 0.125em 0.5em 0.25em 0.5em;
vertical-align: top; vertical-align: top;
} }
tbody tr:first-child td {
padding-top: 0.5em;
}
header { header {
margin-bottom: 4em; margin-bottom: 4em;
text-align: center; text-align: center;
@ -329,7 +332,7 @@
<h1 class="title">Zint Barcode Generator and Zint Barcode Studio User <h1 class="title">Zint Barcode Generator and Zint Barcode Studio User
Manual</h1> Manual</h1>
<p class="author">Version 2.12.0.9</p> <p class="author">Version 2.12.0.9</p>
<p class="date">November 2023</p> <p class="date">December 2023</p>
</header> </header>
<nav id="TOC" role="doc-toc"> <nav id="TOC" role="doc-toc">
<ul> <ul>

View File

@ -1,6 +1,6 @@
% Zint Barcode Generator and Zint Barcode Studio User Manual % Zint Barcode Generator and Zint Barcode Studio User Manual
% Version 2.12.0.9 % Version 2.12.0.9
% November 2023 % December 2023
# 1. Introduction # 1. Introduction

View File

@ -1,6 +1,6 @@
Zint Barcode Generator and Zint Barcode Studio User Manual Zint Barcode Generator and Zint Barcode Studio User Manual
Version 2.12.0.9 Version 2.12.0.9
November 2023 December 2023
******************************************************************************* *******************************************************************************
* For reference the following is a text-only version of the Zint manual, * * For reference the following is a text-only version of the Zint manual, *
@ -4746,7 +4746,7 @@ configured barcode is displayed once the "Generate" button is pressed.
Annex D. Man Page ZINT(1) Annex D. Man Page ZINT(1)
% ZINT(1) Version 2.12.0.9 % % November 2023 % ZINT(1) Version 2.12.0.9 % % December 2023
NAME NAME

View File

@ -217,6 +217,9 @@ td {
padding: 0.125em 0.5em 0.25em 0.5em; padding: 0.125em 0.5em 0.25em 0.5em;
vertical-align: top; vertical-align: top;
} }
tbody tr:first-child td {
padding-top: 0.5em;
}
header { header {
margin-bottom: 4em; margin-bottom: 4em;
text-align: center; text-align: center;

View File

@ -1,6 +1,6 @@
.\" Automatically generated by Pandoc 3.1.9 .\" Automatically generated by Pandoc 3.1.9
.\" .\"
.TH "ZINT" "1" "November 2023" "Version 2.12.0.9" "" .TH "ZINT" "1" "December 2023" "Version 2.12.0.9" ""
.SH NAME .SH NAME
\f[CR]zint\f[R] - encode data as a barcode image \f[CR]zint\f[R] - encode data as a barcode image
.SH SYNOPSIS .SH SYNOPSIS

View File

@ -1,6 +1,6 @@
% ZINT(1) Version 2.12.0.9 % ZINT(1) Version 2.12.0.9
% %
% November 2023 % December 2023
# NAME # NAME