]> git.sur5r.net Git - glabels/blob - barcode-0.98/library.c
Imported Upstream version 2.2.8
[glabels] / barcode-0.98 / library.c
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 }