Tidy up loose ends

This commit is contained in:
hooper114 2009-10-31 22:42:10 +00:00
parent 56e75788c2
commit 6beac47e8d
4 changed files with 82 additions and 18 deletions

View File

@ -904,10 +904,11 @@ void place_layer_id(char* grid, int size, int layers, int modules, int ecc_level
int grid_matrix(struct zint_symbol *symbol, unsigned char source[], int length)
{
int size, modules, dark, error_number;
int layers, ecc_level, x, y, i, j, glyph;
int auto_layers, min_layers, layers, auto_ecc_level, min_ecc_level, ecc_level;
int x, y, i, j, glyph;
char binary[9300];
int data_cw;
int word[1460];
int word[1460], data_max;
#ifndef _MSC_VER
int utfdata[length + 1];
@ -962,14 +963,53 @@ int grid_matrix(struct zint_symbol *symbol, unsigned char source[], int length)
/* Determine the size of the symbol */
data_cw = strlen(binary) / 7;
layers = 13;
auto_layers = 13;
for(i = 12; i > 0; i--) {
if(gm_recommend_cw[(i - 1)] >= data_cw) { layers = i; }
if(gm_recommend_cw[(i - 1)] >= data_cw) { auto_layers = i; }
}
min_layers = 13;
for(i = 12; i > 0; i--) {
if(gm_max_cw[(i - 1)] >= data_cw) { min_layers = i; }
}
ecc_level = 3;
if(layers == 1) { ecc_level = 5; }
if((layers == 2) || (layers == 3)) { ecc_level = 4; }
layers = auto_layers;
if((symbol->option_2 >= 1) && (symbol->option_2 <= 13)) {
if(symbol->option_2 > min_layers) {
layers = symbol->option_2;
} else {
layers = min_layers;
}
}
auto_ecc_level = 3;
if(layers == 1) { auto_ecc_level = 5; }
if((layers == 2) || (layers == 3)) { auto_ecc_level = 4; }
min_ecc_level = 1;
if(layers == 1) { min_ecc_level = 4; }
if((layers == 2) || (layers == 3)) { min_ecc_level = 2; }
ecc_level = auto_ecc_level;
if((symbol->option_1 >= 1) && (symbol->option_1 <= 5)) {
if(symbol->option_1 > min_ecc_level) {
ecc_level = symbol->option_1;
} else {
ecc_level = min_ecc_level;
}
}
data_max = 1313;
switch(ecc_level) {
case 2: data_max = 1167; break;
case 3: data_max = 1021; break;
case 4: data_max = 875; break;
case 5: data_max = 729; break;
}
if(data_cw > data_max) {
strcpy(symbol->errtxt, "Input data too long");
return ERROR_TOO_LONG;
}
gm_add_ecc(binary, data_cw, layers, ecc_level, word);
size = 6 + (layers * 12);

View File

@ -37,6 +37,7 @@ static char shift_set[] = {
};
static int gm_recommend_cw[] = { 9, 30, 59, 114, 170, 237, 315, 405, 506, 618, 741, 875, 1021 };
static int gm_max_cw[] = { 11, 40, 79, 146, 218, 305, 405, 521, 650, 794, 953, 1125, 1313 };
static int gm_total_cw[] = { 18, 50, 98, 162, 242, 338, 450, 578, 722, 882, 1058, 1250, 1458 };
static int gm_data_codewords[] = {

View File

@ -357,7 +357,7 @@ int ZBarcode_ValidID(int symbol_id)
case BARCODE_RSS_EXPSTACK_CC:
case BARCODE_CHANNEL:
case BARCODE_CODEONE:
/* case BARCODE_GRIDMATRIX: */
case BARCODE_GRIDMATRIX:
result = 1;
break;
}

View File

@ -107,7 +107,7 @@ void define_mode(char mode[], int jisdata[], int length)
}
}
int estimate_binary_length(char mode[], int length)
int estimate_binary_length(char mode[], int length, int gs1)
{
/* Make an estimate (worst case scenario) of how long the binary string will be */
int i, count = 0;
@ -115,6 +115,8 @@ int estimate_binary_length(char mode[], int length)
int a_count = 0;
int n_count = 0;
if(gs1) { count += 4; }
for(i = 0; i < length; i++) {
if(mode[i] != current) {
switch(mode[i]) {
@ -154,14 +156,14 @@ int estimate_binary_length(char mode[], int length)
return count;
}
void qr_binary(int datastream[], int version, int target_binlen, char mode[], int jisdata[], int length)
void qr_binary(int datastream[], int version, int target_binlen, char mode[], int jisdata[], int length, int gs1)
{
/* Convert input data to a binary stream and add padding */
int position = 0, debug = 0;
int short_data_block_length, i, scheme;
char data_block, padbits;
int current_binlen, current_bytes;
int toggle;
int toggle, percent;
#ifndef _MSC_VER
char binary[target_binlen * 8];
@ -170,6 +172,10 @@ void qr_binary(int datastream[], int version, int target_binlen, char mode[], in
#endif
strcpy(binary, "");
if(gs1) {
concat(binary, "0101"); /* FNC1 */
}
if(version <= 9) {
scheme = 1;
}
@ -187,6 +193,8 @@ void qr_binary(int datastream[], int version, int target_binlen, char mode[], in
printf("\n");
}
percent = 0;
do {
data_block = mode[position];
short_data_block_length = 0;
@ -287,6 +295,10 @@ void qr_binary(int datastream[], int version, int target_binlen, char mode[], in
for(i = 0; i < short_data_block_length; i++) {
int byte = jisdata[position + i];
if(gs1 && (byte == '[')) {
byte = 0x1d; /* FNC1 */
}
if(byte & 0x80) { concat(binary, "1"); } else { concat(binary, "0"); }
if(byte & 0x40) { concat(binary, "1"); } else { concat(binary, "0"); }
if(byte & 0x20) { concat(binary, "1"); } else { concat(binary, "0"); }
@ -365,7 +377,7 @@ void qr_binary(int datastream[], int version, int target_binlen, char mode[], in
if(debug) { printf("0x%4X ", prod); }
i += 2;
i += count;
};
if(debug) { printf("\n"); }
@ -441,7 +453,7 @@ void qr_binary(int datastream[], int version, int target_binlen, char mode[], in
if(debug) { printf("0x%4X (%d)", prod, prod); }
i += 3;
i += count;
};
if(debug) { printf("\n"); }
@ -1053,7 +1065,7 @@ int qr_code(struct zint_symbol *symbol, unsigned char source[], int length)
{
int error_number, i, j, glyph, est_binlen;
int ecc_level, autosize, version, max_cw, target_binlen, blocks, size;
int bitmask;
int bitmask, gs1;
#ifndef _MSC_VER
int utfdata[length + 1];
@ -1065,6 +1077,12 @@ int qr_code(struct zint_symbol *symbol, unsigned char source[], int length)
char* mode = (char *)_alloca(length + 1);
#endif
if(symbol->input_mode == GS1_MODE) {
gs1 = 1;
} else {
gs1 = 0;
}
switch(symbol->input_mode) {
case DATA_MODE:
for(i = 0; i < length; i++) {
@ -1099,7 +1117,7 @@ int qr_code(struct zint_symbol *symbol, unsigned char source[], int length)
}
define_mode(mode, jisdata, length);
est_binlen = estimate_binary_length(mode, length);
est_binlen = estimate_binary_length(mode, length, gs1);
ecc_level = LEVEL_L;
max_cw = 2956;
@ -1153,6 +1171,11 @@ int qr_code(struct zint_symbol *symbol, unsigned char source[], int length)
version = autosize;
}
/* Ensure maxium error correction capacity */
if(est_binlen <= qr_data_codewords_M[version - 1]) { ecc_level = LEVEL_M; }
if(est_binlen <= qr_data_codewords_Q[version - 1]) { ecc_level = LEVEL_Q; }
if(est_binlen <= qr_data_codewords_H[version - 1]) { ecc_level = LEVEL_H; }
target_binlen = qr_data_codewords_L[version - 1]; blocks = qr_blocks_L[version - 1];
switch(ecc_level) {
case LEVEL_M: target_binlen = qr_data_codewords_M[version - 1]; blocks = qr_blocks_M[version - 1]; break;
@ -1168,7 +1191,7 @@ int qr_code(struct zint_symbol *symbol, unsigned char source[], int length)
int* fullstream = (int *)_alloca((qr_total_codewords[version - 1] + 1) * sizeof(int));
#endif
qr_binary(datastream, version, target_binlen, mode, jisdata, length);
qr_binary(datastream, version, target_binlen, mode, jisdata, length, gs1);
add_ecc(fullstream, datastream, version, target_binlen, blocks);
size = qr_sizes[version - 1];