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 == SHIFTB) && (length > 1)) { /* Rule 5 */ list[1][i] = LATCHB; current = LATCHB; }
|
||||||
if((current == SHIFTA) && (last == LATCHA)) { list[1][i] = LATCHA; current = LATCHA; }
|
if((current == SHIFTA) && (last == LATCHA)) { list[1][i] = LATCHA; current = LATCHA; }
|
||||||
if((current == SHIFTB) && (last == LATCHB)) { list[1][i] = LATCHB; current = LATCHB; }
|
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 */
|
} /* Rule 2 is implimented elsewhere, Rule 6 is implied */
|
||||||
}
|
}
|
||||||
grwp(indexliste);
|
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 == SHIFTB) && (length > 1)) { /* Rule 5 */ list[1][i] = LATCHB; current = LATCHB; }
|
||||||
if((current == SHIFTA) && (last == LATCHA)) { list[1][i] = LATCHA; current = LATCHA; }
|
if((current == SHIFTA) && (last == LATCHA)) { list[1][i] = LATCHA; current = LATCHA; }
|
||||||
if((current == SHIFTB) && (last == LATCHB)) { list[1][i] = LATCHB; current = LATCHB; }
|
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 */
|
} /* Rule 2 is implimented elsewhere, Rule 6 is implied */
|
||||||
}
|
}
|
||||||
grwp16(indexliste);
|
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)
|
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];
|
char xor_register[17];
|
||||||
int machine_cycles;
|
int machine_cycles;
|
||||||
char input_bit, out1, out2, out3;
|
char input_bit, out1, out2, out3;
|
||||||
@ -55,11 +55,11 @@ void crc_machine(char data_prefix_bitstream[], int scheme, unsigned char source[
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch(scheme) {
|
switch(scheme) {
|
||||||
case 11: strcpy(precrc_bitstream, "0000000100000000"); break;
|
case 11: strcpy(precrc_bitstream, "0000000100000000"); if(debug) { printf("Scheme 11\n"); } break;
|
||||||
case 27: strcpy(precrc_bitstream, "0000001000000000"); break;
|
case 27: strcpy(precrc_bitstream, "0000001000000000"); if(debug) { printf("Scheme 27\n"); } break;
|
||||||
case 41: strcpy(precrc_bitstream, "0000001100000000"); break;
|
case 41: strcpy(precrc_bitstream, "0000001100000000"); if(debug) { printf("Scheme 41\n"); } break;
|
||||||
case 37: strcpy(precrc_bitstream, "0000010000000000"); break;
|
case 37: strcpy(precrc_bitstream, "0000010000000000"); if(debug) { printf("Scheme 37\n"); } break;
|
||||||
default: strcpy(precrc_bitstream, "0000010100000000"); break;
|
default: strcpy(precrc_bitstream, "0000010100000000"); if(debug) { printf("Scheme DE\n"); } break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 0; i < input_length; i++) {
|
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] & 0x02) { concat(precrc_bitstream, "1"); } else { concat(precrc_bitstream, "0"); }
|
||||||
if(source[i] & 0x01) { 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 */
|
/* pre-CRC bit stream byte reversal */
|
||||||
for(i = 0; i < (input_length + 2); i++) {
|
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';
|
precrc_bitstream_reversed[strlen(precrc_bitstream)] = '\0';
|
||||||
machine_cycles = strlen(precrc_bitstream_reversed);
|
machine_cycles = strlen(precrc_bitstream_reversed);
|
||||||
|
if(debug) { printf("Reversed CRC bitstream:\n%s\n", precrc_bitstream_reversed); }
|
||||||
|
|
||||||
/* Start up the machine */
|
/* Start up the machine */
|
||||||
for(i = 0; i < 16; i++) {
|
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[i + 5] = xor_register[15 - i];
|
||||||
}
|
}
|
||||||
data_prefix_bitstream[16 + 5] = '\0';
|
data_prefix_bitstream[16 + 5] = '\0';
|
||||||
|
if(debug) { printf("Data Prefix:\n%s\n", data_prefix_bitstream); }
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -704,10 +707,6 @@ void protect_ecc080(char protected_stream[], char unprotected_stream[])
|
|||||||
{
|
{
|
||||||
/* ECC 080 - 3-2-11 convolutional code */
|
/* ECC 080 - 3-2-11 convolutional code */
|
||||||
/* State machine illustrated in figure K2 */
|
/* 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 top_reg[12];
|
||||||
char low_reg[12];
|
char low_reg[12];
|
||||||
char u1, u2;
|
char u1, u2;
|
||||||
@ -743,7 +742,7 @@ void protect_ecc080(char protected_stream[], char unprotected_stream[])
|
|||||||
|
|
||||||
gate_input[0] = u1;
|
gate_input[0] = u1;
|
||||||
gate_input[1] = top_reg[0];
|
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[3] = top_reg[4];
|
||||||
gate_input[4] = top_reg[5];
|
gate_input[4] = top_reg[5];
|
||||||
gate_input[5] = top_reg[6];
|
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[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[2] = top_reg[4];
|
||||||
gate_input[3] = top_reg[7];
|
gate_input[3] = top_reg[7];
|
||||||
gate_input[4] = top_reg[8];
|
gate_input[4] = top_reg[8];
|
||||||
|
Loading…
Reference in New Issue
Block a user