Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,

GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
  better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
  namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
This commit is contained in:
gitlost 2022-05-09 19:50:50 +01:00
parent 3b9d989894
commit f58c80e290
81 changed files with 12026 additions and 4701 deletions

View file

@ -46,16 +46,17 @@ static const char EUROPIUM[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijkl
static const char EUROPIUM_UPR[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ ";
static const char EUROPIUM_LWR[] = "abcdefghijklmnopqrstuvwxyz ";
/* define_mode() stuff */
/* gm_define_mode() stuff */
/* Bits multiplied by this for costs, so as to be whole integer divisible by 2 and 3 */
#define GM_MULT 6
static const char numeral_nondigits[] = " +-.,"; /* Non-digit numeral set, excluding EOL (carriage return/linefeed) */
/* Non-digit numeral set, excluding EOL (carriage return/linefeed) */
static const char gm_numeral_nondigits[] = " +-.,";
/* Whether in numeral or not. If in numeral, *p_numeral_end is set to position after numeral,
* and *p_numeral_cost is set to per-numeral cost */
static int in_numeral(const unsigned int gbdata[], const int length, const int in_posn,
static int gm_in_numeral(const unsigned int ddata[], const int length, const int in_posn,
unsigned int *p_numeral_end, unsigned int *p_numeral_cost) {
int i, digit_cnt, nondigit, nondigit_posn;
@ -69,15 +70,15 @@ static int in_numeral(const unsigned int gbdata[], const int length, const int i
block of three numeric characters) */
for (i = in_posn, digit_cnt = 0, nondigit = 0, nondigit_posn = 0; i < length && i < in_posn + 4 && digit_cnt < 3;
i++) {
if (gbdata[i] >= '0' && gbdata[i] <= '9') {
if (ddata[i] >= '0' && ddata[i] <= '9') {
digit_cnt++;
} else if (posn(numeral_nondigits, (const char) gbdata[i]) != -1) {
} else if (posn(gm_numeral_nondigits, (const char) ddata[i]) != -1) {
if (nondigit) {
break;
}
nondigit = 1;
nondigit_posn = i;
} else if (i < length - 1 && gbdata[i] == 13 && gbdata[i + 1] == 10) {
} else if (i < length - 1 && ddata[i] == 13 && ddata[i + 1] == 10) {
if (nondigit) {
break;
}
@ -128,7 +129,7 @@ static int in_numeral(const unsigned int gbdata[], const int length, const int i
/* Calculate optimized encoding modes. Adapted from Project Nayuki */
/* Copyright (c) Project Nayuki. (MIT License) See qr.c for detailed notice */
static void define_mode(char *mode, const unsigned int gbdata[], const int length, const int debug) {
static void gm_define_mode(char *mode, const unsigned int ddata[], const int length, const int debug_print) {
/* Must be in same order as GM_H etc */
static const char mode_types[] = { GM_CHINESE, GM_NUMBER, GM_LOWER, GM_UPPER, GM_MIXED, GM_BYTE, '\0' };
@ -183,24 +184,24 @@ static void define_mode(char *mode, const unsigned int gbdata[], const int lengt
space = numeric = lower = upper = control = double_digit = eol = 0;
double_byte = gbdata[i] > 0xFF;
double_byte = ddata[i] > 0xFF;
if (!double_byte) {
space = gbdata[i] == ' ';
space = ddata[i] == ' ';
if (!space) {
numeric = gbdata[i] >= '0' && gbdata[i] <= '9';
numeric = ddata[i] >= '0' && ddata[i] <= '9';
if (!numeric) {
lower = gbdata[i] >= 'a' && gbdata[i] <= 'z';
lower = ddata[i] >= 'a' && ddata[i] <= 'z';
if (!lower) {
upper = gbdata[i] >= 'A' && gbdata[i] <= 'Z';
upper = ddata[i] >= 'A' && ddata[i] <= 'Z';
if (!upper) {
control = gbdata[i] < 0x7F; /* Exclude DEL */
control = ddata[i] < 0x7F; /* Exclude DEL */
if (control && i + 1 < length) {
eol = gbdata[i] == 13 && gbdata[i + 1] == 10;
eol = ddata[i] == 13 && ddata[i + 1] == 10;
}
}
}
} else if (i + 1 < length) {
double_digit = gbdata[i + 1] >= '0' && gbdata[i + 1] <= '9';
double_digit = ddata[i + 1] >= '0' && ddata[i + 1] <= '9';
}
}
}
@ -222,7 +223,7 @@ static void define_mode(char *mode, const unsigned int gbdata[], const int lengt
char_modes[cm_i + GM_B] = GM_BYTE;
byte_count += double_byte ? 2 : 1;
if (in_numeral(gbdata, length, i, &numeral_end, &numeral_cost)) {
if (gm_in_numeral(ddata, length, i, &numeral_end, &numeral_cost)) {
cur_costs[GM_N] = prev_costs[GM_N] + numeral_cost;
char_modes[cm_i + GM_N] = GM_NUMBER;
}
@ -290,20 +291,20 @@ static void define_mode(char *mode, const unsigned int gbdata[], const int lengt
mode[i] = cur_mode;
}
if (debug & ZINT_DEBUG_PRINT) {
if (debug_print) {
printf(" Mode: %.*s\n", length, mode);
}
}
/* Add the length indicator for byte encoded blocks */
static void add_byte_count(char binary[], const int byte_count_posn, const int byte_count) {
static void gm_add_byte_count(char binary[], const int byte_count_posn, const int byte_count) {
/* AIMD014 6.3.7: "Let L be the number of bytes of input data to be encoded in the 8-bit binary data set.
* First output (L-1) as a 9-bit binary prefix to record the number of bytes..." */
bin_append_posn(byte_count - 1, 9, binary, byte_count_posn);
}
/* Add a control character to the data stream */
static int add_shift_char(char binary[], int bp, int shifty, int debug) {
static int gm_add_shift_char(char binary[], int bp, int shifty, const int debug_print) {
int i;
int glyph = 0;
@ -318,7 +319,7 @@ static int add_shift_char(char binary[], int bp, int shifty, int debug) {
}
}
if (debug & ZINT_DEBUG_PRINT) {
if (debug_print) {
printf("SHIFT [%d] ", glyph);
}
@ -327,46 +328,29 @@ static int add_shift_char(char binary[], int bp, int shifty, int debug) {
return bp;
}
static int gm_encode(unsigned int gbdata[], const int length, char binary[], const int reader,
const struct zint_structapp *p_structapp, const int eci, int *bin_len, int debug) {
static int gm_encode(unsigned int ddata[], const int length, char binary[], const int eci, int *p_bp,
const int debug_print) {
/* Create a binary stream representation of the input data.
7 sets are defined - Chinese characters, Numerals, Lower case letters, Upper case letters,
Mixed numerals and latters, Control characters and 8-bit binary data */
int sp;
int current_mode, last_mode;
int sp = 0;
int current_mode = 0;
int last_mode;
unsigned int glyph = 0;
int c1, c2, done;
int p = 0, ppos;
int numbuf[3], punt = 0;
int number_pad_posn, byte_count_posn = 0;
int number_pad_posn = 0;
int byte_count_posn = 0;
int byte_count = 0;
int shift;
int bp;
int bp = *p_bp;
#ifndef _MSC_VER
char mode[length];
#else
char *mode = (char *) _alloca(length);
#endif
*binary = '\0';
bp = 0;
sp = 0;
current_mode = 0;
number_pad_posn = 0;
if (reader && (!p_structapp || p_structapp->index == 1)) { /* Appears only in 1st symbol if Structured Append */
bp = bin_append_posn(10, 4, binary, bp); /* FNC3 - Reader Initialisation */
}
if (p_structapp) {
bp = bin_append_posn(9, 4, binary, bp); /* FNC2 - Structured Append */
bp = bin_append_posn(to_int((const unsigned char *) p_structapp->id, (int) strlen(p_structapp->id)), 8,
binary, bp); /* File signature */
bp = bin_append_posn(p_structapp->count - 1, 4, binary, bp);
bp = bin_append_posn(p_structapp->index - 1, 4, binary, bp);
}
if (eci != 0) {
/* ECI assignment according to Table 8 */
bp = bin_append_posn(12, 4, binary, bp); /* ECI */
@ -381,7 +365,7 @@ static int gm_encode(unsigned int gbdata[], const int length, char binary[], con
}
}
define_mode(mode, gbdata, length, debug);
gm_define_mode(mode, ddata, length, debug_print);
do {
const int next_mode = mode[sp];
@ -476,7 +460,7 @@ static int gm_encode(unsigned int gbdata[], const int length, char binary[], con
break;
case GM_BYTE:
/* add byte block length indicator */
add_byte_count(binary, byte_count_posn, byte_count);
gm_add_byte_count(binary, byte_count_posn, byte_count);
byte_count = 0;
switch (next_mode) {
case GM_CHINESE: bp = bin_append_posn(1, 4, binary, bp);
@ -492,7 +476,7 @@ static int gm_encode(unsigned int gbdata[], const int length, char binary[], con
}
break;
}
if (debug & ZINT_DEBUG_PRINT) {
if (debug_print) {
switch (next_mode) {
case GM_CHINESE: printf("CHIN ");
break;
@ -515,10 +499,10 @@ static int gm_encode(unsigned int gbdata[], const int length, char binary[], con
switch (current_mode) {
case GM_CHINESE:
done = 0;
if (gbdata[sp] > 0xff) {
if (ddata[sp] > 0xff) {
/* GB2312 character */
c1 = (gbdata[sp] & 0xff00) >> 8;
c2 = gbdata[sp] & 0xff;
c1 = (ddata[sp] & 0xff00) >> 8;
c2 = ddata[sp] & 0xff;
if ((c1 >= 0xa1) && (c1 <= 0xa9)) {
glyph = (0x60 * (c1 - 0xa1)) + (c2 - 0xa0);
@ -529,7 +513,7 @@ static int gm_encode(unsigned int gbdata[], const int length, char binary[], con
}
if (!(done)) {
if (sp != (length - 1)) {
if ((gbdata[sp] == 13) && (gbdata[sp + 1] == 10)) {
if ((ddata[sp] == 13) && (ddata[sp + 1] == 10)) {
/* End of Line */
glyph = 7776;
sp++;
@ -539,10 +523,10 @@ static int gm_encode(unsigned int gbdata[], const int length, char binary[], con
}
if (!(done)) {
if (sp != (length - 1)) {
if (((gbdata[sp] >= '0') && (gbdata[sp] <= '9')) &&
((gbdata[sp + 1] >= '0') && (gbdata[sp + 1] <= '9'))) {
if (((ddata[sp] >= '0') && (ddata[sp] <= '9')) &&
((ddata[sp + 1] >= '0') && (ddata[sp + 1] <= '9'))) {
/* Two digits */
glyph = 8033 + (10 * (gbdata[sp] - '0')) + (gbdata[sp + 1] - '0');
glyph = 8033 + (10 * (ddata[sp] - '0')) + (ddata[sp + 1] - '0');
sp++;
done = 1;
}
@ -550,10 +534,10 @@ static int gm_encode(unsigned int gbdata[], const int length, char binary[], con
}
if (!(done)) {
/* Byte value */
glyph = 7777 + gbdata[sp];
glyph = 7777 + ddata[sp];
}
if (debug & ZINT_DEBUG_PRINT) {
if (debug_print) {
printf("[%d] ", (int) glyph);
}
@ -577,21 +561,21 @@ static int gm_encode(unsigned int gbdata[], const int length, char binary[], con
numbuf[1] = '0';
numbuf[2] = '0';
do {
if ((gbdata[sp] >= '0') && (gbdata[sp] <= '9')) {
numbuf[p] = gbdata[sp];
if ((ddata[sp] >= '0') && (ddata[sp] <= '9')) {
numbuf[p] = ddata[sp];
p++;
} else if (posn(numeral_nondigits, (const char) gbdata[sp]) != -1) {
} else if (posn(gm_numeral_nondigits, (const char) ddata[sp]) != -1) {
if (ppos != -1) {
break;
}
punt = gbdata[sp];
punt = ddata[sp];
ppos = p;
} else if (sp < (length - 1) && (gbdata[sp] == 13) && (gbdata[sp + 1] == 10)) {
} else if (sp < (length - 1) && (ddata[sp] == 13) && (ddata[sp + 1] == 10)) {
/* <end of line> */
if (ppos != -1) {
break;
}
punt = gbdata[sp];
punt = ddata[sp];
sp++;
ppos = p;
} else {
@ -618,7 +602,7 @@ static int gm_encode(unsigned int gbdata[], const int length, char binary[], con
glyph += ppos;
glyph += 1000;
if (debug & ZINT_DEBUG_PRINT) {
if (debug_print) {
printf("[%d] ", (int) glyph);
}
@ -626,7 +610,7 @@ static int gm_encode(unsigned int gbdata[], const int length, char binary[], con
}
glyph = (100 * (numbuf[0] - '0')) + (10 * (numbuf[1] - '0')) + (numbuf[2] - '0');
if (debug & ZINT_DEBUG_PRINT) {
if (debug_print) {
printf("[%d] ", (int) glyph);
}
@ -639,7 +623,7 @@ static int gm_encode(unsigned int gbdata[], const int length, char binary[], con
byte_count_posn = bp;
bp = bin_append_posn(0, 9, binary, bp);
}
glyph = gbdata[sp];
glyph = ddata[sp];
if (byte_count == 512 || (glyph > 0xFF && byte_count == 511)) {
/* Maximum byte block size is 512 bytes. If longer is needed then start a new block */
if (glyph > 0xFF && byte_count == 511) { /* Split double-byte */
@ -647,14 +631,14 @@ static int gm_encode(unsigned int gbdata[], const int length, char binary[], con
glyph &= 0xFF;
byte_count++;
}
add_byte_count(binary, byte_count_posn, byte_count);
gm_add_byte_count(binary, byte_count_posn, byte_count);
bp = bin_append_posn(7, 4, binary, bp);
byte_count_posn = bp;
bp = bin_append_posn(0, 9, binary, bp);
byte_count = 0;
}
if (debug & ZINT_DEBUG_PRINT) {
if (debug_print) {
printf("[%d] ", (int) glyph);
}
bp = bin_append_posn(glyph, glyph > 0xFF ? 16 : 8, binary, bp);
@ -667,20 +651,20 @@ static int gm_encode(unsigned int gbdata[], const int length, char binary[], con
case GM_MIXED:
shift = 1;
if ((gbdata[sp] >= '0') && (gbdata[sp] <= '9')) {
if ((ddata[sp] >= '0') && (ddata[sp] <= '9')) {
shift = 0;
} else if ((gbdata[sp] >= 'A') && (gbdata[sp] <= 'Z')) {
} else if ((ddata[sp] >= 'A') && (ddata[sp] <= 'Z')) {
shift = 0;
} else if ((gbdata[sp] >= 'a') && (gbdata[sp] <= 'z')) {
} else if ((ddata[sp] >= 'a') && (ddata[sp] <= 'z')) {
shift = 0;
} else if (gbdata[sp] == ' ') {
} else if (ddata[sp] == ' ') {
shift = 0;
}
if (shift == 0) {
/* Mixed Mode character */
glyph = posn(EUROPIUM, (const char) gbdata[sp]);
if (debug & ZINT_DEBUG_PRINT) {
glyph = posn(EUROPIUM, (const char) ddata[sp]);
if (debug_print) {
printf("[%d] ", (int) glyph);
}
@ -688,7 +672,7 @@ static int gm_encode(unsigned int gbdata[], const int length, char binary[], con
} else {
/* Shift Mode character */
bp = bin_append_posn(1014, 10, binary, bp); /* shift indicator */
bp = add_shift_char(binary, bp, gbdata[sp], debug);
bp = gm_add_shift_char(binary, bp, ddata[sp], debug_print);
}
sp++;
@ -696,16 +680,16 @@ static int gm_encode(unsigned int gbdata[], const int length, char binary[], con
case GM_UPPER:
shift = 1;
if ((gbdata[sp] >= 'A') && (gbdata[sp] <= 'Z')) {
if ((ddata[sp] >= 'A') && (ddata[sp] <= 'Z')) {
shift = 0;
} else if (gbdata[sp] == ' ') {
} else if (ddata[sp] == ' ') {
shift = 0;
}
if (shift == 0) {
/* Upper Case character */
glyph = posn(EUROPIUM_UPR, (const char) gbdata[sp]);
if (debug & ZINT_DEBUG_PRINT) {
glyph = posn(EUROPIUM_UPR, (const char) ddata[sp]);
if (debug_print) {
printf("[%d] ", (int) glyph);
}
@ -713,7 +697,7 @@ static int gm_encode(unsigned int gbdata[], const int length, char binary[], con
} else {
/* Shift Mode character */
bp = bin_append_posn(125, 7, binary, bp); /* shift indicator */
bp = add_shift_char(binary, bp, gbdata[sp], debug);
bp = gm_add_shift_char(binary, bp, ddata[sp], debug_print);
}
sp++;
@ -721,16 +705,16 @@ static int gm_encode(unsigned int gbdata[], const int length, char binary[], con
case GM_LOWER:
shift = 1;
if ((gbdata[sp] >= 'a') && (gbdata[sp] <= 'z')) {
if ((ddata[sp] >= 'a') && (ddata[sp] <= 'z')) {
shift = 0;
} else if (gbdata[sp] == ' ') {
} else if (ddata[sp] == ' ') {
shift = 0;
}
if (shift == 0) {
/* Lower Case character */
glyph = posn(EUROPIUM_LWR, (const char) gbdata[sp]);
if (debug & ZINT_DEBUG_PRINT) {
glyph = posn(EUROPIUM_LWR, (const char) ddata[sp]);
if (debug_print) {
printf("[%d] ", (int) glyph);
}
@ -738,7 +722,7 @@ static int gm_encode(unsigned int gbdata[], const int length, char binary[], con
} else {
/* Shift Mode character */
bp = bin_append_posn(125, 7, binary, bp); /* shift indicator */
bp = add_shift_char(binary, bp, gbdata[sp], debug);
bp = gm_add_shift_char(binary, bp, ddata[sp], debug_print);
}
sp++;
@ -767,7 +751,7 @@ static int gm_encode(unsigned int gbdata[], const int length, char binary[], con
if (current_mode == GM_BYTE) {
/* Add byte block length indicator */
add_byte_count(binary, byte_count_posn, byte_count);
gm_add_byte_count(binary, byte_count_posn, byte_count);
}
/* Add "end of data" character */
@ -785,21 +769,58 @@ static int gm_encode(unsigned int gbdata[], const int length, char binary[], con
break;
}
if (bp > 9191) {
return ZINT_ERROR_TOO_LONG;
}
*p_bp = bp;
if (debug_print) {
printf("\nBinary (%d): %.*s\n", bp, bp, binary);
}
return 0;
}
static int gm_encode_segs(unsigned int ddata[], const struct zint_seg segs[], const int seg_count, char binary[],
const int reader, const struct zint_structapp *p_structapp, int *p_bin_len, const int debug_print) {
int i;
unsigned int *dd = ddata;
int bp = 0;
int p;
if (reader && (!p_structapp || p_structapp->index == 1)) { /* Appears only in 1st symbol if Structured Append */
bp = bin_append_posn(10, 4, binary, bp); /* FNC3 - Reader Initialisation */
}
if (p_structapp) {
bp = bin_append_posn(9, 4, binary, bp); /* FNC2 - Structured Append */
bp = bin_append_posn(to_int((const unsigned char *) p_structapp->id, (int) strlen(p_structapp->id)), 8,
binary, bp); /* File signature */
bp = bin_append_posn(p_structapp->count - 1, 4, binary, bp);
bp = bin_append_posn(p_structapp->index - 1, 4, binary, bp);
}
for (i = 0; i < seg_count; i++) {
int error_number = gm_encode(dd, segs[i].length, binary, segs[i].eci, &bp, debug_print);
if (error_number != 0) {
return error_number;
}
dd += segs[i].length;
}
/* Add padding bits if required */
p = 7 - (bp % 7);
if (p % 7) {
bp = bin_append_posn(0, p, binary, bp);
}
/* Note bit-padding can't tip `bp` over max 9191 (1313 * 7) */
if (bp > 9191) {
return ZINT_ERROR_TOO_LONG;
if (debug_print) {
printf("\nBinary (%d): %.*s\n", bp, bp, binary);
}
binary[bp] = '\0';
*bin_len = bp;
if (debug & ZINT_DEBUG_PRINT) {
printf("\nBinary (%d): %s\n", bp, binary);
}
*p_bin_len = bp;
return 0;
}
@ -893,7 +914,7 @@ static void gm_add_ecc(const char binary[], const int data_posn, const int layer
}
}
static void place_macromodule(char grid[], int x, int y, int word1, int word2, int size) {
static void gm_place_macromodule(char grid[], int x, int y, int word1, int word2, int size) {
int i, j;
i = (x * 6) + 1;
@ -943,20 +964,20 @@ static void place_macromodule(char grid[], int x, int y, int word1, int word2, i
}
}
static void place_data_in_grid(unsigned char word[], char grid[], int modules, int size) {
static void gm_place_data_in_grid(unsigned char word[], char grid[], int modules, int size) {
int x, y, macromodule, offset;
offset = 13 - ((modules - 1) / 2);
for (y = 0; y < modules; y++) {
for (x = 0; x < modules; x++) {
macromodule = gm_macro_matrix[((y + offset) * 27) + (x + offset)];
place_macromodule(grid, x, y, word[macromodule * 2], word[(macromodule * 2) + 1], size);
gm_place_macromodule(grid, x, y, word[macromodule * 2], word[(macromodule * 2) + 1], size);
}
}
}
/* Place the layer ID into each macromodule */
static void place_layer_id(char *grid, int size, int layers, int modules, int ecc_level) {
static void gm_place_layer_id(char *grid, int size, int layers, int modules, int ecc_level) {
int i, j, layer, start, stop;
#ifndef _MSC_VER
@ -1009,7 +1030,7 @@ static void place_layer_id(char *grid, int size, int layers, int modules, int ec
}
}
INTERNAL int gridmatrix(struct zint_symbol *symbol, unsigned char source[], int length) {
INTERNAL int gridmatrix(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count) {
int warn_number = 0;
int size, modules, error_number;
int auto_layers, min_layers, layers, auto_ecc_level, min_ecc_level, ecc_level;
@ -1022,42 +1043,52 @@ INTERNAL int gridmatrix(struct zint_symbol *symbol, unsigned char source[], int
const struct zint_structapp *p_structapp = NULL;
int size_squared;
int bin_len;
const int eci_length = get_eci_length(symbol->eci, source, length);
const int debug_print = symbol->debug & ZINT_DEBUG_PRINT;
const int eci_length_segs = get_eci_length_segs(segs, seg_count);
#ifndef _MSC_VER
unsigned int gbdata[eci_length + 1];
struct zint_seg local_segs[seg_count];
unsigned int ddata[eci_length_segs];
#else
struct zint_seg *local_segs = (struct zint_seg *) _alloca(sizeof(struct zint_seg) * seg_count);
unsigned int *ddata = (unsigned int *) _alloca(sizeof(unsigned int) * eci_length_segs);
char *grid;
unsigned int *gbdata = (unsigned int *) _alloca((eci_length + 1) * sizeof(unsigned int));
#endif
segs_cpy(segs, seg_count, local_segs); /* Shallow copy (needed to set default ECIs & protect lengths) */
/* If ZINT_FULL_MULTIBYTE set use Hanzi mode in DATA_MODE or for non-GB 2312 in UNICODE_MODE */
full_multibyte = (symbol->option_3 & 0xFF) == ZINT_FULL_MULTIBYTE;
if ((symbol->input_mode & 0x07) == DATA_MODE) {
gb2312_cpy(source, &length, gbdata, full_multibyte);
gb2312_cpy_segs(local_segs, seg_count, ddata, full_multibyte);
} else {
int done = 0;
if (symbol->eci != 29) { /* Unless ECI 29 (GB 2312) */
/* Try other conversions (ECI 0 defaults to ISO/IEC 8859-1) */
error_number = gb2312_utf8_to_eci(symbol->eci, source, &length, gbdata, full_multibyte);
if (error_number == 0) {
done = 1;
} else if (symbol->eci) {
sprintf(symbol->errtxt, "535: Invalid character in input data for ECI %d", symbol->eci);
return error_number;
unsigned int *dd = ddata;
for (i = 0; i < seg_count; i++) {
int done = 0;
if (local_segs[i].eci != 29 || seg_count > 1) { /* Unless ECI 29 (GB 2312) or have multiple segments */
/* Try other conversions (ECI 0 defaults to ISO/IEC 8859-1) */
error_number = gb2312_utf8_to_eci(local_segs[i].eci, local_segs[i].source, &local_segs[i].length,
dd, full_multibyte);
if (error_number == 0) {
done = 1;
} else if (local_segs[i].eci || seg_count > 1) {
sprintf(symbol->errtxt, "535: Invalid character in input data for ECI %d", local_segs[i].eci);
return error_number;
}
}
}
if (!done) {
/* Try GB 2312 (EUC-CN) */
error_number = gb2312_utf8(symbol, source, &length, gbdata);
if (error_number != 0) {
return error_number;
}
if (symbol->eci != 29) {
strcpy(symbol->errtxt, "540: Converted to GB 2312 but no ECI specified");
warn_number = ZINT_WARN_NONCOMPLIANT;
if (!done) {
/* Try GB 2312 (EUC-CN) */
error_number = gb2312_utf8(symbol, local_segs[i].source, &local_segs[i].length, dd);
if (error_number != 0) {
return error_number;
}
if (local_segs[i].eci != 29) {
strcpy(symbol->errtxt, "540: Converted to GB 2312 but no ECI specified");
warn_number = ZINT_WARN_NONCOMPLIANT;
}
}
dd += local_segs[i].length;
}
}
@ -1100,7 +1131,7 @@ INTERNAL int gridmatrix(struct zint_symbol *symbol, unsigned char source[], int
return ZINT_ERROR_INVALID_OPTION;
}
error_number = gm_encode(gbdata, length, binary, reader, p_structapp, symbol->eci, &bin_len, symbol->debug);
error_number = gm_encode_segs(ddata, local_segs, seg_count, binary, reader, p_structapp, &bin_len, debug_print);
if (error_number != 0) {
strcpy(symbol->errtxt, "531: Input data too long");
return error_number;
@ -1205,8 +1236,8 @@ INTERNAL int gridmatrix(struct zint_symbol *symbol, unsigned char source[], int
memset(grid, '0', size_squared);
place_data_in_grid(word, grid, modules, size);
place_layer_id(grid, size, layers, modules, ecc_level);
gm_place_data_in_grid(word, grid, modules, size);
gm_place_layer_id(grid, size, layers, modules, ecc_level);
/* Add macromodule frames */
for (x = 0; x < modules; x++) {