]> git.sur5r.net Git - glabels/blob - glabels2/barcode-0.98/plessey.c
2007-04-30 Jim Evins <evins@snaught.com>
[glabels] / glabels2 / barcode-0.98 / plessey.c
1 /*
2  * plessey.c -- encoding for 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 static char * patterns[] = { "13", "31" };
30
31 /* this is ordered in decades to simplify encoding */
32 static char alphabet[] = 
33    "0123456789" "ABCDEF";
34
35 /* stop sequence may be 231311313 (barcodemill.com) */
36 static char *fillers[] = { "031311331", "331311313" };
37
38 static int width = 16, startpos = 16;
39
40 /*
41  * Check that the text can be encoded. Returns 0 or -1.
42  * If it's all lowecase convert to uppercase and accept it
43  */
44 int Barcode_pls_verify(unsigned char *text)
45 {
46     int i, upper = 0, lower = 0;
47
48     if (!strlen(text))
49         return -1;
50     for (i=0; text[i]; i++) {
51         if (!strchr(alphabet,toupper(text[i])))
52             return -1;
53         if (isupper(text[i])) upper++;
54         if (islower(text[i])) lower++;
55     }
56     if (upper && lower)
57         return -1;
58     return 0;
59 }
60
61 static int add_one(char *ptr, int code)
62 {
63     sprintf(ptr, "%s%s%s%s", 
64         patterns[code & 1],
65         patterns[(code >> 1) & 1],
66         patterns[(code >> 2) & 1],
67         patterns[(code >> 3) & 1]
68     );
69     return 0;
70 }
71
72 /*
73  * The encoding functions fills the "partial" and "textinfo" fields.
74  * Lowercase chars are converted to uppercase
75  */
76 int Barcode_pls_encode(struct Barcode_Item *bc)
77 {
78     static char *text;
79     static char *partial;  /* dynamic */
80     static char *textinfo; /* dynamic */
81     char *c, *ptr, *textptr;
82     unsigned char *checkptr;
83     int i, code, textpos;
84     static char check[9] = {1,1,1,1,0,1,0,0,1};
85     if (bc->partial)
86         free(bc->partial);
87     if (bc->textinfo)
88         free(bc->textinfo);
89     bc->partial = bc->textinfo = NULL; /* safe */
90
91     if (!bc->encoding)
92         bc->encoding = strdup("plessey");
93
94     text = bc->ascii;
95     if (!text) {
96         bc->error = EINVAL;
97         return -1;
98     }
99     /* the partial code is 8 * (head + text + check + tail) + margin + term. */
100     partial = malloc( (strlen(text) + 4) * 8 + 3);
101     checkptr = calloc (1, strlen(text) * 4 + 8);
102
103     if (!partial || !checkptr) {
104         if (partial) free(partial);
105         if (checkptr) free(checkptr);
106         bc->error = errno;
107         return -1;
108     }
109
110     /* the text information is at most "nnn:fff:c " * strlen +term */
111     textinfo = malloc(10*strlen(text) + 2);
112     if (!textinfo) {
113         bc->error = errno;
114         free(partial);
115         return -1;
116     }
117
118     strcpy(partial, fillers[0]);
119     ptr = partial + strlen(partial);
120     textptr = textinfo;
121     textpos = startpos;
122     
123     for (i=0; i<strlen(text); i++) {
124         c = strchr(alphabet, toupper(text[i]));
125         if (!c) {
126             bc->error = EINVAL; /* impossible if text is verified */
127             free(partial);
128             free(textinfo);
129             return -1;
130         }
131         code = c - alphabet;
132         add_one(ptr, code);
133         sprintf(textptr, "%i:12:%c ", textpos, toupper(text[i]));
134         
135         textpos += width; /* width of each code */
136         textptr += strlen(textptr);
137         ptr += strlen(ptr); 
138         checkptr[4*i] = code & 1;
139         checkptr[4*i+1] = (code >> 1) & 1;
140         checkptr[4*i+2] = (code >> 2) & 1;
141         checkptr[4*i+3] = (code >> 3) & 1;
142     }
143     /* The CRC checksum is required */
144     for (i=0; i < 4*strlen(text); i++) {
145         int j;
146         if (checkptr[i])
147                 for (j = 0; j < 9; j++)
148                         checkptr[i+j] ^= check[j];
149     }
150     for (i = 0; i < 8; i++) {
151         sprintf(ptr, patterns[checkptr[strlen(text) * 4 + i]]);
152         ptr += 2;
153     }
154     fprintf(stderr, "CRC: ");
155     for (i = 0; i < 8; i++) {
156         fputc('0' + checkptr[strlen(text) * 4 + i], stderr);
157     }
158     fputc('\n', stderr);
159     strcpy(ptr, fillers[1]);
160     bc->partial = partial;
161     bc->textinfo = textinfo;
162
163     return 0;
164 }