diff options
Diffstat (limited to 'glabels1/barcode-0.98/code128.c')
-rw-r--r-- | glabels1/barcode-0.98/code128.c | 607 |
1 files changed, 0 insertions, 607 deletions
diff --git a/glabels1/barcode-0.98/code128.c b/glabels1/barcode-0.98/code128.c deleted file mode 100644 index cebba54..0000000 --- a/glabels1/barcode-0.98/code128.c +++ /dev/null @@ -1,607 +0,0 @@ -/* - * code128.c -- encoding for code128 (A, B, C) - * - * Copyright (c) 1999,2000 Alessandro Rubini (rubini@gnu.org) - * Copyright (c) 1999 Prosa Srl. (prosa@prosa.it) - * Copyright (c) 2000 Leonid A. Broukhis (leob@mailcom.com) - * - * 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 2 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <errno.h> - -#include "barcode.h" - -static char *codeset[] = { - "212222", "222122", "222221", "121223", "121322", /* 0 - 4 */ - "131222", "122213", "122312", "132212", "221213", - "221312", "231212", "112232", "122132", "122231", /* 10 - 14 */ - "113222", "123122", "123221", "223211", "221132", - "221231", "213212", "223112", "312131", "311222", /* 20 - 24 */ - "321122", "321221", "312212", "322112", "322211", - "212123", "212321", "232121", "111323", "131123", /* 30 - 34 */ - "131321", "112313", "132113", "132311", "211313", - "231113", "231311", "112133", "112331", "132131", /* 40 - 44 */ - "113123", "113321", "133121", "313121", "211331", - "231131", "213113", "213311", "213131", "311123", /* 50 - 54 */ - "311321", "331121", "312113", "312311", "332111", - "314111", "221411", "431111", "111224", "111422", /* 60 - 64 */ - "121124", "121421", "141122", "141221", "112214", - "112412", "122114", "122411", "142112", "142211", /* 70 - 74 */ - "241211", "221114", "413111", "241112", "134111", - "111242", "121142", "121241", "114212", "124112", /* 80 - 84 */ - "124211", "411212", "421112", "421211", "212141", - "214121", "412121", "111143", "111341", "131141", /* 90 - 94 */ - "114113", "114311", "411113", "411311", "113141", - "114131", "311141", "411131", "b1a4a2", "b1a2a4", /* 100 - 104 */ - "b1a2c2", "b3c1a1b" -}; - -#define START_A 103 -#define START_B 104 -#define START_C 105 -#define STOP 106 -#define SHIFT 98 /* only A and B */ -#define CODE_A 101 /* only B and C */ -#define CODE_B 100 /* only A and C */ -#define CODE_C 99 /* only A and B */ -#define FUNC_1 102 /* all of them */ -#define FUNC_2 97 /* only A and B */ -#define FUNC_3 96 /* only A and B */ -/* FUNC_4 is CODE_A when in A and CODE_B when in B */ - -#define SYMBOL_WID 11 /* all of them are 11-bar wide */ - -/* - * code 128-b includes all printable ascii chars - */ - -int Barcode_128b_verify(unsigned char *text) -{ - if (text[0] == '\0') - return -1; - while (*text && *text>=32 && !(*text&0x80)) - text++; - if (*text) - return -1; /* a non-ascii char */ - return 0; /* ok */ -} - -int Barcode_128b_encode(struct Barcode_Item *bc) -{ - static char *text; - static char *partial; /* dynamic */ - static char *textinfo; /* dynamic */ - char *textptr; - int i, code, textpos, checksum = 0; - - if (bc->partial) - free(bc->partial); - if (bc->textinfo) - free(bc->textinfo); - bc->partial = bc->textinfo = NULL; /* safe */ - - if (!bc->encoding) - bc->encoding = strdup("code 128-B"); - - text = bc->ascii; - if (!text) { - bc->error = EINVAL; - return -1; - } - /* the partial code is 6* (head + text + check + tail) + final + term. */ - partial = malloc( (strlen(text) + 4) * 6 +2); - if (!partial) { - bc->error = errno; - return -1; - } - - /* the text information is at most "nnn:fff:c " * strlen +term */ - textinfo = malloc(10*strlen(text) + 2); - if (!textinfo) { - bc->error = errno; - free(partial); - return -1; - } - - /* up to now, it was the same code as other encodings */ - - strcpy(partial, "0"); /* the first space */ - strcat(partial, codeset[START_B]); - checksum += START_B; /* the start char is counted in the checksum */ - textptr = textinfo; - textpos = SYMBOL_WID; - - for (i=0; i<strlen(text); i++) { - if ( text[i] < 32 || (text[i] & 0x80)) { - bc->error = EINVAL; /* impossible if text is verified */ - free(partial); - free(textinfo); - return -1; - } - code = text[i]-32; - strcat(partial, codeset[code]); - checksum += code * (i+1); /* first * 1 + second * 2 + third * 3... */ - sprintf(textptr, "%i:12:%c ", textpos, text[i]); - textptr += strlen(textptr); - textpos += SYMBOL_WID; /* width of each code */ - } - /* Add the checksum, independent of BARCODE_NO_CHECKSUM */ - checksum %= 103; - strcat(partial, codeset[checksum]); - /* and the end marker */ - strcat(partial, codeset[STOP]); - - bc->partial = partial; - bc->textinfo = textinfo; - - return 0; -} - -/* - * code 128-c is only digits, but two per symbol - */ - -int Barcode_128c_verify(unsigned char *text) -{ - if (text[0] == '\0') - return -1; - /* must be an even number of digits */ - if (strlen(text)%2) - return -1; - /* and must be all digits */ - for (; *text; text++) - if (!isdigit(*text)) - return -1; - return 0; -} - -int Barcode_128c_encode(struct Barcode_Item *bc) -{ - static char *text; - static char *partial; /* dynamic */ - static char *textinfo; /* dynamic */ - char *textptr; - int i, code, textpos, checksum = 0; - - if (bc->partial) - free(bc->partial); - if (bc->textinfo) - free(bc->textinfo); - bc->partial = bc->textinfo = NULL; /* safe */ - - if (!bc->encoding) - bc->encoding = strdup("code 128-C"); - - text = bc->ascii; - if (!text) { - bc->error = EINVAL; - return -1; - } - /* the partial code is 6* (head + text + check + tail) + final + term. */ - partial = malloc( (strlen(text) + 3) * 6 +2); - if (!partial) { - bc->error = errno; - return -1; - } - - /* the text information is at most "nnn.5:fff:c " * strlen +term */ - textinfo = malloc(12*strlen(text) + 2); - if (!textinfo) { - bc->error = errno; - free(partial); - return -1; - } - - strcpy(partial, "0"); /* the first space */ - strcat(partial, codeset[START_C]); - checksum += START_C; /* the start char is counted in the checksum */ - textptr = textinfo; - textpos = SYMBOL_WID; - - for (i=0; text[i]; i+=2) { - if (!isdigit(text[i]) || !isdigit(text[i+1])) { - bc->error = EINVAL; /* impossible if text is verified */ - free(partial); - free(textinfo); - return -1; - } - code = (text[i]-'0') * 10 + text[i+1]-'0'; - strcat(partial, codeset[code]); - checksum += code * (i/2+1); /* first * 1 + second * 2 + third * 3... */ - - /* print as "%s", because we have ".5" positions */ - sprintf(textptr, "%g:9:%c %g:9:%c ", (double)textpos, text[i], - textpos + (double)SYMBOL_WID/2, text[i+1]); - textptr += strlen(textptr); - textpos += SYMBOL_WID; /* width of each code */ - } - /* Add the checksum, independent of BARCODE_NO_CHECKSUM */ - checksum %= 103; - strcat(partial, codeset[checksum]); - /* and the end marker */ - strcat(partial, codeset[STOP]); - - bc->partial = partial; - bc->textinfo = textinfo; - - return 0; -} - -/* - * generic (full-featured) code128 implementation: it selects between - * A, B, C according to the data being encoded. F1, F2, F3, F4 are expressed - * using ascii chars 0xc1, 0xc2, 0xc3, 0xc4 (0301, 0302, 0303, 0304). - * Char '\0' is expressed by 0x80 (0200). - */ - -int Barcode_128_verify(unsigned char *text) -{ - if (text[0] == '\0') - return -1; - while (*text && (*text<=0x80 || (*text >= 0xc1 && *text <= 0xc4))) - text++; - if (*text) - return -1; /* unencodable character */ - return 0; /* ok */ -} - - -/* - * These functions are extracted from Barcode_128_encode for clarity. - * It deals with choosing the symbols used to represent the text - * and returns a dynamic array of integers, terminated by -1. - * - * The algorithm used in choosing the codes comes from App 2 of - * "El Codigo Estandar EAN/UCC 128", courtesy of AECOC, Spain. - * Thanks to Dani Pardo for getting permission and giving me a copy - * of the document - */ - -#define NEED_CODE_A(c) ((c)<32 || (c)==0x80) -#define NEED_CODE_B(c) ((c)>=96 && (c)<128) - -static int Barcode_a_or_b(unsigned char *text) -{ - for ( ; *text; text++) { - if (NEED_CODE_A(*text)) - return 'A'; - if (NEED_CODE_B(*text)) - return 'B'; - } - return 0; /* any */ -} - -/* code is either 'A' or 'B', and value must be valid */ -static int Barcode_encode_as(int code, int value) -{ - - /* first check the special chars */ - if (value == 0xC1) return FUNC_1; - if (value == 0xC2) return FUNC_2; - if (value == 0xC3) return FUNC_3; - if (value == 0xC4) { /* F4 */ - if (code == 'A') return CODE_A; - return CODE_B; - } - - /* then check ascii values */ - if (value >= 0x20 && value <= 0x5F) - return value - 0x20; /* both codes */ - if (value == 0x80) return 64; /* code A */ - if (value < 0x20) return value+64; /* code A */ - if (value >= 0x60) return value - 0x20; /* code B */ - /* can't happen */ - return -1; -} - -static int *Barcode_128_make_array(struct Barcode_Item *bc, int *lptr) -{ - int len, *codes; - unsigned char *s; - int i=0, j, code, checksum; - - /* allocate twice the text length + 5, as this is the worst case */ - len = 2 * strlen(bc->ascii) + 5; - codes = malloc(len * sizeof(int)); - s = bc->ascii; - - /* choose the starting code */ - if (s[2]=='\0' && isdigit(s[0]) && isdigit(s[1])) { - code = 'C'; - } else if (isdigit(s[0])&&isdigit(s[1]) && isdigit(s[2])&&isdigit(s[3])) { - code = 'C'; - } else { - code = Barcode_a_or_b(s); - if (!code) code = 'B'; /* default */ - } - codes[i++] = START_A + code - 'A'; - - for (s = bc->ascii; *s; /* increments are in the loop */) { - switch(code) { - - case 'C': - if (s[0] == 0xC1) { /* F1 is valid */ - codes[i++] = FUNC_1; - s++; - } else if (isdigit(s[0]) && isdigit(s[1])) { - /* encode two digits */ - codes[i++] = (s[0]-'0') * 10 + s[1]-'0'; - s += 2; - } else { - /* change code */ - code = Barcode_a_or_b(s); - if (!code) code = 'B'; - codes[i++] = (code == 'A') ? CODE_A : CODE_B; - } - break; - - case 'B': - case 'A': - for (j=0; isdigit(s[j]); j++) - ; - if (j>=4) { /* if there are 4 or more digits, turn to C */ - if (j&1) { - /* odd number: encode one first */ - codes[i++] = *(s++) - ' '; - } - codes[i++] = CODE_C; - code = 'C'; - } else if (code == 'A' && NEED_CODE_B(*s)) { - /* check whether we should use SHIFT or change code */ - j = Barcode_a_or_b(s+1); - if (j == 'B') { - codes[i++] = CODE_B; - code = 'B'; - } else { - codes[i++] = SHIFT; - codes[i++] = Barcode_encode_as('B', *s); - s++; - } - } else if (code == 'B' && NEED_CODE_A(*s)) { - /* check whether we should use SHIFT or change code */ - j = Barcode_a_or_b(s+1); - if (j == 'A') { - codes[i++] = CODE_A; - code = 'A'; - } else { - codes[i++] = SHIFT; - codes[i++] = Barcode_encode_as('A', *s); - s++; - } - } else { - codes[i++] = Barcode_encode_as(code, *s); - s++; - } - break; - } - } - /* add the checksum */ - checksum = codes[0]; - for (j=1; j<i; j++) - checksum += j * codes[j]; - checksum %= 103; - codes[i++] = checksum; - codes[i++] = STOP; - if (i > len) { - fprintf(stderr, "impossible: length is > allocated len\n"); - } - *lptr = i; - return codes; -} - -/* - * Encoding is tricky, in that we cannot print the ascii - * representation in an easy way. Therefore, just skip non-printable - * chars and try to fit the rest somehow. - */ -int Barcode_128_encode(struct Barcode_Item *bc) -{ - static char *text; - static char *partial; /* dynamic */ - static char *textinfo; /* dynamic */ - char *textptr; - int *codes; /* dynamic */ - int i, c, len; - double textpos, size, step; - - if (bc->partial) - free(bc->partial); - if (bc->textinfo) - free(bc->textinfo); - bc->partial = bc->textinfo = NULL; /* safe */ - - if (!bc->encoding) - bc->encoding = strdup("code 128"); - - text = bc->ascii; - if (!text) { - bc->error = EINVAL; - return -1; - } - - codes = Barcode_128_make_array(bc, &len); - if (!codes) return -1; - - /* the partial code is 6*codelen + ini + term (+margin) */ - partial = malloc( 6 * len + 4); - if (!partial) { - bc->error = errno; - free(codes); - return -1; - } - - /* the text information is at most "nnn.n:ff.f:c " * strlen +term */ - textptr = textinfo = malloc(13*strlen(text) + 2); - if (!textinfo) { - bc->error = errno; - free(partial); - free(codes); - return -1; - } - - /* up to now, it was almost the same code as other encodings */ - - strcpy(partial, "0"); /* the first space */ - for (i=0; i<len; i++) /* the symbols */ - strcat(partial, codeset[codes[i]]); - - /* avoid bars that fall lower than other bars */ - for (i=0; partial[i]; i++) - if (isalpha(partial[i])) - partial[i] += '1' - 'a'; - - /* - * the accompanying text: reserve a space for every char. - * F[1-4] are rendered as spaces (separators), other unprintable chars - * are rendered as underscoress (placeholders) - */ - - /* - * A size of 9 is good for code-C (used above), so 18 for each symbol, - * but we place an upper limit of 12 to avoid overlapping on the bars. - */ - size = (int)(180.0 * (len-3) / strlen(text) + .5) / 10.0; - if (size > 12.0) size = 12.0; - - /* align the text to the left, using its natural size */ - step = (int)(10 * (size/18.0 * SYMBOL_WID) + .5) / 10.0; - textpos = SYMBOL_WID; - - for (i=0; i<strlen(text); i++) { - c = text[i]; - if (c < 32 || c == 0x80) c = '_'; /* not printable */ - if (c > 0xc0) c = ' '; /* F code */ - sprintf(textptr, "%g:%g:%c ", textpos, size, c); - textptr += strlen(textptr); - textpos += step; - } - - bc->partial = partial; - bc->textinfo = textinfo; - free(codes); - return 0; -} - -/* - * A raw 128 code is given as a sequence of space separated numbers - * from 0 to 105, starting from the start code to be (Leonid) - */ - -int Barcode_128raw_verify(unsigned char *text) -{ - int n; - unsigned val; - - if (!strlen(text)) - return -1; - while (*text) { - if (sscanf(text, "%u%n", &val, &n) < 1) - return -1; - if (val > 105) - return -1; - text += n; - } - return 0; -} - -int Barcode_128raw_encode(struct Barcode_Item *bc) -{ - static char *text; - static char *partial; /* dynamic */ - static char *textinfo; /* dynamic */ - char *textptr; - int i, n, count, code, textpos, checksum = 0; - - if (bc->partial) - free(bc->partial); - if (bc->textinfo) - free(bc->textinfo); - bc->partial = bc->textinfo = NULL; /* safe */ - - if (!bc->encoding) - bc->encoding = strdup("128raw"); - - text = bc->ascii; - if (!text) { - bc->error = EINVAL; - return -1; - } - /* - * length of partial code is unknown in advance, but it is - * at most 6* (1+text/2 + check + tail) + final + terminator - */ - partial = malloc( (3+ strlen(text)/2) * 6 + 2); - if (!partial) { - bc->error = errno; - return -1; - } - - /* the text information is at most "nnn.5:fff:c " * 1+strlen/2 +term */ - textinfo = malloc(12 * (1+strlen(text)/2) + 2); - if (!textinfo) { - bc->error = errno; - free(partial); - return -1; - } - - strcpy(partial, "0"); /* the first space */ - textptr = textinfo; - textpos = 0; - - for (i=0, count = 0; i < strlen(text); count++) { - if (sscanf(text + i, "%u%n", &code, &n) < 1) { - bc->error = EINVAL; /* impossible if text is verified */ - free(partial); - free(textinfo); - return -1; - } - strcat(partial, codeset[code]); - - /* - * since the start code is part of the "raw" input, it is - * counted in the checksum by itself - */ - if (!count) checksum += code; /* the start code */ - else checksum += code * count; /* first * 1 + second * 2 ... */ - - /* - * print as "%s", because we have ".5" positions - * also, use a size of 9 like codeC above, as each symbol is - * represented by two chars - */ - sprintf(textptr, "%g:9:%c %g:9:%c ", (double)textpos, - code >= 100 ? 'A' : code/10 + '0', - textpos + (double)SYMBOL_WID/2, code%10 + '0'); - textptr += strlen(textptr); - textpos += SYMBOL_WID; /* width of each code */ - i += n; - } - /* Add the checksum, independent of BARCODE_NO_CHECKSUM */ - checksum %= 103; - strcat(partial, codeset[checksum]); - /* and the end marker */ - strcat(partial, codeset[STOP]); - - bc->partial = partial; - bc->textinfo = textinfo; - - return 0; -} - |