Handle UNICODE_MODE ECI conversion for reduced charset barcodes and QRCODE/MICROQR

This commit is contained in:
gitlost 2019-11-27 16:16:14 +00:00
parent 385a0a246f
commit fed7378675
36 changed files with 17680 additions and 7275 deletions

View File

@ -4,7 +4,7 @@ project(zint)
find_package(PNG)
set(zint_COMMON_SRCS common.c library.c render.c large.c reedsol.c gs1.c eci.c general_field.c)
set(zint_COMMON_SRCS common.c library.c large.c reedsol.c gs1.c eci.c general_field.c sjis.c)
set(zint_ONEDIM_SRCS code.c code128.c 2of5.c upcean.c telepen.c medical.c plessey.c rss.c)
set(zint_POSTAL_SRCS postal.c auspost.c imail.c mailmark.c)
set(zint_TWODIM_SRCS code16k.c codablock.c dmatrix.c pdf417.c qr.c maxicode.c composite.c aztec.c code49.c code1.c gridmtx.c hanxin.c dotcode.c ultra.c)

View File

@ -29,6 +29,7 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
/* vim: set ts=4 sw=4 et : */
#include <stdio.h>
#include <string.h>
@ -987,7 +988,7 @@ int aztec(struct zint_symbol *symbol, unsigned char source[], const size_t lengt
memset(binary_string, 0, 20000);
memset(adjusted_string, 0, 20000);
if (symbol->input_mode == GS1_MODE) {
if ((symbol->input_mode & 0x07) == GS1_MODE) {
gs1 = 1;
} else {
gs1 = 0;

View File

@ -29,6 +29,7 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
/* vim: set ts=4 sw=4 et : */
#include <stdio.h>
#include <math.h>
@ -660,7 +661,7 @@ int codablock(struct zint_symbol *symbol,const unsigned char source[], const siz
return ZINT_ERROR_INVALID_OPTION;
}
/* GS1 not implemented */
if (symbol->input_mode == GS1_MODE) {
if ((symbol->input_mode & 0x07) == GS1_MODE) {
strcpy(symbol->errtxt, "412: GS1 mode not supported");
return ZINT_ERROR_INVALID_OPTION;
}

View File

@ -29,6 +29,7 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
/* vim: set ts=4 sw=4 et : */
#include "common.h"
#include "code1.h"
@ -369,7 +370,7 @@ int c1_encode(struct zint_symbol *symbol, unsigned char source[], unsigned int t
edi_p = 0;
strcpy(decimal_binary, "");
if (symbol->input_mode == GS1_MODE) {
if ((symbol->input_mode & 0x07) == GS1_MODE) {
gs1 = 1;
} else {
gs1 = 0;

View File

@ -29,6 +29,7 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
/* vim: set ts=4 sw=4 et : */
/* Updated to comply with BS EN 12323:2005 */
@ -273,7 +274,7 @@ int code16k(struct zint_symbol *symbol, unsigned char source[], const size_t len
strcpy(width_pattern, "");
input_length = length;
if (symbol->input_mode == GS1_MODE) {
if ((symbol->input_mode & 0x07) == GS1_MODE) {
gs1 = 1;
} else {
gs1 = 0;

View File

@ -29,6 +29,7 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
/* vim: set ts=4 sw=4 et : */
#include <string.h>
#include <stdio.h>
@ -55,7 +56,7 @@ int code_49(struct zint_symbol *symbol, unsigned char source[], const int length
strcpy(symbol->errtxt, "430: Input too long");
return ZINT_ERROR_TOO_LONG;
}
if (symbol->input_mode == GS1_MODE) {
if ((symbol->input_mode & 0x07) == GS1_MODE) {
gs1 = 1;
strcpy(intermediate, "*"); /* FNC1 */
} else {

View File

@ -260,56 +260,81 @@ int istwodigits(const unsigned char source[], const size_t position) {
return 0;
}
/* State machine to decode UTF-8 to Unicode codepoints (state 0 means done, state 12 means error) */
unsigned int decode_utf8(unsigned int* state, unsigned int* codep, const unsigned char byte) {
/*
Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
See https://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details.
*/
static const unsigned char utf8d[] = {
/* The first part of the table maps bytes to character classes that
* reduce the size of the transition table and create bitmasks. */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8,
/* The second part is a transition table that maps a combination
* of a state of the automaton and a character class to a state. */
0,12,24,36,60,96,84,12,12,12,48,72, 12,12,12,12,12,12,12,12,12,12,12,12,
12, 0,12,12,12,12,12, 0,12, 0,12,12, 12,24,12,12,12,12,12,24,12,24,12,12,
12,12,12,12,12,12,12,24,12,12,12,12, 12,24,12,12,12,12,12,12,12,24,12,12,
12,12,12,12,12,12,12,36,12,36,12,12, 12,36,12,12,12,12,12,36,12,36,12,12,
12,36,12,12,12,12,12,12,12,12,12,12,
};
unsigned int type = utf8d[byte];
*codep = *state != 0 ? (byte & 0x3fu) | (*codep << 6) : (0xff >> type) & byte;
*state = utf8d[256 + *state + type];
return *state;
}
/* Convert UTF-8 to UTF-16 for codepoints <= U+FFFF (ie four-byte sequences (requiring UTF-16 surrogates) not allowed) */
int utf8toutf16(struct zint_symbol *symbol, const unsigned char source[], int vals[], size_t *length) {
size_t bpos;
int jpos, error_number;
int next;
int jpos;
unsigned int codepoint, state = 0;
bpos = 0;
jpos = 0;
error_number = 0;
next = 0;
do {
if (source[bpos] <= 0x7f) {
/* 1 byte mode (7-bit ASCII) */
vals[jpos] = source[bpos];
next = bpos + 1;
jpos++;
} else {
if ((source[bpos] >= 0x80) && (source[bpos] <= 0xbf)) {
strcpy(symbol->errtxt, "240: Corrupt Unicode data");
return ZINT_ERROR_INVALID_DATA;
}
if ((source[bpos] >= 0xc0) && (source[bpos] <= 0xc1)) {
strcpy(symbol->errtxt, "241: Overlong encoding not supported");
return ZINT_ERROR_INVALID_DATA;
}
while (bpos < *length) {
do {
decode_utf8(&state, &codepoint, source[bpos++]);
} while (bpos < *length && state != 0 && state != 12);
if ((source[bpos] >= 0xc2) && (source[bpos] <= 0xdf)) {
/* 2 byte mode */
vals[jpos] = ((source[bpos] & 0x1f) << 6) + (source[bpos + 1] & 0x3f);
next = bpos + 2;
jpos++;
} else
if ((source[bpos] >= 0xe0) && (source[bpos] <= 0xef)) {
/* 3 byte mode */
vals[jpos] = ((source[bpos] & 0x0f) << 12) + ((source[bpos + 1] & 0x3f) << 6) + (source[bpos + 2] & 0x3f);
next = bpos + 3;
jpos++;
} else
if (source[bpos] >= 0xf0) {
strcpy(symbol->errtxt, "242: Unicode sequences of more than 3 bytes not supported");
return ZINT_ERROR_INVALID_DATA;
}
if (state != 0) {
strcpy(symbol->errtxt, "240: Corrupt Unicode data");
return ZINT_ERROR_INVALID_DATA;
}
if (codepoint > 0xffff) {
strcpy(symbol->errtxt, "242: Unicode sequences of more than 3 bytes not supported");
return ZINT_ERROR_INVALID_DATA;
}
bpos = next;
vals[jpos] = codepoint;
jpos++;
} while (bpos < *length);
}
*length = jpos;
return error_number;
return 0;
}

View File

@ -73,6 +73,7 @@ extern "C" {
extern int is_stackable(const int symbology);
extern int is_extendable(const int symbology);
extern int is_composite(const int symbology);
extern unsigned int decode_utf8(unsigned int* state, unsigned int* codep, const unsigned char byte);
extern int utf8toutf16(struct zint_symbol *symbol, const unsigned char source[], int vals[], size_t *length);
extern void set_minimum_height(struct zint_symbol *symbol, const int min_height);
#ifdef __cplusplus

View File

@ -37,6 +37,7 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
/* vim: set ts=4 sw=4 et : */
#include <stdio.h>
#include <stdlib.h>
@ -528,7 +529,7 @@ static int look_ahead_test(const unsigned char inputData[], const size_t sourcel
/* Encodes data using ASCII, C40, Text, X12, EDIFACT or Base 256 modes as appropriate
Supports encoding FNC1 in supporting systems */
static int dm200encode(struct zint_symbol *symbol, const unsigned char source[], unsigned char target[], int *last_mode, size_t *length_p, int process_buffer[], int *process_p) {
static int dm200encode(struct zint_symbol *symbol, const unsigned char source[], unsigned char target[], int *last_mode, size_t *length_p, int process_buffer[], int *process_p, int *binlen_p) {
size_t sp;
int tp, i, gs1;
@ -536,9 +537,9 @@ static int dm200encode(struct zint_symbol *symbol, const unsigned char source[],
size_t inputlen = *length_p;
int debug = symbol->debug;
#ifndef _MSC_VER
char binary[2 * inputlen];
char binary[2 * inputlen + 1 + 4 + 1]; /* Allow for GS1/READER_INIT, ECI and nul chars overhead */
#else
char* binary = (char*) _alloca(2 * inputlen);
char* binary = (char*) _alloca(2 * inputlen + 1 + 4 + 1);
#endif
sp = 0;
@ -552,7 +553,7 @@ static int dm200encode(struct zint_symbol *symbol, const unsigned char source[],
next_mode = DM_ASCII;
/* gs1 flag values: 0: no gs1, 1: gs1 with FNC1 serparator, 2: GS separator */
if (symbol->input_mode == GS1_MODE) {
if ((symbol->input_mode & 0x07) == GS1_MODE) {
if (symbol->output_options & GS1_GS_SEPARATOR) {
gs1 = 2;
} else {
@ -971,7 +972,8 @@ static int dm200encode(struct zint_symbol *symbol, const unsigned char source[],
}
if (tp > 1558) {
return 0;
strcpy(symbol->errtxt, "520: Data too long to fit in symbol");
return ZINT_ERROR_TOO_LONG;
}
} /* while */
@ -1018,7 +1020,8 @@ static int dm200encode(struct zint_symbol *symbol, const unsigned char source[],
}
*(last_mode) = current_mode;
return tp;
*binlen_p = tp;
return 0;
}
static int dm200encode_remainder(unsigned char target[], int target_length, const unsigned char source[], const size_t inputlen, const int last_mode, const int process_buffer[], const int process_p, const int symbols_left) {
@ -1162,8 +1165,8 @@ static void add_tail(unsigned char target[], int tp, const int tail_length) {
}
int data_matrix_200(struct zint_symbol *symbol,const unsigned char source[], const size_t in_length) {
int i, skew = 0;
size_t inputlen=in_length;
int i, skew = 0;
size_t inputlen = in_length;
unsigned char binary[2200];
int binlen;
int process_buffer[8]; /* holds remaining data to finalised */
@ -1175,11 +1178,9 @@ int data_matrix_200(struct zint_symbol *symbol,const unsigned char source[], con
int symbols_left;
/* inputlen may be decremented by 2 if macro character is used */
binlen = dm200encode(symbol, source, binary, &last_mode, &inputlen, process_buffer, &process_p);
if (binlen == 0) {
strcpy(symbol->errtxt, "520: Data too long to fit in symbol");
return ZINT_ERROR_TOO_LONG;
error_number = dm200encode(symbol, source, binary, &last_mode, &inputlen, process_buffer, &process_p, &binlen);
if (error_number != 0) {
return error_number;
}
if ((symbol->option_2 >= 1) && (symbol->option_2 <= DMSIZESCOUNT)) {

View File

@ -29,6 +29,7 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
/* vim: set ts=4 sw=4 et : */
/*
* Attempts to encode DotCode according to AIMD013 Rev 1.34a, dated Feb 19, 2009
@ -475,7 +476,7 @@ int dotcode_encode_message(struct zint_symbol *symbol, const unsigned char sourc
array_length++;
}
if (symbol->input_mode != GS1_MODE) {
if ((symbol->input_mode & 0x07) != GS1_MODE) {
if (length > 2) {
if (((source[input_position] >= '0') && (source[input_position] <= '9')) &&
((source[input_position + 1] >= '0') && (source[input_position + 1] <= '9'))) {
@ -650,7 +651,7 @@ int dotcode_encode_message(struct zint_symbol *symbol, const unsigned char sourc
}
if ((!done) && (encoding_mode == 'C')) {
if (datum_c(source, input_position, length) || ((source[input_position] == '[') && (symbol->input_mode == GS1_MODE))) {
if (datum_c(source, input_position, length) || ((source[input_position] == '[') && ((symbol->input_mode & 0x07) == GS1_MODE))) {
if (source[input_position] == '[') {
codeword_array[array_length] = 107; // FNC1
input_position++;
@ -751,7 +752,7 @@ int dotcode_encode_message(struct zint_symbol *symbol, const unsigned char sourc
/* Step C2 */
if ((!done) && (encoding_mode == 'B')) {
if ((source[input_position] == '[') && (symbol->input_mode == GS1_MODE)) {
if ((source[input_position] == '[') && ((symbol->input_mode & 0x07) == GS1_MODE)) {
codeword_array[array_length] = 107; // FNC1
array_length++;
input_position++;
@ -879,7 +880,7 @@ int dotcode_encode_message(struct zint_symbol *symbol, const unsigned char sourc
/* Step D2 */
if ((!done) && (encoding_mode == 'A')) {
if ((source[input_position] == '[') && (symbol->input_mode == GS1_MODE)) {
if ((source[input_position] == '[') && ((symbol->input_mode & 0x07) == GS1_MODE)) {
codeword_array[array_length] = 107; // FNC1
array_length++;
input_position++;

View File

@ -28,6 +28,7 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
/* vim: set ts=4 sw=4 et : */
/* This code attempts to implement Han Xin Code according to AIMD-015:2010 (Rev 0.8) */
@ -368,6 +369,7 @@ static void calculate_binary(char binary[], char mode[], int source[], const siz
printf("Numeric\n");
}
count = 0; /* Suppress gcc -Wmaybe-uninitialized */
i = 0;
while (i < block_length) {
@ -1131,8 +1133,8 @@ int hx_apply_bitmask(unsigned char *grid, int size) {
unsigned char p;
#ifndef _MSC_VER
unsigned char mask[size * size];
unsigned char eval[size * size];
unsigned char mask[(unsigned int)(size * size)]; /* Cast to suppress gcc -Walloc-size-larger-than */
unsigned char eval[(unsigned int)(size * size)];
#else
unsigned char* mask = (unsigned char *) _alloca((size * size) * sizeof (unsigned char));
unsigned char* eval = (unsigned char *) _alloca((size * size) * sizeof (unsigned char));
@ -1249,7 +1251,7 @@ int han_xin(struct zint_symbol *symbol, const unsigned char source[], size_t len
unsigned char *grid;
#endif
if ((symbol->input_mode == DATA_MODE) || (symbol->eci != 0)) {
if (((symbol->input_mode & 0x07) == DATA_MODE) || (symbol->eci != 0)) {
for (i = 0; i < length; i++) {
gbdata[i] = (int) source[i];
}

View File

@ -640,11 +640,13 @@ int ZBarcode_ValidID(int symbol_id) {
return result;
}
static int extended_charset(struct zint_symbol *symbol, const unsigned char *source, const int length) {
static int reduced_charset(struct zint_symbol *symbol, const unsigned char *source, size_t in_length);
static int extended_or_reduced_charset(struct zint_symbol *symbol, const unsigned char *source, const int length) {
int error_number = 0;
/* These are the "elite" standards which can support multiple character sets */
switch (symbol->symbology) {
/* These are the "elite" standards which have support for specific character sets */
case BARCODE_QRCODE: error_number = qr_code(symbol, source, length);
break;
case BARCODE_MICROQR: error_number = microqr(symbol, source, length);
@ -655,13 +657,15 @@ static int extended_charset(struct zint_symbol *symbol, const unsigned char *sou
break;
case BARCODE_UPNQR: error_number = upnqr(symbol, source, length);
break;
default: error_number = reduced_charset(symbol, source, length);
break;
}
return error_number;
}
static int reduced_charset(struct zint_symbol *symbol, const unsigned char *source, size_t in_length) {
/* These are the "norm" standards which only support Latin-1 at most */
/* These are the "norm" standards which only support Latin-1 at most, though a few support ECI */
int error_number = 0;
#ifndef _MSC_VER
@ -693,7 +697,8 @@ static int reduced_charset(struct zint_symbol *symbol, const unsigned char *sour
preprocessed[in_length] = '\0';
break;
case UNICODE_MODE:
error_number = utf_to_eci(symbol->eci, source, preprocessed, &in_length);
/* Prior check ensures ECI only set for those that support it */
error_number = utf_to_eci(symbol->eci && symbol->eci <= 899 ? symbol->eci : 3, source, preprocessed, &in_length);
if (error_number != 0) {
strcpy(symbol->errtxt, "204: Invalid characters in input data");
return error_number;
@ -941,7 +946,7 @@ int escape_char_process(struct zint_symbol *symbol, unsigned char *input_string,
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 & UNICODE_MODE) != 0) {
if (hex1 > 7 && (symbol->input_mode & 0x07) == UNICODE_MODE) {
// Convert to UTF-8
escaped_string[out_posn] = 0xc0 + (hex1 >> 2);
out_posn++;
@ -980,7 +985,6 @@ int escape_char_process(struct zint_symbol *symbol, unsigned char *input_string,
int ZBarcode_Encode(struct zint_symbol *symbol, const unsigned char *source, int in_length) {
int error_number, error_buffer, i;
int input_mode = symbol->input_mode;
#ifdef _MSC_VER
unsigned char* local_source;
#endif
@ -1146,6 +1150,10 @@ int ZBarcode_Encode(struct zint_symbol *symbol, const unsigned char *source, int
error_number = ZINT_ERROR_INVALID_OPTION;
}
if ((symbol->input_mode & 0x07) > 2) {
symbol->input_mode = DATA_MODE; /* Reset completely */
}
if (error_number > 4) {
error_tag(symbol->errtxt, error_number);
return error_number;
@ -1157,16 +1165,19 @@ int ZBarcode_Encode(struct zint_symbol *symbol, const unsigned char *source, int
local_source[in_length] = '\0';
/* Start acting on input mode */
if (input_mode & ESCAPE_MODE) {
if (symbol->input_mode & ESCAPE_MODE) {
error_number = escape_char_process(symbol, local_source, &in_length);
if (error_number != 0) {
error_tag(symbol->errtxt, error_number);
return error_number;
}
input_mode -= ESCAPE_MODE;
}
if ((input_mode == GS1_MODE) || (check_force_gs1(symbol->symbology))) {
if ((symbol->input_mode & 0x07) == UNICODE_MODE) {
strip_bom(local_source, &in_length);
}
if (((symbol->input_mode & 0x07) == GS1_MODE) || (check_force_gs1(symbol->symbology))) {
if (gs1_compliant(symbol->symbology) == 1) {
// Reduce input for composite and non-forced symbologies, others (EAN128 and RSS_EXP based) will handle it themselves
if (is_composite(symbol->symbology) || !check_force_gs1(symbol->symbology)) {
@ -1190,68 +1201,21 @@ int ZBarcode_Encode(struct zint_symbol *symbol, const unsigned char *source, int
}
}
if ((input_mode < 0) || (input_mode > 2)) {
input_mode = DATA_MODE;
}
if ((symbol->eci != 0) && (symbol->eci != 26)) {
input_mode = DATA_MODE;
}
error_number = extended_or_reduced_charset(symbol, local_source, in_length);
if (input_mode == UNICODE_MODE) {
strip_bom(local_source, &in_length);
}
switch (symbol->symbology) {
case BARCODE_QRCODE:
case BARCODE_MICROQR:
case BARCODE_GRIDMATRIX:
case BARCODE_HANXIN:
case BARCODE_UPNQR:
error_number = extended_charset(symbol, local_source, in_length);
break;
default:
error_number = reduced_charset(symbol, local_source, in_length);
break;
}
if ((error_number == ZINT_ERROR_INVALID_DATA) && (supports_eci(symbol->symbology)
&& (input_mode == UNICODE_MODE))) {
if ((error_number == ZINT_ERROR_INVALID_DATA) && symbol->eci == 0 && supports_eci(symbol->symbology)
&& (symbol->input_mode & 0x07) == UNICODE_MODE) {
/* Try another ECI mode */
symbol->eci = get_best_eci(local_source, in_length);
switch (symbol->symbology) {
case BARCODE_QRCODE:
case BARCODE_MICROQR:
case BARCODE_GRIDMATRIX:
case BARCODE_HANXIN:
{
#ifndef _MSC_VER
unsigned char temp[in_length + 1];
#else
unsigned char *temp = (unsigned char*) _alloca(in_length + 1);
#endif
size_t temp_len = in_length;
memcpy(temp, local_source, temp_len);
temp[temp_len] = '\0';
error_number = utf_to_eci(symbol->eci, local_source, temp, &temp_len);
if (error_number == 0) {
in_length = (int) temp_len;
memcpy(local_source, temp, in_length);
local_source[in_length] = '\0';
error_number = extended_charset(symbol, local_source, in_length);
}
}
break;
default:
error_number = reduced_charset(symbol, local_source, in_length);
break;
}
error_number = extended_or_reduced_charset(symbol, local_source, in_length);
if (error_number == 0) {
error_number = ZINT_WARN_USES_ECI;
strcpy(symbol->errtxt, "222: Encoded data includes ECI");
if (symbol->debug) printf("Data ECI %d\n", symbol->eci);
if (!(symbol->debug & ZINT_DEBUG_TEST)) {
strcpy(symbol->errtxt, "222: Encoded data includes ECI");
}
if (symbol->debug & ZINT_DEBUG_PRINT) printf("Data ECI %d\n", symbol->eci);
}
}
@ -1269,7 +1233,7 @@ int ZBarcode_Encode(struct zint_symbol *symbol, const unsigned char *source, int
}
error_tag(symbol->errtxt, error_number);
if (error_number <= 5) {
if (error_number < 5) {
check_row_heights(symbol);
}

View File

@ -30,6 +30,7 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
/* vim: set ts=4 sw=4 et : */
#include <string.h>
#include <stdlib.h>
@ -582,11 +583,9 @@ int japan_post(struct zint_symbol *symbol, unsigned char source[], int length) {
}
if (check <= 9) {
check_char = check + '0';
}
if (check == 10) {
} else if (check == 10) {
check_char = '-';
}
if (check >= 11) {
} else {
check_char = (check - 11) + 'a';
}
strcat(pattern, JapanTable[posn(KASUTSET, check_char)]);

View File

@ -29,6 +29,7 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
/* vim: set ts=4 sw=4 et : */
#include <string.h>
#ifdef _MSC_VER
@ -47,15 +48,14 @@ extern int utf_to_eci(const int eci, const unsigned char source[], unsigned char
/* Returns true if input glyph is in the Alphanumeric set */
static int in_alpha(const int glyph) {
int retval = 0;
char cglyph = (char) glyph;
if ((cglyph >= '0') && (cglyph <= '9')) {
if ((glyph >= '0') && (glyph <= '9')) {
retval = 1;
}
if ((cglyph >= 'A') && (cglyph <= 'Z')) {
if ((glyph >= 'A') && (glyph <= 'Z')) {
retval = 1;
}
switch (cglyph) {
switch (glyph) {
case ' ':
case '$':
case '%':
@ -72,7 +72,7 @@ static int in_alpha(const int glyph) {
return retval;
}
static void define_mode(char mode[],const int jisdata[], const size_t length,const int gs1) {
static void define_mode(char mode[], const unsigned int jisdata[], const size_t length, const int gs1) {
/* Values placed into mode[] are: K = Kanji, B = Binary, A = Alphanumeric, N = Numeric */
size_t i;
int mlen, j;
@ -95,16 +95,18 @@ static void define_mode(char mode[],const int jisdata[], const size_t length,con
}
/* If less than 6 numeric digits together then don't use numeric mode */
for (i = 0; i < length; i++) {
if (mode[i] == 'N') {
if (((i != 0) && (mode[i - 1] != 'N')) || (i == 0)) {
mlen = 0;
while (((mlen + i) < length) && (mode[mlen + i] == 'N')) {
mlen++;
};
if (mlen < 6) {
for (j = 0; j < mlen; j++) {
mode[i + j] = 'A';
if (ustrchr_cnt((unsigned char*) mode, length, 'N') != length) {
for (i = 0; i < length; i++) {
if (mode[i] == 'N') {
if (((i != 0) && (mode[i - 1] != 'N')) || (i == 0)) {
mlen = 0;
while (((mlen + i) < length) && (mode[mlen + i] == 'N')) {
mlen++;
};
if (mlen < 6) {
for (j = 0; j < mlen; j++) {
mode[i + j] = 'A';
}
}
}
}
@ -112,16 +114,18 @@ static void define_mode(char mode[],const int jisdata[], const size_t length,con
}
/* If less than 4 alphanumeric characters together then don't use alphanumeric mode */
for (i = 0; i < length; i++) {
if (mode[i] == 'A') {
if (((i != 0) && (mode[i - 1] != 'A')) || (i == 0)) {
mlen = 0;
while (((mlen + i) < length) && (mode[mlen + i] == 'A')) {
mlen++;
};
if (mlen < 4) {
for (j = 0; j < mlen; j++) {
mode[i + j] = 'B';
if (ustrchr_cnt((unsigned char*) mode, length, 'A') != length) {
for (i = 0; i < length; i++) {
if (mode[i] == 'A') {
if (((i != 0) && (mode[i - 1] != 'A')) || (i == 0)) {
mlen = 0;
while (((mlen + i) < length) && (mode[mlen + i] == 'A')) {
mlen++;
};
if (mlen < 4) {
for (j = 0; j < mlen; j++) {
mode[i + j] = 'B';
}
}
}
}
@ -147,7 +151,8 @@ static int tribus(const int version,const int a,const int b,const int c) {
}
/* Convert input data to a binary stream and add padding */
static void qr_binary(int datastream[], const int version, const int target_binlen, const char mode[], const int jisdata[], const size_t length, const int gs1, const int eci, const int est_binlen,const int debug) {
static void qr_binary(unsigned char datastream[], const int version, const int target_binlen, const char mode[], const unsigned int jisdata[], const size_t length,
const int gs1, const int eci, const int est_binlen, const int debug) {
int position = 0;
int i;
char padbits;
@ -177,7 +182,7 @@ static void qr_binary(int datastream[], const int version, const int target_binl
}
}
if (debug) {
if (debug & ZINT_DEBUG_PRINT) {
for (i = 0; i < length; i++) {
printf("%c", mode[i]);
}
@ -189,7 +194,11 @@ static void qr_binary(int datastream[], const int version, const int target_binl
do {
char data_block = mode[position];
int short_data_block_length = 0;
int double_byte = 0;
do {
if (data_block == 'B' && jisdata[position + short_data_block_length] > 0xFF) {
double_byte++;
}
short_data_block_length++;
} while (((short_data_block_length + position) < length)
&& (mode[position + short_data_block_length] == data_block));
@ -203,13 +212,13 @@ static void qr_binary(int datastream[], const int version, const int target_binl
/* Character count indicator */
bin_append(short_data_block_length, tribus(version, 8, 10, 12), binary);
if (debug) {
if (debug & ZINT_DEBUG_PRINT) {
printf("Kanji block (length %d)\n\t", short_data_block_length);
}
/* Character representation */
for (i = 0; i < short_data_block_length; i++) {
int jis = jisdata[position + i];
unsigned int jis = jisdata[position + i];
int prod;
if (jis >= 0x8140 && jis <= 0x9ffc)
@ -222,12 +231,12 @@ static void qr_binary(int datastream[], const int version, const int target_binl
bin_append(prod, 13, binary);
if (debug) {
if (debug & ZINT_DEBUG_PRINT) {
printf("0x%4X ", prod);
}
}
if (debug) {
if (debug & ZINT_DEBUG_PRINT) {
printf("\n");
}
@ -238,28 +247,28 @@ static void qr_binary(int datastream[], const int version, const int target_binl
strcat(binary, "0100");
/* Character count indicator */
bin_append(short_data_block_length, tribus(version, 8, 16, 16), binary);
bin_append(short_data_block_length + double_byte, tribus(version, 8, 16, 16), binary);
if (debug) {
printf("Byte block (length %d)\n\t", short_data_block_length);
if (debug & ZINT_DEBUG_PRINT) {
printf("Byte block (length %d)\n\t", short_data_block_length + double_byte);
}
/* Character representation */
for (i = 0; i < short_data_block_length; i++) {
int byte = jisdata[position + i];
unsigned int byte = jisdata[position + i];
if (gs1 && (byte == '[')) {
byte = 0x1d; /* FNC1 */
}
bin_append(byte, 8, binary);
bin_append(byte, byte > 0xFF ? 16 : 8, binary);
if (debug) {
if (debug & ZINT_DEBUG_PRINT) {
printf("0x%2X(%d) ", byte, byte);
}
}
if (debug) {
if (debug & ZINT_DEBUG_PRINT) {
printf("\n");
}
@ -275,11 +284,11 @@ static void qr_binary(int datastream[], const int version, const int target_binl
percent_count++;
}
}
/* Character count indicator */
bin_append(short_data_block_length + percent_count, tribus(version, 9, 11, 13), binary);
if (debug) {
if (debug & ZINT_DEBUG_PRINT) {
printf("Alpha block (length %d)\n\t", short_data_block_length + percent_count);
}
@ -352,12 +361,12 @@ static void qr_binary(int datastream[], const int version, const int target_binl
bin_append(prod, 1 + (5 * count), binary);
if (debug) {
if (debug & ZINT_DEBUG_PRINT) {
printf("0x%4X ", prod);
}
};
if (debug) {
if (debug & ZINT_DEBUG_PRINT) {
printf("\n");
}
@ -370,7 +379,7 @@ static void qr_binary(int datastream[], const int version, const int target_binl
/* Character count indicator */
bin_append(short_data_block_length, tribus(version, 10, 12, 14), binary);
if (debug) {
if (debug & ZINT_DEBUG_PRINT) {
printf("Number block (length %d)\n\t", short_data_block_length);
}
@ -398,14 +407,14 @@ static void qr_binary(int datastream[], const int version, const int target_binl
bin_append(prod, 1 + (3 * count), binary);
if (debug) {
if (debug & ZINT_DEBUG_PRINT) {
printf("0x%4X (%d)", prod, prod);
}
i += count;
};
if (debug) {
if (debug & ZINT_DEBUG_PRINT) {
printf("\n");
}
@ -453,7 +462,7 @@ static void qr_binary(int datastream[], const int version, const int target_binl
}
}
if (debug) {
if (debug & ZINT_DEBUG_PRINT) {
printf("Resulting codewords:\n\t");
for (i = 0; i < target_binlen; i++) {
printf("0x%2X ", datastream[i]);
@ -463,25 +472,24 @@ static void qr_binary(int datastream[], const int version, const int target_binl
}
/* Split data into blocks, add error correction and then interleave the blocks and error correction data */
static void add_ecc(int fullstream[],const int datastream[],const int version,const int data_cw,const int blocks) {
static void add_ecc(unsigned char fullstream[], const unsigned char datastream[], const int version, const int data_cw, const int blocks, int debug) {
int ecc_cw = qr_total_codewords[version - 1] - data_cw;
int short_data_block_length = data_cw / blocks;
int qty_long_blocks = data_cw % blocks;
int qty_short_blocks = blocks - qty_long_blocks;
int ecc_block_length = ecc_cw / blocks;
int i, j, length_this_block, posn, debug = 0;
int i, j, length_this_block, posn;
#ifndef _MSC_VER
unsigned char data_block[short_data_block_length + 2];
unsigned char ecc_block[ecc_block_length + 2];
int interleaved_data[data_cw + 2];
int interleaved_ecc[ecc_cw + 2];
unsigned char interleaved_data[data_cw + 2];
unsigned char interleaved_ecc[ecc_cw + 2];
#else
unsigned char* data_block = (unsigned char *) _alloca(short_data_block_length + 2);
unsigned char* ecc_block = (unsigned char *) _alloca(ecc_block_length + 2);
int* interleaved_data = (int *) _alloca((data_cw + 2) * sizeof (int));
int* interleaved_ecc = (int *) _alloca((ecc_cw + 2) * sizeof (int));
unsigned char* interleaved_data = (unsigned char *) _alloca(data_cw + 2);
unsigned char* interleaved_ecc = (unsigned char *) _alloca(ecc_cw + 2);
#endif
posn = 0;
@ -498,7 +506,7 @@ static void add_ecc(int fullstream[],const int datastream[],const int version,co
}
for (j = 0; j < length_this_block; j++) {
data_block[j] = (unsigned char) datastream[posn + j];
data_block[j] = datastream[posn + j];
}
rs_init_gf(0x11d);
@ -506,7 +514,7 @@ static void add_ecc(int fullstream[],const int datastream[],const int version,co
rs_encode(length_this_block, data_block, ecc_block);
rs_free();
if (debug) {
if (debug & ZINT_DEBUG_PRINT) {
printf("Block %d: ", i + 1);
for (j = 0; j < length_this_block; j++) {
printf("%2X ", data_block[j]);
@ -522,15 +530,15 @@ static void add_ecc(int fullstream[],const int datastream[],const int version,co
}
for (j = 0; j < short_data_block_length; j++) {
interleaved_data[(j * blocks) + i] = (int) data_block[j];
interleaved_data[(j * blocks) + i] = data_block[j];
}
if (i >= qty_short_blocks) {
interleaved_data[(short_data_block_length * blocks) + (i - qty_short_blocks)] = (int) data_block[short_data_block_length];
interleaved_data[(short_data_block_length * blocks) + (i - qty_short_blocks)] = data_block[short_data_block_length];
}
for (j = 0; j < ecc_block_length; j++) {
interleaved_ecc[(j * blocks) + i] = (int) ecc_block[ecc_block_length - j - 1];
interleaved_ecc[(j * blocks) + i] = ecc_block[ecc_block_length - j - 1];
}
posn += length_this_block;
@ -543,7 +551,7 @@ static void add_ecc(int fullstream[],const int datastream[],const int version,co
fullstream[j + data_cw] = interleaved_ecc[j];
}
if (debug) {
if (debug & ZINT_DEBUG_PRINT) {
printf("\nData Stream: \n");
for (j = 0; j < (data_cw + ecc_cw); j++) {
printf("%2X ", fullstream[j]);
@ -660,7 +668,7 @@ static void setup_grid(unsigned char* grid,const int size,const int version) {
}
}
static int cwbit(const int* fullstream,const int i) {
static int cwbit(const unsigned char* fullstream, const int i) {
int resultant = 0;
if (fullstream[(i / 8)] & (0x80 >> (i % 8))) {
@ -670,7 +678,7 @@ static int cwbit(const int* fullstream,const int i) {
return resultant;
}
static void populate_grid(unsigned char* grid,const int size,const int* fullstream,const int cw) {
static void populate_grid(unsigned char* grid, const int size, const unsigned char* fullstream, const int cw) {
int direction = 1; /* up */
int row = 0; /* right hand side */
@ -681,6 +689,7 @@ static void populate_grid(unsigned char* grid,const int size,const int* fullstre
i = 0;
do {
int x = (size - 2) - (row * 2);
if (x < 6)
x--; /* skip over vertical timing pattern */
@ -1321,7 +1330,7 @@ static size_t blockLength(const size_t start,const char inputMode[],const size_t
return count;
}
static int getBinaryLength(const int version,char inputMode[],const int inputData[],const size_t inputLength,const int gs1,const int eci) {
static int getBinaryLength(const int version, char inputMode[], const unsigned int inputData[], const size_t inputLength, const int gs1, const int eci) {
/* Calculate the actual bitlength of the proposed binary string */
size_t i;
char currentMode;
@ -1339,7 +1348,14 @@ static int getBinaryLength(const int version,char inputMode[],const int inputDat
}
if (eci != 0) {
count += 12;
count += 4;
if (eci <= 127) {
count += 8;
} else if (eci <= 16383) {
count += 16;
} else {
count += 24;
}
}
for (i = 0; i < inputLength; i++) {
@ -1404,6 +1420,14 @@ static int getBinaryLength(const int version,char inputMode[],const int inputDat
return count;
}
static void qr_test_codeword_dump(struct zint_symbol *symbol, unsigned char* codewords, int length) {
int i;
for (i = 0; i < length && i < 33; i++) { // 33*3 < errtxt 100 chars
sprintf(symbol->errtxt + i * 3, "%02X ", codewords[i]);
}
symbol->errtxt[strlen(symbol->errtxt) - 1] = '\0';
}
int qr_code(struct zint_symbol *symbol, const unsigned char source[], size_t length) {
int i, j, est_binlen;
int ecc_level, autosize, version, max_cw, target_binlen, blocks, size;
@ -1411,48 +1435,37 @@ int qr_code(struct zint_symbol *symbol, const unsigned char source[], size_t len
int canShrink;
#ifndef _MSC_VER
int utfdata[length + 1];
int jisdata[length + 1];
unsigned int jisdata[length + 1];
char mode[length + 1];
#else
int* datastream;
int* fullstream;
unsigned char* datastream;
unsigned char* fullstream;
unsigned char* grid;
int* utfdata = (int *) _alloca((length + 1) * sizeof (int));
int* jisdata = (int *) _alloca((length + 1) * sizeof (int));
unsigned int* jisdata = (unsigned int *) _alloca((length + 1) * sizeof (unsigned int));
char* mode = (char *) _alloca(length + 1);
#endif
gs1 = (symbol->input_mode == GS1_MODE);
gs1 = ((symbol->input_mode & 0x07) == GS1_MODE);
if ((symbol->input_mode == DATA_MODE) || (symbol->eci != 0)) {
for (i = 0; i < length; i++) {
jisdata[i] = (int) source[i];
}
if ((symbol->input_mode & 0x07) == DATA_MODE) {
sjis_cpy(source, &length, jisdata);
} else {
/* Convert Unicode input to Shift-JIS */
int error_number = utf8toutf16(symbol, source, utfdata, &length);
if (error_number != 0) {
return error_number;
int done = 0;
if (symbol->eci != 20) { /* Unless ECI 20 (Shift JIS) */
/* Try single byte (Latin) conversion first */
int error_number = sjis_utf8tosb(symbol->eci && symbol->eci <= 899 ? symbol->eci : 3, source, &length, jisdata);
if (error_number == 0) {
done = 1;
} else if (symbol->eci && symbol->eci <= 899) {
strcpy(symbol->errtxt, "575: Invalid characters in input data");
return error_number;
}
}
for (i = 0; i < length; i++) {
if (utfdata[i] <= 0xff) {
jisdata[i] = utfdata[i];
} else {
int glyph = 0;
j = 0;
do {
if (sjis_lookup[j * 2] == utfdata[i]) {
glyph = sjis_lookup[(j * 2) + 1];
}
j++;
} while ((j < 6843) && (glyph == 0));
if (glyph == 0) {
strcpy(symbol->errtxt, "560: Invalid character in input data");
return ZINT_ERROR_INVALID_DATA;
}
jisdata[i] = glyph;
if (!done) {
/* Try Shift-JIS */
int error_number = sjis_utf8tomb(symbol, source, &length, jisdata);
if (error_number != 0) {
return error_number;
}
}
}
@ -1569,7 +1582,7 @@ int qr_code(struct zint_symbol *symbol, const unsigned char source[], size_t len
return ZINT_ERROR_TOO_LONG;
}
}
/* Ensure maxium error correction capacity */
if (est_binlen <= qr_data_codewords_M[version - 1] * 8) {
ecc_level = LEVEL_M;
@ -1596,15 +1609,16 @@ int qr_code(struct zint_symbol *symbol, const unsigned char source[], size_t len
}
#ifndef _MSC_VER
int datastream[target_binlen + 1];
int fullstream[qr_total_codewords[version - 1] + 1];
unsigned char datastream[target_binlen + 1];
unsigned char fullstream[qr_total_codewords[version - 1] + 1];
#else
datastream = (int *) _alloca((target_binlen + 1) * sizeof (int));
fullstream = (int *) _alloca((qr_total_codewords[version - 1] + 1) * sizeof (int));
datastream = (unsigned char *) _alloca(target_binlen + 1);
fullstream = (unsigned char *) _alloca(qr_total_codewords[version - 1] + 1);
#endif
qr_binary(datastream, version, target_binlen, mode, jisdata, length, gs1, symbol->eci, est_binlen, symbol->debug);
add_ecc(fullstream, datastream, version, target_binlen, blocks);
if (symbol->debug & ZINT_DEBUG_TEST) qr_test_codeword_dump(symbol, datastream, target_binlen);
add_ecc(fullstream, datastream, version, target_binlen, blocks, symbol->debug);
size = qr_sizes[version - 1];
#ifndef _MSC_VER
@ -1647,9 +1661,7 @@ int qr_code(struct zint_symbol *symbol, const unsigned char source[], size_t len
return 0;
}
/* NOTE: From this point forward concerns Micro QR Code only */
static int micro_qr_intermediate(char binary[], const int jisdata[], const char mode[], const size_t length, int *kanji_used, int *alphanum_used, int *byte_used,const int debug) {
static int micro_qr_intermediate(char binary[], const unsigned int jisdata[], const char mode[], const size_t length, int *kanji_used, int *alphanum_used, int *byte_used, const int debug) {
/* Convert input data to an "intermediate stage" where data is binary encoded but
control information is not */
int position = 0;
@ -1658,7 +1670,7 @@ static int micro_qr_intermediate(char binary[], const int jisdata[], const char
strcpy(binary, "");
if (debug) {
if (debug & ZINT_DEBUG_PRINT) {
for (i = 0; i < length; i++) {
printf("%c", mode[i]);
}
@ -1668,12 +1680,16 @@ static int micro_qr_intermediate(char binary[], const int jisdata[], const char
do {
char data_block;
int short_data_block_length = 0;
int double_byte = 0;
if (strlen(binary) > 128) {
return ZINT_ERROR_TOO_LONG;
}
data_block = mode[position];
do {
if (data_block == 'B' && jisdata[position + short_data_block_length] > 0xFF) {
double_byte++;
}
short_data_block_length++;
} while (((short_data_block_length + position) < length) && (mode[position + short_data_block_length] == data_block));
@ -1689,7 +1705,7 @@ static int micro_qr_intermediate(char binary[], const int jisdata[], const char
buffer[1] = '\0';
strcat(binary, buffer);
if (debug) {
if (debug & ZINT_DEBUG_PRINT) {
printf("Kanji block (length %d)\n\t", short_data_block_length);
}
@ -1708,7 +1724,7 @@ static int micro_qr_intermediate(char binary[], const int jisdata[], const char
bin_append(prod, 13, binary);
if (debug) {
if (debug & ZINT_DEBUG_PRINT) {
printf("0x%4X ", prod);
}
@ -1717,7 +1733,7 @@ static int micro_qr_intermediate(char binary[], const int jisdata[], const char
}
}
if (debug) {
if (debug & ZINT_DEBUG_PRINT) {
printf("\n");
}
@ -1729,21 +1745,21 @@ static int micro_qr_intermediate(char binary[], const int jisdata[], const char
*byte_used = 1;
/* Character count indicator */
buffer[0] = short_data_block_length;
buffer[0] = short_data_block_length + double_byte;
buffer[1] = '\0';
strcat(binary, buffer);
if (debug) {
printf("Byte block (length %d)\n\t", short_data_block_length);
if (debug & ZINT_DEBUG_PRINT) {
printf("Byte block (length %d)\n\t", short_data_block_length + double_byte);
}
/* Character representation */
for (i = 0; i < short_data_block_length; i++) {
int byte = jisdata[position + i];
bin_append(byte, 8, binary);
bin_append(byte, byte > 0xFF ? 16 : 8, binary);
if (debug) {
if (debug & ZINT_DEBUG_PRINT) {
printf("0x%4X ", byte);
}
@ -1752,7 +1768,7 @@ static int micro_qr_intermediate(char binary[], const int jisdata[], const char
}
}
if (debug) {
if (debug & ZINT_DEBUG_PRINT) {
printf("\n");
}
@ -1768,7 +1784,7 @@ static int micro_qr_intermediate(char binary[], const int jisdata[], const char
buffer[1] = '\0';
strcat(binary, buffer);
if (debug) {
if (debug & ZINT_DEBUG_PRINT) {
printf("Alpha block (length %d)\n\t", short_data_block_length);
}
@ -1790,7 +1806,7 @@ static int micro_qr_intermediate(char binary[], const int jisdata[], const char
bin_append(prod, 1 + (5 * count), binary);
if (debug) {
if (debug & ZINT_DEBUG_PRINT) {
printf("0x%4X ", prod);
}
@ -1801,7 +1817,7 @@ static int micro_qr_intermediate(char binary[], const int jisdata[], const char
i += 2;
};
if (debug) {
if (debug & ZINT_DEBUG_PRINT) {
printf("\n");
}
@ -1816,7 +1832,7 @@ static int micro_qr_intermediate(char binary[], const int jisdata[], const char
buffer[1] = '\0';
strcat(binary, buffer);
if (debug) {
if (debug & ZINT_DEBUG_PRINT) {
printf("Number block (length %d)\n\t", short_data_block_length);
}
@ -1844,7 +1860,7 @@ static int micro_qr_intermediate(char binary[], const int jisdata[], const char
bin_append(prod, 1 + (3 * count), binary);
if (debug) {
if (debug & ZINT_DEBUG_PRINT) {
printf("0x%4X (%d)", prod, prod);
}
@ -1855,7 +1871,7 @@ static int micro_qr_intermediate(char binary[], const int jisdata[], const char
i += 3;
};
if (debug) {
if (debug & ZINT_DEBUG_PRINT) {
printf("\n");
}
@ -1863,7 +1879,7 @@ static int micro_qr_intermediate(char binary[], const int jisdata[], const char
}
position += short_data_block_length;
} while (position < length - 1);
} while (position < length);
return 0;
}
@ -2000,7 +2016,7 @@ static void microqr_expand_binary(const char binary_stream[], char full_stream[]
} while (i < length);
}
static void micro_qr_m1(char binary_data[]) {
static void micro_qr_m1(struct zint_symbol *symbol, char binary_data[]) {
int i, j, latch;
int bits_total, bits_left;
int data_codewords, ecc_codewords;
@ -2071,6 +2087,8 @@ static void micro_qr_m1(char binary_data[]) {
}
}
if (symbol->debug & ZINT_DEBUG_TEST) qr_test_codeword_dump(symbol, data_blocks, data_codewords);
/* Calculate Reed-Solomon error codewords */
rs_init_gf(0x11d);
rs_init_code(ecc_codewords, 0);
@ -2083,7 +2101,7 @@ static void micro_qr_m1(char binary_data[]) {
}
}
static void micro_qr_m2(char binary_data[],const int ecc_mode) {
static void micro_qr_m2(struct zint_symbol *symbol, char binary_data[], const int ecc_mode) {
int i, j, latch;
int bits_total=0, bits_left;
int data_codewords=0, ecc_codewords=0;
@ -2149,6 +2167,8 @@ static void micro_qr_m2(char binary_data[],const int ecc_mode) {
}
}
if (symbol->debug & ZINT_DEBUG_TEST) qr_test_codeword_dump(symbol, data_blocks, data_codewords);
/* Calculate Reed-Solomon error codewords */
rs_init_gf(0x11d);
rs_init_code(ecc_codewords, 0);
@ -2163,7 +2183,7 @@ static void micro_qr_m2(char binary_data[],const int ecc_mode) {
return;
}
static void micro_qr_m3(char binary_data[],const int ecc_mode) {
static void micro_qr_m3(struct zint_symbol *symbol, char binary_data[], const int ecc_mode) {
int i, j, latch;
int bits_total=0, bits_left;
int data_codewords=0, ecc_codewords=0;
@ -2261,6 +2281,8 @@ static void micro_qr_m3(char binary_data[],const int ecc_mode) {
}
}
if (symbol->debug & ZINT_DEBUG_TEST) qr_test_codeword_dump(symbol, data_blocks, data_codewords);
/* Calculate Reed-Solomon error codewords */
rs_init_gf(0x11d);
rs_init_code(ecc_codewords, 0);
@ -2275,7 +2297,7 @@ static void micro_qr_m3(char binary_data[],const int ecc_mode) {
return;
}
static void micro_qr_m4(char binary_data[],const int ecc_mode) {
static void micro_qr_m4(struct zint_symbol *symbol, char binary_data[], const int ecc_mode) {
int i, j, latch;
int bits_total=0, bits_left;
int data_codewords=0, ecc_codewords=0;
@ -2348,6 +2370,8 @@ static void micro_qr_m4(char binary_data[],const int ecc_mode) {
}
}
if (symbol->debug & ZINT_DEBUG_TEST) qr_test_codeword_dump(symbol, data_blocks, data_codewords);
/* Calculate Reed-Solomon error codewords */
rs_init_gf(0x11d);
rs_init_code(ecc_codewords, 0);
@ -2568,9 +2592,8 @@ int microqr(struct zint_symbol *symbol, const unsigned char source[], size_t len
int j, size;
char binary_stream[200];
char full_stream[200];
int utfdata[40];
int jisdata[40];
unsigned int jisdata[40];
char mode[40];
int error_number, kanji_used = 0, alphanum_used = 0, byte_used = 0;
int version_valid[4];
@ -2610,34 +2633,16 @@ int microqr(struct zint_symbol *symbol, const unsigned char source[], size_t len
version_valid[i] = 1;
}
if (symbol->input_mode == DATA_MODE) {
for (i = 0; i < length; i++) {
jisdata[i] = (int) source[i];
}
if ((symbol->input_mode & 0x07) == DATA_MODE) {
sjis_cpy(source, &length, jisdata);
} else {
/* Convert Unicode input to Shift-JIS */
error_number = utf8toutf16(symbol, source, utfdata, &length);
/* Try ISO 8859-1 conversion first */
int error_number = sjis_utf8tosb(3, source, &length, jisdata);
if (error_number != 0) {
return error_number;
}
for (i = 0; i < length; i++) {
if (utfdata[i] <= 0xff) {
jisdata[i] = utfdata[i];
} else {
int glyph = 0;
j = 0;
do {
if (sjis_lookup[j * 2] == utfdata[i]) {
glyph = sjis_lookup[(j * 2) + 1];
}
j++;
} while ((j < 6843) && (glyph == 0));
if (glyph == 0) {
strcpy(symbol->errtxt, "563: Invalid character in input data");
return ZINT_ERROR_INVALID_DATA;
}
jisdata[i] = glyph;
/* Try Shift-JIS */
int error_number = sjis_utf8tomb(symbol, source, &length, jisdata);
if (error_number != 0) {
return error_number;
}
}
}
@ -2677,7 +2682,7 @@ int microqr(struct zint_symbol *symbol, const unsigned char source[], size_t len
get_bitlength(binary_count, binary_stream);
/* Eliminate possivle versions depending on type of content */
/* Eliminate possible versions depending on type of content */
if (byte_used) {
version_valid[0] = 0;
version_valid[1] = 0;
@ -2780,13 +2785,13 @@ int microqr(struct zint_symbol *symbol, const unsigned char source[], size_t len
microqr_expand_binary(binary_stream, full_stream, version);
switch (version) {
case 0: micro_qr_m1(full_stream);
case 0: micro_qr_m1(symbol, full_stream);
break;
case 1: micro_qr_m2(full_stream, ecc_level);
case 1: micro_qr_m2(symbol, full_stream, ecc_level);
break;
case 2: micro_qr_m3(full_stream, ecc_level);
case 2: micro_qr_m3(symbol, full_stream, ecc_level);
break;
case 3: micro_qr_m4(full_stream, ecc_level);
case 3: micro_qr_m4(symbol, full_stream, ecc_level);
break;
}
@ -2905,13 +2910,13 @@ int upnqr(struct zint_symbol *symbol, const unsigned char source[], size_t lengt
int bitmask, error_number;
#ifndef _MSC_VER
int jisdata[length + 1];
unsigned int jisdata[length + 1];
char mode[length + 1];
#else
int* datastream;
int* fullstream;
unsigned char* datastream;
unsigned char* fullstream;
unsigned char* grid;
int* jisdata = (int *) _alloca((length + 1) * sizeof (int));
unsigned int* jisdata = (unsigned int *) _alloca((length + 1) * sizeof (unsigned int));
char* mode = (char *) _alloca(length + 1);
#endif
@ -2921,11 +2926,13 @@ int upnqr(struct zint_symbol *symbol, const unsigned char source[], size_t lengt
unsigned char* preprocessed = (unsigned char*) _alloca(length + 1);
#endif
switch(symbol->input_mode) {
symbol->eci = 4; /* Set before any processing */
switch (symbol->input_mode & 0x07) {
case DATA_MODE:
/* Input is already in ISO-8859-2 format */
for (i = 0; i < length; i++) {
jisdata[i] = (int) source[i];
jisdata[i] = source[i];
mode[i] = 'B';
}
break;
@ -2940,13 +2947,12 @@ int upnqr(struct zint_symbol *symbol, const unsigned char source[], size_t lengt
return error_number;
}
for (i = 0; i < length; i++) {
jisdata[i] = (int) preprocessed[i];
jisdata[i] = preprocessed[i];
mode[i] = 'B';
}
break;
}
symbol->eci = 4;
est_binlen = getBinaryLength(15, mode, jisdata, length, 0, symbol->eci);
ecc_level = LEVEL_M;
@ -2962,15 +2968,16 @@ int upnqr(struct zint_symbol *symbol, const unsigned char source[], size_t lengt
blocks = qr_blocks_M[version - 1];
#ifndef _MSC_VER
int datastream[target_binlen + 1];
int fullstream[qr_total_codewords[version - 1] + 1];
unsigned char datastream[target_binlen + 1];
unsigned char fullstream[qr_total_codewords[version - 1] + 1];
#else
datastream = (int *) _alloca((target_binlen + 1) * sizeof (int));
fullstream = (int *) _alloca((qr_total_codewords[version - 1] + 1) * sizeof (int));
datastream = (unsigned char *) _alloca(target_binlen + 1);
fullstream = (unsigned char *) _alloca(qr_total_codewords[version - 1] + 1);
#endif
qr_binary(datastream, version, target_binlen, mode, jisdata, length, 0, symbol->eci, est_binlen, symbol->debug);
add_ecc(fullstream, datastream, version, target_binlen, blocks);
if (symbol->debug & ZINT_DEBUG_TEST) qr_test_codeword_dump(symbol, datastream, target_binlen);
add_ecc(fullstream, datastream, version, target_binlen, blocks, symbol->debug);
size = qr_sizes[version - 1];
#ifndef _MSC_VER

1610
backend/sjis.c Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -29,6 +29,7 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
/* vim: set ts=4 sw=4 et : */
#include <locale.h>
#include <string.h>
@ -104,7 +105,7 @@ int svg_plot(struct zint_symbol *symbol) {
int html_len = strlen((char *)symbol->text) + 1;
for (0; i < strlen((char *)symbol->text); i++) {
for (i = 0; i < strlen((char *)symbol->text); i++) {
switch(symbol->text[i]) {
case '>':
case '<':

View File

@ -47,7 +47,9 @@ macro(zint_add_test test_name test_command)
endmacro(zint_add_test)
zint_add_test(channel, test_channel)
zint_add_test(common, test_common)
zint_add_test(composite, test_composite)
zint_add_test(dmatrix, test_dmatrix)
zint_add_test(eci, test_eci)
zint_add_test(gs1, test_gs1)
zint_add_test(imail, test_imail)
@ -58,5 +60,6 @@ zint_add_test(postal, test_postal)
zint_add_test(qr, test_qr)
zint_add_test(raster, test_raster)
zint_add_test(rss, test_rss)
zint_add_test(sjis, test_sjis)
zint_add_test(upcean, test_upcean)
zint_add_test(vector, test_vector)

53
backend/tests/README Normal file
View File

@ -0,0 +1,53 @@
Zint backend test suite
-----------------------
To make:
cd <project-dir>
cd backend/tests
mkdir build
cd build
cmake ..
make
To run all tests:
make test
To run individual tests, eg:
./test_common
./test_vector
To make with gcc sanitize, first set for libzint and make:
cd <project-dir>
cd build
cmake -DZINT_SANITIZE:BOOL=1 ..
make && sudo make install
Then set for tests and make:
cd <project-dir>
cd backend/tests/build
cmake -DZINT_SANITIZE:BOOL=1 ..
make
Similarly to make with gcc debug:
cd <project-dir>
cd build
cmake -DZINT_DEBUG:BOOL=1 ..
make && sudo make install
cd <project-dir>
cd backend/tests/build
cmake -DZINT_DEBUG:BOOL=1 ..
make
To undo sanitize/debug, remake each after setting:
cmake -DZINT_SANITIZE:BOOL=0 ..
cmake -DZINT_DEBUG:BOOL=0 ..
Note that sanitize is not safe to use in production, as it's a security risk.

View File

@ -0,0 +1,85 @@
/*
libzint - the open source barcode library
Copyright (C) 2008-2019 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the project nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
/* vim: set ts=4 sw=4 et : */
#include "testcommon.h"
static void test_utf8toutf16(void)
{
testStart("");
int ret;
struct item {
unsigned char* data;
int length;
int ret;
size_t ret_length;
int expected_vals[20];
char* comment;
};
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = {
/* 0*/ { "", -1, 0, 0, {}, "" },
/* 1*/ { "\000a\302\200\340\240\200", 7, 0, 4, { 0, 'a', 0x80, 0x800 }, "NUL a C280 E0A080" },
/* 2*/ { "\357\277\277", -1, 0, 1, { 0xFFFF }, "EFBFBF" },
/* 3*/ { "\360\220\200\200", -1, ZINT_ERROR_INVALID_DATA, -1, {}, "Four-byte F0908080" },
/* 4*/ { "a\200b", -1, ZINT_ERROR_INVALID_DATA, -1, {}, "Orphan continuation 0x80" },
};
int data_size = sizeof(data) / sizeof(struct item);
int vals[20];
struct zint_symbol symbol;
for (int i = 0; i < data_size; i++) {
int length = data[i].length == -1 ? strlen(data[i].data) : data[i].length;
size_t ret_length = length;
ret = utf8toutf16(&symbol, data[i].data, vals, &ret_length);
assert_equal(ret, data[i].ret, "i:%d ret %d != %d\n", i, ret, data[i].ret);
if (ret == 0) {
assert_equal(ret_length, data[i].ret_length, "i:%d ret_length %ld != %ld\n", i, ret_length, data[i].ret_length);
for (int j = 0; j < ret_length; j++) {
assert_equal(vals[j], data[i].expected_vals[j], "i:%d vals[%d] %04X != %04X\n", i, j, vals[j], data[i].expected_vals[j]);
}
}
}
testFinish();
}
int main()
{
test_utf8toutf16();
testReport();
return 0;
}

View File

@ -0,0 +1,153 @@
/*
libzint - the open source barcode library
Copyright (C) 2008-2019 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the project nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
/* vim: set ts=4 sw=4 et : */
#include "testcommon.h"
//#define TEST_ENCODE_GENERATE_EXPECTED 1
static void test_buffer(void)
{
testStart("");
int ret;
struct item {
unsigned char* data;
int eci;
int input_mode;
int output_options;
int ret;
char* comment;
};
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = {
/* 0*/ { "1", 16383, UNICODE_MODE, READER_INIT, 0, "" },
};
int data_size = sizeof(data) / sizeof(struct item);
for (int i = 0; i < data_size; i++) {
struct zint_symbol* symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
symbol->symbology = BARCODE_DATAMATRIX;
symbol->input_mode = data[i].input_mode;
symbol->eci = data[i].eci;
symbol->output_options = data[i].output_options;
int length = strlen(data[i].data);
ret = ZBarcode_Encode(symbol, data[i].data, length);
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d\n", i, ret, data[i].ret);
ZBarcode_Delete(symbol);
}
testFinish();
}
static void test_encode(void)
{
testStart("");
int ret;
struct item {
unsigned char* data;
int ret;
int expected_rows;
int expected_width;
char* comment;
char* expected;
};
struct item data[] = {
/* 0*/ { "1234abcd", 0, 14, 14, "",
"10101010101010"
"11001010001111"
"11000101100100"
"11001001100001"
"11011001110000"
"10100101011001"
"10101110011000"
"10011101100101"
"10100001001000"
"10101000001111"
"11101100000010"
"11010010100101"
"10011111000100"
"11111111111111"
},
};
int data_size = sizeof(data) / sizeof(struct item);
for (int i = 0; i < data_size; i++) {
struct zint_symbol* symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
symbol->symbology = BARCODE_DATAMATRIX;
int length = strlen(data[i].data);
ret = ZBarcode_Encode(symbol, data[i].data, length);
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d\n", i, ret, data[i].ret);
#ifdef TEST_ENCODE_GENERATE_EXPECTED
printf(" /*%3d*/ { \"%s\", %s, %d, %d, \"%s\",\n", i, data[i].data, testUtilErrorName(data[i].ret), symbol->rows, symbol->width, data[i].comment);
testUtilModulesDump(symbol, " ", "\n");
printf(" },\n");
#else
if (ret < 5) {
assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", i, symbol->rows, data[i].expected_rows, data[i].data);
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);
if (ret == 0) {
int width, row;
ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row);
assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data);
}
}
#endif
ZBarcode_Delete(symbol);
}
testFinish();
}
int main()
{
test_buffer();
test_encode();
testReport();
return 0;
}

View File

@ -27,6 +27,7 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
/* vim: set ts=4 sw=4 et : */
#include "testcommon.h"
@ -105,7 +106,8 @@ static void test_iso_8859_16(void)
testFinish();
}
static void test_encode(void)
// Only testing standard non-extended barcodes here, ie not QRCODE, MICROQR, GRIDMATRIX, HANXIN or UPNQR
static void test_reduced_charset_input(void)
{
testStart("");
@ -115,106 +117,98 @@ static void test_encode(void)
int input_mode;
int eci;
unsigned char* data;
int ret_encode;
float w;
float h;
int ret_vector;
int ret;
int expected_eci;
char* comment;
};
// é U+00E9 in ISO 8859-1 plus other ISO 8859 (but not in ISO 8859-7 or ISO 8859-11), in Shift-JIS, in GB-2312/18030
// β U+03B2 in ISO 8859-7 Greek (but not other ISO 8859), in Shift-JIS, in GB-2312/18030
// ก U+0E01 in ISO 8859-11 Thai (but not other ISO 8859), not in Shift-JIS, not in GB-2312/18030
// ກ U+0E81 Lao not in any ISO 8859 (or Windows page) or Shift-JIS or GB-2312/18030
// Vi} :s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
// é U+00E9 in ISO 8859-1 plus other ISO 8859 (but not in ISO 8859-7 or ISO 8859-11), Win 1250 plus other Win, not in Shift JIS
// β U+03B2 in ISO 8859-7 Greek (but not other ISO 8859 or Win page), in Shift JIS
// ก U+0E01 in ISO 8859-11 Thai (but not other ISO 8859 or Win page), not in Shift JIS
// Ж U+0416 in ISO 8859-5 Cyrillic (but not other ISO 8859), Win 1251, in Shift JIS
// ກ U+0E81 Lao not in any ISO 8859 (or Win page) or Shift JIS
// … U+2026 in Win pages (but not in any ISO 8859)
// テ U+30C6 katakana, in Shift JIS
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = {
/* 0*/ { BARCODE_QRCODE, UNICODE_MODE, 0, "", 0, 100, 30, 0, 0 },
/* 1*/ { BARCODE_QRCODE, UNICODE_MODE, 0, "", 0, 100, 30, 0, 0 }, // Converts to Shift-JIS
/* 2*/ { BARCODE_QRCODE, UNICODE_MODE, 0, "Aก", ZINT_WARN_USES_ECI, 100, 30, 0, 13 }, // ECI 13 == ISO 8859-11
/* 3*/ { BARCODE_QRCODE, UNICODE_MODE, 0, "Aéβ", 0, 100, 30, 0, 0 }, // Converts to Shift-JIS
/* 4*/ { BARCODE_QRCODE, UNICODE_MODE, 0, "Aéβก", ZINT_WARN_USES_ECI, 100, 30, 0, 26 },
/* 5*/ { BARCODE_QRCODE, UNICODE_MODE, 0, "Aກ", ZINT_WARN_USES_ECI, 100, 30, 0, 26 },
/* 6*/ { BARCODE_QRCODE, UNICODE_MODE, 3, "", 0, 100, 30, 0, 3 },
/* 7*/ { BARCODE_MICROQR, UNICODE_MODE, 0, "", 0, 100, 30, 0, 0 },
/* 8*/ { BARCODE_MICROQR, UNICODE_MODE, 0, "", 0, 100, 30, 0, 0 }, // Converts to Shift-JIS
/* 9*/ { BARCODE_MICROQR, UNICODE_MODE, 0, "Aéβ", 0, 100, 30, 0, 0 }, // Converts to Shift-JIS
/* 10*/ { BARCODE_MICROQR, UNICODE_MODE, 0, "", ZINT_ERROR_INVALID_DATA, 100, 30, -1, -1 },
/* 11*/ { BARCODE_MICROQR, UNICODE_MODE, 3, "", 0, 100, 30, 0, 3 },
/* 12*/ { BARCODE_GRIDMATRIX, UNICODE_MODE, 0, "", 0, 100, 30, 0, 0 },
/* 13*/ { BARCODE_GRIDMATRIX, UNICODE_MODE, 0, "", 0, 100, 30, 0, 0 }, // Converts to GB-2312
/* 14*/ { BARCODE_GRIDMATRIX, UNICODE_MODE, 0, "Aก", ZINT_WARN_USES_ECI, 100, 30, 0, 13 }, // ECI 13 == ISO 8859-11
/* 15*/ { BARCODE_GRIDMATRIX, UNICODE_MODE, 0, "Aéβ", 0, 100, 30, 0, 0 }, // Converts to GB-2312
/* 16*/ { BARCODE_GRIDMATRIX, UNICODE_MODE, 0, "Aéβก", ZINT_WARN_USES_ECI, 100, 30, 0, 26 },
/* 17*/ { BARCODE_GRIDMATRIX, UNICODE_MODE, 3, "", 0, 100, 30, 0, 3 },
/* 18*/ { BARCODE_HANXIN, UNICODE_MODE, 0, "", 0, 100, 30, 0, 0 },
/* 19*/ { BARCODE_HANXIN, UNICODE_MODE, 0, "", 0, 100, 30, 0, 0 }, // Converts to GB-18030
/* 20*/ { BARCODE_HANXIN, UNICODE_MODE, 0, "Aก", ZINT_WARN_USES_ECI, 100, 30, 0, 13 }, // ECI 13 == ISO 8859-11
/* 21*/ { BARCODE_HANXIN, UNICODE_MODE, 0, "Aéβ", 0, 100, 30, 0, 0 }, // Converts to GB-18030
/* 22*/ { BARCODE_HANXIN, UNICODE_MODE, 0, "Aéβก", ZINT_WARN_USES_ECI, 100, 30, 0, 26 },
/* 23*/ { BARCODE_HANXIN, UNICODE_MODE, 3, "", 0, 100, 30, 0, 3 },
/* 24*/ { BARCODE_UPNQR, UNICODE_MODE, 0, "", 0, 100, 30, 0, 4 }, // ECI 4 == iSO 8859-2
/* 25*/ { BARCODE_UPNQR, UNICODE_MODE, 0, "", ZINT_ERROR_INVALID_DATA, 100, 30, -1, -1 },
/* 26*/ { BARCODE_UPNQR, UNICODE_MODE, 3, "", 0, 100, 30, 0, 4 },
/* 27*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 0, "", 0, 100, 30, 0, 0 },
/* 28*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 0, "", ZINT_WARN_USES_ECI, 100, 30, 0, 9 }, // ECI 9 == ISO 8859-7
/* 29*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 0, "β", ZINT_WARN_USES_ECI, 100, 30, 0, 9 }, // ECI 9 == ISO 8859-7
/* 30*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 0, "Aก", ZINT_WARN_USES_ECI, 100, 30, 0, 13 }, // ECI 13 == ISO 8859-11
/* 31*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 0, "", ZINT_WARN_USES_ECI, 100, 30, 0, 13 }, // ECI 13 == ISO 8859-11
/* 32*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 0, "Aéβ", ZINT_WARN_USES_ECI, 100, 30, 0, 26 },
/* 33*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 0, "Aéβก", ZINT_WARN_USES_ECI, 100, 30, 0, 26 },
/* 34*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 3, "", 0, 100, 30, 0, 3 },
/* 35*/ { BARCODE_AZTEC, UNICODE_MODE, 0, "", 0, 100, 30, 0, 0 },
/* 36*/ { BARCODE_AZTEC, UNICODE_MODE, 0, "", ZINT_WARN_USES_ECI, 100, 30, 0, 9 }, // ECI 9 == ISO 8859-7
/* 37*/ { BARCODE_AZTEC, UNICODE_MODE, 0, "β", ZINT_WARN_USES_ECI, 100, 30, 0, 9 }, // ECI 9 == ISO 8859-7
/* 38*/ { BARCODE_AZTEC, UNICODE_MODE, 0, "Aก", ZINT_WARN_USES_ECI, 100, 30, 0, 13 }, // ECI 13 == ISO 8859-11
/* 39*/ { BARCODE_AZTEC, UNICODE_MODE, 0, "", ZINT_WARN_USES_ECI, 100, 30, 0, 13 }, // ECI 13 == ISO 8859-11
/* 40*/ { BARCODE_AZTEC, UNICODE_MODE, 0, "Aéβ", ZINT_WARN_USES_ECI, 100, 30, 0, 26 },
/* 41*/ { BARCODE_AZTEC, UNICODE_MODE, 0, "Aéβก", ZINT_WARN_USES_ECI, 100, 30, 0, 26 },
/* 42*/ { BARCODE_AZTEC, UNICODE_MODE, 3, "", 0, 100, 30, 0, 3 },
/* 43*/ { BARCODE_MAXICODE, UNICODE_MODE, 0, "", 0, 100, 30, 0, 0 },
/* 44*/ { BARCODE_MAXICODE, UNICODE_MODE, 0, "", ZINT_WARN_USES_ECI, 100, 30, 0, 9 }, // ECI 9 == ISO 8859-7
/* 45*/ { BARCODE_MAXICODE, UNICODE_MODE, 0, "β", ZINT_WARN_USES_ECI, 100, 30, 0, 9 }, // ECI 9 == ISO 8859-7
/* 46*/ { BARCODE_MAXICODE, UNICODE_MODE, 0, "Aก", ZINT_WARN_USES_ECI, 100, 30, 0, 13 }, // ECI 13 == ISO 8859-11
/* 47*/ { BARCODE_MAXICODE, UNICODE_MODE, 0, "", ZINT_WARN_USES_ECI, 100, 30, 0, 13 }, // ECI 13 == ISO 8859-11
/* 48*/ { BARCODE_MAXICODE, UNICODE_MODE, 0, "Aéβ", ZINT_WARN_USES_ECI, 100, 30, 0, 26 },
/* 49*/ { BARCODE_MAXICODE, UNICODE_MODE, 0, "Aéβก", ZINT_WARN_USES_ECI, 100, 30, 0, 26 },
/* 50*/ { BARCODE_MAXICODE, UNICODE_MODE, 3, "", 0, 100, 30, 0, 3 },
/* 51*/ { BARCODE_MICROPDF417, UNICODE_MODE, 0, "", 0, 100, 30, 0, 0 },
/* 52*/ { BARCODE_MICROPDF417, UNICODE_MODE, 0, "", ZINT_WARN_USES_ECI, 100, 30, 0, 9 }, // ECI 9 == ISO 8859-7
/* 53*/ { BARCODE_MICROPDF417, UNICODE_MODE, 0, "β", ZINT_WARN_USES_ECI, 100, 30, 0, 9 }, // ECI 9 == ISO 8859-7
/* 54*/ { BARCODE_MICROPDF417, UNICODE_MODE, 0, "Aก", ZINT_WARN_USES_ECI, 100, 30, 0, 13 }, // ECI 13 == ISO 8859-11
/* 55*/ { BARCODE_MICROPDF417, UNICODE_MODE, 0, "", ZINT_WARN_USES_ECI, 100, 30, 0, 13 }, // ECI 13 == ISO 8859-11
/* 56*/ { BARCODE_MICROPDF417, UNICODE_MODE, 0, "Aéβ", ZINT_WARN_USES_ECI, 100, 30, 0, 26 },
/* 57*/ { BARCODE_MICROPDF417, UNICODE_MODE, 0, "Aéβก", ZINT_WARN_USES_ECI, 100, 30, 0, 26 },
/* 58*/ { BARCODE_MICROPDF417, UNICODE_MODE, 3, "", 0, 100, 30, 0, 3 },
/* 59*/ { BARCODE_PDF417, UNICODE_MODE, 0, "", 0, 100, 30, 0, 0 },
/* 60*/ { BARCODE_PDF417, UNICODE_MODE, 0, "", ZINT_WARN_USES_ECI, 100, 30, 0, 9 }, // ECI 9 == ISO 8859-7
/* 61*/ { BARCODE_PDF417, UNICODE_MODE, 0, "β", ZINT_WARN_USES_ECI, 100, 30, 0, 9 }, // ECI 9 == ISO 8859-7
/* 62*/ { BARCODE_PDF417, UNICODE_MODE, 0, "Aก", ZINT_WARN_USES_ECI, 100, 30, 0, 13 }, // ECI 13 == ISO 8859-11
/* 63*/ { BARCODE_PDF417, UNICODE_MODE, 0, "", ZINT_WARN_USES_ECI, 100, 30, 0, 13 }, // ECI 13 == ISO 8859-11
/* 64*/ { BARCODE_PDF417, UNICODE_MODE, 0, "Aéβ", ZINT_WARN_USES_ECI, 100, 30, 0, 26 },
/* 65*/ { BARCODE_PDF417, UNICODE_MODE, 0, "Aéβก", ZINT_WARN_USES_ECI, 100, 30, 0, 26 },
/* 66*/ { BARCODE_PDF417, UNICODE_MODE, 3, "", 0, 100, 30, 0, 3 },
/* 67*/ { BARCODE_PDF417TRUNC, UNICODE_MODE, 0, "", 0, 100, 30, 0, 0 },
/* 68*/ { BARCODE_PDF417TRUNC, UNICODE_MODE, 0, "", ZINT_WARN_USES_ECI, 100, 30, 0, 9 }, // ECI 9 == ISO 8859-7
/* 69*/ { BARCODE_PDF417TRUNC, UNICODE_MODE, 0, "β", ZINT_WARN_USES_ECI, 100, 30, 0, 9 }, // ECI 9 == ISO 8859-7
/* 70*/ { BARCODE_PDF417TRUNC, UNICODE_MODE, 0, "Aก", ZINT_WARN_USES_ECI, 100, 30, 0, 13 }, // ECI 13 == ISO 8859-11
/* 71*/ { BARCODE_PDF417TRUNC, UNICODE_MODE, 0, "", ZINT_WARN_USES_ECI, 100, 30, 0, 13 }, // ECI 13 == ISO 8859-11
/* 72*/ { BARCODE_PDF417TRUNC, UNICODE_MODE, 0, "Aéβ", ZINT_WARN_USES_ECI, 100, 30, 0, 26 },
/* 73*/ { BARCODE_PDF417TRUNC, UNICODE_MODE, 0, "Aéβก", ZINT_WARN_USES_ECI, 100, 30, 0, 26 },
/* 74*/ { BARCODE_PDF417TRUNC, UNICODE_MODE, 3, "", 0, 100, 30, 0, 3 },
/* 75*/ { BARCODE_DOTCODE, UNICODE_MODE, 0, "", 0, 100, 30, 0, 0 },
/* 76*/ { BARCODE_DOTCODE, UNICODE_MODE, 0, "", ZINT_WARN_USES_ECI, 100, 30, 0, 9 }, // ECI 9 == ISO 8859-7
/* 77*/ { BARCODE_DOTCODE, UNICODE_MODE, 0, "β", ZINT_WARN_USES_ECI, 100, 30, 0, 9 }, // ECI 9 == ISO 8859-7
/* 78*/ { BARCODE_DOTCODE, UNICODE_MODE, 0, "Aก", ZINT_WARN_USES_ECI, 100, 30, 0, 13 }, // ECI 13 == ISO 8859-11
/* 79*/ { BARCODE_DOTCODE, UNICODE_MODE, 0, "", ZINT_WARN_USES_ECI, 100, 30, 0, 13 }, // ECI 13 == ISO 8859-11
/* 80*/ { BARCODE_DOTCODE, UNICODE_MODE, 0, "Aéβ", ZINT_WARN_USES_ECI, 100, 30, 0, 26 },
/* 81*/ { BARCODE_DOTCODE, UNICODE_MODE, 0, "Aéβก", ZINT_WARN_USES_ECI, 100, 30, 0, 26 },
/* 82*/ { BARCODE_DOTCODE, UNICODE_MODE, 3, "", 0, 100, 30, 0, 3 },
/* 83*/ { BARCODE_CODE11, UNICODE_MODE, 0, "", ZINT_ERROR_INVALID_DATA, 100, 30, -1, -1 },
/* 84*/ { BARCODE_CODE39, UNICODE_MODE, 0, "", ZINT_ERROR_INVALID_DATA, 100, 30, -1, -1 },
/* 85*/ { BARCODE_EXCODE39, UNICODE_MODE, 0, "", ZINT_ERROR_INVALID_DATA, 100, 30, -1, -1 },
/* 86*/ { BARCODE_CODE128, UNICODE_MODE, 0, "", 0, 100, 30, 0, 0 },
/* 87*/ { BARCODE_CODE128, UNICODE_MODE, 0, "", ZINT_ERROR_INVALID_DATA, 100, 30, -1, -1 },
/* 0*/ { BARCODE_CODE11, UNICODE_MODE, 0, "é", ZINT_ERROR_INVALID_DATA, -1, "ASCII subset only" },
/* 1*/ { BARCODE_C25MATRIX, UNICODE_MODE, 0, "é", ZINT_ERROR_INVALID_DATA, -1, "Numbers only" },
/* 2*/ { BARCODE_CODE39, UNICODE_MODE, 0, "é", ZINT_ERROR_INVALID_DATA, -1, "ASCII subset only" },
/* 3*/ { BARCODE_EXCODE39, UNICODE_MODE, 0, "é", ZINT_ERROR_INVALID_DATA, -1, "ASCII only" },
/* 4*/ { BARCODE_EANX, UNICODE_MODE, 0, "é", ZINT_ERROR_INVALID_DATA, -1, "Numbers only" },
/* 5*/ { BARCODE_CODABAR, UNICODE_MODE, 0, "é", ZINT_ERROR_INVALID_DATA, -1, "ASCII subset only" },
/* 6*/ { BARCODE_CODE128, UNICODE_MODE, 0, "é", 0, 0, "" },
/* 7*/ { BARCODE_CODE128, UNICODE_MODE, 3, "é", ZINT_ERROR_INVALID_OPTION, -1, "Does not support ECI" },
/* 8*/ { BARCODE_CODE128, UNICODE_MODE, 0, "β", ZINT_ERROR_INVALID_DATA, -1, "β not in ISO 8859-1" },
/* 9*/ { BARCODE_DPLEIT, UNICODE_MODE, 0, "é", ZINT_ERROR_INVALID_DATA, -1, "Numbers only" },
/* 10*/ { BARCODE_CODE16K, UNICODE_MODE, 0, "é", 0, 0, "" },
/* 11*/ { BARCODE_CODE16K, UNICODE_MODE, 3, "é", ZINT_ERROR_INVALID_OPTION, -1, "Does not support ECI" },
/* 12*/ { BARCODE_CODE16K, UNICODE_MODE, 0, "β", ZINT_ERROR_INVALID_DATA, -1, "β not in ISO 8859-1" },
/* 13*/ { BARCODE_CODE49, UNICODE_MODE, 0, "é", ZINT_ERROR_INVALID_DATA, -1, "ASCII only" },
/* 14*/ { BARCODE_CODE93, UNICODE_MODE, 0, "é", ZINT_ERROR_INVALID_DATA, -1, "ASCII subset only" },
/* 15*/ { BARCODE_FLAT, UNICODE_MODE, 0, "é", ZINT_ERROR_INVALID_DATA, -1, "Numbers only" },
/* 16*/ { BARCODE_RSS14, UNICODE_MODE, 0, "é", ZINT_ERROR_INVALID_DATA, -1, "Numbers only" },
/* 17*/ { BARCODE_RSS_EXP, UNICODE_MODE, 0, "é", ZINT_ERROR_INVALID_DATA, -1, "ASCII subset only" },
/* 18*/ { BARCODE_LOGMARS, UNICODE_MODE, 0, "é", ZINT_ERROR_INVALID_DATA, -1, "ASCII subset only" },
/* 19*/ { BARCODE_PDF417, UNICODE_MODE, 0, "é", 0, 0, "" },
/* 20*/ { BARCODE_PDF417, UNICODE_MODE, 3, "é", 0, 3, "Supports ECI" },
/* 21*/ { BARCODE_PDF417, UNICODE_MODE, 0, "β", ZINT_WARN_USES_ECI, 9, "" },
/* 22*/ { BARCODE_PDF417, UNICODE_MODE, 9, "β", 0, 9, "" },
/* 23*/ { BARCODE_PDF417, UNICODE_MODE, 0, "", ZINT_WARN_USES_ECI, 13, "" },
/* 24*/ { BARCODE_PDF417, UNICODE_MODE, 13, "", 0, 13, "" },
/* 25*/ { BARCODE_PDF417, UNICODE_MODE, 0, "Ж", ZINT_WARN_USES_ECI, 7, "" },
/* 26*/ { BARCODE_PDF417, UNICODE_MODE, 7, "Ж", 0, 7, "" },
/* 27*/ { BARCODE_PDF417, UNICODE_MODE, 0, "", ZINT_WARN_USES_ECI, 21, "" },
/* 28*/ { BARCODE_PDF417, UNICODE_MODE, 21, "", 0, 21, "" },
/* 29*/ { BARCODE_PDF417, UNICODE_MODE, 0, "", ZINT_WARN_USES_ECI, 26, "Defaults to UTF-8 if not in any ISO 8859 or Win page" },
/* 30*/ { BARCODE_PDF417, UNICODE_MODE, 26, "", 0, 26, "" },
/* 31*/ { BARCODE_PDF417, UNICODE_MODE, 20, "", ZINT_ERROR_INVALID_DATA, -1, "テ in ECI 20 but that conversion not currently supported in Zint for non-extended barcodes" },
/* 32*/ { BARCODE_PDF417, UNICODE_MODE, 900, "é", 0, 900, "ECI > 899 ignored for character set conversion" },
/* 33*/ { BARCODE_PDF417, UNICODE_MODE, 900, "β", ZINT_ERROR_INVALID_DATA, 900, "But ECI > 899 suppresses auto-ECI `get_best_eci()`" },
/* 34*/ { BARCODE_PDF417TRUNC, UNICODE_MODE, 0, "é", 0, 0, "" },
/* 35*/ { BARCODE_PDF417TRUNC, UNICODE_MODE, 3, "é", 0, 3, "Supports ECI" },
/* 36*/ { BARCODE_PDF417TRUNC, UNICODE_MODE, 0, "β", ZINT_WARN_USES_ECI, 9, "" },
/* 37*/ { BARCODE_PDF417TRUNC, UNICODE_MODE, 9, "β", 0, 9, "" },
/* 38*/ { BARCODE_PDF417TRUNC, UNICODE_MODE, 26, "", 0, 26, "" },
/* 39*/ { BARCODE_MAXICODE, UNICODE_MODE, 0, "é", 0, 0, "" },
/* 40*/ { BARCODE_MAXICODE, UNICODE_MODE, 3, "é", 0, 3, "Supports ECI" },
/* 41*/ { BARCODE_MAXICODE, UNICODE_MODE, 0, "β", ZINT_WARN_USES_ECI, 9, "" },
/* 42*/ { BARCODE_MAXICODE, UNICODE_MODE, 9, "β", 0, 9, "" },
/* 43*/ { BARCODE_MAXICODE, UNICODE_MODE, 26, "", 0, 26, "" },
/* 44*/ { BARCODE_CODE128B, UNICODE_MODE, 0, "é", 0, 0, "" },
/* 45*/ { BARCODE_CODE128B, UNICODE_MODE, 3, "é", ZINT_ERROR_INVALID_OPTION, -1, "Does not support ECI" },
/* 46*/ { BARCODE_CODE128B, UNICODE_MODE, 0, "β", ZINT_ERROR_INVALID_DATA, -1, "β not in ISO 8859-1" },
/* 47*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 0, "é", 0, 0, "" },
/* 48*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 3, "é", 0, 3, "Supports ECI" },
/* 49*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 0, "β", ZINT_WARN_USES_ECI, 9, "" },
/* 50*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 9, "β", 0, 9, "" },
/* 51*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 26, "", 0, 26, "" },
/* 52*/ { BARCODE_CODABLOCKF, UNICODE_MODE, 0, "é", 0, 0, "" },
/* 53*/ { BARCODE_CODABLOCKF, UNICODE_MODE, 3, "é", ZINT_ERROR_INVALID_OPTION, -1, "Does not support ECI" },
/* 54*/ { BARCODE_CODABLOCKF, UNICODE_MODE, 0, "β", ZINT_ERROR_INVALID_DATA, -1, "β not in ISO 8859-1" },
/* 55*/ { BARCODE_NVE18, UNICODE_MODE, 0, "é", ZINT_ERROR_INVALID_DATA, -1, "Numbers only" },
/* 56*/ { BARCODE_MICROPDF417, UNICODE_MODE, 0, "é", 0, 0, "" },
/* 57*/ { BARCODE_MICROPDF417, UNICODE_MODE, 3, "é", 0, 3, "Supports ECI" },
/* 58*/ { BARCODE_MICROPDF417, UNICODE_MODE, 0, "β", ZINT_WARN_USES_ECI, 9, "" },
/* 59*/ { BARCODE_MICROPDF417, UNICODE_MODE, 9, "β", 0, 9, "" },
/* 60*/ { BARCODE_MICROPDF417, UNICODE_MODE, 26, "", 0, 26, "" },
/* 61*/ { BARCODE_ONECODE, UNICODE_MODE, 0, "é", ZINT_ERROR_INVALID_DATA, -1, "Numbers/dash only" },
/* 62*/ { BARCODE_AZTEC, UNICODE_MODE, 0, "é", 0, 0, "" },
/* 63*/ { BARCODE_AZTEC, UNICODE_MODE, 3, "é", 0, 3, "Supports ECI" },
/* 64*/ { BARCODE_AZTEC, UNICODE_MODE, 0, "β", ZINT_WARN_USES_ECI, 9, "" },
/* 65*/ { BARCODE_AZTEC, UNICODE_MODE, 9, "β", 0, 9, "" },
/* 66*/ { BARCODE_AZTEC, UNICODE_MODE, 26, "", 0, 26, "" },
/* 67*/ { BARCODE_HIBC_128, UNICODE_MODE, 0, "é", ZINT_ERROR_INVALID_DATA, -1, "HIBC ASCII subset only" },
/* 68*/ { BARCODE_HIBC_AZTEC, UNICODE_MODE, 0, "é", ZINT_ERROR_INVALID_DATA, -1, "HIBC ASCII subset only" },
/* 69*/ { BARCODE_DOTCODE, UNICODE_MODE, 0, "é", 0, 0, "" },
/* 70*/ { BARCODE_DOTCODE, UNICODE_MODE, 3, "é", 0, 3, "Supports ECI" },
/* 71*/ { BARCODE_DOTCODE, UNICODE_MODE, 0, "β", ZINT_WARN_USES_ECI, 9, "" },
/* 72*/ { BARCODE_DOTCODE, UNICODE_MODE, 9, "β", 0, 9, "" },
/* 73*/ { BARCODE_DOTCODE, UNICODE_MODE, 26, "", 0, 26, "" },
/* 74*/ { BARCODE_AZRUNE, UNICODE_MODE, 0, "é", ZINT_ERROR_INVALID_DATA, -1, "Numbers <= 255 only" },
/* 75*/ { BARCODE_CODE32, UNICODE_MODE, 0, "é", ZINT_ERROR_INVALID_DATA, -1, "Numbers only" },
/* 76*/ { BARCODE_CODEONE, UNICODE_MODE, 0, "é", 0, 0, "" },
/* 77*/ { BARCODE_CODEONE, UNICODE_MODE, 3, "é", ZINT_ERROR_INVALID_OPTION, -1, "Does not support ECI" },
/* 78*/ { BARCODE_CODEONE, UNICODE_MODE, 0, "β", ZINT_ERROR_INVALID_DATA, -1, "β not in ISO 8859-1" },
};
int data_size = sizeof(data) / sizeof(struct item);
@ -230,13 +224,10 @@ static void test_encode(void)
int length = strlen(data[i].data);
ret = ZBarcode_Encode(symbol, data[i].data, length);
assert_equal(ret, data[i].ret_encode, "i:%d ZBarcode_Encode ret %d != %d\n", i, ret, data[i].ret_encode);
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
if (data[i].ret_vector != -1) {
if (data[i].expected_eci != -1) {
assert_equal(symbol->eci, data[i].expected_eci, "i:%d eci %d != %d\n", i, symbol->eci, data[i].expected_eci);
ret = ZBarcode_Buffer_Vector(symbol, 0);
assert_equal(ret, data[i].ret_vector, "i:%d ZBarcode_Buffer_Vector ret %d != %d\n", i, ret, data[i].ret_vector);
}
ZBarcode_Delete(symbol);
@ -249,7 +240,7 @@ int main()
{
test_bom();
test_iso_8859_16();
//test_encode(); // Disable for now due to ECI change
test_reduced_charset_input();
testReport();

View File

@ -785,11 +785,103 @@ static void test_gs1_verify(void)
testFinish();
}
static void test_input_mode(void)
{
testStart("");
int ret;
struct item {
int symbology;
unsigned char* data;
unsigned char* composite;
int input_mode;
int output_options;
int ret;
int compare_previous;
};
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = {
/* 0*/ { BARCODE_AZTEC, "[01]12345678901234", "", GS1_MODE, -1 , 0, 0 },
/* 1*/ { BARCODE_AZTEC, "[01]12345678901234", "", GS1_MODE | ESCAPE_MODE, -1, 0, 1 },
/* 2*/ { BARCODE_AZTEC, "[01]12345678901234", "", GS1_MODE, READER_INIT, ZINT_ERROR_INVALID_OPTION, 0 },
/* 3*/ { BARCODE_AZTEC, "[01]12345678901234", "", GS1_MODE | ESCAPE_MODE, READER_INIT, ZINT_ERROR_INVALID_OPTION, 0 },
/* 4*/ { BARCODE_AZTEC, "1234", "", GS1_MODE, -1, ZINT_ERROR_INVALID_DATA, 0 },
/* 5*/ { BARCODE_AZTEC, "1234", "", GS1_MODE | ESCAPE_MODE, -1, ZINT_ERROR_INVALID_DATA, 0 },
/* 6*/ { BARCODE_CODABLOCKF, "[01]12345678901234", "", GS1_MODE, -1, ZINT_ERROR_INVALID_OPTION, 0 },
/* 7*/ { BARCODE_CODABLOCKF, "[01]12345678901234", "", GS1_MODE | ESCAPE_MODE, -1, ZINT_ERROR_INVALID_OPTION, 0 },
/* 8*/ { BARCODE_CODABLOCKF, "1234", "", GS1_MODE, -1, ZINT_ERROR_INVALID_OPTION, 0 },
/* 9*/ { BARCODE_CODABLOCKF, "1234", "", GS1_MODE | ESCAPE_MODE, -1, ZINT_ERROR_INVALID_OPTION, 0 },
/* 10*/ { BARCODE_CODEONE, "[01]12345678901234", "", GS1_MODE, -1, 0, 0 },
/* 11*/ { BARCODE_CODEONE, "[01]12345678901234", "", GS1_MODE | ESCAPE_MODE, -1, 0, 1 },
/* 12*/ { BARCODE_CODEONE, "1234", "", GS1_MODE, -1, ZINT_ERROR_INVALID_DATA, 0 },
/* 13*/ { BARCODE_CODEONE, "1234", "", GS1_MODE | ESCAPE_MODE, -1, ZINT_ERROR_INVALID_DATA, 0 },
/* 14*/ { BARCODE_CODE16K, "[01]12345678901234", "", GS1_MODE, -1, 0, 0 },
/* 15*/ { BARCODE_CODE16K, "[01]12345678901234", "", GS1_MODE | ESCAPE_MODE, -1, 0, 1 },
/* 16*/ { BARCODE_CODE16K, "1234", "", GS1_MODE, -1, ZINT_ERROR_INVALID_DATA, 0 },
/* 17*/ { BARCODE_CODE16K, "1234", "", GS1_MODE | ESCAPE_MODE, -1, ZINT_ERROR_INVALID_DATA, 0 },
/* 18*/ { BARCODE_CODE49, "[01]12345678901234", "", GS1_MODE, -1, 0, 0 },
/* 19*/ { BARCODE_CODE49, "[01]12345678901234", "", GS1_MODE | ESCAPE_MODE, -1, 0, 1 },
/* 20*/ { BARCODE_CODE49, "1234", "", GS1_MODE, -1, ZINT_ERROR_INVALID_DATA, 0 },
/* 21*/ { BARCODE_CODE49, "1234", "", GS1_MODE | ESCAPE_MODE, -1, ZINT_ERROR_INVALID_DATA, 0 },
/* 22*/ { BARCODE_DATAMATRIX, "[01]12345678901234", "", GS1_MODE, -1, 0, 0 },
/* 23*/ { BARCODE_DATAMATRIX, "[01]12345678901234", "", GS1_MODE | ESCAPE_MODE, -1, 0, 1 },
/* 24*/ { BARCODE_DATAMATRIX, "[01]12345678901234", "", GS1_MODE, READER_INIT, ZINT_ERROR_INVALID_OPTION, 0 },
/* 25*/ { BARCODE_DATAMATRIX, "[01]12345678901234", "", GS1_MODE | ESCAPE_MODE, READER_INIT, ZINT_ERROR_INVALID_OPTION, 0 },
/* 26*/ { BARCODE_DATAMATRIX, "1234", "", GS1_MODE, -1, ZINT_ERROR_INVALID_DATA, 0 },
/* 27*/ { BARCODE_DATAMATRIX, "1234", "", GS1_MODE | ESCAPE_MODE, -1, ZINT_ERROR_INVALID_DATA, 0 },
/* 28*/ { BARCODE_DOTCODE, "[01]12345678901234", "", GS1_MODE, -1, 0, 0 },
/* 29*/ { BARCODE_DOTCODE, "[01]12345678901234", "", GS1_MODE | ESCAPE_MODE, -1, 0, 1 },
/* 30*/ { BARCODE_DOTCODE, "1234", "", GS1_MODE, -1, ZINT_ERROR_INVALID_DATA, 0 },
/* 31*/ { BARCODE_DOTCODE, "1234", "", GS1_MODE | ESCAPE_MODE, -1, ZINT_ERROR_INVALID_DATA, 0 },
/* 32*/ { BARCODE_QRCODE, "[01]12345678901234", "", GS1_MODE, -1, 0, 0 },
/* 33*/ { BARCODE_QRCODE, "[01]12345678901234", "", GS1_MODE | ESCAPE_MODE, -1, 0, 1 },
/* 34*/ { BARCODE_QRCODE, "1234", "", GS1_MODE, -1, ZINT_ERROR_INVALID_DATA, 0 },
/* 35*/ { BARCODE_QRCODE, "1234", "", GS1_MODE | ESCAPE_MODE, -1, ZINT_ERROR_INVALID_DATA, 0 },
};
int data_size = sizeof(data) / sizeof(struct item);
char* text;
struct zint_symbol previous_symbol;
for (int i = 0; i < data_size; i++) {
struct zint_symbol* symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
symbol->symbology = data[i].symbology;
symbol->input_mode = data[i].input_mode;
if (data[i].output_options != -1) {
symbol->output_options = data[i].output_options;
}
if (strlen(data[i].composite)) {
text = data[i].composite;
strcpy(symbol->primary, data[i].data);
} else {
text = data[i].data;
}
int length = strlen(text);
ret = ZBarcode_Encode(symbol, text, length);
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d %s\n", i, ret, data[i].ret, symbol->errtxt);
if (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));
ZBarcode_Delete(symbol);
}
testFinish();
}
int main()
{
test_gs1_reduce();
test_hrt();
test_gs1_verify();
test_input_mode();
testReport();

View File

@ -95,9 +95,58 @@ static void test_checks(void)
testFinish();
}
static void test_input_mode(void)
{
testStart("");
int ret;
struct item {
unsigned char* data;
int input_mode;
int ret;
int expected_input_mode;
};
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = {
/* 0*/ { "1234", DATA_MODE, 0, DATA_MODE },
/* 1*/ { "1234", DATA_MODE | ESCAPE_MODE, 0, DATA_MODE | ESCAPE_MODE },
/* 2*/ { "1234", UNICODE_MODE, 0, UNICODE_MODE },
/* 3*/ { "1234", UNICODE_MODE | ESCAPE_MODE, 0, UNICODE_MODE | ESCAPE_MODE },
/* 4*/ { "[01]12345678901234", GS1_MODE, 0, GS1_MODE },
/* 5*/ { "[01]12345678901234", GS1_MODE | ESCAPE_MODE, 0, GS1_MODE | ESCAPE_MODE },
/* 6*/ { "1234", 4 | ESCAPE_MODE, 0, DATA_MODE }, // Unknown mode reset to bare DATA_MODE
/* 7*/ { "1234", -1, 0, DATA_MODE },
/* 8*/ { "1234", DATA_MODE | 0x10, 0, DATA_MODE | 0x10 }, // Unknown flags kept (but ignored)
/* 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);
for (int i = 0; i < data_size; i++) {
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;
int length = strlen(data[i].data);
ret = ZBarcode_Encode(symbol, 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(symbol->input_mode, data[i].expected_input_mode, "i:%d symbol->input_mode %d != %d\n", i, symbol->input_mode, data[i].expected_input_mode);
ZBarcode_Delete(symbol);
}
testFinish();
}
int main()
{
test_checks();
test_input_mode();
testReport();

View File

@ -27,6 +27,7 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
/* vim: set ts=4 sw=4 et : */
#include "testcommon.h"
@ -38,8 +39,6 @@ static void test_koreapost(void)
struct item {
unsigned char* data;
int ret_encode;
float w;
float h;
int ret_vector;
int expected_height;
@ -47,7 +46,7 @@ static void test_koreapost(void)
int expected_width;
};
struct item data[] = {
/* 0*/ { "123456", 0, 100, 30, 0, 50, 1, 167 },
/* 0*/ { "123456", 0, 0, 50, 1, 167 },
};
int data_size = sizeof(data) / sizeof(struct item);
@ -77,9 +76,58 @@ static void test_koreapost(void)
testFinish();
}
static void test_japanpost(void)
{
testStart("");
int ret;
struct item {
unsigned char* data;
int ret_encode;
int ret_vector;
int expected_height;
int expected_rows;
int expected_width;
char* comment;
};
struct item data[] = {
/* 0*/ { "123", 0, 0, 8, 3, 133, "Check 3" },
/* 1*/ { "123456-AB", 0, 0, 8, 3, 133, "Check 10" },
/* 2*/ { "123456", 0, 0, 8, 3, 133, "Check 11" },
};
int data_size = sizeof(data) / sizeof(struct item);
for (int i = 0; i < data_size; i++) {
struct zint_symbol* symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
symbol->symbology = BARCODE_JAPANPOST;
int length = strlen(data[i].data);
ret = ZBarcode_Encode(symbol, data[i].data, length);
assert_equal(ret, data[i].ret_encode, "i:%d ZBarcode_Encode ret %d != %d\n", i, ret, data[i].ret_encode);
if (data[i].ret_vector != -1) {
assert_equal(symbol->height, data[i].expected_height, "i:%d symbol->height %d != %d\n", i, symbol->height, data[i].expected_height);
assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows);
assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width);
ret = ZBarcode_Buffer_Vector(symbol, 0);
assert_equal(ret, data[i].ret_vector, "i:%d ZBarcode_Buffer_Vector ret %d != %d\n", i, ret, data[i].ret_vector);
}
ZBarcode_Delete(symbol);
}
testFinish();
}
int main()
{
test_koreapost();
test_japanpost();
testReport();

View File

@ -27,9 +27,18 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
/* vim: set ts=4 sw=4 et : */
#include "testcommon.h"
//#define TEST_QR_INPUT_GENERATE_EXPECTED 1
//#define TEST_MICROQR_INPUT_GENERATE_EXPECTED 1
//#define TEST_UPNQR_INPUT_GENERATE_EXPECTED 1
//#define TEST_QR_ENCODE_GENERATE_EXPECTED 1
//#define TEST_MICROQR_ENCODE_GENERATE_EXPECTED 1
//#define TEST_MICROQR_ENCODE_GENERATE_EXPECTED 1
//#define TEST_UPNQR_ENCODE_GENERATE_EXPECTED 1
static void test_microqr_options(void)
{
testStart("");
@ -45,7 +54,7 @@ static void test_microqr_options(void)
int ret_vector;
int expected_size;
};
// Vi} :s/\/\*[ 0-9]*\*\//\=printf("\/*%2d*\/", line(".") - line("'<"))
// s/\/\*[ 0-9]*\*\//\=printf("\/*%2d*\/", line(".") - line("'<"))
struct item data[] = {
/* 0*/ { "12345", 0, 0, 0, 100, 100, 0, 11 },
/* 1*/ { "12345", 1, 0, 0, 100, 100, 0, 11 },
@ -104,7 +113,7 @@ static void test_microqr_options(void)
int length = strlen(data[i].data);
ret = ZBarcode_Encode(symbol, data[i].data, length);
assert_equal(ret, data[i].ret_encode, "i:%d ZBarcode_Encode ret %d != %d\n", i, ret, data[i].ret_encode);
assert_equal(ret, data[i].ret_encode, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret_encode, symbol->errtxt);
if (data[i].ret_vector != -1) {
ret = ZBarcode_Buffer_Vector(symbol, 0);
@ -119,9 +128,635 @@ static void test_microqr_options(void)
testFinish();
}
static void test_qr_input(void)
{
testStart("");
int ret;
struct item {
int input_mode;
int eci;
unsigned char* data;
int ret;
int expected_eci;
char* expected;
char* comment;
};
// é U+00E9 in ISO 8859-1 plus other ISO 8859 (but not in ISO 8859-7 or ISO 8859-11), Win 1250 plus other Win, not in Shift JIS, UTF-8 C3A9
// β U+03B2 in ISO 8859-7 Greek (but not other ISO 8859 or Win page), in Shift JIS 0x83C0, UTF-8 CEB2
// ก U+0E01 in ISO 8859-11 Thai (but not other ISO 8859 or Win page), not in Shift JIS, UTF-8 E0B881
// Ж U+0416 in ISO 8859-5 Cyrillic (but not other ISO 8859), Win 1251, in Shift JIS 0x8447, UTF-8 D096
// ກ U+0E81 Lao not in any ISO 8859 (or Win page) or Shift JIS, UTF-8 E0BA81
// ¥ U+00A5 in ISO 8859-1 0xA5 (\245), in Shift JIS single-byte 0x5C (\134) (backslash); 0xA5 same codepoint as single-byte half-width katakana ・ (U+FF65) in Shift JIS (below), UTF-8 C2A5
// ・ U+FF65 half-width katakana, not in ISO/Win, in Shift JIS single-byte 0xA5 (\245), UTF-8 EFBDA5
// ¿ U+00BF in ISO 8859-1 0xBF (\277), not in Shift JIS; 0xBF same codepoint as single-byte half-width katakana ソ (U+FF7F) in Shift JIS (below), UTF-8 C2BF
// ソ U+FF7F half-width katakana, not in ISO/Win, in Shift JIS single-byte 0xBF (\277), UTF-8 EFBDBF
// ‾ U+203E overline, not in ISO/Win, in Shift JIS single-byte 0x7E (\176) (tilde), UTF-8 E280BE
// 点 U+70B9 kanji, in Shift JIS 0x935F (\223\137), UTF-8 E782B9
// 茗 U+8317 kanji, in Shift JIS 0xE4AA (\344\252), UTF-8 E88C97
// テ U+30C6 katakana, in Shift JIS 0x8365 (\203\145), UTF-8 E38386
struct item data[] = {
/* 0*/ { UNICODE_MODE, 0, "é", 0, 0, "40 1E 90 EC 11 EC 11 EC 11", "B1 (ISO 8859-1)" },
/* 1*/ { UNICODE_MODE, 3, "é", 0, 3, "70 34 01 E9 00 EC 11 EC 11", "ECI-3 B1 (ISO 8859-1)" },
/* 2*/ { UNICODE_MODE, 20, "é", ZINT_ERROR_INVALID_DATA, -1, "Error 800: Invalid character in input data", "é not in Shift JIS" },
/* 3*/ { UNICODE_MODE, 26, "é", 0, 26, "71 A4 02 C3 A9 00 EC 11 EC", "ECI-26 B2 (UTF-8)" },
/* 4*/ { DATA_MODE, 0, "é", 0, 0, "40 2C 3A 90 EC 11 EC 11 EC", "B2 (UTF-8)" },
/* 5*/ { DATA_MODE, 0, "\351", 0, 0, "40 1E 90 EC 11 EC 11 EC 11", "B1 (ISO 8859-1)" },
/* 6*/ { UNICODE_MODE, 0, "β", 0, 0, "80 11 00 00 EC 11 EC 11 EC", "K1 (Shift JIS)" },
/* 7*/ { UNICODE_MODE, 9, "β", 0, 9, "70 94 01 E2 00 EC 11 EC 11", "ECI-9 B1 (ISO 8859-7)" },
/* 8*/ { UNICODE_MODE, 20, "β", 0, 20, "71 48 01 10 00 00 EC 11 EC", "ECI-20 K1 (Shift JIS)" },
/* 9*/ { UNICODE_MODE, 26, "β", 0, 26, "71 A4 02 CE B2 00 EC 11 EC", "ECI-26 B2 (UTF-8)" },
/* 10*/ { DATA_MODE, 0, "β", 0, 0, "40 2C EB 20 EC 11 EC 11 EC", "B2 (UTF-8)" },
/* 11*/ { UNICODE_MODE, 0, "", ZINT_WARN_USES_ECI, 13, "Warning 70 D4 01 A1 00 EC 11 EC 11", "ECI-13 B1 (ISO 8859-11)" },
/* 12*/ { UNICODE_MODE, 13, "", 0, 13, "70 D4 01 A1 00 EC 11 EC 11", "ECI-13 B1 (ISO 8859-11)" },
/* 13*/ { UNICODE_MODE, 20, "", ZINT_ERROR_INVALID_DATA, -1, "Error 800: Invalid character in input data", "ก not in Shift JIS" },
/* 14*/ { UNICODE_MODE, 26, "", 0, 26, "71 A4 03 E0 B8 81 00 EC 11", "ECI-26 B3 (UTF-8)" },
/* 15*/ { DATA_MODE, 0, "", 0, 0, "40 3E 0B 88 10 EC 11 EC 11", "B3 (UTF-8)" },
/* 16*/ { UNICODE_MODE, 0, "Ж", 0, 0, "80 11 23 80 EC 11 EC 11 EC", "K1 (Shift JIS)" },
/* 17*/ { UNICODE_MODE, 7, "Ж", 0, 7, "70 74 01 B6 00 EC 11 EC 11", "ECI-7 B1 (ISO 8859-5)" },
/* 18*/ { UNICODE_MODE, 20, "Ж", 0, 20, "71 48 01 12 38 00 EC 11 EC", "ECI-20 K1 (Shift JIS)" },
/* 19*/ { UNICODE_MODE, 26, "Ж", 0, 26, "71 A4 02 D0 96 00 EC 11 EC", "ECI-26 B2 (UTF-8)" },
/* 20*/ { DATA_MODE, 0, "Ж", 0, 0, "40 2D 09 60 EC 11 EC 11 EC", "B2 (UTF-8)" },
/* 21*/ { UNICODE_MODE, 0, "", ZINT_WARN_USES_ECI, 26, "Warning 71 A4 03 E0 BA 81 00 EC 11", "ECI-26 B3 (UTF-8)" },
/* 22*/ { UNICODE_MODE, 20, "", ZINT_ERROR_INVALID_DATA, -1, "Error 800: Invalid character in input data", "ກ not in Shift JIS" },
/* 23*/ { UNICODE_MODE, 26, "", 0, 26, "71 A4 03 E0 BA 81 00 EC 11", "ECI-26 B3 (UTF-8)" },
/* 24*/ { DATA_MODE, 0, "", 0, 0, "40 3E 0B A8 10 EC 11 EC 11", "B3 (UTF-8)" },
/* 25*/ { UNICODE_MODE, 0, "\\", 0, 0, "40 15 C0 EC 11 EC 11 EC 11", "B1 (ASCII)" },
/* 26*/ { UNICODE_MODE, 20, "\\", 0, 20, "71 48 01 00 F8 00 EC 11 EC", "ECI-20 K1 (Shift JIS)" },
/* 27*/ { UNICODE_MODE, 20, "[", 0, 20, "71 44 01 5B 00 EC 11 EC 11", "B1 (ASCII)" },
/* 28*/ { UNICODE_MODE, 20, "\177", 0, 20, "71 44 01 7F 00 EC 11 EC 11", "ECI-20 B1 (ASCII)" },
/* 29*/ { UNICODE_MODE, 0, "¥", 0, 0, "40 1A 50 EC 11 EC 11 EC 11", "B1 (ISO 8859-1) (same bytes as ・ Shift JIS below, so ambiguous)" },
/* 30*/ { UNICODE_MODE, 3, "¥", 0, 3, "70 34 01 A5 00 EC 11 EC 11", "ECI-3 B1 (ISO 8859-1)" },
/* 31*/ { UNICODE_MODE, 20, "¥", 0, 20, "71 44 01 5C 00 EC 11 EC 11", "ECI-20 B1 (Shift JIS) (to single-byte backslash codepoint 5C, so byte mode)" },
/* 32*/ { UNICODE_MODE, 26, "¥", 0, 26, "71 A4 02 C2 A5 00 EC 11 EC", "ECI-26 B2 (UTF-8)" },
/* 33*/ { DATA_MODE, 0, "¥", 0, 0, "40 2C 2A 50 EC 11 EC 11 EC", "B2 (UTF-8)" },
/* 34*/ { UNICODE_MODE, 0, "", 0, 0, "40 1A 50 EC 11 EC 11 EC 11", "B1 (Shift JIS) single-byte codepoint A5 (same bytes as ¥ ISO 8859-1 above, so ambiguous)" },
/* 35*/ { UNICODE_MODE, 3, "", ZINT_ERROR_INVALID_DATA, -1, "Error 575: Invalid characters in input data", "" },
/* 36*/ { UNICODE_MODE, 20, "", 0, 20, "71 44 01 A5 00 EC 11 EC 11", "ECI-20 B1 (Shift JIS) single-byte codepoint A5" },
/* 37*/ { UNICODE_MODE, 26, "", 0, 26, "71 A4 03 EF BD A5 00 EC 11", "ECI-26 B3 (UTF-8)" },
/* 38*/ { DATA_MODE, 0, "", 0, 0, "40 3E FB DA 50 EC 11 EC 11", "B3 (UTF-8)" },
/* 39*/ { UNICODE_MODE, 0, "¿", 0, 0, "40 1B F0 EC 11 EC 11 EC 11", "B1 (ISO 8859-1) (same bytes as ソ Shift JIS below, so ambiguous)" },
/* 40*/ { UNICODE_MODE, 3, "¿", 0, 3, "70 34 01 BF 00 EC 11 EC 11", "ECI-3 B1 (ISO 8859-1)" },
/* 41*/ { UNICODE_MODE, 20, "¿", ZINT_ERROR_INVALID_DATA, -1, "Error 800: Invalid character in input data", "¿ not in Shift JIS" },
/* 42*/ { UNICODE_MODE, 26, "¿", 0, 26, "71 A4 02 C2 BF 00 EC 11 EC", "ECI-26 B2 (UTF-8)" },
/* 43*/ { DATA_MODE, 0, "¿", 0, 0, "40 2C 2B F0 EC 11 EC 11 EC", "B2 (UTF-8)" },
/* 44*/ { UNICODE_MODE, 0, "ソ", 0, 0, "40 1B F0 EC 11 EC 11 EC 11", "B1 (Shift JIS) single-byte codepoint BF (same bytes as ¿ ISO 8859-1 above, so ambiguous)" },
/* 45*/ { UNICODE_MODE, 3, "ソ", ZINT_ERROR_INVALID_DATA, -1, "Error 575: Invalid characters in input data", "" },
/* 46*/ { UNICODE_MODE, 20, "ソ", 0, 20, "71 44 01 BF 00 EC 11 EC 11", "ECI-20 B1 (Shift JIS) single-byte codepoint BF" },
/* 47*/ { UNICODE_MODE, 26, "ソ", 0, 26, "71 A4 03 EF BD BF 00 EC 11", "ECI-26 B3 (UTF-8)" },
/* 48*/ { DATA_MODE, 0, "ソ", 0, 0, "40 3E FB DB F0 EC 11 EC 11", "B3 (UTF-8)" },
/* 49*/ { UNICODE_MODE, 0, "~", 0, 0, "40 17 E0 EC 11 EC 11 EC 11", "B1 (ASCII) (same bytes as ‾ Shift JIS below, so ambiguous)" },
/* 50*/ { UNICODE_MODE, 3, "~", 0, 3, "70 34 01 7E 00 EC 11 EC 11", "ECI-3 B1 (ASCII)" },
/* 51*/ { UNICODE_MODE, 20, "~", ZINT_ERROR_INVALID_DATA, -1, "Error 800: Invalid character in input data", "tilde not in Shift JIS (codepoint used for overline)" },
/* 52*/ { UNICODE_MODE, 0, "", 0, 0, "40 17 E0 EC 11 EC 11 EC 11", "B1 (Shift JIS) single-byte codepoint 7E (same bytes as ~ ASCII above, so ambiguous)" },
/* 53*/ { UNICODE_MODE, 3, "", ZINT_ERROR_INVALID_DATA, -1, "Error 575: Invalid characters in input data", "" },
/* 54*/ { UNICODE_MODE, 20, "", 0, 20, "71 44 01 7E 00 EC 11 EC 11", "ECI-20 B1 (Shift JIS) (to single-byte tilde codepoint 7E, so byte mode)" },
/* 55*/ { UNICODE_MODE, 26, "", 0, 26, "71 A4 03 E2 80 BE 00 EC 11", "ECI-26 B3 (UTF-8)" },
/* 56*/ { DATA_MODE, 0, "", 0, 0, "40 3E 28 0B E0 EC 11 EC 11", "B3 (UTF-8)" },
/* 57*/ { UNICODE_MODE, 0, "", 0, 0, "80 16 CF 80 EC 11 EC 11 EC", "K1 (Shift JIS)" },
/* 58*/ { UNICODE_MODE, 3, "", ZINT_ERROR_INVALID_DATA, -1, "Error 575: Invalid characters in input data", "" },
/* 59*/ { UNICODE_MODE, 20, "", 0, 20, "71 48 01 6C F8 00 EC 11 EC", "ECI-20 K1 (Shift JIS)" },
/* 60*/ { UNICODE_MODE, 26, "", 0, 26, "71 A4 03 E7 82 B9 00 EC 11", "ECI-26 B3 (UTF-8)" },
/* 61*/ { DATA_MODE, 0, "", 0, 0, "40 3E 78 2B 90 EC 11 EC 11", "B3 (UTF-8)" },
/* 62*/ { DATA_MODE, 0, "\223\137", 0, 0, "80 16 CF 80 EC 11 EC 11 EC", "K1 (Shift JIS)" },
/* 63*/ { UNICODE_MODE, 0, "¥・点", 0, 0, "40 45 CA 59 35 F0 EC 11 EC", "B4 (Shift JIS) (optimized to byte mode only)" },
/* 64*/ { UNICODE_MODE, 3, "¥・点", ZINT_ERROR_INVALID_DATA, -1, "Error 575: Invalid characters in input data", "" },
/* 65*/ { UNICODE_MODE, 20, "¥・点", 0, 20, "71 44 04 5C A5 93 5F 00 EC", "ECI-20 B4 (Shift JIS)" },
/* 66*/ { UNICODE_MODE, 26, "¥・点", 0, 26, "71 A4 08 C2 A5 EF BD A5 E7 82 B9 00 EC", "ECI-26 B8 (UTF-8)" },
/* 67*/ { DATA_MODE, 0, "\134\245\223\137", 0, 0, "40 45 CA 59 35 F0 EC 11 EC", "B8 (Shift JIS)" },
/* 68*/ { DATA_MODE, 0, "¥・点", 0, 0, "40 8C 2A 5E FB DA 5E 78 2B 90 EC 11 EC", "B8 (UTF-8)" },
/* 69*/ { UNICODE_MODE, 0, "点茗", 0, 0, "80 26 CF EA A8 00 EC 11 EC", "K2 (Shift JIS)" },
/* 70*/ { UNICODE_MODE, 0, "点茗テ", 0, 0, "80 36 CF EA A8 34 A0 EC 11", "K3 (Shift JIS)" },
/* 71*/ { UNICODE_MODE, 0, "点茗テ点", 0, 0, "80 46 CF EA A8 34 AD 9F 00", "K4 (Shift JIS)" },
/* 72*/ { UNICODE_MODE, 0, "点茗テ点茗", 0, 0, "80 56 CF EA A8 34 AD 9F D5 50 00 EC 11", "K5 (Shift JIS)" },
/* 73*/ { UNICODE_MODE, 0, "点茗テ点茗テ", 0, 0, "80 66 CF EA A8 34 AD 9F D5 50 69 40 EC", "K6 (Shift JIS)" },
/* 74*/ { UNICODE_MODE, 0, "点茗テ点茗テソ", 0, 0, "80 66 CF EA A8 34 AD 9F D5 50 69 50 06 FC 00 EC", "K6 B1 (Shift JIS)" },
/* 75*/ { DATA_MODE, 0, "\223\137\344\252\203\145\223\137\344\252\203\145\277", 0, 0, "80 66 CF EA A8 34 AD 9F D5 50 69 50 06 FC 00 EC", "K6 B1 (Shift JIS)" },
/* 76*/ { DATA_MODE, 0, "点茗テ点茗テソ", 0, 0, "41 5E 78 2B 9E 88 C9 7E 38 38 6E 78 2B 9E 88 C9 7E 38 38 6E FB DB F0 EC 11 EC 11 EC", "B21 (UTF-8)" },
};
int data_size = sizeof(data) / sizeof(struct item);
char escaped[1024];
for (int i = 0; i < data_size; i++) {
struct zint_symbol* symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
symbol->symbology = BARCODE_QRCODE;
symbol->input_mode = data[i].input_mode;
symbol->eci = data[i].eci;
symbol->debug = ZINT_DEBUG_TEST; // Needed to get codeword dump in errtxt
int length = strlen(data[i].data);
ret = ZBarcode_Encode(symbol, data[i].data, length);
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d\n", i, ret, data[i].ret);
#ifdef TEST_QR_INPUT_GENERATE_EXPECTED
printf(" /*%3d*/ { %s, %d, \"%s\", %s, %d, \"%s\", \"%s\" },\n",
i, testUtilInputModeName(data[i].input_mode), data[i].eci, testUtilEscape(data[i].data, escaped, sizeof(escaped)), testUtilErrorName(data[i].ret),
ret < 5 ? symbol->eci : -1, symbol->errtxt, data[i].comment);
#else
if (ret < 5) {
assert_equal(symbol->eci, data[i].expected_eci, "i:%d eci %d != %d\n", i, symbol->eci, data[i].expected_eci);
assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected);
}
#endif
ZBarcode_Delete(symbol);
}
testFinish();
}
static void test_microqr_input(void)
{
testStart("");
int ret;
struct item {
int input_mode;
unsigned char* data;
int ret;
char* expected;
char* comment;
};
// é U+00E9 in ISO 8859-1 plus other ISO 8859 (but not in ISO 8859-7 or ISO 8859-11), Win 1250 plus other Win, not in Shift JIS, UTF-8 C3A9
// β U+03B2 in ISO 8859-7 Greek (but not other ISO 8859 or Win page), in Shift JIS 0x83C0, UTF-8 CEB2
// ก U+0E01 in ISO 8859-11 Thai (but not other ISO 8859 or Win page), not in Shift JIS, UTF-8 E0B881
// Ж U+0416 in ISO 8859-5 Cyrillic (but not other ISO 8859), Win 1251, in Shift JIS 0x8447 (\204\107), UTF-8 D096
// ກ U+0E81 Lao not in any ISO 8859 (or Win page) or Shift JIS, UTF-8 E0BA81
// ¥ U+00A5 in ISO 8859-1 0xA5 (\245), in Shift JIS single-byte 0x5C (\134) (backslash); 0xA5 same codepoint as single-byte half-width katakana ・ (U+FF65) in Shift JIS (below), UTF-8 C2A5
// ・ U+FF65 half-width katakana, not in ISO/Win, in Shift JIS single-byte 0xA5 (\245), UTF-8 EFBDA5
// ¿ U+00BF in ISO 8859-1 0xBF (\277), not in Shift JIS; 0xBF same codepoint as single-byte half-width katakana ソ (U+FF7F) in Shift JIS (below), UTF-8 C2BF
// ソ U+FF7F half-width katakana, not in ISO/Win, in Shift JIS single-byte 0xBF (\277), UTF-8 EFBDBF
// ‾ U+203E overline, not in ISO/Win, in Shift JIS single-byte 0x7E (\176) (tilde), UTF-8 E280BE
// 点 U+70B9 kanji, in Shift JIS 0x935F (\223\137), UTF-8 E782B9
// 茗 U+8317 kanji, in Shift JIS 0xE4AA (\344\252), UTF-8 E88C97
struct item data[] = {
/* 0*/ { UNICODE_MODE, "é", 0, "87 A4 00 EC 11 EC 11 EC 00", "B1 (ISO 8859-1)" },
/* 1*/ { DATA_MODE, "é", 0, "8B 0E A4 00 EC 11 EC 11 00", "B2 (UTF-8)" },
/* 2*/ { UNICODE_MODE, "β", 0, "C8 80 00 00 EC 11 EC 11 00", "K1 (Shift JIS)" },
/* 3*/ { UNICODE_MODE, "", ZINT_ERROR_INVALID_DATA, "Error 800: Invalid character in input data", "ก not in Shift JIS" },
/* 4*/ { UNICODE_MODE, "Ж", 0, "C8 91 C0 00 EC 11 EC 11 00", "K1 (Shift JIS)" },
/* 5*/ { UNICODE_MODE, "", ZINT_ERROR_INVALID_DATA, "Error 800: Invalid character in input data", "ກ not in Shift JIS" },
/* 6*/ { UNICODE_MODE, "\\", 0, "85 70 00 EC 11 EC 11 EC 00", "B1 (ASCII)" },
/* 7*/ { UNICODE_MODE, "¥", 0, "86 94 00 EC 11 EC 11 EC 00", "B1 (ISO 8859-1) (same bytes as ・ Shift JIS below, so ambiguous)" },
/* 8*/ { UNICODE_MODE, "", 0, "86 94 00 EC 11 EC 11 EC 00", "B1 (Shift JIS) single-byte codepoint A5 (same bytes as ¥ ISO 8859-1 above, so ambiguous)" },
/* 9*/ { UNICODE_MODE, "¿", 0, "86 FC 00 EC 11 EC 11 EC 00", "B1 (ISO 8859-1) (same bytes as ソ Shift JIS below, so ambiguous)" },
/* 10*/ { UNICODE_MODE, "ソ", 0, "86 FC 00 EC 11 EC 11 EC 00", "B1 (Shift JIS) (same bytes as ¿ ISO 8859-1 above, so ambiguous)" },
/* 11*/ { UNICODE_MODE, "~", 0, "85 F8 00 EC 11 EC 11 EC 00", "B1 (ASCII) (same bytes as ‾ Shift JIS below, so ambiguous)" },
/* 12*/ { UNICODE_MODE, "", 0, "85 F8 00 EC 11 EC 11 EC 00", "B1 (Shift JIS) (same bytes as ~ ASCII above, so ambiguous)" },
/* 13*/ { UNICODE_MODE, "", 0, "CB 67 C0 00 EC 11 EC 11 00", "K1 (Shift JIS)" },
/* 14*/ { DATA_MODE, "\223\137", 0, "CB 67 C0 00 EC 11 EC 11 00", "K1 (Shift JIS)" },
/* 15*/ { DATA_MODE, "", 0, "CF 30 A1 B9 00 EC 11 EC 00", "K1 B1 (UTF-8) (1st 2 UTF-8 bytes E782 encoded in Kanji mode) (non-optimal)" },
/* 16*/ { UNICODE_MODE, "", 0, "CE AA 80 00 EC 11 EC 11 00", "K1 (Shift JIS)" },
/* 17*/ { DATA_MODE, "\344\252", 0, "CE AA 80 00 EC 11 EC 11 00", "K1 (Shift JIS)" },
/* 18*/ { DATA_MODE, "", 0, "CF 63 21 97 00 EC 11 EC 00", "K1 B1 (UTF-8) (1st 2 UTF-8 bytes E88C encoded in Kanji mode) (non-optimal)" },
/* 19*/ { UNICODE_MODE, "¥点", 0, "85 73 2D 9F 00 EC 11 EC 00", "B1 K1 (Shift JIS) (non-optimal)" },
/* 20*/ { DATA_MODE, "\134\223\137", 0, "85 73 2D 9F 00 EC 11 EC 00", "B1 K1 (Shift JIS) (non-optimal)" },
/* 21*/ { DATA_MODE, "¥点", 0, "8B 0A 97 3C C2 86 E4 00 00", "B2 K1 B1 (UTF-8) (last 2 UTF-8 bytes 82B9 encoded in Kanji mode) (non-optimal)" },
/* 22*/ { UNICODE_MODE, "点茗", 0, "D3 67 F5 54 00 EC 11 EC 00", "K2 (Shift JIS)" },
/* 23*/ { DATA_MODE, "\223\137\344\252", 0, "D3 67 F5 54 00 EC 11 EC 00", "K2 (Shift JIS)" },
/* 24*/ { DATA_MODE, "点茗", 0, "CF 30 A1 B9 CF 63 21 97 00", "K1 B1 K1 B1 (UTF-8) (non-optimal)" },
/* 25*/ { UNICODE_MODE, "点茗・", 0, "D3 67 F5 55 0D 28 00 EC 00", "K2 B1 (Shift JIS) (non-optimal)" },
/* 26*/ { DATA_MODE, "\223\137\344\252\245", 0, "D3 67 F5 55 0D 28 00 EC 00", "K2 B1 (Shift JIS) (non-optimal)" },
/* 27*/ { DATA_MODE, "点茗・", 0, "63 CC 24 1B 96 5D 8C 89 7A 15 ED 28 00 EC", "K1 B1 K2 B2 (UTF-8) (non-optimal)" },
/* 28*/ { UNICODE_MODE, "¥点茗・", 0, "85 73 4D 9F D5 54 34 A0 00", "B1 K2 B1 (Shift JIS) (non-optimal)" },
/* 29*/ { DATA_MODE, "\134\223\137\344\252\245", 0, "85 73 4D 9F D5 54 34 A0 00", "B1 K2 B1 (Shift JIS) (non-optimal)" },
/* 30*/ { DATA_MODE, "¥点茗・", 0, "42 C2 A5 63 CC 24 1B 96 5D 8C 89 7A 15 ED 28 00", "B2 K1 B1 K2 B2 (UTF-8) (non-optimal)" },
};
int data_size = sizeof(data) / sizeof(struct item);
char escaped[1024];
for (int i = 0; i < data_size; i++) {
struct zint_symbol* symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
symbol->symbology = BARCODE_MICROQR;
symbol->input_mode = data[i].input_mode;
symbol->debug = ZINT_DEBUG_TEST; // Needed to get codeword dump in errtxt
int length = strlen(data[i].data);
ret = ZBarcode_Encode(symbol, data[i].data, length);
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d\n", i, ret, data[i].ret);
#ifdef TEST_MICROQR_INPUT_GENERATE_EXPECTED
printf(" /*%3d*/ { %s, \"%s\", %s, \"%s\", \"%s\" },\n",
i, testUtilInputModeName(data[i].input_mode), testUtilEscape(data[i].data, escaped, sizeof(escaped)), testUtilErrorName(data[i].ret),
symbol->errtxt, 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);
}
#endif
ZBarcode_Delete(symbol);
}
testFinish();
}
static void test_upnqr_input(void)
{
testStart("");
int ret;
struct item {
int input_mode;
unsigned char* data;
int ret;
char* expected;
char* comment;
};
// Ą U+0104 in ISO 8859-2 0xA1, in other ISO 8859 and Win 1250, UTF-8 C484
// Ŕ U+0154 in ISO 8859-2 0xC0, in Win 1250 but not other ISO 8859 or Win page, UTF-8 C594
// é U+00E9 in ISO 8859-1 plus other ISO 8859 (but not in ISO 8859-7 or ISO 8859-11), Win 1250 plus other Win, not in Shift JIS, UTF-8 C3A9
// β U+03B2 in ISO 8859-7 Greek (but not other ISO 8859 or Win page), in Shift JIS 0x83C0, UTF-8 CEB2
struct item data[] = {
/* 0*/ { UNICODE_MODE, "ĄŔ", 0, "70 44 00 02 A1 C0 00 EC 11 EC 11 EC 11 EC 11 EC 11 EC 11 EC 11 EC 11 EC 11 EC 11 EC 11 EC 11 EC 11", "ECI-4 B2 (ISO 8859-2)" },
/* 1*/ { UNICODE_MODE, "é", 0, "70 44 00 01 E9 00 EC 11 EC 11 EC 11 EC 11 EC 11 EC 11 EC 11 EC 11 EC 11 EC 11 EC 11 EC 11 EC 11 EC", "ECI-4 B1 (ISO 8859-2)" },
/* 2*/ { UNICODE_MODE, "β", ZINT_ERROR_INVALID_DATA, "Error 572: Invalid characters in input data", "β not in ISO 8859-2" },
};
int data_size = sizeof(data) / sizeof(struct item);
char escaped[1024];
for (int i = 0; i < data_size; i++) {
struct zint_symbol* symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
symbol->symbology = BARCODE_UPNQR;
symbol->input_mode = data[i].input_mode;
symbol->debug = ZINT_DEBUG_TEST; // Needed to get codeword dump in errtxt
int length = strlen(data[i].data);
ret = ZBarcode_Encode(symbol, data[i].data, length);
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d\n", i, ret, data[i].ret);
assert_equal(symbol->eci, 4, "i:%d ZBarcode_Encode symbol->eci %d != 4\n", i, symbol->eci);
#ifdef TEST_UPNQR_INPUT_GENERATE_EXPECTED
printf(" /*%3d*/ { %s, \"%s\", %s, \"%s\", \"%s\" },\n",
i, testUtilInputModeName(data[i].input_mode), testUtilEscape(data[i].data, escaped, sizeof(escaped)), testUtilErrorName(data[i].ret),
symbol->errtxt, 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);
}
#endif
ZBarcode_Delete(symbol);
}
testFinish();
}
static void test_qr_encode(void)
{
testStart("");
int ret;
struct item {
unsigned char* data;
int input_mode;
int option_1;
int option_2;
int ret;
int expected_rows;
int expected_width;
char* comment;
char* expected;
};
struct item data[] = {
/* 0*/ { "12345678901234567890123456789012345678901", UNICODE_MODE, -1, -1, 0, 21, 21, "Max capacity Version 1 41 numbers",
"111111100011001111111"
"100000100001001000001"
"101110101110001011101"
"101110100001001011101"
"101110100011001011101"
"100000100100001000001"
"111111101010101111111"
"000000001100100000000"
"111011111000011000100"
"111000000110111000001"
"001001111011110001000"
"001110011011011111001"
"001100101000001000011"
"000000001101100001010"
"111111101011011001011"
"100000101100010001011"
"101110101101010111100"
"101110100000111000010"
"101110101001100011101"
"100000101010111011000"
"111111101000100010101"
},
};
int data_size = sizeof(data) / sizeof(struct item);
for (int i = 0; i < data_size; i++) {
struct zint_symbol* symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
symbol->symbology = BARCODE_QRCODE;
symbol->input_mode = data[i].input_mode;
if (data[i].option_1 != -1) {
symbol->option_1 = data[i].option_1;
}
if (data[i].option_2 != -1) {
symbol->option_2 = data[i].option_2;
}
int length = strlen(data[i].data);
ret = ZBarcode_Encode(symbol, 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);
#ifdef TEST_QR_ENCODE_GENERATE_EXPECTED
printf(" /*%3d*/ { \"%s\", %s, %d, %d, %s, %d, %d, \"%s\",\n",
i, data[i].data, testUtilInputModeName(data[i].input_mode), data[i].option_1, data[i].option_2, testUtilErrorName(data[i].ret),
symbol->rows, symbol->width, data[i].comment);
testUtilModulesDump(symbol, " ", "\n");
printf(" },\n");
#else
if (ret < 5) {
assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", i, symbol->rows, data[i].expected_rows, data[i].data);
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);
if (ret == 0) {
int width, row;
ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row);
assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data);
}
}
#endif
ZBarcode_Delete(symbol);
}
testFinish();
}
static void test_microqr_encode(void)
{
testStart("");
int ret;
struct item {
unsigned char* data;
int input_mode;
int option_1;
int option_2;
int ret;
int expected_rows;
int expected_width;
char* comment;
char* expected;
};
struct item data[] = {
/* 0*/ { "12345", UNICODE_MODE, -1, -1, 0, 11, 11, "Max capacity M1 5 numbers",
"11111110101"
"10000010110"
"10111010100"
"10111010000"
"10111010111"
"10000010011"
"11111110100"
"00000000011"
"11001110011"
"01010001100"
"11110000011"
},
/* 1*/ { "点茗テ点茗テ点茗テ", UNICODE_MODE, -1, -1, 0, 17, 17, "Max capacity M4 9 Kanji",
"11111110101010101"
"10000010111110010"
"10111010000011101"
"10111010110011010"
"10111010001011001"
"10000010110110110"
"11111110101100100"
"00000000010011011"
"10010111011110100"
"00001010100100110"
"11101010001000010"
"00010111101000010"
"11000100010110000"
"01001111010011101"
"10000100101100011"
"01011000000010111"
"11001111011101001"
},
};
int data_size = sizeof(data) / sizeof(struct item);
for (int i = 0; i < data_size; i++) {
struct zint_symbol* symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
symbol->symbology = BARCODE_MICROQR;
symbol->input_mode = data[i].input_mode;
if (data[i].option_1 != -1) {
symbol->option_1 = data[i].option_1;
}
if (data[i].option_2 != -1) {
symbol->option_2 = data[i].option_2;
}
int length = strlen(data[i].data);
ret = ZBarcode_Encode(symbol, 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);
#ifdef TEST_MICROQR_ENCODE_GENERATE_EXPECTED
printf(" /*%3d*/ { \"%s\", %s, %d, %d, %s, %d, %d, \"%s\",\n",
i, data[i].data, testUtilInputModeName(data[i].input_mode), data[i].option_1, data[i].option_2, testUtilErrorName(data[i].ret),
symbol->rows, symbol->width, data[i].comment);
testUtilModulesDump(symbol, " ", "\n");
printf(" },\n");
#else
if (ret < 5) {
assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", i, symbol->rows, data[i].expected_rows, data[i].data);
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);
if (ret == 0) {
int width, row;
ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row);
assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data);
}
}
#endif
ZBarcode_Delete(symbol);
}
testFinish();
}
static void test_upnqr_encode(void)
{
testStart("");
int ret;
struct item {
unsigned char* data;
int input_mode;
int option_1;
int option_2;
int ret;
int expected_rows;
int expected_width;
char* comment;
char* expected;
};
struct item data[] = {
/* 0*/ { "Ą˘Ł¤ĽŚ§¨ŠŞŤŹŽŻ°ą˛ł´ľśˇ¸šşťź˝žżŔÁÂĂÄĹĆÇČÉĘËĚÍÎĎĐŃŇÓÔŐÖ×ŘŮÚŰÜÝŢßŕáâăäĺćçčéęëěíîďđńňóôőö÷řůúűüýţ˙", UNICODE_MODE, -1, -1, 0, 77, 77, "ISO 8859-2",
"11111110000111101001000110101100101001111110111011001111111000110000001111111"
"10000010001011100100110111111011110100001011110000100001001110011010101000001"
"10111010110101111111101101111101001010110101111011011110100001100100101011101"
"10111010100110111001110101101000011101101000110011100111001111101000101011101"
"10111010100110010010011011111101001001111101101111101001101111001011101011101"
"10000010101011011010010010001010010101101010111000100011001110100010001000001"
"11111110101010101010101010101010101010101010101010101010101010101010101111111"
"00000000110101001100101010001100001011110010011000111100111000000000100000000"
"10111110010111011110010011111001111100101111111111100001010110011010001111100"
"10000001110110110001011001111100101000111010111001001101111100111000111100000"
"11111110110010111100110011101011110100001111110110101111010110000010001011010"
"00001100011100001010101111010101001111110100011101010110101000110000010100000"
"11010011100111011010010001110000010010101001110101111101001110000010101001010"
"10000100100110010010011000011101010111111100111011010111100100100001011100000"
"11101110110010111100110111110010001010001011110000110001011110000011101011010"
"00001100011110101011101111011101101010010010011011011010110000111001110100000"
"11011111111100011010010101110001111101001111110011000011010110000010001001010"
"10010000100101010010011100001100101000011010111000101001111100101000111100010"
"11110110111100011100110011100011110101001111110110101011110110000010001111001"
"00111100010001101011101111000010101111100010001101110100011000111100110010011"
"11000111111100011010010111101111011010110111100110111100110110000111111111001"
"10000000111001110010011100010010001111100010101011110110011100101010111010000"
"11111110100100111100110001101111110010010111110011111000010110000001110010010"
"00111000000011101011111101001011010100010010000101011010111000111101011100000"
"11111111110110011010001011111110000001001111101111101011010110000001111110010"
"11101000100001111010011010001011010000011010101000111001111100101111100011100"
"10001010111100101100110110101110000101001111111010100011110100000101101010010"
"01011000101001110011101110001011001000000011011000111000011011111100100010101"
"01101111101010001010011011111110011011010110011111111010110001000100111111001"
"01100101111101101010010101101011001010000011000101100000011011001101101001110"
"01010110111100110000110110010110010101010110010101001010110010000010010101111"
"11110000101111101011011001101011010110001010000000110000011001111111001010010"
"01000010001010001010001111001110000011000111110110011011110110100100110110101"
"10110101111001101010100101101011010110011010100110010000111100101110101101110"
"01111110011100110001111110010110000011001111101000111011010111001000001100100"
"01111101101001101001101001001011010110011001011110010000001101110011100101110"
"00011110001000001001011110001110000011001100001101111010100101111010100000000"
"00110001111011111101110101101011010110001101010111110001000101110001110010010"
"00111111111101100001110110010110000011011010010001011011101100110010000101001"
"11111100101101010011000001101111010110000101100110110000000001011101110110011"
"10011110101001010101000111101100000011010000010100011010111001100100100011001"
"00110000111011111100100100001011010110000110100110010000011001001111101001110"
"00111111111100101111110110110110000011010111101000111010101100100000011000101"
"00111100101101001100100001001100010111100010111110010100011110000111101111111"
"00011110101000110101001110001101100010010110101100111110110110001100110010001"
"00110001011010010000110111100000110110000011110110010000010110101111110111110"
"11111111111100101001111011111011100010010110101111111110110100001000111110101"
"00111000101101001011000110001111010111100101001000110110000011110110100011111"
"00011010110001110111001110101000000010110000001010111000101001111101101010001"
"00111000100011110100110010001001010110100101011000110100000011011111100011110"
"11111111100101101100111011111000000011010010001111110110111000101000111110101"
"00111101101101001000000100110000001010000011011000111000010011001111100011111"
"00011111100000110000101100100101110101010110000110000010110001110101010110001"
"00111100100011110000110010000100100000000011001100101000011011000110100011110"
"11000010000101001110011100001101110101010110000110001010110000101001010110101"
"00101100101110101001000110101000101111100101011000110100001011010111100011111"
"00011110001010110000101011101111111010110000000110011100101001111101110110001"
"00011100001000010000110010100000101111100101001100110110000011010110000011100"
"11000011000101101110011100010011100010010010000100010000011000111000110110110"
"00000101111010001001000010001001010010010101011010111010100011010110000011100"
"00011110011001110000101100100101000101001000000000000011001001111110010110010"
"00111100000101110000110101000000010000011101001010101001100011010010100011010"
"11100110111101101110001011001111100101001010000010000011111000111101010111001"
"00010001110110000001001101010000001001100101011000111100000011010111100011111"
"10010010000001111000111010111101111000110000000110001100101001111001010110101"
"10010000000111110000111011001000101001100101000101111110000011010001100011110"
"01001110100011111110011101000111110100010010001101001000011010111010110110010"
"00001001111000001001000001001000010111110100010010100110100001010111100010101"
"01111010010011110000101011111101100010101001101111111101001111011101111110101"
"00000000110101101000111110001000110011111100101000100111100101010101100011101"
"11111110001101111010001010101111100100001011101010100001011101011010101011100"
"10000010111110000001101010001000001011111101001000111110000011010001100010010"
"10111010110101110101011111111101111100100000011111100101101000111011111111101"
"10111010110001100110111110110000101001111101010001101110100010110000010010010"
"10111010101011111111010111011111110100001010011011000001111000110011100101010"
"10000010011100010001111111000000001011100000001000111111100001011101111000001"
"11111110110101111101111001011101111100101101111101100101000101100100011101000"
},
};
int data_size = sizeof(data) / sizeof(struct item);
for (int i = 0; i < data_size; i++) {
struct zint_symbol* symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
symbol->symbology = BARCODE_UPNQR;
symbol->input_mode = data[i].input_mode;
if (data[i].option_1 != -1) {
symbol->option_1 = data[i].option_1;
}
if (data[i].option_2 != -1) {
symbol->option_2 = data[i].option_2;
}
int length = strlen(data[i].data);
ret = ZBarcode_Encode(symbol, 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);
#ifdef TEST_UPNQR_ENCODE_GENERATE_EXPECTED
printf(" /*%3d*/ { \"%s\", %s, %d, %d, %s, %d, %d, \"%s\",\n",
i, data[i].data, testUtilInputModeName(data[i].input_mode), data[i].option_1, data[i].option_2, testUtilErrorName(data[i].ret),
symbol->rows, symbol->width, data[i].comment);
testUtilModulesDump(symbol, " ", "\n");
printf(" },\n");
#else
if (ret < 5) {
assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", i, symbol->rows, data[i].expected_rows, data[i].data);
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);
if (ret == 0) {
int width, row;
ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row);
assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data);
}
}
#endif
ZBarcode_Delete(symbol);
}
testFinish();
}
int main()
{
test_microqr_options();
test_qr_input();
test_microqr_input();
test_upnqr_input();
test_qr_encode();
test_microqr_encode();
test_upnqr_encode();
testReport();

283
backend/tests/test_sjis.c Normal file
View File

@ -0,0 +1,283 @@
/*
libzint - the open source barcode library
Copyright (C) 2008-2019 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the project nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
/* vim: set ts=4 sw=4 et : */
#include "testcommon.h"
#include "test_sjis_tab.h"
#include "../sjis.h"
// As control convert to Shift JIS using simple table generated from https://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/JIS/SHIFTJIS.TXT plus simple processing
static int sjis_wctomb_zint2(unsigned char* r, unsigned int wc, size_t n)
{
if (wc < 0x20 || wc == 0x7F) {
r[0] = wc;
return 1;
}
// Shortcut
if ((wc > 0x00F7 && wc < 0x0391) || (wc > 0x0451 && wc < 0x2010) || (wc > 0x9FA0 && wc < 0xE000) || (wc > 0xE757 && wc < 0xFF01) || wc > 0xFFE5) {
return 0;
}
if (wc >= 0xE000 && wc <= 0xE757) { // PUA mappings, not in SHIFTJIS.TXT
unsigned short c;
if (wc <= 0xE0BB) {
c = wc - 0xE000 + 0xF040 + (wc >= 0xE000 + 0x3F);
} else if (wc <= 0xE177) {
c = wc - 0xE0BC + 0xF140 + (wc >= 0xE0BC + 0x3F);
} else if (wc <= 0xE233) {
c = wc - 0xE178 + 0xF240 + (wc >= 0xE178 + 0x3F);
} else if (wc <= 0xE2EF) {
c = wc - 0xE234 + 0xF340 + (wc >= 0xE234 + 0x3F);
} else if (wc <= 0xE3AB) {
c = wc - 0xE2F0 + 0xF440 + (wc >= 0xE2F0 + 0x3F);
} else if (wc <= 0xE467) {
c = wc - 0xE3AC + 0xF540 + (wc >= 0xE3AC + 0x3F);
} else if (wc <= 0xE523) {
c = wc - 0xE468 + 0xF640 + (wc >= 0xE468 + 0x3F);
} else if (wc <= 0xE5DF) {
c = wc - 0xE524 + 0xF740 + (wc >= 0xE524 + 0x3F);
} else if (wc <= 0xE69B) {
c = wc - 0xE5E0 + 0xF840 + (wc >= 0xE5E0 + 0x3F);
} else {
c = wc - 0xE69C + 0xF940 + (wc >= 0xE69C + 0x3F);
}
r[0] = (c >> 8);
r[1] = c & 0xFF;
return 2;
}
int tab_length = sizeof(test_sjis_tab) / sizeof(unsigned short);
for (int i = 0; i < tab_length; i += 2) {
if (test_sjis_tab[i + 1] == wc) {
unsigned short c = test_sjis_tab[i];
if (c < 0xFF) {
r[0] = c;
return 1;
}
r[0] = (c >> 8);
r[1] = c & 0xFF;
return 2;
}
}
return 0;
}
static void test_sjis_wctomb_zint(void)
{
testStart("");
int ret, ret2;
unsigned char buf[2], buf2[2];
unsigned int val, val2;
for (unsigned int i = 0; i < 0xFFFE; i++) {
if (i >= 0xD800 && i <= 0xDFFF) { // UTF-16 surrogates
continue;
}
buf[0] = buf[1] = buf2[0] = buf2[1] = 0;
ret = sjis_wctomb_zint(buf, i, 2);
val = ret == 1 ? buf[0] : (buf[0] << 8) | buf[1];
ret2 = sjis_wctomb_zint2(buf2, i, 2);
val2 = ret2 == 1 ? buf2[0] : (buf2[0] << 8) | buf2[1];
if (i == 0xFF3C) { // Extra mapping full-width reverse solidus U+FF3C to 0x815F, duplicate of U+005C (backslash)
assert_equal(ret, 2, "i:%d 0x%04X ret %d != 2, val 0x%04X\n", i, i, ret, val);
assert_equal(val, 0x815F, "i:%d 0x%04X val 0x%04X != 0x815F\n", i, i, val);
assert_zero(ret2, "i:%d 0x%04X ret2 %d != 0, val2 0x%04X\n", i, i, ret2, val2);
} else {
assert_equal(ret, ret2, "i:%d 0x%04X ret %d != ret2 %d, val 0x%04X, val2 0x%04X\n", i, i, ret, ret2, val, val2);
}
if (ret2) {
assert_equal(val, val2, "i:%d 0x%04X val 0x%04X != val2 0x%04X\n", i, i, val, val2);
}
}
testFinish();
}
static void test_sjis_utf8tomb(void)
{
testStart("");
int ret;
struct item {
unsigned char* data;
int length;
int ret;
size_t ret_length;
unsigned int expected_jisdata[20];
char* comment;
};
// é U+00E9 in ISO 8859-1 plus other ISO 8859 (but not in ISO 8859-7 or ISO 8859-11), Win 1250 plus other Win, not in Shift JIS, UTF-8 C3A9
// β U+03B2 in ISO 8859-7 Greek (but not other ISO 8859 or Win page), in Shift JIS 0x83C0, UTF-8 CEB2
// Ж U+0416 in ISO 8859-5 Cyrillic (but not other ISO 8859), Win 1251, in Shift JIS 0x8447, UTF-8 D096
// ¥ U+00A5 in ISO 8859-1 0xA5 (\245), in Shift JIS single-byte 0x5C (\134) (backslash); 0xA5 same codepoint as single-byte half-width katakana ・ (U+FF65) in Shift JIS (below), UTF-8 C2A5
// ・ U+FF65 half-width katakana, not in ISO/Win, in Shift JIS single-byte 0xA5 (\245), UTF-8 EFBDA5
// ソ U+FF7F half-width katakana, not in ISO/Win, in Shift JIS single-byte 0xBF (\277), UTF-8 EFBDBF
// ‾ U+203E overline, not in ISO/Win, in Shift JIS single-byte 0x7E (\176) (tilde), UTF-8 E280BE
// U+FF3C full-width reverse solidus, in Shift JIS 0x815F, duplicate of mapping of U+005C, UTF-8 EFBCBC
// 点 U+70B9 kanji, in Shift JIS 0x935F (\223\137), UTF-8 E782B9
// 茗 U+8317 kanji, in Shift JIS 0xE4AA (\344\252), UTF-8 E88C97
// テ U+30C6 katakana, in Shift JIS 0x8365 (\203\145), UTF-8 E38386
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = {
/* 0*/ { "é", -1, ZINT_ERROR_INVALID_DATA, -1, {}, "" },
/* 1*/ { "~", -1, ZINT_ERROR_INVALID_DATA, -1, {}, "" },
/* 2*/ { "β", -1, 0, 1, { 0x83C0 }, "" },
/* 3*/ { "¥", -1, 0, 1, { 0x5C }, "" },
/* 4*/ { "aβcЖ¥・ソ‾\\\点茗テ", -1, 0, 13, { 'a', 0x83C0, 'c', 0x8447, 0x5C, 0xA5, 0xBF, 0x7E, 0x815F, 0x815F, 0x935F, 0xE4AA, 0x8365 }, "" },
};
int data_size = sizeof(data) / sizeof(struct item);
struct zint_symbol symbol;
unsigned int jisdata[20];
for (int i = 0; i < data_size; i++) {
int length = data[i].length == -1 ? strlen(data[i].data) : data[i].length;
size_t ret_length = length;
ret = sjis_utf8tomb(&symbol, data[i].data, &ret_length, jisdata);
assert_equal(ret, data[i].ret, "i:%d ret %d != %d (%s)\n", i, ret, data[i].ret, symbol.errtxt);
if (ret == 0) {
assert_equal(ret_length, data[i].ret_length, "i:%d ret_length %zu != %zu\n", i, ret_length, data[i].ret_length);
for (int j = 0; j < ret_length; j++) {
assert_equal(jisdata[j], data[i].expected_jisdata[j], "i:%d jisdata[%d] %04X != %04X\n", i, j, jisdata[j], data[i].expected_jisdata[j]);
}
}
}
testFinish();
}
static void test_sjis_utf8tosb(void)
{
testStart("");
int ret;
struct item {
int eci;
unsigned char* data;
int length;
int ret;
size_t ret_length;
unsigned int expected_jisdata[20];
char* comment;
};
// é U+00E9 in ISO 8859-1 0xE9, Win 1250 plus other Win
// β U+03B2 in ISO 8859-7 Greek 0xE2 (but not other ISO 8859 or Win page)
// ¥ U+00A5 in ISO 8859-1 0xA5, in QR Kanji mode first byte range 0x81..9F, 0xE0..EB
// ú U+00FA in ISO 8859-1 0xFA, outside first byte range
// à U+00FA in ISO 8859-1 0xE0, in first byte range
// ë U+00FA in ISO 8859-1 0xEB, in first byte range
// ì U+00FA in ISO 8859-1 0xEC, outside first byte range
// µ U+00B5 in ISO 8859-1 0xB5, outside first byte range
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = {
/* 0*/ { 3, "é", -1, 0, 1, { 0xE9 }, "" },
/* 1*/ { 3, "β", -1, ZINT_ERROR_INVALID_DATA, -1, {}, "" },
/* 2*/ { 9, "β", -1, 0, 1, { 0xE2 }, "" },
/* 3*/ { 3, "¥", -1, 0, 1, { 0xA5 }, "" },
/* 4*/ { 3, "éa", -1, 0, 1, { 0xE961 }, "In QR Kanji mode range" },
/* 5*/ { 3, "éaúbàcëdìeµ", -1, 0, 8, { 0xE961, 0xFA, 0x62, 0xE063, 0xEB64, 0xEC, 0x65, 0xB5 }, "" },
};
int data_size = sizeof(data) / sizeof(struct item);
unsigned int jisdata[20];
for (int i = 0; i < data_size; i++) {
int length = data[i].length == -1 ? strlen(data[i].data) : data[i].length;
size_t ret_length = length;
ret = sjis_utf8tosb(data[i].eci, data[i].data, &ret_length, jisdata);
assert_equal(ret, data[i].ret, "i:%d ret %d != %d\n", i, ret, data[i].ret);
if (ret == 0) {
assert_equal(ret_length, data[i].ret_length, "i:%d ret_length %zu != %zu\n", i, ret_length, data[i].ret_length);
for (int j = 0; j < ret_length; j++) {
assert_equal(jisdata[j], data[i].expected_jisdata[j], "i:%d jisdata[%d] %04X != %04X\n", i, j, jisdata[j], data[i].expected_jisdata[j]);
}
}
}
testFinish();
}
static void test_sjis_cpy(void)
{
testStart("");
int ret;
struct item {
unsigned char* data;
int length;
int ret;
size_t ret_length;
unsigned int expected_jisdata[20];
char* comment;
};
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = {
/* 0*/ { "\351", -1, 0, 1, { 0xE9 }, "In QR Kanji mode first-byte range but only one byte" },
/* 1*/ { "\351\141", -1, 0, 1, { 0xE961 }, "In QR Kanji mode range" },
/* 0*/ { "\201", -1, 0, 1, { 0x81 }, "In QR Kanji mode first-byte range but only one byte" },
/* 0*/ { "\201\141", -1, 0, 1, { 0x8161 }, "In QR Kanji mode range" },
/* 0*/ { "\201\077\201\100\237\374\237\375\340\077\340\100\353\277\353\300", -1, 0, 12, { 0x81, 0x3F, 0x8140, 0x9FFC, 0x9F, 0xFD, 0xE0, 0x3F, 0xE040, 0xEBBF, 0xEB, 0xC0 }, "" },
};
int data_size = sizeof(data) / sizeof(struct item);
unsigned int jisdata[20];
for (int i = 0; i < data_size; i++) {
int length = data[i].length == -1 ? strlen(data[i].data) : data[i].length;
size_t ret_length = length;
sjis_cpy(data[i].data, &ret_length, jisdata);
assert_equal(ret_length, data[i].ret_length, "i:%d ret_length %zu != %zu\n", i, ret_length, data[i].ret_length);
for (int j = 0; j < ret_length; j++) {
assert_equal(jisdata[j], data[i].expected_jisdata[j], "i:%d jisdata[%d] %04X != %04X\n", i, j, jisdata[j], data[i].expected_jisdata[j]);
}
}
testFinish();
}
int main()
{
test_sjis_wctomb_zint();
test_sjis_utf8tomb();
test_sjis_utf8tosb();
test_sjis_cpy();
testReport();
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -351,16 +351,38 @@ int testUtilDAFTConvert(const struct zint_symbol* symbol, char* buffer, int buff
return TRUE;
}
/* Is string valid UTF-8? */
int testUtilIsValidUTF8(const unsigned char str[], const size_t length) {
int i;
unsigned int codepoint, state = 0;
for (i = 0; i < length; i++) {
if (decode_utf8(&state, &codepoint, str[i]) == 12) {
return 0;
}
}
return state == 0;
}
char* testUtilEscape(char* buffer, char* escaped, int escaped_size)
{
int i;
char* b = buffer;
unsigned char* b = buffer;
int non_utf8 = !testUtilIsValidUTF8(buffer, strlen(buffer));
for (i = 0; i < escaped_size && *b; b++) {
if (*b > '\0' && *b < ' ') {
if (non_utf8 || *b < ' ' || *b == '\177') {
if (i < escaped_size - 4) {
sprintf(escaped + i, "\\%.3o", *b);
}
i += 4;
} else if (*b == '\\' || *b == '"') {
if (i < escaped_size - 2) {
escaped[i] = '\\';
escaped[i + 1] = *b;
}
i += 2;
} else {
escaped[i++] = *b;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,57 @@
<?php
/* Generate lookup table from unicode.org mapping file (SHIFTJIS.TXT by default). */
/*
libzint - the open source barcode library
Copyright (C) 2008-2019 Robin Stuart <rstuart114@gmail.com>
*/
/* vim: set ts=4 sw=4 et : */
$basename = basename(__FILE__);
$dirname = dirname(__FILE__);
$opts = getopt('d:f:o:s:');
$data_dirname = isset($opts['d']) ? $opts['d'] : ($dirname . '/data'); // Where to load file from.
$file_name = isset($opts['f']) ? $opts['f'] : 'SHIFTJIS.TXT'; // Name of file.
$out_dirname = isset($opts['o']) ? $opts['o'] : ($dirname . '/..'); // Where to put output.
$suffix_name = isset($opts['s']) ? $opts['s'] : 'sjis_tab'; // Suffix of table and output file.
$file = $data_dirname . '/' . $file_name;
// Read the file.
if (($get = file_get_contents($file)) === false) {
error_log($error = "$basename: ERROR: Could not read mapping file \"$file\"");
exit($error . PHP_EOL);
}
$lines = explode("\n", $get);
// Parse the file.
$tab_lines = array();
$sort = array();
foreach ($lines as $line) {
$line = trim($line);
if ($line === '' || strncmp($line, '0x', 2) !== 0) {
continue;
}
$tab_lines[] = preg_replace_callback('/^0x([0-9A-F]{2,4})[ \t]+0x([0-9A-F]{4}).*$/', function ($matches) {
global $sort;
$mb = hexdec($matches[1]);
$unicode = hexdec($matches[2]);
$sort[] = $unicode;
return sprintf(" 0x%04X, 0x%04X,", $mb, $unicode);
}, $line);
}
array_multisort($sort, $tab_lines);
// Output.
$out = array();
$out[] = '/* Generated by ' . $basename . ' from ' . $file_name . ' */';
$out[] = 'static const unsigned short test_' . $suffix_name . '[] = {';
$out = array_merge($out, $tab_lines);
$out[] = '};';
file_put_contents($out_dirname . '/test_' . $suffix_name . '.h', implode("\n", $out) . "\n");

View File

@ -28,6 +28,7 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
/* vim: set ts=4 sw=4 et : */
#ifndef ZINT_H
#define ZINT_H
@ -288,6 +289,10 @@ extern "C" {
#define OUT_JPG_FILE 180
#define OUT_TIF_FILE 200
// Debug flags
#define ZINT_DEBUG_PRINT 1
#define ZINT_DEBUG_TEST 2
#if defined(__WIN32__) || defined(_WIN32) || defined(WIN32) || defined(_MSC_VER)
#if defined (DLL_EXPORT) || defined(PIC) || defined(_USRDLL)
#define ZINT_EXTERN __declspec(dllexport)

View File

@ -109,6 +109,7 @@ SOURCES += ../backend/2of5.c \
../backend/reedsol.c \
../backend/render.c \
../backend/rss.c \
../backend/sjis.c \
../backend/svg.c \
../backend/telepen.c \
../backend/tif.c \

View File

@ -244,6 +244,10 @@ SOURCE=..\backend\rss.c
# End Source File
# Begin Source File
SOURCE=..\backend\sjis.c
# End Source File
# Begin Source File
SOURCE=..\backend\svg.c
# End Source File
# Begin Source File

View File

@ -319,6 +319,7 @@
<ClCompile Include="..\backend\dotcode.c" />
<ClCompile Include="..\backend\eci.c" />
<ClCompile Include="..\backend\emf.c" />
<ClCompile Include="..\backend\general_field.c" />
<ClCompile Include="..\backend\gif.c" />
<ClCompile Include="..\backend\gridmtx.c" />
<ClCompile Include="..\backend\gs1.c" />
@ -340,9 +341,11 @@
<ClCompile Include="..\backend\reedsol.c" />
<ClCompile Include="..\backend\render.c" />
<ClCompile Include="..\backend\rss.c" />
<ClCompile Include="..\backend\sjis.c" />
<ClCompile Include="..\backend\svg.c" />
<ClCompile Include="..\backend\telepen.c" />
<ClCompile Include="..\backend\tif.c" />
<ClCompile Include="..\backend\ultra.c" />
<ClCompile Include="..\backend\upcean.c" />
<ClCompile Include="..\backend\vector.c" />
</ItemGroup>
@ -360,6 +363,7 @@
<ClInclude Include="..\backend\font.h" />
<ClInclude Include="..\backend\gb18030.h" />
<ClInclude Include="..\backend\gb2312.h" />
<ClInclude Include="..\backend\general_field.h" />
<ClInclude Include="..\backend\gridmtx.h" />
<ClInclude Include="..\backend\gs1.h" />
<ClInclude Include="..\backend\hanxin.h" />
@ -387,4 +391,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

View File

@ -252,6 +252,10 @@ SOURCE=..\..\backend\rss.c
# End Source File
# Begin Source File
SOURCE=..\..\backend\sjis.c
# End Source File
# Begin Source File
SOURCE=..\..\backend\svg.c
# End Source File
# Begin Source File