gbarcode 0.98.16-mswin32

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,182 @@
1
+ /*
2
+ * codabar.c -- encoding for Codabar
3
+ *
4
+ * Copyright (c) 2000 Leonid A. Broukhis (leob@mailcom.com)
5
+ *
6
+ * This program is free software; you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License as published by
8
+ * the Free Software Foundation; either version 2 of the License, or
9
+ * (at your option) any later version.
10
+ *
11
+ * This program is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU General Public License
17
+ * along with this program; if not, write to the Free Software
18
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
19
+ */
20
+
21
+ #include <stdio.h>
22
+ #include <stdlib.h>
23
+ #include <string.h>
24
+ #include <ctype.h>
25
+ #include <errno.h>
26
+
27
+ #include "barcode.h"
28
+
29
+
30
+ /* this is ordered in decades to simplify encoding */
31
+ static char alphabet[] =
32
+ "0123456789" "-$:/.+ABCD";
33
+
34
+ #define CODE_A 16
35
+ #define CODE_B 17
36
+
37
+ #define NARROW 12
38
+ #define WIDE 14
39
+
40
+ /* Patterns */
41
+ static char *patterns[] = {
42
+ "1111133","1111331","1113113","3311111","1131131",
43
+ "3111131","1311113","1311311","1331111","3113111",
44
+ "1113311","1133111","3111313","3131113","3131311",
45
+ "1131313","1133131","1313113","1113133","1113331" };
46
+
47
+ /*
48
+ * Check that the text can be encoded. Returns 0 or -1.
49
+ * If it's all lowecase convert to uppercase and accept it.
50
+ * If the first character is a letter (A to D), the last one must be too;
51
+ * no other character should be a letter.
52
+ */
53
+ int Barcode_cbr_verify(unsigned char *text)
54
+ {
55
+ int i, lower=0, upper=0;
56
+ int startpresent = 0;
57
+
58
+ if (!strlen(text))
59
+ return -1;
60
+ for (i=0; text[i]; i++) {
61
+ char * pos;
62
+ if (isupper(text[i])) upper++;
63
+ if (islower(text[i])) lower++;
64
+ pos = strchr(alphabet,toupper(text[i]));
65
+ if (!pos)
66
+ return -1;
67
+ if (i == 0 && pos - alphabet >= CODE_A)
68
+ startpresent = 1;
69
+ else if (pos - alphabet >= CODE_A &&
70
+ (!startpresent || i != strlen(text) - 1))
71
+ return -1;
72
+ }
73
+ if (lower && upper)
74
+ return -1;
75
+ return 0;
76
+ }
77
+
78
+ static int add_one(char *ptr, int code)
79
+ {
80
+ sprintf(ptr,"1%s", /* separator */ patterns[code]);
81
+ return 0;
82
+ }
83
+
84
+ /*
85
+ * The encoding functions fills the "partial" and "textinfo" fields.
86
+ * Lowercase chars are converted to uppercase
87
+ */
88
+ int Barcode_cbr_encode(struct Barcode_Item *bc)
89
+ {
90
+ static char *text;
91
+ static char *partial; /* dynamic */
92
+ static char *textinfo; /* dynamic */
93
+ char *c, *ptr, *textptr;
94
+ int i, code, textpos, usesum, checksum = 0, startpresent;
95
+
96
+ if (bc->partial)
97
+ free(bc->partial);
98
+ if (bc->textinfo)
99
+ free(bc->textinfo);
100
+ bc->partial = bc->textinfo = NULL; /* safe */
101
+
102
+ if (!bc->encoding)
103
+ bc->encoding = strdup("codabar");
104
+
105
+ text = bc->ascii;
106
+ if (!text) {
107
+ bc->error = EINVAL;
108
+ return -1;
109
+ }
110
+ /* the partial code is 8 * (head + text + check + tail) + margin + term. */
111
+ partial = malloc( (strlen(text) + 3) * 8 + 2);
112
+ if (!partial) {
113
+ bc->error = errno;
114
+ return -1;
115
+ }
116
+
117
+ /* the text information is at most "nnn:fff:c " * (strlen + check) +term */
118
+ textinfo = malloc(10*(strlen(text) + 1) + 2);
119
+ if (!textinfo) {
120
+ bc->error = errno;
121
+ free(partial);
122
+ return -1;
123
+ }
124
+
125
+ ptr = partial;
126
+ textptr = textinfo;
127
+ textpos = 0;
128
+ usesum = bc->flags & BARCODE_NO_CHECKSUM ? 0 : 1;
129
+ /* if no start character specified, A is used as a start character */
130
+ if (!isalpha(text[0])) {
131
+ add_one(ptr, CODE_A);
132
+ ptr += strlen(ptr);
133
+ textpos = WIDE;
134
+ checksum = CODE_A;
135
+ startpresent = 0;
136
+ } else {
137
+ startpresent = 1;
138
+ }
139
+ for (i=0; i<strlen(text); i++) {
140
+ c = strchr(alphabet, toupper(text[i]));
141
+ if (!c) {
142
+ bc->error = EINVAL; /* impossible if text is verified */
143
+ free(partial);
144
+ free(textinfo);
145
+ return -1;
146
+ }
147
+ code = c - alphabet;
148
+ add_one(ptr, code);
149
+ sprintf(textptr, "%i:12:%c ", textpos, toupper(text[i]));
150
+ textpos += code < 12 ? NARROW : WIDE;
151
+ textptr += strlen(textptr);
152
+ ptr += strlen(ptr);
153
+ checksum += code;
154
+ if (startpresent && usesum && i == strlen(text) - 2) {
155
+ /* stuff a check symbol before the stop */
156
+ c = strchr(alphabet, toupper(text[i+1]));
157
+ if (!c) /* impossible */
158
+ continue;
159
+ code = c - alphabet;
160
+ checksum += code;
161
+
162
+ /* Complement to a multiple of 16 */
163
+ checksum = (checksum + 15) / 16 * 16 - checksum;
164
+ add_one(ptr, checksum);
165
+ ptr += strlen(ptr);
166
+ }
167
+ }
168
+ if (!startpresent) {
169
+ if (usesum) {
170
+ /* if no start character specified, B is used as a stop char */
171
+ checksum += CODE_B;
172
+ checksum = (checksum + 15) / 16 * 16 - checksum;
173
+ add_one(ptr, checksum);
174
+ ptr += strlen(ptr);
175
+ }
176
+ add_one(ptr, CODE_B);
177
+ }
178
+ bc->partial = partial;
179
+ bc->textinfo = textinfo;
180
+
181
+ return 0;
182
+ }
@@ -0,0 +1,607 @@
1
+ /*
2
+ * code128.c -- encoding for code128 (A, B, C)
3
+ *
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)
7
+ *
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.
12
+ *
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.
17
+ *
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.
21
+ */
22
+
23
+ #include <stdio.h>
24
+ #include <stdlib.h>
25
+ #include <string.h>
26
+ #include <ctype.h>
27
+ #include <errno.h>
28
+
29
+ #include "barcode.h"
30
+
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 */
53
+ "b1a2c2", "b3c1a1b"
54
+ };
55
+
56
+ #define START_A 103
57
+ #define START_B 104
58
+ #define START_C 105
59
+ #define STOP 106
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 */
68
+
69
+ #define SYMBOL_WID 11 /* all of them are 11-bar wide */
70
+
71
+ /*
72
+ * code 128-b includes all printable ascii chars
73
+ */
74
+
75
+ int Barcode_128b_verify(unsigned char *text)
76
+ {
77
+ if (text[0] == '\0')
78
+ return -1;
79
+ while (*text && *text>=32 && !(*text&0x80))
80
+ text++;
81
+ if (*text)
82
+ return -1; /* a non-ascii char */
83
+ return 0; /* ok */
84
+ }
85
+
86
+ int Barcode_128b_encode(struct Barcode_Item *bc)
87
+ {
88
+ static char *text;
89
+ static char *partial; /* dynamic */
90
+ static char *textinfo; /* dynamic */
91
+ char *textptr;
92
+ int i, code, textpos, checksum = 0;
93
+
94
+ if (bc->partial)
95
+ free(bc->partial);
96
+ if (bc->textinfo)
97
+ free(bc->textinfo);
98
+ bc->partial = bc->textinfo = NULL; /* safe */
99
+
100
+ if (!bc->encoding)
101
+ bc->encoding = strdup("code 128-B");
102
+
103
+ text = bc->ascii;
104
+ if (!text) {
105
+ bc->error = EINVAL;
106
+ return -1;
107
+ }
108
+ /* the partial code is 6* (head + text + check + tail) + final + term. */
109
+ partial = malloc( (strlen(text) + 4) * 6 +2);
110
+ if (!partial) {
111
+ bc->error = errno;
112
+ return -1;
113
+ }
114
+
115
+ /* the text information is at most "nnn:fff:c " * strlen +term */
116
+ textinfo = malloc(10*strlen(text) + 2);
117
+ if (!textinfo) {
118
+ bc->error = errno;
119
+ free(partial);
120
+ return -1;
121
+ }
122
+
123
+ /* up to now, it was the same code as other encodings */
124
+
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 */
128
+ textptr = textinfo;
129
+ textpos = SYMBOL_WID;
130
+
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 */
134
+ free(partial);
135
+ free(textinfo);
136
+ return -1;
137
+ }
138
+ code = text[i]-32;
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 */
144
+ }
145
+ /* Add the checksum, independent of BARCODE_NO_CHECKSUM */
146
+ checksum %= 103;
147
+ strcat(partial, codeset[checksum]);
148
+ /* and the end marker */
149
+ strcat(partial, codeset[STOP]);
150
+
151
+ bc->partial = partial;
152
+ bc->textinfo = textinfo;
153
+
154
+ return 0;
155
+ }
156
+
157
+ /*
158
+ * code 128-c is only digits, but two per symbol
159
+ */
160
+
161
+ int Barcode_128c_verify(unsigned char *text)
162
+ {
163
+ if (text[0] == '\0')
164
+ return -1;
165
+ /* must be an even number of digits */
166
+ if (strlen(text)%2)
167
+ return -1;
168
+ /* and must be all digits */
169
+ for (; *text; text++)
170
+ if (!isdigit(*text))
171
+ return -1;
172
+ return 0;
173
+ }
174
+
175
+ int Barcode_128c_encode(struct Barcode_Item *bc)
176
+ {
177
+ static char *text;
178
+ static char *partial; /* dynamic */
179
+ static char *textinfo; /* dynamic */
180
+ char *textptr;
181
+ int i, code, textpos, checksum = 0;
182
+
183
+ if (bc->partial)
184
+ free(bc->partial);
185
+ if (bc->textinfo)
186
+ free(bc->textinfo);
187
+ bc->partial = bc->textinfo = NULL; /* safe */
188
+
189
+ if (!bc->encoding)
190
+ bc->encoding = strdup("code 128-C");
191
+
192
+ text = bc->ascii;
193
+ if (!text) {
194
+ bc->error = EINVAL;
195
+ return -1;
196
+ }
197
+ /* the partial code is 6* (head + text + check + tail) + final + term. */
198
+ partial = malloc( (strlen(text) + 3) * 6 +2);
199
+ if (!partial) {
200
+ bc->error = errno;
201
+ return -1;
202
+ }
203
+
204
+ /* the text information is at most "nnn.5:fff:c " * strlen +term */
205
+ textinfo = malloc(12*strlen(text) + 2);
206
+ if (!textinfo) {
207
+ bc->error = errno;
208
+ free(partial);
209
+ return -1;
210
+ }
211
+
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 */
215
+ textptr = textinfo;
216
+ textpos = SYMBOL_WID;
217
+
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 */
221
+ free(partial);
222
+ free(textinfo);
223
+ return -1;
224
+ }
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... */
228
+
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 */
234
+ }
235
+ /* Add the checksum, independent of BARCODE_NO_CHECKSUM */
236
+ checksum %= 103;
237
+ strcat(partial, codeset[checksum]);
238
+ /* and the end marker */
239
+ strcat(partial, codeset[STOP]);
240
+
241
+ bc->partial = partial;
242
+ bc->textinfo = textinfo;
243
+
244
+ return 0;
245
+ }
246
+
247
+ /*
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).
252
+ */
253
+
254
+ int Barcode_128_verify(unsigned char *text)
255
+ {
256
+ if (text[0] == '\0')
257
+ return -1;
258
+ while (*text && (*text<=0x80 || (*text >= 0xc1 && *text <= 0xc4)))
259
+ text++;
260
+ if (*text)
261
+ return -1; /* unencodable character */
262
+ return 0; /* ok */
263
+ }
264
+
265
+
266
+ /*
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.
270
+ *
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
274
+ * of the document
275
+ */
276
+
277
+ #define NEED_CODE_A(c) ((c)<32 || (c)==0x80)
278
+ #define NEED_CODE_B(c) ((c)>=96 && (c)<128)
279
+
280
+ static int Barcode_a_or_b(unsigned char *text)
281
+ {
282
+ for ( ; *text; text++) {
283
+ if (NEED_CODE_A(*text))
284
+ return 'A';
285
+ if (NEED_CODE_B(*text))
286
+ return 'B';
287
+ }
288
+ return 0; /* any */
289
+ }
290
+
291
+ /* code is either 'A' or 'B', and value must be valid */
292
+ static int Barcode_encode_as(int code, int value)
293
+ {
294
+
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;
301
+ return CODE_B;
302
+ }
303
+
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 */
310
+ /* can't happen */
311
+ return -1;
312
+ }
313
+
314
+ static int *Barcode_128_make_array(struct Barcode_Item *bc, int *lptr)
315
+ {
316
+ int len, *codes;
317
+ unsigned char *s;
318
+ int i=0, j, code, checksum;
319
+
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));
323
+ s = bc->ascii;
324
+
325
+ /* choose the starting code */
326
+ if (s[2]=='\0' && isdigit(s[0]) && isdigit(s[1])) {
327
+ code = 'C';
328
+ } else if (isdigit(s[0])&&isdigit(s[1]) && isdigit(s[2])&&isdigit(s[3])) {
329
+ code = 'C';
330
+ } else {
331
+ code = Barcode_a_or_b(s);
332
+ if (!code) code = 'B'; /* default */
333
+ }
334
+ codes[i++] = START_A + code - 'A';
335
+
336
+ for (s = bc->ascii; *s; /* increments are in the loop */) {
337
+ switch(code) {
338
+
339
+ case 'C':
340
+ if (s[0] == 0xC1) { /* F1 is valid */
341
+ codes[i++] = FUNC_1;
342
+ s++;
343
+ } else if (isdigit(s[0]) && isdigit(s[1])) {
344
+ /* encode two digits */
345
+ codes[i++] = (s[0]-'0') * 10 + s[1]-'0';
346
+ s += 2;
347
+ } else {
348
+ /* change code */
349
+ code = Barcode_a_or_b(s);
350
+ if (!code) code = 'B';
351
+ codes[i++] = (code == 'A') ? CODE_A : CODE_B;
352
+ }
353
+ break;
354
+
355
+ case 'B':
356
+ case 'A':
357
+ for (j=0; isdigit(s[j]); j++)
358
+ ;
359
+ if (j>=4) { /* if there are 4 or more digits, turn to C */
360
+ if (j&1) {
361
+ /* odd number: encode one first */
362
+ codes[i++] = *(s++) - ' ';
363
+ }
364
+ codes[i++] = CODE_C;
365
+ code = 'C';
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);
369
+ if (j == 'B') {
370
+ codes[i++] = CODE_B;
371
+ code = 'B';
372
+ } else {
373
+ codes[i++] = SHIFT;
374
+ codes[i++] = Barcode_encode_as('B', *s);
375
+ s++;
376
+ }
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);
380
+ if (j == 'A') {
381
+ codes[i++] = CODE_A;
382
+ code = 'A';
383
+ } else {
384
+ codes[i++] = SHIFT;
385
+ codes[i++] = Barcode_encode_as('A', *s);
386
+ s++;
387
+ }
388
+ } else {
389
+ codes[i++] = Barcode_encode_as(code, *s);
390
+ s++;
391
+ }
392
+ break;
393
+ }
394
+ }
395
+ /* add the checksum */
396
+ checksum = codes[0];
397
+ for (j=1; j<i; j++)
398
+ checksum += j * codes[j];
399
+ checksum %= 103;
400
+ codes[i++] = checksum;
401
+ codes[i++] = STOP;
402
+ if (i > len) {
403
+ fprintf(stderr, "impossible: length is > allocated len\n");
404
+ }
405
+ *lptr = i;
406
+ return codes;
407
+ }
408
+
409
+ /*
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.
413
+ */
414
+ int Barcode_128_encode(struct Barcode_Item *bc)
415
+ {
416
+ static char *text;
417
+ static char *partial; /* dynamic */
418
+ static char *textinfo; /* dynamic */
419
+ char *textptr;
420
+ int *codes; /* dynamic */
421
+ int i, c, len;
422
+ double textpos, size, step;
423
+
424
+ if (bc->partial)
425
+ free(bc->partial);
426
+ if (bc->textinfo)
427
+ free(bc->textinfo);
428
+ bc->partial = bc->textinfo = NULL; /* safe */
429
+
430
+ if (!bc->encoding)
431
+ bc->encoding = strdup("code 128");
432
+
433
+ text = bc->ascii;
434
+ if (!text) {
435
+ bc->error = EINVAL;
436
+ return -1;
437
+ }
438
+
439
+ codes = Barcode_128_make_array(bc, &len);
440
+ if (!codes) return -1;
441
+
442
+ /* the partial code is 6*codelen + ini + term (+margin) */
443
+ partial = malloc( 6 * len + 4);
444
+ if (!partial) {
445
+ bc->error = errno;
446
+ free(codes);
447
+ return -1;
448
+ }
449
+
450
+ /* the text information is at most "nnn.n:ff.f:c " * strlen +term */
451
+ textptr = textinfo = malloc(13*strlen(text) + 2);
452
+ if (!textinfo) {
453
+ bc->error = errno;
454
+ free(partial);
455
+ free(codes);
456
+ return -1;
457
+ }
458
+
459
+ /* up to now, it was almost the same code as other encodings */
460
+
461
+ strcpy(partial, "0"); /* the first space */
462
+ for (i=0; i<len; i++) /* the symbols */
463
+ strcat(partial, codeset[codes[i]]);
464
+
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';
469
+
470
+ /*
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)
474
+ */
475
+
476
+ /*
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.
479
+ */
480
+ size = (int)(180.0 * (len-3) / strlen(text) + .5) / 10.0;
481
+ if (size > 12.0) size = 12.0;
482
+
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;
486
+
487
+ for (i=0; i<strlen(text); i++) {
488
+ c = 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);
493
+ textpos += step;
494
+ }
495
+
496
+ bc->partial = partial;
497
+ bc->textinfo = textinfo;
498
+ free(codes);
499
+ return 0;
500
+ }
501
+
502
+ /*
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)
505
+ */
506
+
507
+ int Barcode_128raw_verify(unsigned char *text)
508
+ {
509
+ int n;
510
+ unsigned val;
511
+
512
+ if (!strlen(text))
513
+ return -1;
514
+ while (*text) {
515
+ if (sscanf(text, "%u%n", &val, &n) < 1)
516
+ return -1;
517
+ if (val > 105)
518
+ return -1;
519
+ text += n;
520
+ }
521
+ return 0;
522
+ }
523
+
524
+ int Barcode_128raw_encode(struct Barcode_Item *bc)
525
+ {
526
+ static char *text;
527
+ static char *partial; /* dynamic */
528
+ static char *textinfo; /* dynamic */
529
+ char *textptr;
530
+ int i, n, count, code, textpos, checksum = 0;
531
+
532
+ if (bc->partial)
533
+ free(bc->partial);
534
+ if (bc->textinfo)
535
+ free(bc->textinfo);
536
+ bc->partial = bc->textinfo = NULL; /* safe */
537
+
538
+ if (!bc->encoding)
539
+ bc->encoding = strdup("128raw");
540
+
541
+ text = bc->ascii;
542
+ if (!text) {
543
+ bc->error = EINVAL;
544
+ return -1;
545
+ }
546
+ /*
547
+ * length of partial code is unknown in advance, but it is
548
+ * at most 6* (1+text/2 + check + tail) + final + terminator
549
+ */
550
+ partial = malloc( (3+ strlen(text)/2) * 6 + 2);
551
+ if (!partial) {
552
+ bc->error = errno;
553
+ return -1;
554
+ }
555
+
556
+ /* the text information is at most "nnn.5:fff:c " * 1+strlen/2 +term */
557
+ textinfo = malloc(12 * (1+strlen(text)/2) + 2);
558
+ if (!textinfo) {
559
+ bc->error = errno;
560
+ free(partial);
561
+ return -1;
562
+ }
563
+
564
+ strcpy(partial, "0"); /* the first space */
565
+ textptr = textinfo;
566
+ textpos = 0;
567
+
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 */
571
+ free(partial);
572
+ free(textinfo);
573
+ return -1;
574
+ }
575
+ strcat(partial, codeset[code]);
576
+
577
+ /*
578
+ * since the start code is part of the "raw" input, it is
579
+ * counted in the checksum by itself
580
+ */
581
+ if (!count) checksum += code; /* the start code */
582
+ else checksum += code * count; /* first * 1 + second * 2 ... */
583
+
584
+ /*
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
588
+ */
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 */
594
+ i += n;
595
+ }
596
+ /* Add the checksum, independent of BARCODE_NO_CHECKSUM */
597
+ checksum %= 103;
598
+ strcat(partial, codeset[checksum]);
599
+ /* and the end marker */
600
+ strcat(partial, codeset[STOP]);
601
+
602
+ bc->partial = partial;
603
+ bc->textinfo = textinfo;
604
+
605
+ return 0;
606
+ }
607
+