gbarcode 0.98.16-mswin32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +3 -0
- data/COPYING +0 -0
- data/README +199 -0
- data/Rakefile +109 -0
- data/ext/barcode.h +119 -0
- data/ext/barcode_wrap.c +3192 -0
- data/ext/codabar.c +182 -0
- data/ext/code128.c +607 -0
- data/ext/code39.c +173 -0
- data/ext/code93.c +213 -0
- data/ext/ean.c +774 -0
- data/ext/extconf.rb +6 -0
- data/ext/i25.c +164 -0
- data/ext/library.c +244 -0
- data/ext/msi.c +155 -0
- data/ext/pcl.c +200 -0
- data/ext/plessey.c +164 -0
- data/ext/ps.c +272 -0
- data/ext/svg.c +174 -0
- data/extras/mingw-rbconfig.rb +176 -0
- data/lib/gbarcode.so +0 -0
- data/test/assets/gb-code128b.eps +44 -0
- data/test/gbarcode_test.rb +48 -0
- data/test/test_helper.rb +2 -0
- metadata +77 -0
data/ext/extconf.rb
ADDED
data/ext/i25.c
ADDED
@@ -0,0 +1,164 @@
|
|
1
|
+
/*
|
2
|
+
* i25.c -- "interleaved 2 of 5"
|
3
|
+
*
|
4
|
+
* Copyright (c) 1999,2000 Alessandro Rubini (rubini@gnu.org)
|
5
|
+
* Copyright (c) 1999 Prosa Srl. (prosa@prosa.it)
|
6
|
+
*
|
7
|
+
* This program is free software; you can redistribute it and/or modify
|
8
|
+
* it under the terms of the GNU General Public License as published by
|
9
|
+
* the Free Software Foundation; either version 2 of the License, or
|
10
|
+
* (at your option) any later version.
|
11
|
+
*
|
12
|
+
* This program is distributed in the hope that it will be useful,
|
13
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
* GNU General Public License for more details.
|
16
|
+
*
|
17
|
+
* You should have received a copy of the GNU General Public License
|
18
|
+
* along with this program; if not, write to the Free Software
|
19
|
+
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
20
|
+
*/
|
21
|
+
|
22
|
+
#include <stdio.h>
|
23
|
+
#include <stdlib.h>
|
24
|
+
#include <string.h>
|
25
|
+
#include <ctype.h>
|
26
|
+
#include <errno.h>
|
27
|
+
|
28
|
+
#include "barcode.h"
|
29
|
+
|
30
|
+
static char *codes[] = {
|
31
|
+
"11331", "31113", "13113", "33111", "11313",
|
32
|
+
"31311", "13311", "11133", "31131", "13131"
|
33
|
+
};
|
34
|
+
|
35
|
+
static char *guard[] = {"a1a1", "c1a"}; /* begin end */
|
36
|
+
|
37
|
+
int Barcode_i25_verify(unsigned char *text)
|
38
|
+
{
|
39
|
+
if (!text[0])
|
40
|
+
return -1;
|
41
|
+
while (*text && isdigit(*text))
|
42
|
+
text++;
|
43
|
+
if (*text)
|
44
|
+
return -1; /* a non-digit char */
|
45
|
+
return 0; /* ok */
|
46
|
+
}
|
47
|
+
|
48
|
+
int Barcode_i25_encode(struct Barcode_Item *bc)
|
49
|
+
{
|
50
|
+
unsigned char *text;
|
51
|
+
unsigned char *partial; /* dynamic */
|
52
|
+
unsigned char *textinfo; /* dynamic */
|
53
|
+
unsigned char *textptr, *p1, *p2, *pd;
|
54
|
+
int i, len, sum[2], textpos, usesum = 0;
|
55
|
+
|
56
|
+
if (bc->partial)
|
57
|
+
free(bc->partial);
|
58
|
+
if (bc->textinfo)
|
59
|
+
free(bc->textinfo);
|
60
|
+
bc->partial = bc->textinfo = NULL; /* safe */
|
61
|
+
|
62
|
+
if (!bc->encoding)
|
63
|
+
bc->encoding = strdup("interleaved 2 of 5");
|
64
|
+
|
65
|
+
text = bc->ascii;
|
66
|
+
if (!bc->ascii) {
|
67
|
+
bc->error = EINVAL;
|
68
|
+
return -1;
|
69
|
+
}
|
70
|
+
|
71
|
+
if ((bc->flags & BARCODE_NO_CHECKSUM)) usesum = 0; else usesum = 1;
|
72
|
+
|
73
|
+
/* create the real text string, padded to an even number of digits */
|
74
|
+
text = malloc(strlen(bc->ascii) + 3); /* leading 0, checksum, term. */
|
75
|
+
if (!text) {
|
76
|
+
bc->error = errno;
|
77
|
+
return -1;
|
78
|
+
}
|
79
|
+
/* add the leading 0 if needed */
|
80
|
+
i = strlen(bc->ascii) + usesum;
|
81
|
+
if (i % 2) {
|
82
|
+
/* add a leading 0 */
|
83
|
+
text[0] = '0';
|
84
|
+
strcpy(text+1, bc->ascii);
|
85
|
+
} else {
|
86
|
+
strcpy(text, bc->ascii);
|
87
|
+
}
|
88
|
+
/* add the trailing checksum if needed, the leading 0 is ignored */
|
89
|
+
if (usesum) {
|
90
|
+
sum[0] = sum[1] = 0;
|
91
|
+
for (i=0; text[i]; i++)
|
92
|
+
sum[i%2] += text[i]-'0';
|
93
|
+
/*
|
94
|
+
* The "even" sum must be multiplied by three, and the *
|
95
|
+
* rightmost digit is defined as "even". The digits' position
|
96
|
+
* is already correct, whether or not we added a leading zero.
|
97
|
+
* (e.g., they are in pos. 0..4 or 1..4 of the string)
|
98
|
+
*/
|
99
|
+
i = sum[0] * 3 + sum[1];
|
100
|
+
strcat(text, "0");
|
101
|
+
text[strlen(text)-1] += (10 - (i%10)) % 10;
|
102
|
+
}
|
103
|
+
|
104
|
+
/* the partial code is 5 * (text + check) + 4(head) + 3(tail) + term. */
|
105
|
+
partial = malloc( (strlen(text) + 3) * 5 +2); /* be large... */
|
106
|
+
if (!partial) {
|
107
|
+
bc->error = errno;
|
108
|
+
free(text);
|
109
|
+
return -1;
|
110
|
+
}
|
111
|
+
|
112
|
+
/* the text information is at most "nnn:fff:c " * (strlen+1) +term */
|
113
|
+
textinfo = malloc(10*(strlen(text)+1) + 2);
|
114
|
+
if (!textinfo) {
|
115
|
+
bc->error = errno;
|
116
|
+
free(partial);
|
117
|
+
free(text);
|
118
|
+
return -1;
|
119
|
+
}
|
120
|
+
|
121
|
+
|
122
|
+
strcpy(partial, "0"); /* the first space */
|
123
|
+
strcat(partial, guard[0]); /* start */
|
124
|
+
textpos = 4; /* width of initial guard */
|
125
|
+
textptr = textinfo;
|
126
|
+
|
127
|
+
len = strlen(text);
|
128
|
+
for (i=0; i<len; i+=2) {
|
129
|
+
if (!isdigit(text[i]) || !isdigit(text[i+1])) {
|
130
|
+
bc->error = EINVAL; /* impossible if text is verified */
|
131
|
+
free(partial);
|
132
|
+
free(textinfo);
|
133
|
+
free(text);
|
134
|
+
return -1;
|
135
|
+
}
|
136
|
+
/* interleave two digits */
|
137
|
+
p1 = codes[text[i]-'0'];
|
138
|
+
p2 = codes[text[i+1]-'0'];
|
139
|
+
pd = partial + strlen(partial); /* destination */
|
140
|
+
while (*p1) {
|
141
|
+
*(pd++) = *(p1++);
|
142
|
+
*(pd++) = *(p2++);
|
143
|
+
}
|
144
|
+
*pd = '\0';
|
145
|
+
/* and print the ascii text (but don't print the checksum, if any */
|
146
|
+
if (usesum && strlen(text+i)==2) {
|
147
|
+
/* print only one digit, discard the checksum */
|
148
|
+
sprintf(textptr, "%i:12:%c ", textpos, text[i]);
|
149
|
+
} else {
|
150
|
+
sprintf(textptr, "%i:12:%c %i:12:%c ", textpos, text[i],
|
151
|
+
textpos+9, text[i+1]);
|
152
|
+
}
|
153
|
+
textpos += 18; /* width of two codes */
|
154
|
+
textptr += strlen(textptr);
|
155
|
+
}
|
156
|
+
strcat(partial, guard[1]);
|
157
|
+
|
158
|
+
bc->partial = partial;
|
159
|
+
bc->textinfo = textinfo;
|
160
|
+
free(text);
|
161
|
+
|
162
|
+
return 0;
|
163
|
+
}
|
164
|
+
|
data/ext/library.c
ADDED
@@ -0,0 +1,244 @@
|
|
1
|
+
/*
|
2
|
+
* library.c -- external functions of libbarcode
|
3
|
+
*
|
4
|
+
* Copyright (c) 1999 Alessandro Rubini (rubini@gnu.org)
|
5
|
+
* Copyright (c) 1999 Prosa Srl. (prosa@prosa.it)
|
6
|
+
*
|
7
|
+
* This program is free software; you can redistribute it and/or modify
|
8
|
+
* it under the terms of the GNU General Public License as published by
|
9
|
+
* the Free Software Foundation; either version 2 of the License, or
|
10
|
+
* (at your option) any later version.
|
11
|
+
*
|
12
|
+
* This program is distributed in the hope that it will be useful,
|
13
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
* GNU General Public License for more details.
|
16
|
+
*
|
17
|
+
* You should have received a copy of the GNU General Public License
|
18
|
+
* along with this program; if not, write to the Free Software
|
19
|
+
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
20
|
+
*/
|
21
|
+
|
22
|
+
#include <stdio.h>
|
23
|
+
#include <stdlib.h>
|
24
|
+
#include <string.h>
|
25
|
+
#include <ctype.h>
|
26
|
+
#ifdef HAVE_UNISTD_H /* sometimes (windows, for instance) it's missing */
|
27
|
+
# include <unistd.h>
|
28
|
+
#endif
|
29
|
+
#include <errno.h>
|
30
|
+
|
31
|
+
#include "barcode.h"
|
32
|
+
|
33
|
+
/*
|
34
|
+
* This function allocates a barcode structure and strdup()s the
|
35
|
+
* text string. It returns NULL in case of error
|
36
|
+
*/
|
37
|
+
struct Barcode_Item *Barcode_Create(char *text)
|
38
|
+
{
|
39
|
+
struct Barcode_Item *bc;
|
40
|
+
|
41
|
+
bc = malloc(sizeof(*bc));
|
42
|
+
if (!bc) return NULL;
|
43
|
+
|
44
|
+
memset(bc, 0, sizeof(*bc));
|
45
|
+
bc->ascii = strdup(text);
|
46
|
+
bc->margin = BARCODE_DEFAULT_MARGIN; /* default margin */
|
47
|
+
return bc;
|
48
|
+
}
|
49
|
+
|
50
|
+
|
51
|
+
/*
|
52
|
+
* Free a barcode structure
|
53
|
+
*/
|
54
|
+
int Barcode_Delete(struct Barcode_Item *bc)
|
55
|
+
{
|
56
|
+
if (bc->ascii)
|
57
|
+
free(bc->ascii);
|
58
|
+
if (bc->partial)
|
59
|
+
free(bc->partial);
|
60
|
+
if (bc->textinfo)
|
61
|
+
free(bc->textinfo);
|
62
|
+
if (bc->encoding)
|
63
|
+
free(bc->encoding);
|
64
|
+
free(bc);
|
65
|
+
return 0; /* always success */
|
66
|
+
}
|
67
|
+
|
68
|
+
|
69
|
+
/*
|
70
|
+
* The various supported encodings. This might be extended to support
|
71
|
+
* dynamic addition of extra encodings
|
72
|
+
*/
|
73
|
+
extern int Barcode_ean_verify(unsigned char *text);
|
74
|
+
extern int Barcode_ean_encode(struct Barcode_Item *bc);
|
75
|
+
extern int Barcode_upc_verify(unsigned char *text);
|
76
|
+
extern int Barcode_upc_encode(struct Barcode_Item *bc);
|
77
|
+
extern int Barcode_isbn_verify(unsigned char *text);
|
78
|
+
extern int Barcode_isbn_encode(struct Barcode_Item *bc);
|
79
|
+
extern int Barcode_39_verify(unsigned char *text);
|
80
|
+
extern int Barcode_39_encode(struct Barcode_Item *bc);
|
81
|
+
extern int Barcode_128b_verify(unsigned char *text);
|
82
|
+
extern int Barcode_128b_encode(struct Barcode_Item *bc);
|
83
|
+
extern int Barcode_128c_verify(unsigned char *text);
|
84
|
+
extern int Barcode_128c_encode(struct Barcode_Item *bc);
|
85
|
+
extern int Barcode_128_verify(unsigned char *text);
|
86
|
+
extern int Barcode_128_encode(struct Barcode_Item *bc);
|
87
|
+
extern int Barcode_128raw_verify(unsigned char *text);
|
88
|
+
extern int Barcode_128raw_encode(struct Barcode_Item *bc);
|
89
|
+
extern int Barcode_i25_verify(unsigned char *text);
|
90
|
+
extern int Barcode_i25_encode(struct Barcode_Item *bc);
|
91
|
+
extern int Barcode_cbr_verify(unsigned char *text);
|
92
|
+
extern int Barcode_cbr_encode(struct Barcode_Item *bc);
|
93
|
+
extern int Barcode_msi_verify(unsigned char *text);
|
94
|
+
extern int Barcode_msi_encode(struct Barcode_Item *bc);
|
95
|
+
extern int Barcode_pls_verify(unsigned char *text);
|
96
|
+
extern int Barcode_pls_encode(struct Barcode_Item *bc);
|
97
|
+
extern int Barcode_93_verify(unsigned char *text);
|
98
|
+
extern int Barcode_93_encode(struct Barcode_Item *bc);
|
99
|
+
|
100
|
+
|
101
|
+
struct encoding {
|
102
|
+
int type;
|
103
|
+
int (*verify)(unsigned char *text);
|
104
|
+
int (*encode)(struct Barcode_Item *bc);
|
105
|
+
};
|
106
|
+
|
107
|
+
struct encoding encodings[] = {
|
108
|
+
{BARCODE_EAN, Barcode_ean_verify, Barcode_ean_encode},
|
109
|
+
{BARCODE_UPC, Barcode_upc_verify, Barcode_upc_encode},
|
110
|
+
{BARCODE_ISBN, Barcode_isbn_verify, Barcode_isbn_encode},
|
111
|
+
{BARCODE_128B, Barcode_128b_verify, Barcode_128b_encode},
|
112
|
+
{BARCODE_128C, Barcode_128c_verify, Barcode_128c_encode},
|
113
|
+
{BARCODE_128RAW, Barcode_128raw_verify, Barcode_128raw_encode},
|
114
|
+
{BARCODE_39, Barcode_39_verify, Barcode_39_encode},
|
115
|
+
{BARCODE_I25, Barcode_i25_verify, Barcode_i25_encode},
|
116
|
+
{BARCODE_128, Barcode_128_verify, Barcode_128_encode},
|
117
|
+
{BARCODE_CBR, Barcode_cbr_verify, Barcode_cbr_encode},
|
118
|
+
{BARCODE_PLS, Barcode_pls_verify, Barcode_pls_encode},
|
119
|
+
{BARCODE_MSI, Barcode_msi_verify, Barcode_msi_encode},
|
120
|
+
{BARCODE_93, Barcode_93_verify, Barcode_93_encode},
|
121
|
+
{0, NULL, NULL}
|
122
|
+
};
|
123
|
+
|
124
|
+
/*
|
125
|
+
* A function to encode a string into bc->partial, ready for
|
126
|
+
* postprocessing to the output file. Meaningful bits for "flags" are
|
127
|
+
* the encoding mask and the no-checksum flag. These bits
|
128
|
+
* get saved in the data structure.
|
129
|
+
*/
|
130
|
+
int Barcode_Encode(struct Barcode_Item *bc, int flags)
|
131
|
+
{
|
132
|
+
int validbits = BARCODE_ENCODING_MASK | BARCODE_NO_CHECKSUM;
|
133
|
+
struct encoding *cptr;
|
134
|
+
|
135
|
+
/* If any flag is cleared in "flags", inherit it from "bc->flags" */
|
136
|
+
if (!(flags & BARCODE_ENCODING_MASK))
|
137
|
+
flags |= bc->flags & BARCODE_ENCODING_MASK;
|
138
|
+
if (!(flags & BARCODE_NO_CHECKSUM))
|
139
|
+
flags |= bc->flags & BARCODE_NO_CHECKSUM;
|
140
|
+
flags = bc->flags = (flags & validbits) | (bc->flags & ~validbits);
|
141
|
+
|
142
|
+
if (!(flags & BARCODE_ENCODING_MASK)) {
|
143
|
+
/* get the first code able to handle the text */
|
144
|
+
for (cptr = encodings; cptr->verify; cptr++)
|
145
|
+
if (cptr->verify((unsigned char *)bc->ascii)==0)
|
146
|
+
break;
|
147
|
+
if (!cptr->verify) {
|
148
|
+
bc->error = EINVAL; /* no code can handle this text */
|
149
|
+
return -1;
|
150
|
+
}
|
151
|
+
flags |= cptr->type; /* this works */
|
152
|
+
bc->flags |= cptr->type;
|
153
|
+
}
|
154
|
+
for (cptr = encodings; cptr->verify; cptr++)
|
155
|
+
if (cptr->type == (flags & BARCODE_ENCODING_MASK))
|
156
|
+
break;
|
157
|
+
if (!cptr->verify) {
|
158
|
+
bc->error = EINVAL; /* invalid barcode type */
|
159
|
+
return -1;
|
160
|
+
}
|
161
|
+
if (cptr->verify(bc->ascii) != 0) {
|
162
|
+
bc->error = EINVAL;
|
163
|
+
return -1;
|
164
|
+
}
|
165
|
+
return cptr->encode(bc);
|
166
|
+
}
|
167
|
+
|
168
|
+
|
169
|
+
/*
|
170
|
+
* When multiple output formats are supported, there will
|
171
|
+
* be a jumpt table like the one for the types. Now we don't need it
|
172
|
+
*/
|
173
|
+
extern int Barcode_ps_print(struct Barcode_Item *bc, FILE *f);
|
174
|
+
extern int Barcode_pcl_print(struct Barcode_Item *bc, FILE *f);
|
175
|
+
|
176
|
+
/*
|
177
|
+
* A function to print a partially decoded string. Meaningful bits for
|
178
|
+
* "flags" are the output mask etc. These bits get saved in the data
|
179
|
+
* structure.
|
180
|
+
*/
|
181
|
+
int Barcode_Print(struct Barcode_Item *bc, FILE *f, int flags)
|
182
|
+
{
|
183
|
+
int validbits = BARCODE_OUTPUT_MASK | BARCODE_NO_ASCII
|
184
|
+
| BARCODE_OUT_NOHEADERS;
|
185
|
+
|
186
|
+
/* If any flag is clear in "flags", inherit it from "bc->flags" */
|
187
|
+
if (!(flags & BARCODE_OUTPUT_MASK))
|
188
|
+
flags |= bc->flags & BARCODE_OUTPUT_MASK;
|
189
|
+
if (!(flags & BARCODE_NO_ASCII))
|
190
|
+
flags |= bc->flags & BARCODE_NO_ASCII;
|
191
|
+
if (!(flags & BARCODE_OUT_NOHEADERS))
|
192
|
+
flags |= bc->flags & BARCODE_OUT_NOHEADERS;
|
193
|
+
flags = bc->flags = (flags & validbits) | (bc->flags & ~validbits);
|
194
|
+
|
195
|
+
if (bc->flags & BARCODE_OUT_PCL)
|
196
|
+
return Barcode_pcl_print(bc, f);
|
197
|
+
return Barcode_ps_print(bc, f);
|
198
|
+
}
|
199
|
+
|
200
|
+
/*
|
201
|
+
* Choose the position
|
202
|
+
*/
|
203
|
+
int Barcode_Position(struct Barcode_Item *bc, int wid, int hei,
|
204
|
+
int xoff, int yoff, double scalef)
|
205
|
+
{
|
206
|
+
bc->width = wid; bc->height = hei;
|
207
|
+
bc->xoff = xoff; bc->yoff = yoff;
|
208
|
+
bc->scalef = scalef;
|
209
|
+
return 0;
|
210
|
+
}
|
211
|
+
|
212
|
+
/*
|
213
|
+
* Do it all in one step
|
214
|
+
*/
|
215
|
+
int Barcode_Encode_and_Print(char *text, FILE *f, int wid, int hei,
|
216
|
+
int xoff, int yoff, int flags)
|
217
|
+
{
|
218
|
+
struct Barcode_Item * bc;
|
219
|
+
|
220
|
+
if (!(bc=Barcode_Create(text))) {
|
221
|
+
errno = -ENOMEM;
|
222
|
+
return -1;
|
223
|
+
}
|
224
|
+
if ( Barcode_Position(bc, wid, hei, xoff, yoff, 0.0) < 0
|
225
|
+
|| Barcode_Encode(bc, flags) < 0
|
226
|
+
|| Barcode_Print(bc, f, flags) < 0) {
|
227
|
+
errno = bc->error;
|
228
|
+
Barcode_Delete(bc);
|
229
|
+
return -1;
|
230
|
+
}
|
231
|
+
Barcode_Delete(bc);
|
232
|
+
return 0;
|
233
|
+
}
|
234
|
+
|
235
|
+
/*
|
236
|
+
* Return the version
|
237
|
+
*/
|
238
|
+
|
239
|
+
int Barcode_Version(char *vptr)
|
240
|
+
{
|
241
|
+
if (vptr)
|
242
|
+
strcpy(vptr, BARCODE_VERSION);
|
243
|
+
return BARCODE_VERSION_INT;
|
244
|
+
}
|
data/ext/msi.c
ADDED
@@ -0,0 +1,155 @@
|
|
1
|
+
/*
|
2
|
+
* msi.c -- encoding for MSI-Plessey
|
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
|
+
/* Patterns */
|
31
|
+
static char *patterns[] = { "13", "31" };
|
32
|
+
|
33
|
+
static char *fillers[] = { "031", "131" };
|
34
|
+
|
35
|
+
static int width = 16 /* each character uses 4 patterns */,
|
36
|
+
startpos = 6 /* length of the first filler */;
|
37
|
+
|
38
|
+
/*
|
39
|
+
* Check that the text can be encoded. Returns 0 or -1.
|
40
|
+
*/
|
41
|
+
int Barcode_msi_verify(unsigned char *text)
|
42
|
+
{
|
43
|
+
int i;
|
44
|
+
|
45
|
+
if (!strlen(text))
|
46
|
+
return -1;
|
47
|
+
for (i=0; text[i]; i++) {
|
48
|
+
if (!isdigit(text[i]))
|
49
|
+
return -1;
|
50
|
+
}
|
51
|
+
return 0;
|
52
|
+
}
|
53
|
+
|
54
|
+
static int add_one(char *ptr, int code)
|
55
|
+
{
|
56
|
+
sprintf(ptr, "%s%s%s%s",
|
57
|
+
patterns[(code >> 3) & 1],
|
58
|
+
patterns[(code >> 2) & 1],
|
59
|
+
patterns[(code >> 1) & 1],
|
60
|
+
patterns[code & 1]);
|
61
|
+
return 0;
|
62
|
+
}
|
63
|
+
|
64
|
+
/*
|
65
|
+
* The encoding functions fills the "partial" and "textinfo" fields.
|
66
|
+
* Lowercase chars are converted to uppercase
|
67
|
+
*/
|
68
|
+
int Barcode_msi_encode(struct Barcode_Item *bc)
|
69
|
+
{
|
70
|
+
static char *text;
|
71
|
+
static char *partial; /* dynamic */
|
72
|
+
static char *textinfo; /* dynamic */
|
73
|
+
char *ptr, *textptr;
|
74
|
+
int i, code, textpos, usesum, checksum = 0;
|
75
|
+
|
76
|
+
if (bc->partial)
|
77
|
+
free(bc->partial);
|
78
|
+
if (bc->textinfo)
|
79
|
+
free(bc->textinfo);
|
80
|
+
bc->partial = bc->textinfo = NULL; /* safe */
|
81
|
+
|
82
|
+
if (!bc->encoding)
|
83
|
+
bc->encoding = strdup("msi");
|
84
|
+
|
85
|
+
if ((bc->flags & BARCODE_NO_CHECKSUM))
|
86
|
+
usesum = 0;
|
87
|
+
else
|
88
|
+
usesum = 1;
|
89
|
+
|
90
|
+
text = bc->ascii;
|
91
|
+
|
92
|
+
/* the partial code is head + 8 * (text + check) + tail + margin + term. */
|
93
|
+
partial = malloc( 3 + 8 * (strlen(text) + 1) + 3 + 2 );
|
94
|
+
if (!partial) {
|
95
|
+
bc->error = errno;
|
96
|
+
return -1;
|
97
|
+
}
|
98
|
+
|
99
|
+
/* the text information is at most "nnn:fff:c " * strlen +term */
|
100
|
+
textinfo = malloc(10*strlen(text) + 2);
|
101
|
+
if (!textinfo) {
|
102
|
+
bc->error = errno;
|
103
|
+
free(partial);
|
104
|
+
return -1;
|
105
|
+
}
|
106
|
+
|
107
|
+
strcpy(partial, fillers[0]);
|
108
|
+
ptr = partial + strlen(partial);
|
109
|
+
textptr = textinfo;
|
110
|
+
textpos = startpos;
|
111
|
+
|
112
|
+
for (i=0; i<strlen(text); i++) {
|
113
|
+
code = text[i] - '0';
|
114
|
+
add_one(ptr, code);
|
115
|
+
sprintf(textptr, "%i:12:%c ", textpos, text[i]);
|
116
|
+
|
117
|
+
textpos += width; /* width of each code */
|
118
|
+
textptr += strlen(textptr);
|
119
|
+
ptr += strlen(ptr);
|
120
|
+
if (usesum) {
|
121
|
+
/* For a code ...FEDCBA the checksum is computed
|
122
|
+
* as the sum of digits of the number ...FDB plus
|
123
|
+
* the sum of digits of the number ...ECA * 2.
|
124
|
+
* Which is equivalent to the sum of each digit of ...ECA doubled
|
125
|
+
* plus carry.
|
126
|
+
*/
|
127
|
+
if ((i ^ strlen(text)) & 1) {
|
128
|
+
/* a last digit, 2 away from last, etc. */
|
129
|
+
checksum += 2 * code + (2 * code) / 10;
|
130
|
+
} else {
|
131
|
+
checksum += code;
|
132
|
+
}
|
133
|
+
}
|
134
|
+
}
|
135
|
+
/* Some implementations use a double checksum. Currently the only way
|
136
|
+
* to print a barcode with double checksum is to put the checksum
|
137
|
+
* digit printed below at the end of a code in the command line
|
138
|
+
* and re-run the program.
|
139
|
+
*/
|
140
|
+
if (usesum) {
|
141
|
+
/* the check digit is the complement of the checksum
|
142
|
+
* to a multiple of 10.
|
143
|
+
*/
|
144
|
+
checksum = (checksum + 9) / 10 * 10 - checksum;
|
145
|
+
/* fprintf(stderr, "Checksum: %d\n", checksum); */
|
146
|
+
add_one(ptr, checksum);
|
147
|
+
ptr += strlen(ptr);
|
148
|
+
}
|
149
|
+
|
150
|
+
strcpy(ptr, fillers[1]);
|
151
|
+
bc->partial = partial;
|
152
|
+
bc->textinfo = textinfo;
|
153
|
+
|
154
|
+
return 0;
|
155
|
+
}
|