mirror of
https://git.code.sf.net/p/zint/code
synced 2025-05-12 22:25:59 -04:00
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:
parent
3b9d989894
commit
f58c80e290
81 changed files with 12026 additions and 4701 deletions
|
@ -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++) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue