1 /**
2  *
3  * IEC16022 bar code generation
4  * Adrian Kennard, Andrews & Arnold Ltd
5  * with help from Cliff Hones on the RS coding
6  *
7  * (c) 2004 Adrian Kennard, Andrews & Arnold Ltd
8  * (c) 2006-2007 Stefan Schmidt <stefan@datenfreihafen.org>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
23  *
24  */
25 
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <ctype.h>
29 #include <string.h>
30 #include <time.h>
31 #include <stdlib.h>
32 #include "reedsol.h"
33 #include "iec16022ecc200.h"
34 
35 static const struct ecc200matrix_s {
36 	unsigned char H, W;
37 	unsigned char FH, FW;
38 	unsigned short bytes;
39 	unsigned char datablock, rsblock;
40 } ecc200matrix[] = {
41 	{ 10, 10, 10, 10, 3, 3, 5},	//
42 	{ 12, 12, 12, 12, 5, 5, 7},	//
43 	{  8, 18, 8, 18, 5, 5, 7},	//
44 	{ 14, 14, 14, 14, 8, 8, 10},	//
45 	{  8, 32, 8, 16, 10, 10, 11},	//
46 	{ 16, 16, 16, 16, 12, 12, 12},	//
47 	{ 12, 26, 12, 26, 16, 16, 14},	//
48 	{ 18, 18, 18, 18, 18, 18, 14},	//
49 	{ 20, 20, 20, 20, 22, 22, 18},	//
50 	{ 12, 36, 12, 18, 22, 22, 18},	//
51 	{ 22, 22, 22, 22, 30, 30, 20},	//
52 	{ 16, 36, 16, 18, 32, 32, 24},	//
53 	{ 24, 24, 24, 24, 36, 36, 24},	//
54 	{ 26, 26, 26, 26, 44, 44, 28},	//
55 	{ 16, 48, 16, 24, 49, 49, 28},	//
56 	{ 32, 32, 16, 16, 62, 62, 36},	//
57 	{ 36, 36, 18, 18, 86, 86, 42},	//
58 	{ 40, 40, 20, 20, 114, 114, 48},	//
59 	{ 44, 44, 22, 22, 144, 144, 56},	//
60 	{ 48, 48, 24, 24, 174, 174, 68},	//
61 	{ 52, 52, 26, 26, 204, 102, 42},	//
62 	{ 64, 64, 16, 16, 280, 140, 56},	//
63 	{ 72, 72, 18, 18, 368, 92, 36},	//
64 	{ 80, 80, 20, 20, 456, 114, 48},	//
65 	{ 88, 88, 22, 22, 576, 144, 56},	//
66 	{ 96, 96, 24, 24, 696, 174, 68},	//
67 	{104, 104, 26, 26, 816, 136, 56},	//
68 	{120, 120, 20, 20, 1050, 175, 68},	//
69 	{132, 132, 22, 22, 1304, 163, 62},	//
70 	{144, 144, 24, 24, 1558, 156, 62},	// 156*4+155*2
71 	{0}			// terminate
72 };
73 
74  // simple checked response malloc
safemalloc(int n,int s)75 static void *safemalloc(int n, int s)
76 {
77 	void *p = calloc(n, s);
78 	if (!p) {
79 		fprintf(stderr, "Malloc(%d) failed\n", n);
80 		exit(1);
81 	}
82 	return p;
83 }
84 
85 // Annex M placement alorithm low level
ecc200placementbit(int * array,int NR,int NC,int r,int c,int p,char b)86 static void ecc200placementbit(int *array, int NR, int NC, int r, int c,
87 			       int p, char b)
88 {
89 	if (r < 0) {
90 		r += NR;
91 		c += 4 - ((NR + 4) % 8);
92 	}
93 	if (c < 0) {
94 		c += NC;
95 		r += 4 - ((NC + 4) % 8);
96 	}
97 	array[r * NC + c] = (p << 3) + b;
98 }
99 
ecc200placementblock(int * array,int NR,int NC,int r,int c,int p)100 static void ecc200placementblock(int *array, int NR, int NC, int r,
101 				 int c, int p)
102 {
103 	ecc200placementbit(array, NR, NC, r - 2, c - 2, p, 7);
104 	ecc200placementbit(array, NR, NC, r - 2, c - 1, p, 6);
105 	ecc200placementbit(array, NR, NC, r - 1, c - 2, p, 5);
106 	ecc200placementbit(array, NR, NC, r - 1, c - 1, p, 4);
107 	ecc200placementbit(array, NR, NC, r - 1, c - 0, p, 3);
108 	ecc200placementbit(array, NR, NC, r - 0, c - 2, p, 2);
109 	ecc200placementbit(array, NR, NC, r - 0, c - 1, p, 1);
110 	ecc200placementbit(array, NR, NC, r - 0, c - 0, p, 0);
111 }
112 
ecc200placementcornerA(int * array,int NR,int NC,int p)113 static void ecc200placementcornerA(int *array, int NR, int NC, int p)
114 {
115 	ecc200placementbit(array, NR, NC, NR - 1, 0, p, 7);
116 	ecc200placementbit(array, NR, NC, NR - 1, 1, p, 6);
117 	ecc200placementbit(array, NR, NC, NR - 1, 2, p, 5);
118 	ecc200placementbit(array, NR, NC, 0, NC - 2, p, 4);
119 	ecc200placementbit(array, NR, NC, 0, NC - 1, p, 3);
120 	ecc200placementbit(array, NR, NC, 1, NC - 1, p, 2);
121 	ecc200placementbit(array, NR, NC, 2, NC - 1, p, 1);
122 	ecc200placementbit(array, NR, NC, 3, NC - 1, p, 0);
123 }
124 
ecc200placementcornerB(int * array,int NR,int NC,int p)125 static void ecc200placementcornerB(int *array, int NR, int NC, int p)
126 {
127 	ecc200placementbit(array, NR, NC, NR - 3, 0, p, 7);
128 	ecc200placementbit(array, NR, NC, NR - 2, 0, p, 6);
129 	ecc200placementbit(array, NR, NC, NR - 1, 0, p, 5);
130 	ecc200placementbit(array, NR, NC, 0, NC - 4, p, 4);
131 	ecc200placementbit(array, NR, NC, 0, NC - 3, p, 3);
132 	ecc200placementbit(array, NR, NC, 0, NC - 2, p, 2);
133 	ecc200placementbit(array, NR, NC, 0, NC - 1, p, 1);
134 	ecc200placementbit(array, NR, NC, 1, NC - 1, p, 0);
135 }
136 
ecc200placementcornerC(int * array,int NR,int NC,int p)137 static void ecc200placementcornerC(int *array, int NR, int NC, int p)
138 {
139 	ecc200placementbit(array, NR, NC, NR - 3, 0, p, 7);
140 	ecc200placementbit(array, NR, NC, NR - 2, 0, p, 6);
141 	ecc200placementbit(array, NR, NC, NR - 1, 0, p, 5);
142 	ecc200placementbit(array, NR, NC, 0, NC - 2, p, 4);
143 	ecc200placementbit(array, NR, NC, 0, NC - 1, p, 3);
144 	ecc200placementbit(array, NR, NC, 1, NC - 1, p, 2);
145 	ecc200placementbit(array, NR, NC, 2, NC - 1, p, 1);
146 	ecc200placementbit(array, NR, NC, 3, NC - 1, p, 0);
147 }
148 
ecc200placementcornerD(int * array,int NR,int NC,int p)149 static void ecc200placementcornerD(int *array, int NR, int NC, int p)
150 {
151 	ecc200placementbit(array, NR, NC, NR - 1, 0, p, 7);
152 	ecc200placementbit(array, NR, NC, NR - 1, NC - 1, p, 6);
153 	ecc200placementbit(array, NR, NC, 0, NC - 3, p, 5);
154 	ecc200placementbit(array, NR, NC, 0, NC - 2, p, 4);
155 	ecc200placementbit(array, NR, NC, 0, NC - 1, p, 3);
156 	ecc200placementbit(array, NR, NC, 1, NC - 3, p, 2);
157 	ecc200placementbit(array, NR, NC, 1, NC - 2, p, 1);
158 	ecc200placementbit(array, NR, NC, 1, NC - 1, p, 0);
159 }
160 
161 // Annex M placement alorithm main function
ecc200placement(int * array,int NR,int NC)162 static void ecc200placement(int *array, int NR, int NC)
163 {
164 	// array must be cleared by caller
165 	int r, c, p;
166 	// start
167 	p = 1;
168 	r = 4;
169 	c = 0;
170 	do {
171 		// check corner
172 		if (r == NR && !c)
173 			ecc200placementcornerA(array, NR, NC, p++);
174 		if (r == NR - 2 && !c && NC % 4)
175 			ecc200placementcornerB(array, NR, NC, p++);
176 		if (r == NR - 2 && !c && (NC % 8) == 4)
177 			ecc200placementcornerC(array, NR, NC, p++);
178 		if (r == NR + 4 && c == 2 && !(NC % 8))
179 			ecc200placementcornerD(array, NR, NC, p++);
180 		// up/right
181 		do {
182 			if (r < NR && c >= 0 && !array[r * NC + c])
183 				ecc200placementblock(array, NR, NC, r, c, p++);
184 			r -= 2;
185 			c += 2;
186 		}
187 		while (r >= 0 && c < NC);
188 		r++;
189 		c += 3;
190 		// down/left
191 		do {
192 			if (r >= 0 && c < NC && !array[r * NC + c])
193 				ecc200placementblock(array, NR, NC, r, c, p++);
194 			r += 2;
195 			c -= 2;
196 		}
197 		while (r < NR && c >= 0);
198 		r += 3;
199 		c++;
200 	}
201 	while (r < NR || c < NC);
202 	// unfilled corner
203 	if (!array[NR * NC - 1])
204 		array[NR * NC - 1] = array[NR * NC - NC - 2] = 1;
205 }
206 
207 // calculate and append ecc code, and if necessary interleave
ecc200(unsigned char * binary,int bytes,int datablock,int rsblock)208 static void ecc200(unsigned char *binary, int bytes, int datablock, int rsblock)
209 {
210 	int blocks = (bytes + 2) / datablock, b;
211 	rs_init_gf(0x12d);
212 	rs_init_code(rsblock, 1);
213 	for (b = 0; b < blocks; b++) {
214 		unsigned char buf[256], ecc[256];
215 		int n, p = 0;
216 		for (n = b; n < bytes; n += blocks)
217 			buf[p++] = binary[n];
218 		rs_encode(p, buf, ecc);
219 		p = rsblock - 1;	// comes back reversed
220 		for (n = b; n < rsblock * blocks; n += blocks)
221 			binary[bytes + n] = ecc[p--];
222 	}
223 }
224 
225 /*
226  * perform encoding for ecc200, source s len sl, to target t len tl, using
227  * optional encoding control string e return 1 if OK, 0 if failed. Does all
228  * necessary padding to tl
229  */
230 
ecc200encode(unsigned char * t,int tl,const unsigned char * s,int sl,const char * encoding,int * lenp,int flags)231 static char ecc200encode(unsigned char *t, int tl, const unsigned char *s, int sl,
232 		  const char *encoding, int *lenp, int flags)
233 {
234 	char enc = 'a';		// start in ASCII encoding mode
235 	int tp = 0, sp = 0;
236 	if (flags & IEC16022_FLAG_GS1) {
237 		t[tp++] = 232;
238 		if (sl >= 3 && s[0] == ']' && s[1] == 'd' && s[2] == '2') {
239 			sp = 3;
240 		}
241 	}
242 	if (strlen(encoding) < sl - sp) {
243 		fprintf(stderr, "Encoding string too short\n");
244 		return 0;
245 	}
246 	// do the encoding
247 	while (sp < sl && tp < tl) {
248 		char newenc = enc;	// suggest new encoding
249 		if (tl - tp <= 1 && (enc == 'c' || enc == 't') || tl - tp <= 2
250 		    && enc == 'x')
251 			enc = 'a';	// auto revert to ASCII
252 		newenc = tolower(encoding[sp]);
253 		switch (newenc) {	// encode character
254 		case 'c':	// C40
255 		case 't':	// Text
256 		case 'x':	// X12
257 			{
258 				char out[6];
259 				int p = 0;
260 				const char *e,
261 				    *s2 = "!\"#$%&'()*+,-./:;<=>?@[\\]^_",
262 				    *s3 = 0;
263 				if (newenc == 'c') {
264 					e = " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
265 					s3 = "`abcdefghijklmnopqrstuvwxyz{|}~\177";
266 				}
267 				if (newenc == 't') {
268 					e = " 0123456789abcdefghijklmnopqrstuvwxyz";
269 					s3 = "`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~\177";
270 				}
271 				if (newenc == 'x')
272 					e = " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\r*>";
273 				do {
274 					unsigned char c = s[sp++];
275 					char *w;
276 					if (c & 0x80) {
277 						if (newenc == 'x') {
278 							fprintf(stderr,
279 								"Cannot encode char 0x%02X in X12\n",
280 								c);
281 							return 0;
282 						}
283 						c &= 0x7f;
284 						out[p++] = 1;
285 						out[p++] = 30;
286 					}
287 					w = strchr(e, c);
288 					if (w)
289 						out[p++] = ((w - e) + 3) % 40;
290 					else {
291 						if (newenc == 'x') {
292 							fprintf(stderr,
293 								"Cannot encode char 0x%02X in X12\n",
294 								c);
295 							return 0;
296 						}
297 						if (c < 32) {	// shift 1
298 							out[p++] = 0;
299 							out[p++] = c;
300 						} else {
301 							w = strchr(s2, c);
302 							if (w) {	// shift 2
303 								out[p++] = 1;
304 								out[p++] =
305 								    (w - s2);
306 							} else {
307 								w = strchr(s3,
308 									   c);
309 								if (w) {
310 									out[p++]
311 									    = 2;
312 									out[p++]
313 									    =
314 									    (w -
315 									     s3);
316 								} else {
317 									fprintf
318 									    (stderr,
319 									     "Could not encode 0x%02X, should \
320 									not happen\n", c);
321 									return
322 									    0;
323 								}
324 							}
325 						}
326 					}
327 					while (p >= 3 || (p && sp == sl)) {
328 						int v;
329 						while (p < 3) out[p++] = 0; // pad at end
330 						if (tp + 2 >= tl) return 0; // not enough space
331 						v = out[0] * 1600 +
332 						    out[1] * 40 + out[2] + 1;
333 						if (enc != newenc) {
334 							if (enc == 'c'
335 							    || enc == 't'
336 							    || enc == 'x')
337 								t[tp++] = 254;	// escape C40/text/X12
338 							else if (enc == 'x')
339 								t[tp++] = 0x7C;	// escape EDIFACT
340 							if (newenc == 'c')
341 								t[tp++] = 230;
342 							if (newenc == 't')
343 								t[tp++] = 239;
344 							if (newenc == 'x')
345 								t[tp++] = 238;
346 							enc = newenc;
347 						}
348 						t[tp++] = (v >> 8);
349 						t[tp++] = (v & 0xFF);
350 						p -= 3;
351 						out[0] = out[3];
352 						out[1] = out[4];
353 						out[2] = out[5];
354 					}
355 				}
356 				while (p && sp < sl);
357 			}
358 			break;
359 		case 'e':	// EDIFACT
360 			{
361 				unsigned char out[4], p = 0;
362 				if (enc != 'a' && enc != newenc) {	// can only be from C40/Text/X12
363 					t[tp++] = 254;
364 					enc = 'a';
365 				}
366 				if (enc == 'a')
367 				{
368 					t[tp++] = 240;
369 					enc = 'e';
370 				}
371 				while (sp < sl && tolower(encoding[sp]) == 'e'
372 				       && p < 4) {
373 					if (s[sp] < 32 || s[sp] > 94) {
374 						fprintf(stderr, "Cannot encode 0x%02X in EDIFACT\n", s[sp]);
375 						return 0;
376 					}
377 					out[p++] = s[sp++];
378 				}
379 				if (p < 4) {
380 					out[p++] = 0x1F;
381 					enc = 'a';
382 				}	// termination
383 				t[tp] = ((out[0] & 0x3F) << 2);
384 				t[tp++] |= ((out[1] & 0x30) >> 4);
385 				t[tp] = ((out[1] & 0x0F) << 4);
386 				if (p == 2)
387 					tp++;
388 				else {
389 					t[tp++] |= ((out[2] & 0x3C) >> 2);
390 					t[tp] = ((out[2] & 0x03) << 6);
391 					t[tp++] |= (out[3] & 0x3F);
392 				}
393 			}
394 			break;
395 		case 'a':	// ASCII
396 			if (enc != newenc) {
397 				if (enc == 'c' || enc == 't' || enc == 'x')
398 					t[tp++] = 254;	// escape C40/text/X12
399 				else
400 					t[tp++] = 0x7C;	// escape EDIFACT
401 			}
402 			enc = 'a';
403 			if (sl - sp >= 2 && isdigit(s[sp])
404 			    && isdigit(s[sp + 1])) {
405 				t[tp++] =
406 				    (s[sp] - '0') * 10 + s[sp + 1] - '0' + 130;
407 				sp += 2;
408 			} else if (s[sp] > 127) {
409 				t[tp++] = 235;
410 				t[tp++] = s[sp++] - 127;
411 			} else
412 				t[tp++] = s[sp++] + 1;
413 			break;
414 		case 'b':	// Binary
415 			{
416 				int l = 0;	// how much to encode
417 				int p;
418 				for (p = sp;
419 				     p < sl
420 				     && tolower(encoding[p]) == 'b';
421 				     p++)
422 					l++;
423 				t[tp++] = 231;	// base256
424 				if (l < 250)
425 					t[tp++] = l;
426 				else {
427 					t[tp++] = 249 + (l / 250);
428 					t[tp++] = (l % 250);
429 				}
430 				while (l-- && tp < tl) {
431 					t[tp] = s[sp++] + (((tp + 1) * 149) % 255) + 1;	// see annex H
432 					tp++;
433 				}
434 				if (l) return 0; // not enough space
435 				enc = 'a';	// reverse to ASCII at end
436 			}
437 			break;
438 		default:
439 			fprintf(stderr, "Unknown encoding %c\n", newenc);
440 			return 0;	// failed
441 		}
442 	}
443 	if (lenp)
444 		*lenp = tp;
445 	if (tp < tl && enc != 'a') {
446 		if (enc == 'c' || enc == 'x' || enc == 't')
447 			t[tp++] = 254;	// escape X12/C40/Text
448 		else
449 			t[tp++] = 0x7C;	// escape EDIFACT
450 	}
451 	if (tp < tl)
452 		t[tp++] = 129;	// pad
453 	while (tp < tl) {	// more padding
454 		int v = 129 + (((tp + 1) * 149) % 253) + 1;	// see Annex H
455 		if (v > 254)
456 			v -= 254;
457 		t[tp++] = v;
458 	}
459 	if (tp > tl || sp < sl)
460 		return 0;	// did not fit
461 	/*
462 	 * for (tp = 0; tp < tl; tp++) fprintf (stderr, "%02X ", t[tp]); \
463 	 * fprintf (stderr, "\n");
464 	 */
465 	return 1;		// OK
466 }
467 
468 // Auto encoding format functions
469 static const char encchr[] = "ACTXEB";
470 
471 enum {
472 	E_ASCII,
473 	E_C40,
474 	E_TEXT,
475 	E_X12,
476 	E_EDIFACT,
477 	E_BINARY,
478 	E_MAX
479 };
480 
481 static const unsigned char switchcost[E_MAX][E_MAX] = {
482 	{0, 1, 1, 1, 1, 2},	// From E_ASCII
483 	{1, 0, 2, 2, 2, 3},	// From E_C40
484 	{1, 2, 0, 2, 2, 3},	// From E_TEXT
485 	{1, 2, 2, 0, 2, 3},	// From E_X12
486 	{1, 2, 2, 2, 0, 3},	// From E_EDIFACT
487 	{0, 1, 1, 1, 1, 0},	// From E_BINARY
488 };
489 
490 /*
491  * Creates a encoding list (malloc)
492  * returns encoding string
493  * if lenp not null, target len stored
494  * if error, null returned
495  * if exact specified, then assumes shortcuts applicable for exact fit
496  * in target
497  * 1. No unlatch to return to ASCII for last encoded byte after C40 or
498  * Text or X12
499  * 2. No unlatch to return to ASCII for last 1 or 2 encoded bytes after
500  * EDIFACT
501  * 3. Final C40 or text encoding exactly in last 2 bytes can have a shift
502  * 0 to pad to make a tripple
503  * Only use the encoding from an exact request if the len matches the target,
504  * otherwise free the result and try again with exact=0
505  */
506 
encmake(int l,const unsigned char * s,int * lenp,char exact)507 static char *encmake(int l, const unsigned char *s, int *lenp, char exact)
508 {
509 	char *encoding = 0;
510 	int p = l;
511 	int e;
512 	struct {
513 		// number of bytes of source that can be encoded in a row at this point
514 		// using this encoding mode
515 		short s;
516 		// number of bytes of target generated encoding from this point to end if
517 		// already in this encoding mode
518 		short t;
519 	} enc[MAXBARCODE][E_MAX];
520 	memset(&enc, 0, sizeof(enc));
521 	if (lenp)
522 		*lenp = 0;
523 	if (!l) {
524 		encoding = safemalloc(1, 1);
525 		*encoding = 0;
526 		return encoding;	// no length
527 	}
528 	if (l > MAXBARCODE)
529 		return 0;	// not valid
530 	while (p--) {
531 		int b = 0, sub;
532 		int sl, tl, bl, t;
533 		// consider each encoding from this point
534 		// ASCII
535 		sl = tl = 1;
536 		if (isdigit(s[p]) && p + 1 < l && isdigit(s[p + 1]))
537 			sl = 2;	// double digit
538 		else if (s[p] & 0x80)
539 			tl = 2;	// high shifted
540 		bl = 0;
541 		if (p + sl < l)
542 			for (e = 0; e < E_MAX; e++)
543 				if (enc[p + sl][e].t && ((t = enc[p + sl][e].t +
544 							  switchcost[E_ASCII]
545 							  [e]) < bl || !bl)) {
546 					bl = t;
547 					b = e;
548 				}
549 		enc[p][E_ASCII].t = tl + bl;
550 		enc[p][E_ASCII].s = sl;
551 		if (bl && b == E_ASCII)
552 			enc[p][b].s += enc[p + sl][b].s;
553 		// C40
554 		sub = tl = sl = 0;
555 		do {
556 			unsigned char c = s[p + sl++];
557 			if (c & 0x80) {	// shift + upper
558 				sub += 2;
559 				c &= 0x7F;
560 			}
561 			if (c != ' ' && !isdigit(c) && !isupper(c))
562 				sub++;	// shift
563 			sub++;
564 			while (sub >= 3) {
565 				sub -= 3;
566 				tl += 2;
567 			}
568 		} while (sub && p + sl < l);
569 		if (exact && sub == 2 && p + sl == l) {
570 			// special case, can encode last block with shift 0 at end (Is this
571 			// valid when not end of target buffer?)
572 			sub = 0;
573 			tl += 2;
574 		}
575 		if (!sub) {	// can encode C40
576 			bl = 0;
577 			if (p + sl < l) {
578 				for (e = 0; e < E_MAX; e++)
579 					if (enc[p + sl][e].t
580 					    &&
581 					    ((t =
582 					      enc[p + sl][e].t +
583 					      switchcost[E_C40][e]) < bl
584 					     || !bl)) {
585 						bl = t;
586 						b = e;
587 					}
588 				if (exact && enc[p + sl][E_ASCII].t == 1 && 1 < bl) {
589 					// special case, switch to ASCII for last bytes
590 					bl = 1;
591 					b = E_ASCII;
592 				}
593 			}
594 			enc[p][E_C40].t = tl + bl;
595 			enc[p][E_C40].s = sl;
596 			if (bl && b == E_C40)
597 				enc[p][b].s += enc[p + sl][b].s;
598 		}
599 		// Text
600 		sub = tl = sl = 0;
601 		do {
602 			unsigned char c = s[p + sl++];
603 			if (c & 0x80) {	// shift + upper
604 				sub += 2;
605 				c &= 0x7F;
606 			}
607 			if (c != ' ' && !isdigit(c) && !islower(c))
608 				sub++;	// shift
609 			sub++;
610 			while (sub >= 3) {
611 				sub -= 3;
612 				tl += 2;
613 			}
614 		} while (sub && p + sl < l);
615 		if (exact && sub == 2 && p + sl == l) {
616 			// special case, can encode last block with shift 0 at end (Is this
617 			// valid when not end of target buffer?)
618 			sub = 0;
619 			tl += 2;
620 		}
621 		if (!sub && sl) {	// can encode Text
622 			bl = 0;
623 			if (p + sl < l) {
624 				for (e = 0; e < E_MAX; e++)
625 					if (enc[p + sl][e].t
626 					    &&
627 					    ((t =
628 					      enc[p + sl][e].t +
629 					      switchcost[E_TEXT][e]) < bl
630 					     || !bl)) {
631 						bl = t;
632 						b = e;
633 					}
634 				if (exact && enc[p + sl][E_ASCII].t == 1 && 1 < bl) {	// special case, switch to ASCII for last bytes
635 					bl = 1;
636 					b = E_ASCII;
637 				}
638 			}
639 			enc[p][E_TEXT].t = tl + bl;
640 			enc[p][E_TEXT].s = sl;
641 			if (bl && b == E_TEXT)
642 				enc[p][b].s += enc[p + sl][b].s;
643 		}
644 		// X12
645 		sub = tl = sl = 0;
646 		do {
647 			unsigned char c = s[p + sl++];
648 			if (c != 13 && c != '*' && c != '>' && c != ' '
649 			    && !isdigit(c) && !isupper(c)) {
650 				sl = 0;
651 				break;
652 			}
653 			sub++;
654 			while (sub >= 3) {
655 				sub -= 3;
656 				tl += 2;
657 			}
658 		} while (sub && p + sl < l);
659 		if (!sub && sl) {	// can encode X12
660 			bl = 0;
661 			if (p + sl < l) {
662 				for (e = 0; e < E_MAX; e++)
663 					if (enc[p + sl][e].t
664 					    &&
665 					    ((t =
666 					      enc[p + sl][e].t +
667 					      switchcost[E_X12][e]) < bl
668 					     || !bl)) {
669 						bl = t;
670 						b = e;
671 					}
672 				if (exact && enc[p + sl][E_ASCII].t == 1 && 1 < bl) {
673 					// special case, switch to ASCII for last bytes
674 					bl = 1;
675 					b = E_ASCII;
676 				}
677 			}
678 			enc[p][E_X12].t = tl + bl;
679 			enc[p][E_X12].s = sl;
680 			if (bl && b == E_X12)
681 				enc[p][b].s += enc[p + sl][b].s;
682 		}
683 		// EDIFACT
684 		sl = bl = 0;
685 		if (s[p + 0] >= 32 && s[p + 0] <= 94) {	// can encode 1
686 			char bs = 0;
687 			if (p + 1 == l) {
688 				bl = 2;
689 				bs = 1;
690 			} else
691 				for (e = 0; e < E_MAX; e++)
692 					if (e != E_EDIFACT && enc[p + 1][e].t
693 					    &&
694 					    ((t =
695 					      2 + enc[p + 1][e].t +
696 					      switchcost[E_ASCII][e])
697 					     < bl || !bl))	// E_ASCII as allowed for unlatch
698 					{
699 						bs = 1;
700 						bl = t;
701 						b = e;
702 					}
703 			if (p + 1 < l && s[p + 1] >= 32 && s[p + 1] <= 94) {	// can encode 2
704 				if (p + 2 == l) {
705 					if (!bl || bl > 2) {
706 						bl = 3;
707 						bs = 2;
708 					}
709 				} else
710 					for (e = 0; e < E_MAX; e++)
711 						if (e != E_EDIFACT
712 						    && enc[p + 2][e].t
713 						    &&
714 						    ((t =
715 						      3 + enc[p + 2][e].t +
716 						      switchcost[E_ASCII][e])
717 						     < bl || !bl))	// E_ASCII as allowed for unlatch
718 						{
719 							bs = 2;
720 							bl = t;
721 							b = e;
722 						}
723 				if (p + 2 < l && s[p + 2] >= 32 && s[p + 2] <= 94) {	// can encode 3
724 					if (p + 3 == l) {
725 						if (!bl || bl > 3) {
726 							bl = 3;
727 							bs = 3;
728 						}
729 					} else
730 						for (e = 0; e < E_MAX; e++)
731 							if (e != E_EDIFACT
732 							    && enc[p + 3][e].t
733 							    &&
734 							    ((t =
735 							      3 + enc[p +
736 								      3][e].t +
737 							      switchcost
738 							      [E_ASCII][e])
739 							     < bl || !bl))	// E_ASCII as allowed for unlatch
740 							{
741 								bs = 3;
742 								bl = t;
743 								b = e;
744 							}
745 					if (p + 4 < l && s[p + 3] >= 32 && s[p + 3] <= 94) {	// can encode 4
746 						if (p + 4 == l) {
747 							if (!bl || bl > 3) {
748 								bl = 3;
749 								bs = 4;
750 							}
751 						} else {
752 							for (e = 0; e < E_MAX;
753 							     e++)
754 								if (enc[p + 4]
755 								    [e].t
756 								    &&
757 								    ((t =
758 								      3 +
759 								      enc[p +
760 									  4][e].
761 								      t +
762 								      switchcost
763 								      [E_EDIFACT]
764 								      [e]) < bl
765 								     || !bl)) {
766 									bs = 4;
767 									bl = t;
768 									b = e;
769 								}
770 							if (exact
771 							    && enc[p +
772 								   4][E_ASCII].t
773 							    && enc[p +
774 								   4][E_ASCII].
775 							    t <= 2
776 							    && (t =
777 								3 + enc[p +
778 									4]
779 								[E_ASCII].t) <
780 							    bl) {
781 								// special case, switch to ASCII for last 1 ot two bytes
782 								bs = 4;
783 								bl = t;
784 								b = E_ASCII;
785 							}
786 						}
787 					}
788 				}
789 			}
790 			enc[p][E_EDIFACT].t = bl;
791 			enc[p][E_EDIFACT].s = bs;
792 			if (bl && b == E_EDIFACT)
793 				enc[p][b].s += enc[p + bs][b].s;
794 		}
795 		// Binary
796 		bl = 0;
797 		for (e = 0; e < E_MAX; e++)
798 			if (enc[p + 1][e].t
799 			    &&
800 			    ((t =
801 			      enc[p + 1][e].t + switchcost[E_BINARY][e] +
802 			      ((e == E_BINARY
803 				&& enc[p + 1][e].t == 249) ? 1 : 0))
804 			     < bl || !bl)) {
805 				bl = t;
806 				b = e;
807 			}
808 		enc[p][E_BINARY].t = 1 + bl;
809 		enc[p][E_BINARY].s = 1;
810 		if (bl && b == E_BINARY)
811 			enc[p][b].s += enc[p + 1][b].s;
812 		/*
813 		 * fprintf (stderr, "%d:", p); for (e = 0; e < E_MAX; e++) fprintf \
814 		 * (stderr, " %c*%d/%d", encchr[e], enc[p][e].s, enc[p][e].t); \
815 		 * fprintf (stderr, "\n");
816 		 */
817 	}
818 	encoding = safemalloc(1, l + 1);
819 	p = 0;
820 	{
821 		int cur = E_ASCII;	// starts ASCII
822 		while (p < l) {
823 			int t, m = 0;
824 			int b = 0;
825 			for (e = 0; e < E_MAX; e++)
826 				if (enc[p][e].t
827 				    && ((t = enc[p][e].t + switchcost[cur][e]) <
828 					m || t == m && e == cur || !m)) {
829 					b = e;
830 					m = t;
831 				}
832 			cur = b;
833 			m = enc[p][b].s;
834 			if (!p && lenp)
835 				*lenp = enc[p][b].t;
836 			while (p < l && m--)
837 				encoding[p++] = encchr[b];
838 		}
839 	}
840 	encoding[p] = 0;
841 	return encoding;
842 }
843 
iec16022ecc200(int * Wptr,int * Hptr,char ** encodingptr,int barcodelen,const unsigned char * barcode,int * lenp,int * maxp,int * eccp)844 unsigned char *iec16022ecc200(int *Wptr, int *Hptr, char **encodingptr,
845 			      int barcodelen, const unsigned char *barcode,
846 			      int *lenp, int *maxp, int *eccp)
847 {
848     return iec16022ecc200f(Wptr, Hptr, encodingptr, barcodelen, barcode, lenp, maxp, eccp, 0);
849 }
850 
851 /*
852  * Main encoding function
853  * Returns the grid (malloced) containing the matrix. L corner at 0,0.
854  * Takes suggested size in *Wptr, *Hptr, or 0,0. Fills in actual size.
855  * Takes barcodelen and barcode to be encoded
856  * Note, if *encodingptr is null, then fills with auto picked (malloced)
857  * encoding
858  * If lenp not null, then the length of encoded data before any final
859  * unlatch or pad is stored
860  * If maxp not null, then the max storage of this size code is stored
861  * If eccp not null, then the number of ecc bytes used in this size is
862  * stored
863  * Returns 0 on error (writes to stderr with details).
864  */
865 
iec16022ecc200f(int * Wptr,int * Hptr,char ** encodingptr,int barcodelen,const unsigned char * barcode,int * lenp,int * maxp,int * eccp,int flags)866 unsigned char *iec16022ecc200f(int *Wptr, int *Hptr, char **encodingptr,
867 			      int barcodelen, const unsigned char *barcode,
868 			      int *lenp, int *maxp, int *eccp, int flags)
869 {
870 	unsigned char binary[3000];	// encoded raw data and ecc to place in barcode
871 	int W = 0, H = 0;
872 	char *encoding = 0;
873 	unsigned char *grid = 0;
874 	const struct ecc200matrix_s *matrix;
875 	memset(binary, 0, sizeof(binary));
876 	if (encodingptr)
877 		encoding = *encodingptr;
878 	if (Wptr)
879 		W = *Wptr;
880 	if (Hptr)
881 		H = *Hptr;
882 
883 	// encoding
884 	if (W) {		// known size
885 		for (matrix = ecc200matrix; matrix->W && (matrix->W != W ||
886 							  matrix->H != H);
887 		     matrix++) ;
888 		if (!matrix->W) {
889 			fprintf(stderr, "Invalid size %dx%d\n", W, H);
890 			return 0;
891 		}
892 		if (!encoding) {
893 			int len;
894 			char *e = encmake(barcodelen, barcode, &len, 1);
895 			if (e && len != matrix->bytes) {	// try not an exact fit
896 				free(e);
897 				e = encmake(barcodelen, barcode, &len, 0);
898 				if (len > matrix->bytes) {
899 					fprintf(stderr,
900 						"Cannot make barcode fit %dx%d\n",
901 						W, H);
902 					return 0;
903 				}
904 			}
905 			encoding = e;
906 		}
907 	} else {
908 		// find a suitable encoding
909 		if (encoding == NULL)
910 			encoding = encmake(barcodelen, barcode, NULL, 1);
911 
912 		if (encoding) {	// find one that fits chosen encoding
913 			for (matrix = ecc200matrix; matrix->W; matrix++)
914 				if (ecc200encode
915 				    (binary, matrix->bytes, barcode, barcodelen,
916 				     encoding, 0, flags))
917 					break;
918 		} else {
919 			int len;
920 			char *e;
921 			e = encmake(barcodelen, barcode, &len, 1);
922 			for (matrix = ecc200matrix;
923 			     matrix->W && matrix->bytes != len; matrix++) ;
924 			if (e && !matrix->W) {	// try for non exact fit
925 				free(e);
926 				e = encmake(barcodelen, barcode, &len, 0);
927 				for (matrix = ecc200matrix;
928 				     matrix->W && matrix->bytes < len;
929 				     matrix++) ;
930 			}
931 			encoding = e;
932 		}
933 		if (!matrix->W) {
934 			fprintf(stderr,
935 				"Cannot find suitable size, barcode too long\n");
936 			if (!encodingptr || encoding != *encodingptr)
937 				free(encoding);
938 			return 0;
939 		}
940 		W = matrix->W;
941 		H = matrix->H;
942 	}
943 	if (!encoding) {
944 		fprintf(stderr,
945 			"Barcode too long, could not find encoding\n");
946 		return 0;
947 	}
948 	if (!ecc200encode(binary, matrix->bytes, barcode, barcodelen,
949 			  encoding, lenp, flags)) {
950 		fprintf(stderr, "Barcode too long for %dx%d\n", W, H);
951 		if (!encodingptr || encoding != *encodingptr)
952 			free(encoding);
953 		return 0;
954 	}
955 	// ecc code
956 	ecc200(binary, matrix->bytes, matrix->datablock, matrix->rsblock);
957 	{			// placement
958 		int border_offset_y;
959 		int x, y, NC, NR, *places;
960 		NC = W - 2 * (W / matrix->FW);
961 		NR = H - 2 * (H / matrix->FH);
962 		places = safemalloc(NC, NR * sizeof(int));
963 		ecc200placement(places, NR, NC);
964 		grid = safemalloc(H, W + 16); // extra padding to simplify some operations
965 		for (y = 0; y < H; y += matrix->FH) {
966 			memset(grid + y * W, 1, W);
967 			for (x = 0; x < W; x += 2)
968 				grid[(y + matrix->FH - 1) * W + x] = 1;
969 		}
970 		for (x = 0; x < W; x += matrix->FW) {
971 			for (y = 0; y < H; y++)
972 				grid[y * W + x] = 1;
973 			for (y = 0; y < H; y += 2)
974 				grid[y * W + x + matrix->FW - 1] = 1;
975 		}
976 		border_offset_y = -1;
977 		for (y = 0; y < NR; y++) {
978 			int border_offset_x = -1;
979 			// jump over the 2 border pixels
980 			if (y % (matrix->FH - 2) == 0) border_offset_y += 2;
981 			for (x = 0; x < NC; x++) {
982 				int v = places[(NR - y - 1) * NC + x];
983 				// jump over the 2 border pixels
984 				if (x % (matrix->FW - 2) == 0) border_offset_x += 2;
985 				//fprintf (stderr, "%4d", v);
986 				if (v == 1 || v > 7
987 				    && (binary[(v >> 3) - 1] & (1 << (v & 7))))
988 					grid[(y + border_offset_y) * W +
989 					     x + border_offset_x] = 1;
990 			}
991 			//fprintf (stderr, "\n");
992 		}
993 		free(places);
994 	}
995 	if (Wptr)
996 		*Wptr = W;
997 	if (Hptr)
998 		*Hptr = H;
999 	if (encodingptr)
1000 		*encodingptr = encoding;
1001 	if (maxp)
1002 		*maxp = matrix->bytes;
1003 	if (eccp)
1004 		*eccp =
1005 		    (matrix->bytes + 2) / matrix->datablock * matrix->rsblock;
1006 	return grid;
1007 }
1008