From 0b80592f877c55f3672725fffb508faadff94bff Mon Sep 17 00:00:00 2001 From: gitlost Date: Fri, 15 Jan 2021 14:22:32 +0000 Subject: [PATCH] escape_char_process: "\xNN" simple convert (reverts [dddf29]), "\uNNNN" BMP check --- backend/library.c | 18 +++-- backend/tests/test_library.c | 105 +++++++++++++++++++-------- docs/manual.txt | 135 ++++++++++++++++++++--------------- frontend/main.c | 2 + frontend/tests/test_args.c | 30 ++++---- 5 files changed, 181 insertions(+), 109 deletions(-) diff --git a/backend/library.c b/backend/library.c index cb4b48d8..25b2bdde 100644 --- a/backend/library.c +++ b/backend/library.c @@ -1006,14 +1006,7 @@ static int escape_char_process(struct zint_symbol *symbol, unsigned char *input_ hex1 = ctoi(input_string[in_posn + 2]); hex2 = ctoi(input_string[in_posn + 3]); if ((hex1 >= 0) && (hex2 >= 0)) { - if (hex1 > 7 && (symbol->input_mode & 0x07) == UNICODE_MODE) { - // Convert to UTF-8 - escaped_string[out_posn] = 0xc0 + (hex1 >> 2); - out_posn++; - escaped_string[out_posn] = 0x80 + ((hex1 & 0x03) << 4) + hex2; - } else { - escaped_string[out_posn] = (hex1 << 4) + hex2; - } + escaped_string[out_posn] = (hex1 << 4) + hex2; in_posn += 4; } else { strcpy(symbol->errtxt, "233: Corrupt escape character in input data"); @@ -1025,18 +1018,23 @@ static int escape_char_process(struct zint_symbol *symbol, unsigned char *input_ break; case 'u': if (in_posn + 6 > *length) { - strcpy(symbol->errtxt, "209: Incomplete unicode escape character in input data"); + strcpy(symbol->errtxt, "209: Incomplete Unicode escape character in input data"); return ZINT_ERROR_INVALID_DATA; } unicode = 0; for (i = 0; i < 4; i++) { if (ctoi(input_string[in_posn + i + 2]) == -1) { - strcpy(symbol->errtxt, "211: Corrupt unicode escape character in input data"); + strcpy(symbol->errtxt, "211: Corrupt Unicode escape character in input data"); return ZINT_ERROR_INVALID_DATA; } unicode = unicode << 4; unicode += ctoi(input_string[in_posn + i + 2]); } + /* Exclude reversed BOM and surrogates */ + if (unicode == 0xfffe || (unicode >= 0xd800 && unicode < 0xe000)) { + strcpy(symbol->errtxt, "246: Invalid Unicode BMP escape character in input data"); + return ZINT_ERROR_INVALID_DATA; + } if (unicode >= 0x800) { escaped_string[out_posn] = 0xe0 + ((unicode & 0xf000) >> 12); out_posn++; diff --git a/backend/tests/test_library.c b/backend/tests/test_library.c index 71436afe..fc3e133c 100644 --- a/backend/tests/test_library.c +++ b/backend/tests/test_library.c @@ -32,6 +32,7 @@ #include "testcommon.h" #include #include +#include #include static void test_checks(int index, int debug) { @@ -159,7 +160,7 @@ static void test_input_mode(int index, int debug) { /* 9*/ { "1234", UNICODE_MODE | 0x10, 0, UNICODE_MODE | 0x10 }, /* 10*/ { "[01]12345678901234", GS1_MODE | 0x20, 0, GS1_MODE | 0x20 }, }; - int data_size = sizeof(data) / sizeof(struct item); + int data_size = ARRAY_SIZE(data); for (int i = 0; i < data_size; i++) { @@ -168,11 +169,7 @@ static void test_input_mode(int index, int debug) { struct zint_symbol *symbol = ZBarcode_Create(); assert_nonnull(symbol, "Symbol not created\n"); - symbol->symbology = BARCODE_CODE49; // Supports GS1 - symbol->input_mode = data[i].input_mode; - symbol->debug |= debug; - - int length = strlen(data[i].data); + int length = testUtilSetSymbol(symbol, BARCODE_CODE49 /*Supports GS1*/, data[i].input_mode, -1 /*eci*/, -1 /*option_1*/, -1, -1, -1 /*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); @@ -191,33 +188,47 @@ static void test_escape_char_process(int index, int generate, int debug) { int ret; struct item { int input_mode; + int eci; char *data; int ret; int expected_width; char *expected; + int compare_previous; char *comment; }; struct item data[] = { - /* 0*/ { DATA_MODE, "\\0\\E\\a\\b\\t\\n\\v\\f\\r\\e\\G\\R\\x81\\\\", 0, 200, "(18) 103 64 68 71 72 73 74 75 76 77 91 93 94 101 65 60 44 106", "" }, - /* 1*/ { DATA_MODE, "\\c", ZINT_ERROR_INVALID_DATA, 0, "Error 234: Unrecognised escape character in input data", "" }, - /* 2*/ { DATA_MODE, "\\", ZINT_ERROR_INVALID_DATA, 0, "Error 236: Incomplete escape character in input data", "" }, - /* 3*/ { DATA_MODE, "\\x", ZINT_ERROR_INVALID_DATA, 0, "Error 232: Incomplete escape character in input data", "" }, - /* 4*/ { DATA_MODE, "\\x1", ZINT_ERROR_INVALID_DATA, 0, "Error 232: Incomplete escape character in input data", "" }, - /* 5*/ { DATA_MODE, "\\x1g", ZINT_ERROR_INVALID_DATA, 0, "Error 233: Corrupt escape character in input data", "" }, - /* 6*/ { UNICODE_MODE, "\\xA01\\xFF", 0, 90, "(8) 104 100 0 17 100 95 100 106", "" }, - /* 7*/ { UNICODE_MODE, "\\u00A01\\u00FF", 0, 90, "(8) 104 100 0 17 100 95 100 106", "" }, - /* 8*/ { DATA_MODE, "\\xc3\\xbF", 0, 79, "(7) 104 100 35 100 31 80 106", "" }, - /* 9*/ { DATA_MODE, "\\u00fF", 0, 79, "(7) 104 100 35 100 31 80 106", "" }, - /* 10*/ { DATA_MODE, "\\u", ZINT_ERROR_INVALID_DATA, 0, "Error 235: Incomplete unicode escape character in input data", "" }, - /* 11*/ { DATA_MODE, "\\uF", ZINT_ERROR_INVALID_DATA, 0, "Error 235: Incomplete unicode escape character in input data", "" }, - /* 12*/ { DATA_MODE, "\\u0F", ZINT_ERROR_INVALID_DATA, 0, "Error 235: Incomplete unicode escape character in input data", "" }, - /* 13*/ { DATA_MODE, "\\uFG", ZINT_ERROR_INVALID_DATA, 0, "Error 235: Incomplete unicode escape character in input data", "" }, - /* 14*/ { DATA_MODE, "\\u00F", ZINT_ERROR_INVALID_DATA, 0, "Error 235: Incomplete unicode escape character in input data", "" }, - /* 15*/ { DATA_MODE, "\\u00FG", ZINT_ERROR_INVALID_DATA, 0, "Error 236: Corrupt unicode escape character in input data", "" }, + /* 0*/ { DATA_MODE, -1, "\\0\\E\\a\\b\\t\\n\\v\\f\\r\\e\\G\\R\\x81\\\\", 0, 26, "01 05 08 09 0A 0B 0C 0D E7 DE 7B 1F B6 4D 45 B6 E6 78 98 0D 54 2E 58 21 AE 22 2B 3E 8B 22", 0, "" }, + /* 1*/ { DATA_MODE, -1, "\\c", ZINT_ERROR_INVALID_DATA, 0, "Error 234: Unrecognised escape character in input data", 0, "" }, + /* 2*/ { DATA_MODE, -1, "\\", ZINT_ERROR_INVALID_DATA, 0, "Error 236: Incomplete escape character in input data", 0, "" }, + /* 3*/ { DATA_MODE, -1, "\\x", ZINT_ERROR_INVALID_DATA, 0, "Error 232: Incomplete escape character in input data", 0, "" }, + /* 4*/ { DATA_MODE, -1, "\\x1", ZINT_ERROR_INVALID_DATA, 0, "Error 232: Incomplete escape character in input data", 0, "" }, + /* 5*/ { DATA_MODE, -1, "\\x1g", ZINT_ERROR_INVALID_DATA, 0, "Error 233: Corrupt escape character in input data", 0, "" }, + /* 6*/ { DATA_MODE, -1, "\\xA01\\xFF", 0, 12, "EB 21 32 EB 80 D8 49 44 DC 7D 9E 3B", 0, "" }, + /* 7*/ { UNICODE_MODE, -1, "\\u00A01\\u00FF", 0, 12, "EB 21 32 EB 80 D8 49 44 DC 7D 9E 3B", 1, "" }, + /* 8*/ { DATA_MODE, -1, "\\xc3\\xbF", 0, 12, "EB 44 EB 40 81 30 87 17 C5 68 5C 91", 0, "" }, + /* 9*/ { DATA_MODE, -1, "\\u00fF", 0, 12, "EB 44 EB 40 81 30 87 17 C5 68 5C 91", 1, "" }, + /* 10*/ { UNICODE_MODE, -1, "\\xc3\\xbF", 0, 10, "EB 80 81 47 1E 45 FC 93", 0, "" }, + /* 11*/ { UNICODE_MODE, -1, "\\u00fF", 0, 10, "EB 80 81 47 1E 45 FC 93", 1, "" }, + /* 12*/ { DATA_MODE, -1, "\\u", ZINT_ERROR_INVALID_DATA, 0, "Error 209: Incomplete Unicode escape character in input data", 0, "" }, + /* 13*/ { DATA_MODE, -1, "\\uF", ZINT_ERROR_INVALID_DATA, 0, "Error 209: Incomplete Unicode escape character in input data", 0, "" }, + /* 14*/ { DATA_MODE, -1, "\\u0F", ZINT_ERROR_INVALID_DATA, 0, "Error 209: Incomplete Unicode escape character in input data", 0, "" }, + /* 15*/ { DATA_MODE, -1, "\\uFG", ZINT_ERROR_INVALID_DATA, 0, "Error 209: Incomplete Unicode escape character in input data", 0, "" }, + /* 16*/ { DATA_MODE, -1, "\\u00F", ZINT_ERROR_INVALID_DATA, 0, "Error 209: Incomplete Unicode escape character in input data", 0, "" }, + /* 17*/ { DATA_MODE, -1, "\\u00FG", ZINT_ERROR_INVALID_DATA, 0, "Error 211: Corrupt Unicode escape character in input data", 0, "" }, + /* 18*/ { DATA_MODE, -1, "\\ufffe", ZINT_ERROR_INVALID_DATA, 0, "Error 246: Invalid Unicode BMP escape character in input data", 0, "Reversed BOM" }, + /* 19*/ { DATA_MODE, -1, "\\ud800", ZINT_ERROR_INVALID_DATA, 0, "Error 246: Invalid Unicode BMP escape character in input data", 0, "Surrogate" }, + /* 20*/ { DATA_MODE, -1, "\\udfff", ZINT_ERROR_INVALID_DATA, 0, "Error 246: Invalid Unicode BMP escape character in input data", 0, "Surrogate" }, + /* 21*/ { UNICODE_MODE, 17, "\\xE2\\x82\\xAC", 0, 12, "F1 12 EB 25 81 4A 0A 8C 31 AC E3 2E", 0, "Zint manual 4.10 Ex1" }, + /* 22*/ { UNICODE_MODE, 17, "\\u20AC", 0, 12, "F1 12 EB 25 81 4A 0A 8C 31 AC E3 2E", 1, "" }, + /* 23*/ { DATA_MODE, 17, "\\xA4", 0, 12, "F1 12 EB 25 81 4A 0A 8C 31 AC E3 2E", 1, "" }, + /* 24*/ { DATA_MODE, 28, "\\xB1\\x60", 0, 12, "F1 1D EB 32 61 D9 1C 0C C2 46 C3 B2", 0, "Zint manual 4.10 Ex2" }, + /* 25*/ { UNICODE_MODE, 28, "\\u5E38", 0, 12, "F1 1D EB 32 61 D9 1C 0C C2 46 C3 B2", 1, "" }, }; int data_size = ARRAY_SIZE(data); char escaped[1024]; + struct zint_symbol previous_symbol; + char *input_filename = "test_escape.txt"; for (int i = 0; i < data_size; i++) { @@ -228,19 +239,53 @@ static void test_escape_char_process(int index, int generate, int debug) { symbol->debug = ZINT_DEBUG_TEST; // Needed to get codeword dump in errtxt - int length = testUtilSetSymbol(symbol, BARCODE_CODE128, data[i].input_mode | ESCAPE_MODE, -1 /*eci*/, -1 /*option_1*/, -1, -1, -1 /*output_options*/, data[i].data, -1, debug); + int length = testUtilSetSymbol(symbol, BARCODE_DATAMATRIX, data[i].input_mode | ESCAPE_MODE, data[i].eci, -1 /*option_1*/, -1, -1, -1 /*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 (generate) { - printf(" /*%3d*/ { %s, \"%s\", %s, %d, \"%s\", \"%s\" },\n", - i, testUtilInputModeName(data[i].input_mode), testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), - testUtilErrorName(data[i].ret), symbol->width, symbol->errtxt, data[i].comment); + printf(" /*%3d*/ { %s, %d, \"%s\", %s, %d, \"%s\", %d, \"%s\" },\n", + i, testUtilInputModeName(data[i].input_mode), data[i].eci, testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), + testUtilErrorName(data[i].ret), symbol->width, symbol->errtxt, data[i].compare_previous, data[i].comment); } else { - if (ret < 5) { + assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected); + + if (ret < ZINT_ERROR) { assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", i, symbol->width, data[i].expected_width, data[i].data); - assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected); + if (index == -1 && data[i].compare_previous) { + ret = testUtilSymbolCmp(symbol, &previous_symbol); + assert_zero(ret, "i:%d testUtilSymbolCmp ret %d != 0\n", i, ret); + } + } + memcpy(&previous_symbol, symbol, sizeof(previous_symbol)); + + if (ret < 5) { + // Test from input file + + FILE *fp; + fp = fopen(input_filename, "wb"); + assert_nonnull(fp, "i:%d fopen(%s) failed\n", i, input_filename); + assert_nonzero(fputs(data[i].data, fp), "i%d fputs(%s) failed\n", i, data[i].data); + assert_zero(fclose(fp), "i%d fclose() failed\n", i); + + struct zint_symbol *symbol2 = ZBarcode_Create(); + assert_nonnull(symbol, "Symbol2 not created\n"); + + symbol2->debug = ZINT_DEBUG_TEST; // Needed to get codeword dump in errtxt + + (void)testUtilSetSymbol(symbol2, BARCODE_DATAMATRIX, data[i].input_mode | ESCAPE_MODE, data[i].eci, -1 /*option_1*/, -1, -1, -1 /*output_options*/, data[i].data, -1, debug); + + ret = ZBarcode_Encode_File(symbol2, input_filename); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode_File ret %d != %d (%s)\n", i, ret, data[i].ret, symbol2->errtxt); + assert_zero(strcmp(symbol2->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol2->errtxt, data[i].expected); + + ret = testUtilSymbolCmp(symbol2, symbol); + assert_zero(ret, "i:%d testUtilSymbolCmp symbol2 ret %d != 0\n", i, ret); + + assert_zero(remove(input_filename), "i:%d remove(%s) != 0 (%d)\n", i, input_filename, errno); + + ZBarcode_Delete(symbol2); } } @@ -474,6 +519,8 @@ static void test_valid_id(void) { testFinish(); } +STATIC_UNLESS_ZINT_TEST int error_tag(char error_string[100], int error_number); + static void test_error_tag(int index) { testStart(""); @@ -583,8 +630,6 @@ static void test_is_valid_utf8(int index) { testFinish(); } -STATIC_UNLESS_ZINT_TEST int error_tag(char error_string[100], int error_number); - int main(int argc, char *argv[]) { testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */ diff --git a/docs/manual.txt b/docs/manual.txt index a9e5991b..9f918ab6 100644 --- a/docs/manual.txt +++ b/docs/manual.txt @@ -23,7 +23,7 @@ of which it is possible to translate that data from either Unicode (UTF-8) or a raw 8-bit data stream. The image can be rendered as either a Portable Network Graphic (PNG) image, Windows Bitmap (BMP), Graphics Interchange Format (GIF), ZSoft Paintbrush image (PCX), Tagged Image File Format (TIF), Enhanced Metafile -Format (EMF), as Encapsulated Post Script (EPS), or as a Scalable Vector Graphic +Format (EMF), as Encapsulated PostScript (EPS), or as a Scalable Vector Graphic (SVG). Many options are available for setting the characteristics of the output image including the size and colour of the image, the amount of error correction used in the symbol and the orientation of the image. @@ -197,34 +197,35 @@ output file will be out.gif. The data input to Zint is assumed to be encoded in Unicode (UTF-8) format. If you are encoding characters beyond the 7-bit ASCII set using a scheme other than UTF-8 then you will need to set the appropriate input options as shown in -section 4.11 below. +section 4.10 below. Non-printing characters can be entered on the command line using the backslash (\) as an escape character in combination with the --esc switch. Permissible -characters are shown in the table below. +sequences are shown in the table below. --------------------------------------------------------------------- -Escape Character | ASCII Equivalent | Interpretation --------------------------------------------------------------------- -\0 | 0x00 | NUL character -\E | 0x04 | End of Transmission -\a | 0x07 | Bell -\b | 0x08 | Backspace -\t | 0x09 | Horizontal Tab -\n | 0x0A | Line Feed -\v | 0x0B | Vertical Tab -\f | 0x0C | Form Feed -\r | 0x0D | Carriage Return -\e | 0x1B | Escape -\G | 0x1D | Group Separator -\R | 0x1E | Record Separator -\\ | 0x5C | Backslash -\xNN | 0xNN | Any other 8-bit character - | | where NN is hexadecimal -\uNNNN | | Any 16-bit Unicode - | | character where NNNN - | | is hexadecimal --------------------------------------------------------------------- +------------------------------------------------------------------------------ +Escape Sequence | ASCII Equivalent | Name | Interpretation +------------------------------------------------------------------------------ +\0 | 0x00 | NUL | Null character +\E | 0x04 | EOT | End of Transmission +\a | 0x07 | BEL | Bell +\b | 0x08 | BS | Backspace +\t | 0x09 | HT | Horizontal Tab +\n | 0x0A | LF | Line Feed +\v | 0x0B | VT | Vertical Tab +\f | 0x0C | FF | Form Feed +\r | 0x0D | CR | Carriage Return +\e | 0x1B | ESC | Escape +\G | 0x1D | GS | Group Separator +\R | 0x1E | RS | Record Separator +\\ | 0x5C | \ | Backslash +\xNN | 0xNN | | Any 8-bit character where NN + | | | is hexadecimal +\uNNNN | | | Any 16-bit Unicode Basic + | | | Multilingual Plane (BMP) + | | | character where NNNN is + | | | hexadecimal +------------------------------------------------------------------------------ Input data can be read directly from file using the -i switch as shown below. The input file is assumed to be Unicode (UTF-8) formatted unless an alternative @@ -232,6 +233,10 @@ mode is selected. This command replaces the use of the -d switch. zint -i ./somefile.txt +Note that except when batch processing (section 4.11 below), the file should not +end with a newline (LF on Unix, CR+LF on Windows) unless you want the newline to +be encoded in the symbol. + 4.2 Directing Output -------------------- Output can be directed to a file other than the default using the -o switch. @@ -239,9 +244,9 @@ For example: zint -o here.png -d "This Text" -This draws a Code 128 barcode in the file here.png. If an encapsulated Post -Script file is needed simply append the file name with .eps, and so on for the -other supported file types: +This draws a Code 128 barcode in the file here.png. If an encapsulated +PostScript file is needed simply append the file name with .eps, and so on for +the other supported file types: zint -o there.eps -d "This Text" @@ -265,7 +270,7 @@ Numeric Value | Barcode Name 7 | Code 2 of 5 Industrial 8 | Code 3 of 9 (Code 39) 9 | Extended Code 3 of 9 (Code 39+) -13 | EAN (Including EAN-8 and EAN-13) +13 | EAN (including EAN-8 and EAN-13) 14 | EAN + Check Digit 16 | GS1-128 (UCC.EAN-128) 18 | Codabar @@ -292,7 +297,7 @@ Numeric Value | Barcode Name 52 | PZN 53 | Pharmacode Two-Track 55 | PDF417 -56 | Compact PDF417 +56 | Compact PDF417 (Truncated PDF417) 57 | MaxiCode 58 | QR Code 60 | Code 128 (Subset B) @@ -325,10 +330,11 @@ Numeric Value | Barcode Name 97 | Micro QR Code 98 | HIBC Code 128 99 | HIBC Code 39 -102 | HIBC Data Matrix +102 | HIBC Data Matrix ECC200 104 | HIBC QR Code 106 | HIBC PDF417 108 | HIBC MicroPDF417 +110 | HIBC Codablock-F 112 | HIBC Aztec Code 115 | DotCode 116 | Han Xin (Chinese Sensible) Code @@ -375,11 +381,11 @@ This specifies a whitespace width of 10 times the X-dimension of the symbol. 4.6 Adding boundary bars and boxes ---------------------------------- -Zint allows the symbol to be bound with 'boundary bars' using the option ---bind. These bars help to prevent misreading of the symbol by corrupting a -scan if the scanning beam strays off the top or bottom of the symbol. Zint can -also put a border right around the symbol and its whitespace with the --box -option. +Zint allows the symbol to be bound with 'boundary bars' (also known as 'bearer +bars') using the option --bind. These bars help to prevent misreading of the +symbol by corrupting a scan if the scanning beam strays off the top or bottom of +the symbol. Zint can also put a border right around the symbol and its +whitespace with the --box option. The width of the boundary or box can be specified using the --border switch. For example: @@ -469,17 +475,17 @@ doesn't need to be set) for GS1-128, EAN-14, DataBar and Composite symbologies but is also available for Aztec Code, Code 16k, Code 49, Code One, Data Matrix, DotCode, QR Code and Ultracode. -HIBC data may also be encoded in the symbologies Code 39, Code128, Codablock-F, -Data Matrix, QR Code, PDF417 and Aztec Code. Within this mode, the leading '+' -and the check character are automatically added, conforming to HIBC Labeler -Identification Code (HIBC LIC). For HIBC Provider Applications Standard +HIBC data may also be encoded in the symbologies Code 39, Code 128, Codablock-F, +Data Matrix, QR Code, PDF417, MicroPDF417 and Aztec Code. Within this mode, the +leading '+' and the check character are automatically added, conforming to HIBC +Labeler Identification Code (HIBC LIC). For HIBC Provider Applications Standard (HIBC PAS), preface the data with a slash "/". The --binary option encodes the input data as given. Automatic code page translations to ECI pages is disabled, and no validation of the data's encoding takes place. This may be used for raw binary or binary encrypted data. This switch plays together with the built-in ECI logic and examples may -be found in that section. +be found below. The --fullmultibyte option uses the multibyte modes of QR Code, Micro QR Code, Rectangular Micro QR Code, Han Xin Code and Grid Matrix for binary and Latin @@ -547,23 +553,37 @@ ECI Code | Character Encoding Scheme ------------------------------------------------------------ Three examples: -Ex1: The Euro sign U+20AC can be encoded in ISO/IEC 8859-15. -The Euro sign has the ISO/IEC 8859-15 codepoint hex A4. -It is encoded in UTF-8 as the hex sequence: e2 82 ac -Those 3 bytes are contained in the file "utf8euro.txt" -This command will generate the corresponding code: +Ex1: The Euro sign U+20AC can be encoded in ISO/IEC 8859-15. The Euro sign has +the ISO/IEC 8859-15 codepoint hex A4. It is encoded in UTF-8 as the hex +sequence: E2 82 AC. Those 3 bytes are contained in the file "utf8euro.txt". This +command will generate the corresponding code: -zint.exe -b 71 --square --scale 10 --eci 17 -i utf8euro.txt +zint -b 71 --square --scale 10 --eci 17 -i utf8euro.txt + +This is equivalent to the commands (using the --esc switch): + +zint -b 71 --square --scale 10 --eci 17 --esc -d "\xE2\x82\xAC" + +zint -b 71 --square --scale 10 --eci 17 --esc -d "\u20AC" Ex2: The Chinese character with Unicode codepoint U+5E38 can be encoded in Big5 -encoding. The Big5 representation of this character is the two hex bytes: 9C 75 +encoding. The Big5 representation of this character is the two hex bytes: B1 60 (contained in the file big5char.txt). The generation command for Data Matrix is: zint -b 71 --square --scale 10 --eci 28 --binary -i big5char.txt +This is equivalent to the command (using the --esc switch): + +zint -b 71 --square --scale 10 --eci 28 --binary --esc -d "\xB1\x60" + +and to the command (no --binary switch so conversion occurs): + +zint -b 71 --square --scale 10 --eci 28 --esc -d "\u5E38" + Ex3: Some decoders (in particular mobile app ones) for QR Code assume UTF-8 encoding by default and do not support ECI. In this case supply UTF-8 data and -use the --binary switch: +use the --binary switch so that the data will be encoded as UTF-8 without +conversion: zint -b 58 --binary -d "UTF-8 data" @@ -574,7 +594,7 @@ separate barcode image for each line of text in that file. To do this use the --batch switch. To select the input file from which to read data use the –i option. Zint will automatically detect the end of a line of text (in either Unix or Windows formatted text files) and produce a symbol each time it finds -this. Input files should end with a return character – if this is not present +this. Input files should end with a line feed character – if this is not present then Zint will not encode the last line of text, and will warn you that there is a problem. @@ -1056,7 +1076,7 @@ Value | 7 | BARCODE_C25IND | Code 2 of 5 Industrial 8 | BARCODE_CODE39 | Code 3 of 9 (Code 39) 9 | BARCODE_EXCODE39 | Extended Code 3 of 9 (Code 39+) -13 | BARCODE_EANX | EAN +13 | BARCODE_EANX | EAN (including EAN-8 and EAN-13) 14 | BARCODE_EANX_CHK | EAN + Check Digit 16* | BARCODE_GS1_128 | GS1-128 (UCC.EAN-128) 18 | BARCODE_CODABAR | Codabar @@ -1067,7 +1087,8 @@ Value | 24 | BARCODE_CODE49 | Code 49 25 | BARCODE_CODE93 | Code 93 28 | BARCODE_FLAT | Flattermarken -29* | BARCODE_DBAR_OMN | GS1 DataBar Omnidirectional +29* | BARCODE_DBAR_OMN | GS1 DataBar Omnidirectional (including + | | GS1 DataBar Truncated) 30* | BARCODE_DBAR_LTD | GS1 DataBar Limited 31* | BARCODE_DBAR_EXP | GS1 DataBar Expanded 32 | BARCODE_TELEPEN | Telepen Alpha @@ -1120,7 +1141,7 @@ Value | 104 | BARCODE_HIBC_QR | HIBC QR Code 106 | BARCODE_HIBC_PDF | HIBC PDF417 108 | BARCODE_HIBC_MICPDF | HIBC MicroPDF417 -110 | BARCODE_HIBC_BLOCKF | HIBC Codablock F +110 | BARCODE_HIBC_BLOCKF | HIBC Codablock-F 112 | BARCODE_HIBC_AZTEC | HIBC Aztec Code 115 | BARCODE_DOTCODE | DotCode 116 | BARCODE_HANXIN | Han Xin (Chinese Sensible) Code @@ -1154,8 +1175,8 @@ Value | Note: Symbologies marked with an asterisk (*) in the above table used different names in Zint before version 2.9.0. For example, symbology 29 used the name -"BARCODE_RSS14". These names are now depreciated but are still recognised by -Zint and will continue to be supported in future versions. +"BARCODE_RSS14". These names are now deprecated but are still recognised by Zint +and will continue to be supported in future versions. 5.8 Adjusting other output options ---------------------------------- @@ -2962,7 +2983,7 @@ v2.7.0 - new features: - New GS1 AIs 7240, 235, 417, 7040, 8026, updated checks for 7007, 8008 - New Symbology rMQR - QR and Gridmatrix optimisation for GB2312 -- removed depreciated interface for gLabels program. Please use current +- removed deprecated interface for gLabels program. Please use current interface. v2.8.0 @@ -3032,7 +3053,7 @@ international standards: > ANSI/AIM BC6-2000 - Uniform Symbology Specification Code 49 > ANSI/HIBC 2.6-2016 - The Health Industry Bar Code (HIBC) Supplier Labeling Standard -> AIM ISS-X-24 - Uniform Symbology Specification Codablock F +> AIM ISS-X-24 - Uniform Symbology Specification Codablock-F > AIMD013 (v 1.34a) – Information technology – Automatic identification and data capture techniques – Bar code symbology specification – DotCode (Revised 19th Feb 2009) diff --git a/frontend/main.c b/frontend/main.c index 2643f312..e83a4659 100644 --- a/frontend/main.c +++ b/frontend/main.c @@ -430,6 +430,8 @@ static int batch_process(struct zint_symbol *symbol, char *filename, int mirror_ i++; if (buffer[i] == 'x') { i += 2; + } else if (buffer[i] == 'u') { + i += 4; } } i++; diff --git a/frontend/tests/test_args.c b/frontend/tests/test_args.c index f11549aa..b1c19569 100644 --- a/frontend/tests/test_args.c +++ b/frontend/tests/test_args.c @@ -290,6 +290,7 @@ static void test_input(int index, int debug) { struct item { int b; int batch; + int input_mode; int mirror; char *filetype; char *input; @@ -300,18 +301,22 @@ static void test_input(int index, int debug) { }; // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<")) struct item data[] = { - /* 0*/ { BARCODE_CODE128, 1, 0, NULL, "123\n456\n", "test_batch~.png", 2, "test_batch1.png\000test_batch2.png" }, - /* 1*/ { BARCODE_CODE128, 1, 1, NULL, "123\n456\n7890123456789\n", NULL, 3, "123.png\000456.png\0007890123456789.png" }, - /* 2*/ { BARCODE_CODE128, 1, 1, "svg", "123\n456\n7890123456789\n", NULL, 3, "123.svg\000456.svg\0007890123456789.svg" }, - /* 3*/ { BARCODE_CODE128, 1, 0, NULL, "\n", "test_batch.png", 0, NULL }, - /* 4*/ { BARCODE_CODE128, 1, 0, NULL, "123\n456\n", "test_67890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890~.png", 2, "test_678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901.png\000test_678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678902.png" }, - /* 5*/ { BARCODE_CODE128, 0, 0, "svg", "123", "test_678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901.png", 1, "test_678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901.svg" }, - /* 6*/ { BARCODE_CODE128, 1, 0, "svg", "123\n", "test_678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901.png", 1, "test_678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901.svg" }, - /* 7*/ { BARCODE_CODE128, 1, 0, NULL, "123\n", "test_batch.jpeg", 1, "test_batch.jpeg.png" }, - /* 8*/ { BARCODE_CODE128, 1, 0, NULL, "123\n", "test_batch.jpg", 1, "test_batch.png" }, - /* 9*/ { BARCODE_CODE128, 1, 0, "emf", "123\n", "test_batch.jpeg", 1, "test_batch.jpeg.emf" }, - /* 10*/ { BARCODE_CODE128, 1, 0, "emf", "123\n", "test_batch.jpg", 1, "test_batch.emf" }, - /* 11*/ { BARCODE_CODE128, 1, 0, "eps", "123\n", "test_batch.ps", 1, "test_batch.eps" }, + /* 0*/ { BARCODE_CODE128, 1, -1, 0, NULL, "123\n456\n", "test_batch~.png", 2, "test_batch1.png\000test_batch2.png" }, + /* 1*/ { BARCODE_CODE128, 1, -1, 1, NULL, "123\n456\n7890123456789\n", NULL, 3, "123.png\000456.png\0007890123456789.png" }, + /* 2*/ { BARCODE_CODE128, 1, -1, 1, "svg", "123\n456\n7890123456789\n", NULL, 3, "123.svg\000456.svg\0007890123456789.svg" }, + /* 3*/ { BARCODE_CODE128, 1, -1, 1, NULL, "123\n456\n7890123456789\nA\\xA0B\n", NULL, 4, "123.png\000456.png\0007890123456789.png\000A_xA0B.png" }, + /* 4*/ { BARCODE_CODE128, 1, ESCAPE_MODE, 1, NULL, "123\n456\n7890123456789\nA\\xA0B\n", NULL, 4, "123.png\000456.png\0007890123456789.png\000A_B.png" }, + /* 5*/ { BARCODE_CODE128, 1, -1, 1, NULL, "123\n456\n7890123456789\nA\\u00A0B\n", NULL, 4, "123.png\000456.png\0007890123456789.png\000A_u00A0B.png" }, + /* 6*/ { BARCODE_CODE128, 1, ESCAPE_MODE, 1, NULL, "123\n456\n7890123456789\nA\\u00A0B\n", NULL, 4, "123.png\000456.png\0007890123456789.png\000A_B.png" }, + /* 7*/ { BARCODE_CODE128, 1, -1, 0, NULL, "\n", "test_batch.png", 0, NULL }, + /* 8*/ { BARCODE_CODE128, 1, -1, 0, NULL, "123\n456\n", "test_67890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890~.png", 2, "test_678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901.png\000test_678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678902.png" }, + /* 9*/ { BARCODE_CODE128, 0, -1, 0, "svg", "123", "test_678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901.png", 1, "test_678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901.svg" }, + /* 10*/ { BARCODE_CODE128, 1, -1, 0, "svg", "123\n", "test_678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901.png", 1, "test_678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901.svg" }, + /* 11*/ { BARCODE_CODE128, 1, -1, 0, NULL, "123\n", "test_batch.jpeg", 1, "test_batch.jpeg.png" }, + /* 12*/ { BARCODE_CODE128, 1, -1, 0, NULL, "123\n", "test_batch.jpg", 1, "test_batch.png" }, + /* 13*/ { BARCODE_CODE128, 1, -1, 0, "emf", "123\n", "test_batch.jpeg", 1, "test_batch.jpeg.emf" }, + /* 14*/ { BARCODE_CODE128, 1, -1, 0, "emf", "123\n", "test_batch.jpg", 1, "test_batch.emf" }, + /* 15*/ { BARCODE_CODE128, 1, -1, 0, "eps", "123\n", "test_batch.ps", 1, "test_batch.eps" }, }; int data_size = ARRAY_SIZE(data); @@ -332,6 +337,7 @@ static void test_input(int index, int debug) { arg_int(cmd, "-b ", data[i].b); arg_bool(cmd, "--batch", data[i].batch); + arg_input_mode(cmd, data[i].input_mode); arg_bool(cmd, "--mirror", data[i].mirror); arg_data(cmd, "--filetype=", data[i].filetype); arg_input(cmd, input_filename, data[i].input);