Improved compression for Latin-1 encoding in Code 128

This commit is contained in:
hooper114 2009-05-14 22:22:01 +00:00
parent 2170302bf5
commit 76e51fc0ee
3 changed files with 71 additions and 29 deletions

View File

@ -197,7 +197,7 @@ void c128_set_c(unsigned char source_a, unsigned char source_b, char dest[], int
int code_128(struct zint_symbol *symbol, unsigned char source[]) int code_128(struct zint_symbol *symbol, unsigned char source[])
{ /* Handle Code 128 and NVE-18 */ { /* Handle Code 128 and NVE-18 */
int i, j, k, e_count, values[170], bar_characters, read, total_sum, nve_check; int i, j, k, e_count, values[170], bar_characters, read, total_sum, nve_check;
int error_number, indexchaine, indexliste, sourcelen; int error_number, indexchaine, indexliste, sourcelen, f_state;
char set[170], fset[170], mode, last_set, last_fset, current_set = ' '; char set[170], fset[170], mode, last_set, last_fset, current_set = ' ';
float glyph_count; float glyph_count;
char dest[1000]; char dest[1000];
@ -211,6 +211,7 @@ int code_128(struct zint_symbol *symbol, unsigned char source[])
e_count = 0; e_count = 0;
bar_characters = 0; bar_characters = 0;
nve_check = 0; nve_check = 0;
f_state = 0;
for(i = 0; i < 170; i++) { for(i = 0; i < 170; i++) {
values[i] = 0; values[i] = 0;
@ -221,7 +222,7 @@ int code_128(struct zint_symbol *symbol, unsigned char source[])
if(sourcelen > 160) { if(sourcelen > 160) {
/* This only blocks rediculously long input - the actual length of the /* This only blocks rediculously long input - the actual length of the
resulting barcode depends on the type of data, so this is trapped later */ resulting barcode depends on the type of data, so this is trapped later */
strcpy(symbol->errtxt, "Input too long [201]"); strcpy(symbol->errtxt, "Input too long");
return ERROR_TOO_LONG; return ERROR_TOO_LONG;
} }
@ -257,6 +258,23 @@ int code_128(struct zint_symbol *symbol, unsigned char source[])
} }
} }
/* Decide if it is worth reverting to 646 encodation for a few characters as described in 4.3.4.2 (d) */
if(sourcelen > 1) {
for(i = 1; i < sourcelen; i++) {
if((fset[i - 1] == 'F') && (fset[i] == ' ')) {
/* Detected a change from 8859-1 to 646 - count how long for */
for(j = 0; (fset[i + j] == ' ') && ((i + j) < sourcelen); j++);
if((j < 5) || ((j < 3) && ((i + j) == (sourcelen - 1)))) {
/* Uses the same figures recommended by Annex E note 3 */
/* Change to shifting back rather than latching back */
for(k = 0; k < j; k++) {
fset[i + k] = 'n';
}
}
}
}
}
/* Decide on mode using same system as PDF417 and rules of ISO 15417 Annex E */ /* Decide on mode using same system as PDF417 and rules of ISO 15417 Annex E */
indexliste = 0; indexliste = 0;
indexchaine = 0; indexchaine = 0;
@ -348,7 +366,7 @@ int code_128(struct zint_symbol *symbol, unsigned char source[])
if((set[i] == 'a') || (set[i] == 'b')) { if((set[i] == 'a') || (set[i] == 'b')) {
glyph_count = glyph_count + 1.0; glyph_count = glyph_count + 1.0;
} }
if(fset[i] == 'f') { if((fset[i] == 'f') || (fset[i] == 'n')) {
glyph_count = glyph_count + 1.0; glyph_count = glyph_count + 1.0;
} }
if(((set[i] == 'A') || (set[i] == 'B')) || (set[i] == 'C')) { if(((set[i] == 'A') || (set[i] == 'B')) || (set[i] == 'C')) {
@ -380,7 +398,7 @@ int code_128(struct zint_symbol *symbol, unsigned char source[])
} }
} }
if(glyph_count > 80.0) { if(glyph_count > 80.0) {
strcpy(symbol->errtxt, "Input too long [204]"); strcpy(symbol->errtxt, "Input too long");
return ERROR_TOO_LONG; return ERROR_TOO_LONG;
} }
@ -423,6 +441,7 @@ int code_128(struct zint_symbol *symbol, unsigned char source[])
break; break;
} }
bar_characters += 2; bar_characters += 2;
f_state = 1;
} }
/* Encode the data */ /* Encode the data */
@ -451,8 +470,8 @@ int code_128(struct zint_symbol *symbol, unsigned char source[])
} }
} }
if((read != 0) && (fset[read] != fset[read - 1])) { if(read != 0) {
if(fset[read] == 'F') { if((fset[read] == 'F') && (f_state == 0)) {
/* Latch beginning of extended mode */ /* Latch beginning of extended mode */
switch(current_set) { switch(current_set) {
case 'A': case 'A':
@ -469,8 +488,9 @@ int code_128(struct zint_symbol *symbol, unsigned char source[])
break; break;
} }
bar_characters += 2; bar_characters += 2;
f_state = 1;
} }
if(fset[read - 1] == 'F') { if((fset[read] == ' ') && (f_state == 1)) {
/* Latch end of extended mode */ /* Latch end of extended mode */
switch(current_set) { switch(current_set) {
case 'A': case 'A':
@ -487,18 +507,19 @@ int code_128(struct zint_symbol *symbol, unsigned char source[])
break; break;
} }
bar_characters += 2; bar_characters += 2;
f_state = 0;
} }
} }
if(fset[read] == 'f') { if((fset[read] == 'f') || (fset[read] == 'n')) {
/* Shift extended mode */ /* Shift to or from extended mode */
switch(current_set) { switch(current_set) {
case 'A': case 'A':
concat(dest, C128Table[101]); concat(dest, C128Table[101]); /* FNC 4 */
values[bar_characters] = 101; values[bar_characters] = 101;
break; break;
case 'B': case 'B':
concat(dest, C128Table[100]); concat(dest, C128Table[100]); /* FNC 4 */
values[bar_characters] = 100; values[bar_characters] = 100;
break; break;
} }
@ -584,7 +605,7 @@ int ean_128(struct zint_symbol *symbol, unsigned char source[])
if(sourcelen > 160) { if(sourcelen > 160) {
/* This only blocks rediculously long input - the actual length of the /* This only blocks rediculously long input - the actual length of the
resulting barcode depends on the type of data, so this is trapped later */ resulting barcode depends on the type of data, so this is trapped later */
strcpy(symbol->errtxt, "Input too long [161]"); strcpy(symbol->errtxt, "Input too long");
return ERROR_TOO_LONG; return ERROR_TOO_LONG;
} }
@ -701,7 +722,7 @@ int ean_128(struct zint_symbol *symbol, unsigned char source[])
} }
} }
if(glyph_count > 80.0) { if(glyph_count > 80.0) {
strcpy(symbol->errtxt, "Input too long [164]"); strcpy(symbol->errtxt, "Input too long");
return ERROR_TOO_LONG; return ERROR_TOO_LONG;
} }
@ -874,13 +895,13 @@ int nve_18(struct zint_symbol *symbol, unsigned char source[])
sourcelen = ustrlen(source); sourcelen = ustrlen(source);
if(sourcelen > 17) { if(sourcelen > 17) {
strcpy(symbol->errtxt, "Input too long [203]"); strcpy(symbol->errtxt, "Input too long");
return ERROR_TOO_LONG; return ERROR_TOO_LONG;
} }
error_number = is_sane(NESET, source); error_number = is_sane(NESET, source);
if(error_number == ERROR_INVALID_DATA) { if(error_number == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "Invalid characters in data [202]"); strcpy(symbol->errtxt, "Invalid characters in data");
return error_number; return error_number;
} }
@ -923,13 +944,13 @@ int ean_14(struct zint_symbol *symbol, unsigned char source[])
input_length = ustrlen(source); input_length = ustrlen(source);
if(input_length > 13) { if(input_length > 13) {
strcpy(symbol->errtxt, "Input wrong length [721]"); strcpy(symbol->errtxt, "Input wrong length");
return ERROR_TOO_LONG; return ERROR_TOO_LONG;
} }
error_number = is_sane(NESET, source); error_number = is_sane(NESET, source);
if(error_number == ERROR_INVALID_DATA) { if(error_number == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "Invalid character in data [722]"); strcpy(symbol->errtxt, "Invalid character in data");
return error_number; return error_number;
} }

View File

@ -116,7 +116,7 @@ int code16k(struct zint_symbol *symbol, unsigned char source[])
{ {
char width_pattern[100]; char width_pattern[100];
int current_row, rows_needed, flip_flop, looper, first_check, second_check; int current_row, rows_needed, flip_flop, looper, first_check, second_check;
int indexliste, indexchaine, pads_needed; int indexliste, indexchaine, pads_needed, f_state;
char set[160], fset[160], mode, last_set, last_fset, current_set; char set[160], fset[160], mode, last_set, last_fset, current_set;
unsigned int i, j, k, m, e_count, read, mx_reader, writer; unsigned int i, j, k, m, e_count, read, mx_reader, writer;
unsigned int values[160]; unsigned int values[160];
@ -133,7 +133,7 @@ int code16k(struct zint_symbol *symbol, unsigned char source[])
if(symbol->input_mode == GS1_MODE) { gs1 = 1; } else { gs1 = 0; } if(symbol->input_mode == GS1_MODE) { gs1 = 1; } else { gs1 = 0; }
if(input_length > 157) { if(input_length > 157) {
strcpy(symbol->errtxt, "Input too long [231]"); strcpy(symbol->errtxt, "Input too long");
return ERROR_TOO_LONG; return ERROR_TOO_LONG;
} }
@ -161,7 +161,7 @@ int code16k(struct zint_symbol *symbol, unsigned char source[])
do { do {
j++; j++;
} while(fset[i + j] == 'f'); } while(fset[i + j] == 'f');
if((j >= 5) || ((j >= 3) && ((i + j) == input_length))) { if((j >= 5) || ((j >= 3) && ((i + j) == (input_length - 1)))) {
for(k = 0; k <= j; k++) { for(k = 0; k <= j; k++) {
fset[i + k] = 'F'; fset[i + k] = 'F';
} }
@ -169,6 +169,22 @@ int code16k(struct zint_symbol *symbol, unsigned char source[])
} }
} }
/* Decide if it is worth reverting to 646 encodation for a few characters */
if(input_length > 1) {
for(i = 1; i < input_length; i++) {
if((fset[i - 1] == 'F') && (fset[i] == ' ')) {
/* Detected a change from 8859-1 to 646 - count how long for */
for(j = 0; (fset[i + j] == ' ') && ((i + j) < input_length); j++);
if((j < 5) || ((j < 3) && ((i + j) == (input_length - 1)))) {
/* Change to shifting back rather than latching back */
for(k = 0; k < j; k++) {
fset[i + k] = 'n';
}
}
}
}
}
/* Detect mode A, B and C characters */ /* Detect mode A, B and C characters */
indexliste = 0; indexliste = 0;
indexchaine = 0; indexchaine = 0;
@ -268,7 +284,7 @@ int code16k(struct zint_symbol *symbol, unsigned char source[])
if((set[i] == 'a') || (set[i] == 'b')) { if((set[i] == 'a') || (set[i] == 'b')) {
glyph_count = glyph_count + 1.0; glyph_count = glyph_count + 1.0;
} }
if(fset[i] == 'f') { if((fset[i] == 'f') || (fset[i] == 'n')) {
glyph_count = glyph_count + 1.0; glyph_count = glyph_count + 1.0;
} }
if(((set[i] == 'A') || (set[i] == 'B')) || (set[i] == 'C')) { if(((set[i] == 'A') || (set[i] == 'B')) || (set[i] == 'C')) {
@ -314,7 +330,7 @@ int code16k(struct zint_symbol *symbol, unsigned char source[])
} }
if(glyph_count > 77.0) { if(glyph_count > 77.0) {
strcpy(symbol->errtxt, "Input too long [232]"); strcpy(symbol->errtxt, "Input too long");
return ERROR_TOO_LONG; return ERROR_TOO_LONG;
} }
@ -350,6 +366,8 @@ int code16k(struct zint_symbol *symbol, unsigned char source[])
bar_characters++; bar_characters++;
current_set = set[0]; current_set = set[0];
f_state = 0; /* f_state remembers if we are in Extended ASCII mode (value 1) or
in ISO/IEC 646 mode (value 0) */
if(fset[0] == 'F') { if(fset[0] == 'F') {
switch(current_set) { switch(current_set) {
case 'A': case 'A':
@ -362,6 +380,7 @@ int code16k(struct zint_symbol *symbol, unsigned char source[])
break; break;
} }
bar_characters += 2; bar_characters += 2;
f_state = 1;
} }
read = 0; read = 0;
@ -395,8 +414,8 @@ int code16k(struct zint_symbol *symbol, unsigned char source[])
} }
} }
if((read != 0) && (fset[read] != fset[read - 1])) { if(read != 0) {
if(fset[read] == 'F') { if((fset[read] == 'F') && (f_state == 0)) {
/* Latch beginning of extended mode */ /* Latch beginning of extended mode */
switch(current_set) { switch(current_set) {
case 'A': case 'A':
@ -409,8 +428,9 @@ int code16k(struct zint_symbol *symbol, unsigned char source[])
break; break;
} }
bar_characters += 2; bar_characters += 2;
f_state = 1;
} }
if(fset[read - 1] == 'F') { if((fset[read] == ' ') && (f_state == 1)) {
/* Latch end of extended mode */ /* Latch end of extended mode */
switch(current_set) { switch(current_set) {
case 'A': case 'A':
@ -423,17 +443,18 @@ int code16k(struct zint_symbol *symbol, unsigned char source[])
break; break;
} }
bar_characters += 2; bar_characters += 2;
f_state = 0;
} }
} }
if(fset[i] == 'f') { if((fset[i] == 'f') || (fset[i] == 'n')) {
/* Shift extended mode */ /* Shift extended mode */
switch(current_set) { switch(current_set) {
case 'A': case 'A':
values[bar_characters] = 101; values[bar_characters] = 101; /* FNC 4 */
break; break;
case 'B': case 'B':
values[bar_characters] = 100; values[bar_characters] = 100; /* FNC 4 */
break; break;
} }
bar_characters++; bar_characters++;

View File

@ -388,7 +388,7 @@ int ZBarcode_Encode(struct zint_symbol *symbol, unsigned char *source)
unsigned char preprocessed[input_length]; unsigned char preprocessed[input_length];
if(ustrlen(source) == 0) { if(ustrlen(source) == 0) {
strcpy(symbol->errtxt, "No input data [Z00]"); strcpy(symbol->errtxt, "No input data");
error_tag(symbol->errtxt, ERROR_INVALID_DATA); error_tag(symbol->errtxt, ERROR_INVALID_DATA);
return ERROR_INVALID_DATA; return ERROR_INVALID_DATA;
} }