diff --git a/backend/blockf.c b/backend/blockf.c index 7c086455..cac6ed68 100644 --- a/backend/blockf.c +++ b/backend/blockf.c @@ -97,9 +97,9 @@ int character_subset_select(unsigned char source[], int input_position, char nul return MODEB; } -int data_encode_blockf(unsigned char source[], int subset_selector[], int blockmatrix[][62], int *columns_needed, int *rows_needed, int *final_mode, char nullchar) +int data_encode_blockf(unsigned char source[], int subset_selector[], int blockmatrix[][62], int *columns_needed, int *rows_needed, int *final_mode, char nullchar, int gs1) { - int i, input_position, input_length, current_mode, current_row, error_number; + int i, j, input_position, input_length, current_mode, current_row, error_number; int column_position, c, done, exit_status; error_number = 0; @@ -120,122 +120,138 @@ int data_encode_blockf(unsigned char source[], int subset_selector[], int blockm c = (*columns_needed); current_mode = character_subset_select(source, input_position, nullchar); subset_selector[current_row] = current_mode; + if((current_row == 0) && gs1) { + /* Section 4.4.7.1 */ + blockmatrix[current_row][column_position] = 102; /* FNC1 */ + column_position++; + c--; + } } - if(c <= 2) { - /* Annex B section 1 rule 1 */ - /* Ensure that there is sufficient encodation capacity to continue (using the rules of Annex B.2). */ - switch(current_mode) { - case MODEA: /* Table B1 applies */ - if(parunmodd(source[input_position], nullchar) == ABORC) { - blockmatrix[current_row][column_position] = a3_convert(source[input_position], nullchar); - column_position++; - c--; - input_position++; - done = 1; - } - - if((parunmodd(source[input_position], nullchar) == SHIFTB) && (c == 1)) { - /* Needs two symbols */ - blockmatrix[current_row][column_position] = 100; /* Code B */ - column_position++; - c--; - done = 1; - } - - if((source[input_position] >= 244) && (done == 0)) { - /* Needs three symbols */ - blockmatrix[current_row][column_position] = 100; /* Code B */ - column_position++; - c--; - if(c == 1) { - blockmatrix[current_row][column_position] = 101; /* Code A */ + if(gs1 && (source[input_position] == '[')) { + blockmatrix[current_row][column_position] = 102; /* FNC1 */ + column_position++; + c--; + input_position++; + done = 1; + } + + if(done == 0) { + if(c <= 2) { + /* Annex B section 1 rule 1 */ + /* Ensure that there is sufficient encodation capacity to continue (using the rules of Annex B.2). */ + switch(current_mode) { + case MODEA: /* Table B1 applies */ + if(parunmodd(source[input_position], nullchar) == ABORC) { + blockmatrix[current_row][column_position] = a3_convert(source[input_position], nullchar); column_position++; c--; + input_position++; + done = 1; } - done = 1; - } - - if((source[input_position] >= 128) && (done == 0)) { - /* Needs two symbols */ - if(c == 1) { + + if((parunmodd(source[input_position], nullchar) == SHIFTB) && (c == 1)) { + /* Needs two symbols */ blockmatrix[current_row][column_position] = 100; /* Code B */ column_position++; c--; done = 1; } - } - break; - case MODEB: /* Table B2 applies */ - if(parunmodd(source[input_position], nullchar) == ABORC) { - blockmatrix[current_row][column_position] = a3_convert(source[input_position], nullchar); - column_position++; - c--; - input_position++; - done = 1; - } - - if((parunmodd(source[input_position], nullchar) == SHIFTA) && (c == 1)) { - /* Needs two symbols */ - blockmatrix[current_row][column_position] = 101; /* Code A */ - column_position++; - c--; - done = 1; - } - - if(((source[input_position] >= 128) && (source[input_position] <= 159)) && (done == 0)) { - /* Needs three symbols */ - blockmatrix[current_row][column_position] = 101; /* Code A */ - column_position++; - c--; - if(c == 1) { + + if((source[input_position] >= 244) && (done == 0)) { + /* Needs three symbols */ blockmatrix[current_row][column_position] = 100; /* Code B */ column_position++; c--; + if(c == 1) { + blockmatrix[current_row][column_position] = 101; /* Code A */ + column_position++; + c--; + } + done = 1; } - done = 1; - } - - if((source[input_position] >= 160) && (done == 0)) { - /* Needs two symbols */ - if(c == 1) { + + if((source[input_position] >= 128) && (done == 0)) { + /* Needs two symbols */ + if(c == 1) { + blockmatrix[current_row][column_position] = 100; /* Code B */ + column_position++; + c--; + done = 1; + } + } + break; + case MODEB: /* Table B2 applies */ + if(parunmodd(source[input_position], nullchar) == ABORC) { + blockmatrix[current_row][column_position] = a3_convert(source[input_position], nullchar); + column_position++; + c--; + input_position++; + done = 1; + } + + if((parunmodd(source[input_position], nullchar) == SHIFTA) && (c == 1)) { + /* Needs two symbols */ blockmatrix[current_row][column_position] = 101; /* Code A */ column_position++; c--; done = 1; } - } - break; - case MODEC: /* Table B3 applies */ - if((parunmodd(source[input_position], nullchar) != ABORC) && (c == 1)) { - /* Needs two symbols */ - blockmatrix[current_row][column_position] = 101; /* Code A */ - column_position++; - c--; - done = 1; - } - - if(((parunmodd(source[input_position], nullchar) == ABORC) && (parunmodd(source[input_position + 1], nullchar) != ABORC)) - && (c == 1)) { - /* Needs two symbols */ - blockmatrix[current_row][column_position] = 101; /* Code A */ - column_position++; - c--; - done = 1; - } - - if(source[input_position] >= 128) { - /* Needs three symbols */ - blockmatrix[current_row][column_position] = 101; /* Code A */ - column_position++; - c--; - if(c == 1) { - blockmatrix[current_row][column_position] = 100; /* Code B */ + + if(((source[input_position] >= 128) && (source[input_position] <= 159)) && (done == 0)) { + /* Needs three symbols */ + blockmatrix[current_row][column_position] = 101; /* Code A */ column_position++; c--; + if(c == 1) { + blockmatrix[current_row][column_position] = 100; /* Code B */ + column_position++; + c--; + } + done = 1; } - } - break; + + if((source[input_position] >= 160) && (done == 0)) { + /* Needs two symbols */ + if(c == 1) { + blockmatrix[current_row][column_position] = 101; /* Code A */ + column_position++; + c--; + done = 1; + } + } + break; + case MODEC: /* Table B3 applies */ + if((parunmodd(source[input_position], nullchar) != ABORC) && (c == 1)) { + /* Needs two symbols */ + blockmatrix[current_row][column_position] = 101; /* Code A */ + column_position++; + c--; + done = 1; + } + + if(((parunmodd(source[input_position], nullchar) == ABORC) && (parunmodd(source[input_position + 1], nullchar) != ABORC)) + && (c == 1)) { + /* Needs two symbols */ + blockmatrix[current_row][column_position] = 101; /* Code A */ + column_position++; + c--; + done = 1; + } + + if(source[input_position] >= 128) { + /* Needs three symbols */ + blockmatrix[current_row][column_position] = 101; /* Code A */ + column_position++; + c--; + if(c == 1) { + blockmatrix[current_row][column_position] = 100; /* Code B */ + column_position++; + c--; + } + } + break; + } } } @@ -290,7 +306,7 @@ int data_encode_blockf(unsigned char source[], int subset_selector[], int blockm } if(done == 0) { - if(((current_mode == MODEA) || (current_mode == MODEB)) && (parunmodd(source[input_position], nullchar) == ABORC)) { + if(((current_mode == MODEA) || (current_mode == MODEB)) && ((parunmodd(source[input_position], nullchar) == ABORC) || (gs1 && (source[input_position] == '[')))) { /* Count the number of numeric digits */ /* If 4 or more numeric data characters occur together when in subsets A or B: a. If there is an even number of numeric data characters, insert a Code C character before the @@ -298,7 +314,12 @@ int data_encode_blockf(unsigned char source[], int subset_selector[], int blockm b. If there is an odd number of numeric data characters, insert a Code Set C character immedi- ately after the first numeric digit to change to subset C. */ i = 0; - do { i++; } while(parunmodd(source[input_position + i], nullchar) == ABORC); + j = 0; + do { + i++; + if(gs1 && (source[input_position + j] == '[')) { i++; } + j++; + } while((parunmodd(source[input_position + j], nullchar) == ABORC) || (gs1 && (source[input_position + j] == '['))); i--; if(i >= 4) { @@ -562,6 +583,7 @@ int codablock(struct zint_symbol *symbol, unsigned char source[]) int subset_selector[44], row_indicator[44], row_check[44]; long int k1_sum, k2_sum; int k1_check, k2_check; + int gs1; error_number = 0; input_length = ustrlen(source); @@ -572,6 +594,8 @@ int codablock(struct zint_symbol *symbol, unsigned char source[]) return ERROR_TOO_LONG; } + if(symbol->input_mode == GS1_MODE) { gs1 = 1; } else { gs1 = 0; } + /* Make a guess at how many characters will be needed to encode the data */ estimate_codelength = 0.0; last_mode = AORB; /* Codablock always starts with Code A */ @@ -603,7 +627,7 @@ int codablock(struct zint_symbol *symbol, unsigned char source[]) } /* Encode the data */ - error_number = data_encode_blockf(source, subset_selector, blockmatrix, &columns_needed, &rows_needed, &final_mode, symbol->nullchar); + error_number = data_encode_blockf(source, subset_selector, blockmatrix, &columns_needed, &rows_needed, &final_mode, symbol->nullchar, gs1); if(error_number > 0) { if(error_number == ERROR_TOO_LONG) { strcpy(symbol->errtxt, "Input data too long [743]"); diff --git a/backend/dm200.c b/backend/dm200.c index 20cf7157..f05d4a7b 100644 --- a/backend/dm200.c +++ b/backend/dm200.c @@ -6,6 +6,7 @@ * * (c) 2004 Adrian Kennard, Andrews & Arnold Ltd * (c) 2006 Stefan Schmidt + * (c) 2009 Robin Stuart * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -230,7 +231,7 @@ static void ecc200(unsigned char *binary, int bytes, int datablock, int rsblock) * necessary padding to tl */ -char ecc200encode(unsigned char *t, int tl, unsigned char *s, int sl, char *encoding, int *lenp) +char ecc200encode(unsigned char *t, int tl, unsigned char *s, int sl, char *encoding, int *lenp, int gs1) { char enc = 'a'; // start in ASCII encoding mode int tp = 0, sp = 0; @@ -239,6 +240,8 @@ char ecc200encode(unsigned char *t, int tl, unsigned char *s, int sl, char *enco return 0; } + if(gs1) { t[tp++] = 232; } /* FNC1 */ + // do the encoding while (sp < sl && tp < tl) { char newenc = enc; // suggest new encoding @@ -291,18 +294,23 @@ char ecc200encode(unsigned char *t, int tl, unsigned char *s, int sl, char *enco out[(int)p++] = 0; out[(int)p++] = c; } else { - w = strchr(s2, c); - if (w) { // shift 2 + if(gs1 && (c == '[')) { out[(int)p++] = 1; - out[(int)p++] = (w - s2); + out[(int)p++] = 27; /* FNC1 */ } else { - w = strchr(s3, c); - if (w) { - out[(int)p++] = 2; - out[(int)p++] = (w - s3); + w = strchr(s2, c); + if (w) { // shift 2 + out[(int)p++] = 1; + out[(int)p++] = (w - s2); } else { - fprintf (stderr, "Could not encode 0x%02X, should not happen\n", c); - return 0; + w = strchr(s3, c); + if (w) { + out[(int)p++] = 2; + out[(int)p++] = (w - s3); + } else { + fprintf (stderr, "Could not encode 0x%02X, should not happen\n", c); + return 0; + } } } } @@ -373,11 +381,17 @@ char ecc200encode(unsigned char *t, int tl, unsigned char *s, int sl, char *enco if (sl - sp >= 2 && isdigit(s[sp]) && isdigit(s[sp + 1])) { t[tp++] = (s[sp] - '0') * 10 + s[sp + 1] - '0' + 130; sp += 2; - } else if (s[sp] > 127) { - t[tp++] = 235; - t[tp++] = s[sp++] - 127; - } else - t[tp++] = s[sp++] + 1; + } else { + if (gs1 && (s[sp] == '[')) { + t[tp++] = 232; /* FNC1 */ + } else { + if (s[sp] > 127) { + t[tp++] = 235; + t[tp++] = s[sp++] - 127; + } else + t[tp++] = s[sp++] + 1; + } + } break; case 'b': // Binary { @@ -476,7 +490,7 @@ unsigned char switchcost[E_MAX][E_MAX] = { * otherwise free the result and try again with exact=0 */ -static char *encmake(int l, unsigned char *s, int *lenp, char exact) +static char *encmake(int l, unsigned char *s, int *lenp, char exact, int gs1) { char *encoding = 0; int p = l; @@ -628,7 +642,7 @@ static char *encmake(int l, unsigned char *s, int *lenp, char exact) } // EDIFACT sl = bl = 0; - if (s[p + 0] >= 32 && s[p + 0] <= 94) { // can encode 1 + if ((s[p + 0] >= 32 && s[p + 0] <= 94) && (!(gs1 && (s[p + 0] == '[')))) { // can encode 1 char bs = 0; if (p + 1 == l && (!bl || bl < 2)) { bl = 2; @@ -642,7 +656,7 @@ static char *encmake(int l, unsigned char *s, int *lenp, char exact) bl = t; b = e; } - if (p + 1 < l && s[p + 1] >= 32 && s[p + 1] <= 94) { // can encode 2 + if ((p + 1 < l && s[p + 1] >= 32 && s[p + 1] <= 94) && (!(gs1 && (s[p + 1] == '[')))) { // can encode 2 if (p + 2 == l && (!bl || bl < 2)) { bl = 3; bs = 2; @@ -655,7 +669,7 @@ static char *encmake(int l, unsigned char *s, int *lenp, char exact) bl = t; b = e; } - if (p + 2 < l && s[p + 2] >= 32 && s[p + 2] <= 94) { // can encode 3 + if ((p + 2 < l && s[p + 2] >= 32 && s[p + 2] <= 94) && (!(gs1 && (s[p + 2] == '[')))) { // can encode 3 if (p + 3 == l && (!bl || bl < 3)) { bl = 3; bs = 3; @@ -668,7 +682,7 @@ static char *encmake(int l, unsigned char *s, int *lenp, char exact) bl = t; b = e; } - if (p + 4 < l && s[p + 3] >= 32 && s[p + 3] <= 94) { // can encode 4 + if ((p + 4 < l && s[p + 3] >= 32 && s[p + 3] <= 94) && (!(gs1 && (s[p + 3] == '[')))) { // can encode 4 if (p + 4 == l && (!bl || bl < 3)) { bl = 3; bs = 4; @@ -759,11 +773,13 @@ int iec16022ecc200(unsigned char *barcode, int barcodelen, struct zint_symbol *s struct ecc200matrix_s *matrix; memset(binary, 0, sizeof(binary)); unsigned char adjusted[barcodelen]; - int i; + int i, gs1; lend = 0; lenp = &lend; + if(symbol->input_mode == GS1_MODE) { gs1 = 1; } else { gs1 = 0; } + switch(symbol->option_2) { case 1: W = 10; H = 10; break; case 2: W = 12; H = 12; break; @@ -816,10 +832,10 @@ int iec16022ecc200(unsigned char *barcode, int barcodelen, struct zint_symbol *s } if (!encoding) { int len; - char *e = encmake(barcodelen, adjusted, &len, 1); + char *e = encmake(barcodelen, adjusted, &len, 1, gs1); if (e && len != matrix->bytes) { // try not an exact fit free(e); - e = encmake(barcodelen, adjusted, &len, 0); + e = encmake(barcodelen, adjusted, &len, 0, gs1); if (len > matrix->bytes) { strcpy(symbol->errtxt, "Cannot make barcode fit"); if (e) free (e); @@ -831,22 +847,22 @@ int iec16022ecc200(unsigned char *barcode, int barcodelen, struct zint_symbol *s } else { // find a suitable encoding if (encoding == NULL) - encoding = encmake(barcodelen, adjusted, NULL, 1); + encoding = encmake(barcodelen, adjusted, NULL, 1, gs1); if (encoding) { // find one that fits chosen encoding for (matrix = ecc200matrix; matrix->W; matrix++) - if (ecc200encode(binary, matrix->bytes, adjusted, barcodelen, encoding, 0)) { + if (ecc200encode(binary, matrix->bytes, adjusted, barcodelen, encoding, 0, gs1)) { break; } } else { int len; char *e; - e = encmake(barcodelen, adjusted, &len, 1); + e = encmake(barcodelen, adjusted, &len, 1, gs1); for (matrix = ecc200matrix; matrix->W && matrix->bytes != len; matrix++) ; if (e && !matrix->W) { // try for non exact fit free(e); - e = encmake(barcodelen, adjusted, &len, 0); + e = encmake(barcodelen, adjusted, &len, 0, gs1); for (matrix = ecc200matrix; matrix->W && matrix->bytes < len; matrix++) ; } encoding = e; @@ -858,7 +874,7 @@ int iec16022ecc200(unsigned char *barcode, int barcodelen, struct zint_symbol *s W = matrix->W; H = matrix->H; } - if (!ecc200encode(binary, matrix->bytes, adjusted, barcodelen, encoding, lenp)) { + if (!ecc200encode(binary, matrix->bytes, adjusted, barcodelen, encoding, lenp, gs1)) { strcpy(symbol->errtxt, "Barcode too long"); free(encoding); return ERROR_INVALID_OPTION; diff --git a/backend/library.c b/backend/library.c index ae97a592..c11e43dd 100644 --- a/backend/library.c +++ b/backend/library.c @@ -202,6 +202,8 @@ int gs1_compliant(int symbology) case BARCODE_RSS_EXPSTACK_CC: case BARCODE_CODE16K: case BARCODE_AZTEC: + case BARCODE_DATAMATRIX: + case BARCODE_CODABLOCKF: result = 1; break; }