From 9b63e2ae2211467ef6dab1a59f5fc71d33f9111d Mon Sep 17 00:00:00 2001 From: gitlost Date: Fri, 28 May 2021 15:05:06 +0100 Subject: [PATCH] DOTCODE: allow for max 200 cols in CLI, GUI, Tcl; more detailed size error messages --- backend/dotcode.c | 14 +- backend/tests/test_dotcode.c | 148 +++++++---- backend_tcl/zint.c | 4 +- frontend/main.c | 2 +- frontend/tests/test_args.c | 2 +- frontend_qt/grpDotCode.ui | 480 +++++++++++++++++++++++++++++++++-- frontend_qt/mainwindow.cpp | 5 +- 7 files changed, 586 insertions(+), 69 deletions(-) diff --git a/backend/dotcode.c b/backend/dotcode.c index fec910e6..eed9d24a 100644 --- a/backend/dotcode.c +++ b/backend/dotcode.c @@ -1424,12 +1424,22 @@ INTERNAL int dotcode(struct zint_symbol *symbol, unsigned char source[], int len } if ((height > 200) || (width > 200)) { - strcpy(symbol->errtxt, "526: Specified symbol size is too large"); + if (height > 200 && width > 200) { + sprintf(symbol->errtxt, "526: Symbol size %dx%d (WxH) is too large", width, height); + } else { + sprintf(symbol->errtxt, "528: Symbol %s %d is too large", + width > 200 ? "width" : "height", width > 200 ? width : height); + } return ZINT_ERROR_INVALID_OPTION; } if ((height < 5) || (width < 5)) { - strcpy(symbol->errtxt, "527: Specified symbol size has a dimension which is too small"); + if (height < 5 && width < 5) { + sprintf(symbol->errtxt, "527: Symbol size %dx%d (WxH) is too small", width, height); + } else { + sprintf(symbol->errtxt, "529: Symbol %s %d is too small", + width < 5 ? "width" : "height", width < 5 ? width : height); + } return ZINT_ERROR_INVALID_OPTION; } diff --git a/backend/tests/test_dotcode.c b/backend/tests/test_dotcode.c index 781106fb..660cd8df 100644 --- a/backend/tests/test_dotcode.c +++ b/backend/tests/test_dotcode.c @@ -31,6 +31,102 @@ #include "testcommon.h" +static void test_large(int index, int debug) { + + testStart(""); + + int ret; + struct item { + int option_2; + char datum; + int length; + int ret; + }; + // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<")) + struct item data[] = { + /* 0*/ { 200, '0', 2940, 0 }, // 2940 largest Code Set C data that fits in 200x199 HxW + /* 1*/ { 200, '0', 2941, ZINT_ERROR_INVALID_OPTION }, + /* 2*/ { 200, '9', 200, 0 }, // Changes a number of mask scores re pre-Rev. 4 version, but best score still the same (7) + /* 3*/ { 201, '0', 2940, ZINT_ERROR_INVALID_OPTION }, + /* 4*/ { 30, '\001', 71, 0 }, // Codeword length 72, ECC length 39, for ND + 1 == 112 + }; + int data_size = ARRAY_SIZE(data); + + char data_buf[4096]; + + for (int i = 0; i < data_size; i++) { + + if (index != -1 && i != index) continue; + + struct zint_symbol *symbol = ZBarcode_Create(); + assert_nonnull(symbol, "Symbol not created\n"); + + memset(data_buf, data[i].datum, data[i].length); + + int length = testUtilSetSymbol(symbol, BARCODE_DOTCODE, -1 /*input_mode*/, -1 /*eci*/, -1 /*option_1*/, data[i].option_2, -1, -1 /*output_options*/, data_buf, data[i].length, debug); + + ret = ZBarcode_Encode(symbol, (unsigned char *) data_buf, length); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + + ZBarcode_Delete(symbol); + } + + testFinish(); +} + +static void test_options(int index, int debug) { + + testStart(""); + + int ret; + struct item { + int input_mode; + int output_options; + int option_2; + char *data; + int ret; + + int expected_rows; + int expected_width; + }; + // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<")) + struct item data[] = { + /* 0*/ { -1, -1, -1, "1", 0, 9, 14 }, + /* 1*/ { -1, -1, -1, "1234567890", 0, 12, 19 }, + /* 2*/ { -1, -1, 19, "1234567890", 0, 12, 19 }, + /* 3*/ { -1, -1, 12, "1234567890", 0, 19, 12 }, + /* 4*/ { -1, -1, 5, "1234567890", 0, 44, 5 }, + /* 5*/ { -1, -1, 4, "1234567890", ZINT_ERROR_INVALID_OPTION, -1, -1 }, // Cols < 5 + /* 6*/ { -1, -1, 200, "1234567890", ZINT_ERROR_INVALID_OPTION, -1, -1 }, // Not enough data - height 3 too small + /* 7*/ { -1, -1, 200, "1234567890123456789012345678901234567890", 0, 5, 200 }, // Cols 200 max + /* 8*/ { -1, -1, 200, "12345678901234567890123456789012345678901234567890123456789012345678901234567890", 0, 7, 200 }, + /* 9*/ { -1, -1, 201, "12345678901234567890123456789012345678901234567890123456789012345678901234567890", ZINT_ERROR_INVALID_OPTION, -1, -1 }, + }; + int data_size = ARRAY_SIZE(data); + + for (int i = 0; i < data_size; i++) { + + if (index != -1 && i != index) continue; + + struct zint_symbol *symbol = ZBarcode_Create(); + assert_nonnull(symbol, "Symbol not created\n"); + + int length = testUtilSetSymbol(symbol, BARCODE_DOTCODE, data[i].input_mode, -1 /*eci*/, -1 /*option_1*/, data[i].option_2, -1, data[i].output_options, data[i].data, -1, debug); + + 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); + + if (ret < ZINT_ERROR) { + assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", i, symbol->rows, data[i].expected_rows, symbol->errtxt); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", i, symbol->width, data[i].expected_width, symbol->errtxt); + } + + ZBarcode_Delete(symbol); + } + + testFinish(); +} + static void test_input(int index, int generate, int debug) { testStart(""); @@ -627,6 +723,13 @@ static void test_encode(int index, int generate, int debug) { "00010001010000000100010101000100010001010001000101" "10001000001010101000001000100010100010100000101010" }, + /* 33*/ { UNICODE_MODE, 200, -1, "123456789012345678901234567890123456789012345678901234567890", -1, 0, 5, 200, 1, "Max cols", + "10101000100010101010000010101000000010001000100000101010100010100000101000100010000000101000101010001010100000100000101010100000001000101000001010100010001010000010001010001010100000100010101000000010" + "00010101010000000101000100010001000101000101000100010001000001010001000001010100000001000101010000000101010100010101010000010001000101010001000001000001010000010100010001010101000001000001010100000001" + "10100010000000100010101000101010100000001010001000100000101000101000001000101010001000000010101010100010101000000010100010001000001010100000101000100000101010100010000000001000001010101000101010100000" + "00010001010001010000000101000100010001010000010000010100010100000100010101010001000101000000010100010001010100010000010100000101000100010100000101010000000101000001010100010100010001000101000001010001" + "10100010001010101000000010001000001010001010001000001010100010000000101010001010000010101010000000101000100010100010100000100010100010001010100000001010101000001010000000001000101000101010000010101010" + }, }; int data_size = ARRAY_SIZE(data); @@ -740,55 +843,14 @@ static void test_fuzz(int index, int debug) { testFinish(); } -static void test_large(int index, int debug) { - - testStart(""); - - int ret; - struct item { - int option_2; - char datum; - int length; - int ret; - }; - // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<")) - struct item data[] = { - /* 0*/ { 200, '0', 2940, 0 }, // 2940 largest Code Set C data that fits in 200x199 HxW - /* 1*/ { 200, '0', 2941, ZINT_ERROR_INVALID_OPTION }, - /* 2*/ { 200, '9', 200, 0 }, // Changes a number of mask scores re pre-Rev. 4 version, but best score still the same (7) - /* 3*/ { 30, '\001', 71, 0 }, // Codeword length 72, ECC length 39, for ND + 1 == 112 - }; - int data_size = ARRAY_SIZE(data); - - char data_buf[4096]; - - for (int i = 0; i < data_size; i++) { - - if (index != -1 && i != index) continue; - - struct zint_symbol *symbol = ZBarcode_Create(); - assert_nonnull(symbol, "Symbol not created\n"); - - memset(data_buf, data[i].datum, data[i].length); - - int length = testUtilSetSymbol(symbol, BARCODE_DOTCODE, -1 /*input_mode*/, -1 /*eci*/, -1 /*option_1*/, data[i].option_2, -1, -1 /*output_options*/, data_buf, data[i].length, debug); - - ret = ZBarcode_Encode(symbol, (unsigned char *) data_buf, length); - assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); - - ZBarcode_Delete(symbol); - } - - testFinish(); -} - int main(int argc, char *argv[]) { testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */ + { "test_large", test_large, 1, 0, 1 }, + { "test_options", test_options, 1, 0, 1 }, { "test_input", test_input, 1, 1, 1 }, { "test_encode", test_encode, 1, 1, 1 }, { "test_fuzz", test_fuzz, 1, 0, 1 }, - { "test_large", test_large, 1, 0, 1 }, }; testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); diff --git a/backend_tcl/zint.c b/backend_tcl/zint.c index d5dccb21..796027e9 100644 --- a/backend_tcl/zint.c +++ b/backend_tcl/zint.c @@ -115,6 +115,8 @@ - Added -gs1parens option 2021-05-22 GL - Added -vwhitesp option +2021-05-28 GL +- -cols maximum changed from 108 to 200 (DotCode) */ #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32) @@ -994,7 +996,7 @@ static int Encode(Tcl_Interp *interp, int objc, case iVers: /* >> Int in Option 2 */ if (intValue < 1 - || (optionIndex==iCols && intValue > 108) + || (optionIndex==iCols && intValue > 200) || (optionIndex==iVers && intValue > 47)) { Tcl_SetObjResult(interp, diff --git a/frontend/main.c b/frontend/main.c index fa8d2076..0261a2ab 100644 --- a/frontend/main.c +++ b/frontend/main.c @@ -919,7 +919,7 @@ int main(int argc, char **argv) { fprintf(stderr, "Error 131: Invalid columns value\n"); return do_exit(1); } - if ((val >= 1) && (val <= 108)) { + if ((val >= 1) && (val <= 200)) { my_symbol->option_2 = val; } else { fprintf(stderr, "Warning 111: Number of columns out of range\n"); diff --git a/frontend/tests/test_args.c b/frontend/tests/test_args.c index 64e0ded3..36b5132c 100644 --- a/frontend/tests/test_args.c +++ b/frontend/tests/test_args.c @@ -559,7 +559,7 @@ static void test_checks(int index, int debug) { /* 4*/ { -1, 1001, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Warning 108: Border width out of range" }, /* 5*/ { -1, -1, -1, 0.009, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Warning 106: Invalid dot radius value" }, /* 6*/ { -1, -1, -2, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Error 131: Invalid columns value" }, - /* 7*/ { -1, -1, 109, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Warning 111: Number of columns out of range" }, + /* 7*/ { -1, -1, 201, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Warning 111: Number of columns out of range" }, /* 8*/ { -1, -1, -1, -1, -2, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Error 138: Invalid ECI value" }, /* 9*/ { -1, -1, -1, -1, 1000000, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Warning 118: Invalid ECI code" }, /* 10*/ { -1, -1, -1, -1, -1, "jpg", -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, "Warning 142: File type 'jpg' not supported, ignoring" }, diff --git a/frontend_qt/grpDotCode.ui b/frontend_qt/grpDotCode.ui index a2b10492..3673fa01 100644 --- a/frontend_qt/grpDotCode.ui +++ b/frontend_qt/grpDotCode.ui @@ -45,26 +45,6 @@ Automatic - - - 1 - - - - - 2 - - - - - 3 - - - - - 4 - - 5 @@ -585,6 +565,466 @@ 108 + + + 109 + + + + + 110 + + + + + 111 + + + + + 112 + + + + + 113 + + + + + 114 + + + + + 115 + + + + + 116 + + + + + 117 + + + + + 118 + + + + + 119 + + + + + 120 + + + + + 121 + + + + + 122 + + + + + 123 + + + + + 124 + + + + + 125 + + + + + 126 + + + + + 127 + + + + + 128 + + + + + 129 + + + + + 130 + + + + + 131 + + + + + 132 + + + + + 133 + + + + + 134 + + + + + 135 + + + + + 136 + + + + + 137 + + + + + 138 + + + + + 139 + + + + + 140 + + + + + 141 + + + + + 142 + + + + + 143 + + + + + 144 + + + + + 145 + + + + + 146 + + + + + 147 + + + + + 148 + + + + + 149 + + + + + 150 + + + + + 151 + + + + + 152 + + + + + 153 + + + + + 154 + + + + + 155 + + + + + 156 + + + + + 157 + + + + + 158 + + + + + 159 + + + + + 160 + + + + + 161 + + + + + 162 + + + + + 163 + + + + + 164 + + + + + 165 + + + + + 166 + + + + + 167 + + + + + 168 + + + + + 169 + + + + + 170 + + + + + 171 + + + + + 172 + + + + + 173 + + + + + 174 + + + + + 175 + + + + + 176 + + + + + 177 + + + + + 178 + + + + + 179 + + + + + 180 + + + + + 181 + + + + + 182 + + + + + 183 + + + + + 184 + + + + + 185 + + + + + 186 + + + + + 187 + + + + + 188 + + + + + 189 + + + + + 190 + + + + + 191 + + + + + 192 + + + + + 193 + + + + + 194 + + + + + 195 + + + + + 196 + + + + + 197 + + + + + 198 + + + + + 199 + + + + + 200 + + diff --git a/frontend_qt/mainwindow.cpp b/frontend_qt/mainwindow.cpp index 6fd66cb9..dc2a3cfd 100644 --- a/frontend_qt/mainwindow.cpp +++ b/frontend_qt/mainwindow.cpp @@ -1254,7 +1254,10 @@ void MainWindow::update_preview() case BARCODE_DOTCODE: m_bc.bc.setSymbol(BARCODE_DOTCODE); - m_bc.bc.setOption2(m_optionWidget->findChild("cmbDotCols")->currentIndex()); + item_val = m_optionWidget->findChild("cmbDotCols")->currentIndex(); + if (item_val) { + m_bc.bc.setOption2(item_val + 4); // Cols 1-4 not listed + } item_val = m_optionWidget->findChild("cmbDotMask")->currentIndex(); if (item_val) { m_bc.bc.setOption3((item_val << 8) | m_bc.bc.option3());