mirror of
https://github.com/zint/zint
synced 2024-11-16 20:57:25 +13:00
Bugfixes for Code 128 and Data Matrix encoding. Remove Codablock-F
This commit is contained in:
parent
984395311c
commit
a348bb22e5
761
backend/blockf.c
761
backend/blockf.c
@ -1,761 +0,0 @@
|
||||
/* blockf.c - Codablock F */
|
||||
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2008 Robin Stuart <robin@zint.org.uk>
|
||||
|
||||
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
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Includes bugfixes thanks to rens.dol@gmail.com
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include "common.h"
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#define SHIFTA 90
|
||||
#define LATCHA 91
|
||||
#define SHIFTB 92
|
||||
#define LATCHB 93
|
||||
#define SHIFTC 94
|
||||
#define LATCHC 95
|
||||
#define AORB 96
|
||||
#define ABORC 97
|
||||
#define CANDB 98
|
||||
#define CANDBB 99
|
||||
|
||||
#define MODEA 98
|
||||
#define MODEB 100
|
||||
#define MODEC 99
|
||||
|
||||
/* Annex A Table A.1 */
|
||||
static char *C128Table[107] = {"212222", "222122", "222221", "121223", "121322", "131222", "122213",
|
||||
"122312", "132212", "221213", "221312", "231212", "112232", "122132", "122231", "113222",
|
||||
"123122", "123221", "223211", "221132", "221231", "213212", "223112", "312131", "311222",
|
||||
"321122", "321221", "312212", "322112", "322211", "212123", "212321", "232121", "111323",
|
||||
"131123", "131321", "112313", "132113", "132311", "211313", "231113", "231311", "112133",
|
||||
"112331", "132131", "113123", "113321", "133121", "313121", "211331", "231131", "213113",
|
||||
"213311", "213131", "311123", "311321", "331121", "312113", "312311", "332111", "314111",
|
||||
"221411", "431111", "111224", "111422", "121124", "121421", "141122", "141221", "112214",
|
||||
"112412", "122114", "122411", "142112", "142211", "241211", "221114", "413111", "241112",
|
||||
"134111", "111242", "121142", "121241", "114212", "124112", "124211", "411212", "421112",
|
||||
"421211", "212141", "214121", "412121", "111143", "111341", "131141", "114113", "114311",
|
||||
"411113", "411311", "113141", "114131", "311141", "411131", "211412", "211214", "211232",
|
||||
"2331112"};
|
||||
|
||||
void grwp(int *indexliste);
|
||||
void dxsmooth(int *indexliste);
|
||||
|
||||
int a3_convert(unsigned char source) {
|
||||
/* Annex A section 3 */
|
||||
if(source < 32) { return source + 64; }
|
||||
if((source >= 32) && (source <= 127)) { return source - 32; }
|
||||
if((source >= 128) && (source <= 159)) { return (source - 128) + 64; }
|
||||
/* if source >= 160 */
|
||||
return (source - 128) - 32;
|
||||
}
|
||||
|
||||
int character_subset_select(unsigned char source[], int input_position) {
|
||||
/* Section 4.5.2 - Determining the Character Subset Selector in a Row */
|
||||
|
||||
if((source[input_position] >= '0') && (source[input_position + 1] <= '9')) {
|
||||
/* Rule 1 */
|
||||
return MODEC;
|
||||
}
|
||||
|
||||
if((source[input_position] >= 128) && (source[input_position] <= 160)) {
|
||||
/* Rule 2 (i) */
|
||||
return MODEA;
|
||||
}
|
||||
|
||||
if((source[input_position] >= 0) && (source[input_position] <= 31)) {
|
||||
/* Rule 3 */
|
||||
return MODEA;
|
||||
}
|
||||
|
||||
/* Rule 4 */
|
||||
return MODEB;
|
||||
}
|
||||
|
||||
int data_encode_blockf(unsigned char source[], int input_length, int subset_selector[], int blockmatrix[][62], int *columns_needed, int *rows_needed, int *final_mode, int gs1, int reader)
|
||||
{
|
||||
int i, j, input_position, current_mode, current_row, error_number;
|
||||
int column_position, c, done, exit_status;
|
||||
|
||||
error_number = 0;
|
||||
exit_status = 0;
|
||||
current_row = 0;
|
||||
current_mode = MODEA;
|
||||
column_position = 0;
|
||||
input_position = 0;
|
||||
done = 0;
|
||||
c = 0;
|
||||
do {
|
||||
done = 0;
|
||||
/* 'done' ensures that the instructions are followed in the correct order for each input character */
|
||||
|
||||
if(column_position == 0) {
|
||||
/* The Beginning of a row */
|
||||
c = (*columns_needed);
|
||||
current_mode = character_subset_select(source, input_position);
|
||||
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((current_row == 0) && reader) {
|
||||
/* Reader Initialise (4.4.7.3) */
|
||||
blockmatrix[current_row][column_position] = 96; /* FNC3 */
|
||||
column_position++;
|
||||
c--;
|
||||
}
|
||||
}
|
||||
|
||||
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]) == ABORC) {
|
||||
blockmatrix[current_row][column_position] = a3_convert(source[input_position]);
|
||||
column_position++;
|
||||
c--;
|
||||
input_position++;
|
||||
done = 1;
|
||||
}
|
||||
|
||||
if((parunmodd(source[input_position]) == 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 */
|
||||
column_position++;
|
||||
c--;
|
||||
}
|
||||
done = 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]) == ABORC) {
|
||||
blockmatrix[current_row][column_position] = a3_convert(source[input_position]);
|
||||
column_position++;
|
||||
c--;
|
||||
input_position++;
|
||||
done = 1;
|
||||
}
|
||||
|
||||
if((parunmodd(source[input_position]) == 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) {
|
||||
blockmatrix[current_row][column_position] = 100; /* Code B */
|
||||
column_position++;
|
||||
c--;
|
||||
}
|
||||
done = 1;
|
||||
}
|
||||
|
||||
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]) != ABORC) && (c == 1)) {
|
||||
/* Needs two symbols */
|
||||
blockmatrix[current_row][column_position] = 101; /* Code A */
|
||||
column_position++;
|
||||
c--;
|
||||
done = 1;
|
||||
}
|
||||
|
||||
if(((parunmodd(source[input_position]) == ABORC) && (parunmodd(source[input_position + 1]) != 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(done == 0) {
|
||||
if(((parunmodd(source[input_position]) == AORB) || (parunmodd(source[input_position]) == SHIFTA)) && (current_mode == MODEA)) {
|
||||
/* Annex B section 1 rule 2 */
|
||||
/* If in Code Subset A and the next data character can be encoded in Subset A encode the next
|
||||
character. */
|
||||
if(source[input_position] >= 128) {
|
||||
/* Extended ASCII character */
|
||||
blockmatrix[current_row][column_position] = 101; /* FNC4 */
|
||||
column_position++;
|
||||
c--;
|
||||
}
|
||||
blockmatrix[current_row][column_position] = a3_convert(source[input_position]);
|
||||
column_position++;
|
||||
c--;
|
||||
input_position++;
|
||||
done = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(done == 0) {
|
||||
if(((parunmodd(source[input_position]) == AORB) || (parunmodd(source[input_position]) == SHIFTB)) && (current_mode == MODEB)) {
|
||||
/* Annex B section 1 rule 3 */
|
||||
/* If in Code Subset B and the next data character can be encoded in subset B, encode the next
|
||||
character. */
|
||||
if(source[input_position] >= 128) {
|
||||
/* Extended ASCII character */
|
||||
blockmatrix[current_row][column_position] = 100; /* FNC4 */
|
||||
column_position++;
|
||||
c--;
|
||||
}
|
||||
blockmatrix[current_row][column_position] = a3_convert(source[input_position]);
|
||||
column_position++;
|
||||
c--;
|
||||
input_position++;
|
||||
done = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(done == 0) {
|
||||
if(((parunmodd(source[input_position]) == ABORC) && (parunmodd(source[input_position + 1]) == ABORC)) && (current_mode == MODEC)) {
|
||||
/* Annex B section 1 rule 4 */
|
||||
/* If in Code Subset C and the next data are 2 digits, encode them. */
|
||||
blockmatrix[current_row][column_position] = (ctoi(source[input_position]) * 10) + ctoi(source[input_position + 1]);
|
||||
column_position++;
|
||||
c--;
|
||||
input_position += 2;
|
||||
done = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(done == 0) {
|
||||
if(((current_mode == MODEA) || (current_mode == MODEB)) && ((parunmodd(source[input_position]) == 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
|
||||
first numeric digit to change to subset C.
|
||||
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;
|
||||
j = 0;
|
||||
do {
|
||||
i++;
|
||||
if(gs1 && (source[input_position + j] == '[')) { i++; }
|
||||
j++;
|
||||
} while((parunmodd(source[input_position + j]) == ABORC) || (gs1 && (source[input_position + j] == '[')));
|
||||
i--;
|
||||
|
||||
if(i >= 4) {
|
||||
/* Annex B section 1 rule 5 */
|
||||
if((i % 2) == 1) {
|
||||
/* Annex B section 1 rule 5a */
|
||||
blockmatrix[current_row][column_position] = 99; /* Code C */
|
||||
column_position++;
|
||||
c--;
|
||||
blockmatrix[current_row][column_position] = (ctoi(source[input_position]) * 10) + ctoi(source[input_position + 1]);
|
||||
column_position++;
|
||||
c--;
|
||||
input_position += 2;
|
||||
current_mode = MODEC;
|
||||
} else {
|
||||
/* Annex B section 1 rule 5b */
|
||||
blockmatrix[current_row][column_position] = a3_convert(source[input_position]);
|
||||
column_position++;
|
||||
c--;
|
||||
input_position++;
|
||||
}
|
||||
done = 1;
|
||||
} else {
|
||||
blockmatrix[current_row][column_position] = a3_convert(source[input_position]);
|
||||
column_position++;
|
||||
c--;
|
||||
input_position++;
|
||||
done = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(done == 0) {
|
||||
if((current_mode == MODEB) && (parunmodd(source[input_position]) == SHIFTA)) {
|
||||
/* Annex B section 1 rule 6 */
|
||||
/* When in subset B and an ASCII control character occurs in the data:
|
||||
a. If there is a lower case character immediately following the control character, insert a Shift
|
||||
character before the control character.
|
||||
b. Otherwise, insert a Code A character before the control character to change to subset A. */
|
||||
if((source[input_position + 1] >= 96) && (source[input_position + 1] <= 127)) {
|
||||
/* Annex B section 1 rule 6a */
|
||||
blockmatrix[current_row][column_position] = 98; /* Shift */
|
||||
column_position++;
|
||||
c--;
|
||||
if(source[input_position] >= 128) {
|
||||
/* Extended ASCII character */
|
||||
blockmatrix[current_row][column_position] = 100; /* FNC4 */
|
||||
column_position++;
|
||||
c--;
|
||||
}
|
||||
blockmatrix[current_row][column_position] = a3_convert(source[input_position]);
|
||||
column_position++;
|
||||
c--;
|
||||
input_position++;
|
||||
} else {
|
||||
/* Annex B section 1 rule 6b */
|
||||
blockmatrix[current_row][column_position] = 101; /* Code A */
|
||||
column_position++;
|
||||
c--;
|
||||
if(source[input_position] >= 128) {
|
||||
/* Extended ASCII character */
|
||||
blockmatrix[current_row][column_position] = 100; /* FNC4 */
|
||||
column_position++;
|
||||
c--;
|
||||
}
|
||||
blockmatrix[current_row][column_position] = a3_convert(source[input_position]);
|
||||
column_position++;
|
||||
c--;
|
||||
input_position++;
|
||||
current_mode = MODEA;
|
||||
}
|
||||
done = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(done == 0) {
|
||||
if((current_mode == MODEA) && (parunmodd(source[input_position]) == SHIFTB)) {
|
||||
/* Annex B section 1 rule 7 */
|
||||
/* When in subset A and a lower case character occurs in the data:
|
||||
a. If following that character, a control character occurs in the data before the occurrence of
|
||||
another lower case character, insert a Shift character before the lower case character.
|
||||
b. Otherwise, insert a Code B character before the lower case character to change to subset B. */
|
||||
if((parunmodd(source[input_position + 1]) == SHIFTA) &&
|
||||
(parunmodd(source[input_position + 2]) == SHIFTB)) {
|
||||
/* Annex B section 1 rule 7a */
|
||||
blockmatrix[current_row][column_position] = 98; /* Shift */
|
||||
column_position++;
|
||||
c--;
|
||||
if(source[input_position] >= 128) {
|
||||
/* Extended ASCII character */
|
||||
blockmatrix[current_row][column_position] = 101; /* FNC4 */
|
||||
column_position++;
|
||||
c--;
|
||||
}
|
||||
blockmatrix[current_row][column_position] = a3_convert(source[input_position]);
|
||||
column_position++;
|
||||
c--;
|
||||
input_position++;
|
||||
} else {
|
||||
/* Annex B section 1 rule 7b */
|
||||
blockmatrix[current_row][column_position] = 100; /* Code B */
|
||||
column_position++;
|
||||
c--;
|
||||
if(source[input_position] >= 128) {
|
||||
/* Extended ASCII character */
|
||||
blockmatrix[current_row][column_position] = 101; /* FNC4 */
|
||||
column_position++;
|
||||
c--;
|
||||
}
|
||||
blockmatrix[current_row][column_position] = a3_convert(source[input_position]);
|
||||
column_position++;
|
||||
c--;
|
||||
input_position++;
|
||||
current_mode = MODEB;
|
||||
}
|
||||
done = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(done == 0) {
|
||||
if((current_mode == MODEC) && ((parunmodd(source[input_position]) != ABORC) ||
|
||||
(parunmodd(source[input_position + 1]) != ABORC))) {
|
||||
/* Annex B section 1 rule 8 */
|
||||
/* When in subset C and a non-numeric character (or a single digit) occurs in the data, insert a Code
|
||||
A or Code B character before that character, following rules 8a and 8b to determine between code
|
||||
subsets A and B.
|
||||
a. If an ASCII control character (eg NUL) occurs in the data before any lower case character, use
|
||||
Code A.
|
||||
b. Otherwise use Code B. */
|
||||
if(parunmodd(source[input_position]) == SHIFTA) {
|
||||
/* Annex B section 1 rule 8a */
|
||||
blockmatrix[current_row][column_position] = 101; /* Code A */
|
||||
column_position++;
|
||||
c--;
|
||||
if(source[input_position] >= 128) {
|
||||
/* Extended ASCII character */
|
||||
blockmatrix[current_row][column_position] = 101; /* FNC4 */
|
||||
column_position++;
|
||||
c--;
|
||||
}
|
||||
blockmatrix[current_row][column_position] = a3_convert(source[input_position]);
|
||||
column_position++;
|
||||
c--;
|
||||
input_position++;
|
||||
current_mode = MODEA;
|
||||
} else {
|
||||
/* Annex B section 1 rule 8b */
|
||||
blockmatrix[current_row][column_position] = 100; /* Code B */
|
||||
column_position++;
|
||||
c--;
|
||||
if(source[input_position] >= 128) {
|
||||
/* Extended ASCII character */
|
||||
blockmatrix[current_row][column_position] = 100; /* FNC4 */
|
||||
column_position++;
|
||||
c--;
|
||||
}
|
||||
blockmatrix[current_row][column_position] = a3_convert(source[input_position]);
|
||||
column_position++;
|
||||
c--;
|
||||
input_position++;
|
||||
current_mode = MODEB;
|
||||
}
|
||||
done = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(input_position == input_length) {
|
||||
/* End of data - Annex B rule 5a */
|
||||
if (c == 1) {
|
||||
if(current_mode == MODEA) {
|
||||
blockmatrix[current_row][column_position] = 100; /* Code B */
|
||||
current_mode = MODEB;
|
||||
} else {
|
||||
blockmatrix[current_row][column_position] = 101; /* Code A */
|
||||
current_mode = MODEA;
|
||||
}
|
||||
column_position++;
|
||||
c--;
|
||||
}
|
||||
|
||||
if (c == 0) {
|
||||
/* Another row is needed */
|
||||
column_position = 0;
|
||||
c = (*columns_needed);
|
||||
current_row++;
|
||||
subset_selector[current_row] = MODEA;
|
||||
current_mode = MODEA;
|
||||
}
|
||||
|
||||
if (c > 2) {
|
||||
/* Fill up the last row */
|
||||
do {
|
||||
if(current_mode == MODEA) {
|
||||
blockmatrix[current_row][column_position] = 100; /* Code B */
|
||||
current_mode = MODEB;
|
||||
} else {
|
||||
blockmatrix[current_row][column_position] = 101; /* Code A */
|
||||
current_mode = MODEA;
|
||||
}
|
||||
column_position++;
|
||||
c--;
|
||||
} while (c > 2);
|
||||
}
|
||||
|
||||
/* If (c == 2) { do nothing } */
|
||||
|
||||
exit_status = 1;
|
||||
*(final_mode) = current_mode;
|
||||
} else {
|
||||
if(c <= 0) {
|
||||
/* Start new row - Annex B rule 5b */
|
||||
column_position = 0;
|
||||
current_row++;
|
||||
if(current_row > 43) {
|
||||
return ERROR_TOO_LONG;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} while (exit_status == 0);
|
||||
|
||||
if(current_row == 0) {
|
||||
/* fill up the first row */
|
||||
for(c = column_position; c <= *(columns_needed); c++) {
|
||||
if(current_mode == MODEA) {
|
||||
blockmatrix[current_row][c] = 100; /* Code B */
|
||||
current_mode = MODEB;
|
||||
} else {
|
||||
blockmatrix[current_row][c] = 101; /* Code A */
|
||||
current_mode = MODEA;
|
||||
}
|
||||
}
|
||||
current_row++;
|
||||
/* add a second row */
|
||||
subset_selector[current_row] = MODEA;
|
||||
current_mode = MODEA;
|
||||
for(c = 0; c <= *(columns_needed) - 2; c++) {
|
||||
if(current_mode == MODEA) {
|
||||
blockmatrix[current_row][c] = 100; /* Code B */
|
||||
current_mode = MODEB;
|
||||
} else {
|
||||
blockmatrix[current_row][c] = 101; /* Code A */
|
||||
current_mode = MODEA;
|
||||
}
|
||||
}
|
||||
}
|
||||
*(rows_needed) = current_row + 1;
|
||||
|
||||
return error_number;
|
||||
}
|
||||
|
||||
int codablock(struct zint_symbol *symbol, unsigned char source[], int length)
|
||||
{
|
||||
int error_number, input_length, i, j, k, h;
|
||||
int rows_needed, columns_needed;
|
||||
int min_module_height;
|
||||
int last_mode, this_mode, final_mode;
|
||||
float estimate_codelength;
|
||||
int blockmatrix[44][62];
|
||||
char row_pattern[750];
|
||||
int subset_selector[44], row_indicator[44], row_check[44];
|
||||
long int k1_sum, k2_sum;
|
||||
int k1_check, k2_check;
|
||||
int gs1, reader;
|
||||
|
||||
error_number = 0;
|
||||
input_length = length;
|
||||
final_mode = MODEA;
|
||||
|
||||
if(input_length > 5450) {
|
||||
strcpy(symbol->errtxt, "Input data too long");
|
||||
return ERROR_TOO_LONG;
|
||||
}
|
||||
|
||||
if(symbol->input_mode == GS1_MODE) { gs1 = 1; } else { gs1 = 0; }
|
||||
if(symbol->output_options & READER_INIT) { reader = 1; } else { reader = 0; }
|
||||
if((gs1 == 1) && (reader == 1)) {
|
||||
strcpy(symbol->errtxt, "Cannot encode GS1 data and Reader Initialise in the same symbol");
|
||||
return ERROR_INVALID_OPTION;
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
for(i = 0; i < input_length; i++) {
|
||||
this_mode = parunmodd(source[i]);
|
||||
if(this_mode != last_mode) {
|
||||
estimate_codelength += 1.0;
|
||||
}
|
||||
if(this_mode != ABORC) {
|
||||
estimate_codelength += 1.0;
|
||||
} else {
|
||||
estimate_codelength += 0.5;
|
||||
}
|
||||
if(source[i] > 127) {
|
||||
estimate_codelength += 1.0;
|
||||
}
|
||||
last_mode = this_mode;
|
||||
}
|
||||
|
||||
/* Decide symbol size based on the above guess */
|
||||
rows_needed = 0.5 + sqrt((estimate_codelength + 2) / 1.45);
|
||||
if(rows_needed < 2) { rows_needed = 2; }
|
||||
if(rows_needed > 44) { rows_needed = 44; }
|
||||
columns_needed = (estimate_codelength + 2) / rows_needed;
|
||||
if(columns_needed < 4) { columns_needed = 4; }
|
||||
if(columns_needed > 62) {
|
||||
strcpy(symbol->errtxt, "Input data too long");
|
||||
return ERROR_TOO_LONG;
|
||||
}
|
||||
|
||||
/* Encode the data */
|
||||
error_number = data_encode_blockf(source, input_length, subset_selector, blockmatrix, &columns_needed, &rows_needed, &final_mode, gs1, reader);
|
||||
if(error_number > 0) {
|
||||
if(error_number == ERROR_TOO_LONG) {
|
||||
strcpy(symbol->errtxt, "Input data too long");
|
||||
}
|
||||
return error_number;
|
||||
}
|
||||
|
||||
/* Add check digits - Annex F */
|
||||
k1_sum = 0;
|
||||
k2_sum = 0;
|
||||
for(i = 0; i < input_length; i++) {
|
||||
if(gs1 && source[i] == '[') {
|
||||
k1_sum += (i + 1) * 29; /* GS */
|
||||
k2_sum += i * 29;
|
||||
} else {
|
||||
k1_sum += (i + 1) * source[i];
|
||||
k2_sum += i * source[i];
|
||||
}
|
||||
}
|
||||
k1_check = k1_sum % 86;
|
||||
k2_check = k2_sum % 86;
|
||||
if((final_mode == MODEA) || (final_mode == MODEB)) {
|
||||
k1_check = k1_check + 64;
|
||||
if(k1_check > 95) { k1_check -= 96; }
|
||||
k2_check = k2_check + 64;
|
||||
if(k2_check > 95) { k2_check -= 96; }
|
||||
}
|
||||
blockmatrix[rows_needed - 1][columns_needed - 2] = k1_check;
|
||||
blockmatrix[rows_needed - 1][columns_needed - 1] = k2_check;
|
||||
|
||||
/* Calculate row height (4.6.1.a) */
|
||||
min_module_height = (0.55 * (columns_needed + 3)) + 3;
|
||||
if(min_module_height < 8) { min_module_height = 8; }
|
||||
|
||||
/* Encode the Row Indicator in the First Row of the Symbol - Table D2 */
|
||||
if(subset_selector[0] == 99) {
|
||||
/* Code C */
|
||||
row_indicator[0] = rows_needed - 2;
|
||||
} else {
|
||||
/* Code A or B */
|
||||
row_indicator[0] = rows_needed + 62;
|
||||
|
||||
if(row_indicator[0] > 95) {
|
||||
row_indicator[0] -= 95;
|
||||
}
|
||||
}
|
||||
|
||||
/* Encode the Row Indicator in the Second and Subsequent Rows of the Symbol - Table D3 */
|
||||
for(i = 1; i < rows_needed; i++) {
|
||||
/* Note that the second row is row number 1 because counting starts from 0 */
|
||||
if(subset_selector[i] == 99) {
|
||||
/* Code C */
|
||||
row_indicator[i] = i + 42;
|
||||
} else {
|
||||
/* Code A or B */
|
||||
if( i < 6 )
|
||||
row_indicator[i] = i + 10;
|
||||
else
|
||||
row_indicator[i] = i + 20;
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculate row check digits - Annex E */
|
||||
for(i = 0; i < rows_needed; i++) {
|
||||
k = 103;
|
||||
k += subset_selector[i];
|
||||
k += 2 * row_indicator[i];
|
||||
for(j = 0; j < columns_needed; j++) {
|
||||
k+= (j + 3) * blockmatrix[i][j];
|
||||
}
|
||||
row_check[i] = k % 103;
|
||||
}
|
||||
|
||||
/* Resolve the data into patterns and place in symbol structure */
|
||||
for(i = 0; i < rows_needed; i++) {
|
||||
int writer, flip_flop;
|
||||
/*
|
||||
printf("row %d: ",i);
|
||||
printf("103 %d %d [", subset_selector[i], row_indicator[i]);
|
||||
for(j = 0; j < columns_needed; j++) {
|
||||
printf("%d ",blockmatrix[i][j]);
|
||||
}
|
||||
printf("] %d 106\n", row_check[i]);
|
||||
*/
|
||||
strcpy(row_pattern, "");
|
||||
/* Start character */
|
||||
concat(row_pattern, C128Table[103]); /* Always Start A */
|
||||
|
||||
concat(row_pattern, C128Table[subset_selector[i]]);
|
||||
concat(row_pattern, C128Table[row_indicator[i]]);
|
||||
|
||||
for(j = 0; j < columns_needed; j++) {
|
||||
concat(row_pattern, C128Table[blockmatrix[i][j]]);
|
||||
}
|
||||
|
||||
concat(row_pattern, C128Table[row_check[i]]);
|
||||
|
||||
/* Stop character */
|
||||
concat(row_pattern, C128Table[106]);
|
||||
|
||||
/* Write the information into the symbol */
|
||||
writer = 0;
|
||||
flip_flop = 1;
|
||||
h = strlen(row_pattern);
|
||||
for (j = 0; j < h; j++) {
|
||||
for(k = 0; k < ctoi(row_pattern[j]); k++) {
|
||||
if(flip_flop == 1) {
|
||||
set_module(symbol, i, writer);
|
||||
writer++;
|
||||
} else {
|
||||
writer++;
|
||||
}
|
||||
}
|
||||
if(flip_flop == 0) { flip_flop = 1; } else { flip_flop = 0; }
|
||||
}
|
||||
symbol->row_height[i] = min_module_height + 2;
|
||||
}
|
||||
|
||||
symbol->border_width = 2;
|
||||
symbol->output_options = BARCODE_BIND;
|
||||
symbol->rows = rows_needed;
|
||||
symbol->width = (11 * (columns_needed + 5)) + 2;
|
||||
|
||||
return error_number;
|
||||
}
|
@ -134,6 +134,8 @@ void dxsmooth(int *indexliste)
|
||||
if((current == SHIFTB) && (length > 1)) { /* Rule 5 */ list[1][i] = LATCHB; current = LATCHB; }
|
||||
if((current == SHIFTA) && (last == LATCHA)) { list[1][i] = LATCHA; current = LATCHA; }
|
||||
if((current == SHIFTB) && (last == LATCHB)) { list[1][i] = LATCHB; current = LATCHB; }
|
||||
if((current == SHIFTA) && (last == LATCHC)) { list[1][i] = LATCHA; current = LATCHA; }
|
||||
if((current == SHIFTB) && (last == LATCHC)) { list[1][i] = LATCHB; current = LATCHB; }
|
||||
} /* Rule 2 is implimented elsewhere, Rule 6 is implied */
|
||||
}
|
||||
grwp(indexliste);
|
||||
|
@ -122,6 +122,8 @@ void dxsmooth16(int *indexliste)
|
||||
if((current == SHIFTB) && (length > 1)) { /* Rule 5 */ list[1][i] = LATCHB; current = LATCHB; }
|
||||
if((current == SHIFTA) && (last == LATCHA)) { list[1][i] = LATCHA; current = LATCHA; }
|
||||
if((current == SHIFTB) && (last == LATCHB)) { list[1][i] = LATCHB; current = LATCHB; }
|
||||
if((current == SHIFTA) && (last == LATCHC)) { list[1][i] = LATCHA; current = LATCHA; }
|
||||
if((current == SHIFTB) && (last == LATCHC)) { list[1][i] = LATCHB; current = LATCHB; }
|
||||
} /* Rule 2 is implimented elsewhere, Rule 6 is implied */
|
||||
}
|
||||
grwp16(indexliste);
|
||||
|
@ -39,7 +39,7 @@ extern int data_matrix_200(struct zint_symbol *symbol, unsigned char source[], i
|
||||
|
||||
void crc_machine(char data_prefix_bitstream[], int scheme, unsigned char source[], int length)
|
||||
{
|
||||
int input_length, i;
|
||||
int input_length, i, debug = 0;
|
||||
char xor_register[17];
|
||||
int machine_cycles;
|
||||
char input_bit, out1, out2, out3;
|
||||
@ -55,11 +55,11 @@ void crc_machine(char data_prefix_bitstream[], int scheme, unsigned char source[
|
||||
#endif
|
||||
|
||||
switch(scheme) {
|
||||
case 11: strcpy(precrc_bitstream, "0000000100000000"); break;
|
||||
case 27: strcpy(precrc_bitstream, "0000001000000000"); break;
|
||||
case 41: strcpy(precrc_bitstream, "0000001100000000"); break;
|
||||
case 37: strcpy(precrc_bitstream, "0000010000000000"); break;
|
||||
default: strcpy(precrc_bitstream, "0000010100000000"); break;
|
||||
case 11: strcpy(precrc_bitstream, "0000000100000000"); if(debug) { printf("Scheme 11\n"); } break;
|
||||
case 27: strcpy(precrc_bitstream, "0000001000000000"); if(debug) { printf("Scheme 27\n"); } break;
|
||||
case 41: strcpy(precrc_bitstream, "0000001100000000"); if(debug) { printf("Scheme 41\n"); } break;
|
||||
case 37: strcpy(precrc_bitstream, "0000010000000000"); if(debug) { printf("Scheme 37\n"); } break;
|
||||
default: strcpy(precrc_bitstream, "0000010100000000"); if(debug) { printf("Scheme DE\n"); } break;
|
||||
}
|
||||
|
||||
for(i = 0; i < input_length; i++) {
|
||||
@ -72,6 +72,7 @@ void crc_machine(char data_prefix_bitstream[], int scheme, unsigned char source[
|
||||
if(source[i] & 0x02) { concat(precrc_bitstream, "1"); } else { concat(precrc_bitstream, "0"); }
|
||||
if(source[i] & 0x01) { concat(precrc_bitstream, "1"); } else { concat(precrc_bitstream, "0"); }
|
||||
}
|
||||
if(debug) { printf("CRC bitstream:\n%s\n", precrc_bitstream); }
|
||||
|
||||
/* pre-CRC bit stream byte reversal */
|
||||
for(i = 0; i < (input_length + 2); i++) {
|
||||
@ -86,6 +87,7 @@ void crc_machine(char data_prefix_bitstream[], int scheme, unsigned char source[
|
||||
}
|
||||
precrc_bitstream_reversed[strlen(precrc_bitstream)] = '\0';
|
||||
machine_cycles = strlen(precrc_bitstream_reversed);
|
||||
if(debug) { printf("Reversed CRC bitstream:\n%s\n", precrc_bitstream_reversed); }
|
||||
|
||||
/* Start up the machine */
|
||||
for(i = 0; i < 16; i++) {
|
||||
@ -123,6 +125,7 @@ void crc_machine(char data_prefix_bitstream[], int scheme, unsigned char source[
|
||||
data_prefix_bitstream[i + 5] = xor_register[15 - i];
|
||||
}
|
||||
data_prefix_bitstream[16 + 5] = '\0';
|
||||
if(debug) { printf("Data Prefix:\n%s\n", data_prefix_bitstream); }
|
||||
|
||||
return;
|
||||
}
|
||||
@ -704,10 +707,6 @@ void protect_ecc080(char protected_stream[], char unprotected_stream[])
|
||||
{
|
||||
/* ECC 080 - 3-2-11 convolutional code */
|
||||
/* State machine illustrated in figure K2 */
|
||||
/* NOTE: Figure K.2 of ISO/IEC 16022:2006 has an error in that input 2 of gate 1 and input 1 of gate 2 are
|
||||
both connected to module 2 _and_ module 3 of the top register. This is obviously not correct so I have
|
||||
made a guess at the correct interpretation and made a comment where a correction may be needed if this
|
||||
guess is not correct */
|
||||
char top_reg[12];
|
||||
char low_reg[12];
|
||||
char u1, u2;
|
||||
@ -743,7 +742,7 @@ void protect_ecc080(char protected_stream[], char unprotected_stream[])
|
||||
|
||||
gate_input[0] = u1;
|
||||
gate_input[1] = top_reg[0];
|
||||
gate_input[2] = top_reg[3]; /* ? top_reg[2] ? */
|
||||
gate_input[2] = top_reg[2];
|
||||
gate_input[3] = top_reg[4];
|
||||
gate_input[4] = top_reg[5];
|
||||
gate_input[5] = top_reg[6];
|
||||
@ -767,7 +766,7 @@ void protect_ecc080(char protected_stream[], char unprotected_stream[])
|
||||
}
|
||||
|
||||
gate_input[0] = top_reg[0];
|
||||
gate_input[1] = top_reg[2]; /* ? top_reg[3] ? */
|
||||
gate_input[1] = top_reg[3];
|
||||
gate_input[2] = top_reg[4];
|
||||
gate_input[3] = top_reg[7];
|
||||
gate_input[4] = top_reg[8];
|
||||
|
Loading…
Reference in New Issue
Block a user