2 * code128.c -- encoding for code128 (A, B, C)
4 * Copyright (c) 1999,2000 Alessandro Rubini (rubini@gnu.org)
5 * Copyright (c) 1999 Prosa Srl. (prosa@prosa.it)
6 * Copyright (c) 2000 Leonid A. Broukhis (leob@mailcom.com)
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
31 static char *codeset[] = {
32 "212222", "222122", "222221", "121223", "121322", /* 0 - 4 */
33 "131222", "122213", "122312", "132212", "221213",
34 "221312", "231212", "112232", "122132", "122231", /* 10 - 14 */
35 "113222", "123122", "123221", "223211", "221132",
36 "221231", "213212", "223112", "312131", "311222", /* 20 - 24 */
37 "321122", "321221", "312212", "322112", "322211",
38 "212123", "212321", "232121", "111323", "131123", /* 30 - 34 */
39 "131321", "112313", "132113", "132311", "211313",
40 "231113", "231311", "112133", "112331", "132131", /* 40 - 44 */
41 "113123", "113321", "133121", "313121", "211331",
42 "231131", "213113", "213311", "213131", "311123", /* 50 - 54 */
43 "311321", "331121", "312113", "312311", "332111",
44 "314111", "221411", "431111", "111224", "111422", /* 60 - 64 */
45 "121124", "121421", "141122", "141221", "112214",
46 "112412", "122114", "122411", "142112", "142211", /* 70 - 74 */
47 "241211", "221114", "413111", "241112", "134111",
48 "111242", "121142", "121241", "114212", "124112", /* 80 - 84 */
49 "124211", "411212", "421112", "421211", "212141",
50 "214121", "412121", "111143", "111341", "131141", /* 90 - 94 */
51 "114113", "114311", "411113", "411311", "113141",
52 "114131", "311141", "411131", "b1a4a2", "b1a2a4", /* 100 - 104 */
60 #define SHIFT 98 /* only A and B */
61 #define CODE_A 101 /* only B and C */
62 #define CODE_B 100 /* only A and C */
63 #define CODE_C 99 /* only A and B */
64 #define FUNC_1 102 /* all of them */
65 #define FUNC_2 97 /* only A and B */
66 #define FUNC_3 96 /* only A and B */
67 /* FUNC_4 is CODE_A when in A and CODE_B when in B */
69 #define SYMBOL_WID 11 /* all of them are 11-bar wide */
72 * code 128-b includes all printable ascii chars
75 int Barcode_128b_verify(unsigned char *text)
79 while (*text && *text>=32 && !(*text&0x80))
82 return -1; /* a non-ascii char */
86 int Barcode_128b_encode(struct Barcode_Item *bc)
89 static char *partial; /* dynamic */
90 static char *textinfo; /* dynamic */
92 int i, code, textpos, checksum = 0;
98 bc->partial = bc->textinfo = NULL; /* safe */
101 bc->encoding = strdup("code 128-B");
108 /* the partial code is 6* (head + text + check + tail) + final + term. */
109 partial = malloc( (strlen(text) + 4) * 6 +2);
115 /* the text information is at most "nnn:fff:c " * strlen +term */
116 textinfo = malloc(10*strlen(text) + 2);
123 /* up to now, it was the same code as other encodings */
125 strcpy(partial, "0"); /* the first space */
126 strcat(partial, codeset[START_B]);
127 checksum += START_B; /* the start char is counted in the checksum */
129 textpos = SYMBOL_WID;
131 for (i=0; i<strlen(text); i++) {
132 if ( text[i] < 32 || (text[i] & 0x80)) {
133 bc->error = EINVAL; /* impossible if text is verified */
139 strcat(partial, codeset[code]);
140 checksum += code * (i+1); /* first * 1 + second * 2 + third * 3... */
141 sprintf(textptr, "%i:12:%c ", textpos, text[i]);
142 textptr += strlen(textptr);
143 textpos += SYMBOL_WID; /* width of each code */
145 /* Add the checksum, independent of BARCODE_NO_CHECKSUM */
147 strcat(partial, codeset[checksum]);
148 /* and the end marker */
149 strcat(partial, codeset[STOP]);
151 bc->partial = partial;
152 bc->textinfo = textinfo;
158 * code 128-c is only digits, but two per symbol
161 int Barcode_128c_verify(unsigned char *text)
165 /* must be an even number of digits */
168 /* and must be all digits */
169 for (; *text; text++)
175 int Barcode_128c_encode(struct Barcode_Item *bc)
178 static char *partial; /* dynamic */
179 static char *textinfo; /* dynamic */
181 int i, code, textpos, checksum = 0;
187 bc->partial = bc->textinfo = NULL; /* safe */
190 bc->encoding = strdup("code 128-C");
197 /* the partial code is 6* (head + text + check + tail) + final + term. */
198 partial = malloc( (strlen(text) + 3) * 6 +2);
204 /* the text information is at most "nnn.5:fff:c " * strlen +term */
205 textinfo = malloc(12*strlen(text) + 2);
212 strcpy(partial, "0"); /* the first space */
213 strcat(partial, codeset[START_C]);
214 checksum += START_C; /* the start char is counted in the checksum */
216 textpos = SYMBOL_WID;
218 for (i=0; text[i]; i+=2) {
219 if (!isdigit(text[i]) || !isdigit(text[i+1])) {
220 bc->error = EINVAL; /* impossible if text is verified */
225 code = (text[i]-'0') * 10 + text[i+1]-'0';
226 strcat(partial, codeset[code]);
227 checksum += code * (i/2+1); /* first * 1 + second * 2 + third * 3... */
229 /* print as "%s", because we have ".5" positions */
230 sprintf(textptr, "%g:9:%c %g:9:%c ", (double)textpos, text[i],
231 textpos + (double)SYMBOL_WID/2, text[i+1]);
232 textptr += strlen(textptr);
233 textpos += SYMBOL_WID; /* width of each code */
235 /* Add the checksum, independent of BARCODE_NO_CHECKSUM */
237 strcat(partial, codeset[checksum]);
238 /* and the end marker */
239 strcat(partial, codeset[STOP]);
241 bc->partial = partial;
242 bc->textinfo = textinfo;
248 * generic (full-featured) code128 implementation: it selects between
249 * A, B, C according to the data being encoded. F1, F2, F3, F4 are expressed
250 * using ascii chars 0xc1, 0xc2, 0xc3, 0xc4 (0301, 0302, 0303, 0304).
251 * Char '\0' is expressed by 0x80 (0200).
254 int Barcode_128_verify(unsigned char *text)
258 while (*text && (*text<=0x80 || (*text >= 0xc1 && *text <= 0xc4)))
261 return -1; /* unencodable character */
267 * These functions are extracted from Barcode_128_encode for clarity.
268 * It deals with choosing the symbols used to represent the text
269 * and returns a dynamic array of integers, terminated by -1.
271 * The algorithm used in choosing the codes comes from App 2 of
272 * "El Codigo Estandar EAN/UCC 128", courtesy of AECOC, Spain.
273 * Thanks to Dani Pardo for getting permission and giving me a copy
277 #define NEED_CODE_A(c) ((c)<32 || (c)==0x80)
278 #define NEED_CODE_B(c) ((c)>=96 && (c)<128)
280 static int Barcode_a_or_b(unsigned char *text)
282 for ( ; *text; text++) {
283 if (NEED_CODE_A(*text))
285 if (NEED_CODE_B(*text))
291 /* code is either 'A' or 'B', and value must be valid */
292 static int Barcode_encode_as(int code, int value)
295 /* first check the special chars */
296 if (value == 0xC1) return FUNC_1;
297 if (value == 0xC2) return FUNC_2;
298 if (value == 0xC3) return FUNC_3;
299 if (value == 0xC4) { /* F4 */
300 if (code == 'A') return CODE_A;
304 /* then check ascii values */
305 if (value >= 0x20 && value <= 0x5F)
306 return value - 0x20; /* both codes */
307 if (value == 0x80) return 64; /* code A */
308 if (value < 0x20) return value+64; /* code A */
309 if (value >= 0x60) return value - 0x20; /* code B */
314 static int *Barcode_128_make_array(struct Barcode_Item *bc, int *lptr)
318 int i=0, j, code, checksum;
320 /* allocate twice the text length + 5, as this is the worst case */
321 len = 2 * strlen(bc->ascii) + 5;
322 codes = malloc(len * sizeof(int));
325 /* choose the starting code */
326 if (s[2]=='\0' && isdigit(s[0]) && isdigit(s[1])) {
328 } else if (isdigit(s[0])&&isdigit(s[1]) && isdigit(s[2])&&isdigit(s[3])) {
331 code = Barcode_a_or_b(s);
332 if (!code) code = 'B'; /* default */
334 codes[i++] = START_A + code - 'A';
336 for (s = bc->ascii; *s; /* increments are in the loop */) {
340 if (s[0] == 0xC1) { /* F1 is valid */
343 } else if (isdigit(s[0]) && isdigit(s[1])) {
344 /* encode two digits */
345 codes[i++] = (s[0]-'0') * 10 + s[1]-'0';
349 code = Barcode_a_or_b(s);
350 if (!code) code = 'B';
351 codes[i++] = (code == 'A') ? CODE_A : CODE_B;
357 for (j=0; isdigit(s[j]); j++)
359 if (j>=4) { /* if there are 4 or more digits, turn to C */
361 /* odd number: encode one first */
362 codes[i++] = *(s++) - ' ';
366 } else if (code == 'A' && NEED_CODE_B(*s)) {
367 /* check whether we should use SHIFT or change code */
368 j = Barcode_a_or_b(s+1);
374 codes[i++] = Barcode_encode_as('B', *s);
377 } else if (code == 'B' && NEED_CODE_A(*s)) {
378 /* check whether we should use SHIFT or change code */
379 j = Barcode_a_or_b(s+1);
385 codes[i++] = Barcode_encode_as('A', *s);
389 codes[i++] = Barcode_encode_as(code, *s);
395 /* add the checksum */
398 checksum += j * codes[j];
400 codes[i++] = checksum;
403 fprintf(stderr, "impossible: length is > allocated len\n");
410 * Encoding is tricky, in that we cannot print the ascii
411 * representation in an easy way. Therefore, just skip non-printable
412 * chars and try to fit the rest somehow.
414 int Barcode_128_encode(struct Barcode_Item *bc)
417 static char *partial; /* dynamic */
418 static char *textinfo; /* dynamic */
420 int *codes; /* dynamic */
422 double textpos, size, step;
428 bc->partial = bc->textinfo = NULL; /* safe */
431 bc->encoding = strdup("code 128");
439 codes = Barcode_128_make_array(bc, &len);
440 if (!codes) return -1;
442 /* the partial code is 6*codelen + ini + term (+margin) */
443 partial = malloc( 6 * len + 4);
450 /* the text information is at most "nnn.n:ff.f:c " * strlen +term */
451 textptr = textinfo = malloc(13*strlen(text) + 2);
459 /* up to now, it was almost the same code as other encodings */
461 strcpy(partial, "0"); /* the first space */
462 for (i=0; i<len; i++) /* the symbols */
463 strcat(partial, codeset[codes[i]]);
465 /* avoid bars that fall lower than other bars */
466 for (i=0; partial[i]; i++)
467 if (isalpha(partial[i]))
468 partial[i] += '1' - 'a';
471 * the accompanying text: reserve a space for every char.
472 * F[1-4] are rendered as spaces (separators), other unprintable chars
473 * are rendered as underscoress (placeholders)
477 * A size of 9 is good for code-C (used above), so 18 for each symbol,
478 * but we place an upper limit of 12 to avoid overlapping on the bars.
480 size = (int)(180.0 * (len-3) / strlen(text) + .5) / 10.0;
481 if (size > 12.0) size = 12.0;
483 /* align the text to the left, using its natural size */
484 step = (int)(10 * (size/18.0 * SYMBOL_WID) + .5) / 10.0;
485 textpos = SYMBOL_WID;
487 for (i=0; i<strlen(text); i++) {
489 if (c < 32 || c == 0x80) c = '_'; /* not printable */
490 if (c > 0xc0) c = ' '; /* F code */
491 sprintf(textptr, "%g:%g:%c ", textpos, size, c);
492 textptr += strlen(textptr);
496 bc->partial = partial;
497 bc->textinfo = textinfo;
503 * A raw 128 code is given as a sequence of space separated numbers
504 * from 0 to 105, starting from the start code to be (Leonid)
507 int Barcode_128raw_verify(unsigned char *text)
515 if (sscanf(text, "%u%n", &val, &n) < 1)
524 int Barcode_128raw_encode(struct Barcode_Item *bc)
527 static char *partial; /* dynamic */
528 static char *textinfo; /* dynamic */
530 int i, n, count, code, textpos, checksum = 0;
536 bc->partial = bc->textinfo = NULL; /* safe */
539 bc->encoding = strdup("128raw");
547 * length of partial code is unknown in advance, but it is
548 * at most 6* (1+text/2 + check + tail) + final + terminator
550 partial = malloc( (3+ strlen(text)/2) * 6 + 2);
556 /* the text information is at most "nnn.5:fff:c " * 1+strlen/2 +term */
557 textinfo = malloc(12 * (1+strlen(text)/2) + 2);
564 strcpy(partial, "0"); /* the first space */
568 for (i=0, count = 0; i < strlen(text); count++) {
569 if (sscanf(text + i, "%u%n", &code, &n) < 1) {
570 bc->error = EINVAL; /* impossible if text is verified */
575 strcat(partial, codeset[code]);
578 * since the start code is part of the "raw" input, it is
579 * counted in the checksum by itself
581 if (!count) checksum += code; /* the start code */
582 else checksum += code * count; /* first * 1 + second * 2 ... */
585 * print as "%s", because we have ".5" positions
586 * also, use a size of 9 like codeC above, as each symbol is
587 * represented by two chars
589 sprintf(textptr, "%g:9:%c %g:9:%c ", (double)textpos,
590 code >= 100 ? 'A' : code/10 + '0',
591 textpos + (double)SYMBOL_WID/2, code%10 + '0');
592 textptr += strlen(textptr);
593 textpos += SYMBOL_WID; /* width of each code */
596 /* Add the checksum, independent of BARCODE_NO_CHECKSUM */
598 strcat(partial, codeset[checksum]);
599 /* and the end marker */
600 strcat(partial, codeset[STOP]);
602 bc->partial = partial;
603 bc->textinfo = textinfo;