1 /* composite.c - Handles GS1 Composite Symbols */
2
3 /*
4 libzint - the open source barcode library
5 Copyright (C) 2008-2017 Robin Stuart <rstuart114@gmail.com>
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 1. Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13 2. Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in the
15 documentation and/or other materials provided with the distribution.
16 3. Neither the name of the project nor the names of its contributors
17 may be used to endorse or promote products derived from this software
18 without specific prior written permission.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
24 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 SUCH DAMAGE.
31 */
32
33 /* The functions "getBit", "init928" and "encode928" are copyright BSI and are
34 released with permission under the following terms:
35
36 "Copyright subsists in all BSI publications. BSI also holds the copyright, in the
37 UK, of the international standardisation bodies. Except as
38 permitted under the Copyright, Designs and Patents Act 1988 no extract may be
39 reproduced, stored in a retrieval system or transmitted in any form or by any
40 means - electronic, photocopying, recording or otherwise - without prior written
41 permission from BSI.
42
43 "This does not preclude the free use, in the course of implementing the standard,
44 of necessary details such as symbols, and size, type or grade designations. If these
45 details are to be used for any other purpose than implementation then the prior
46 written permission of BSI must be obtained."
47
48 The date of publication for these functions is 31 May 2006
49 */
50
51 #include <stdio.h>
52 #include <string.h>
53 #include <stdlib.h>
54 #include <assert.h>
55 #include <math.h>
56 #include <assert.h>
57 #ifdef _MSC_VER
58 #include <malloc.h>
59 #endif
60 #include "common.h"
61 #include "large.h"
62 #include "composite.h"
63 #include "pdf417.h"
64 #include "gs1.h"
65
66 #define UINT unsigned short
67
68 extern int general_rules(char field[], char type[]);
69 extern int eanx(struct zint_symbol *symbol, unsigned char source[], int length);
70 extern int ean_128(struct zint_symbol *symbol, unsigned char source[], const size_t length);
71 extern int rss14(struct zint_symbol *symbol, unsigned char source[], int length);
72 extern int rsslimited(struct zint_symbol *symbol, unsigned char source[], int length);
73 extern int rssexpanded(struct zint_symbol *symbol, unsigned char source[], int length);
74
75 static UINT pwr928[69][7];
76
_min(int first,int second)77 static int _min(int first, int second) {
78
79 if (first <= second)
80 return first;
81 else
82 return second;
83 }
84
85 /* gets bit in bitString at bitPos */
getBit(UINT * bitStr,int bitPos)86 static int getBit(UINT *bitStr, int bitPos) {
87 return !!(bitStr[bitPos >> 4] & (0x8000 >> (bitPos & 15)));
88 }
89
90 /* initialize pwr928 encoding table */
init928(void)91 static void init928(void) {
92 int i, j, v;
93 int cw[7];
94 cw[6] = 1L;
95 for (i = 5; i >= 0; i--)
96 cw[i] = 0;
97
98 for (i = 0; i < 7; i++)
99 pwr928[0][i] = cw[i];
100 for (j = 1; j < 69; j++) {
101 for (v = 0, i = 6; i >= 1; i--) {
102 v = (2 * cw[i]) + (v / 928);
103 pwr928[j][i] = cw[i] = v % 928;
104 }
105 pwr928[j][0] = cw[0] = (2 * cw[0]) + (v / 928);
106 }
107 return;
108 }
109
110 /* converts bit string to base 928 values, codeWords[0] is highest order */
encode928(UINT bitString[],UINT codeWords[],int bitLng)111 static int encode928(UINT bitString[], UINT codeWords[], int bitLng) {
112 int i, j, b, bitCnt, cwNdx, cwCnt, cwLng;
113 for (cwNdx = cwLng = b = 0; b < bitLng; b += 69, cwNdx += 7) {
114 bitCnt = _min(bitLng - b, 69);
115 cwLng += cwCnt = bitCnt / 10 + 1;
116 for (i = 0; i < cwCnt; i++)
117 codeWords[cwNdx + i] = 0; /* init 0 */
118 for (i = 0; i < bitCnt; i++) {
119 if (getBit(bitString, b + bitCnt - i - 1)) {
120 for (j = 0; j < cwCnt; j++)
121 codeWords[cwNdx + j] += pwr928[i][j + 7 - cwCnt];
122 }
123 }
124 for (i = cwCnt - 1; i > 0; i--) {
125 /* add "carries" */
126 codeWords[cwNdx + i - 1] += codeWords[cwNdx + i] / 928L;
127 codeWords[cwNdx + i] %= 928L;
128 }
129 }
130 return (cwLng);
131 }
132
133 /* CC-A 2D component */
cc_a(struct zint_symbol * symbol,char source[],int cc_width)134 static int cc_a(struct zint_symbol *symbol, char source[], int cc_width) {
135 int i, strpos, segment, bitlen, cwCnt, variant, rows;
136 int k, offset, j, total, rsCodeWords[8];
137 int LeftRAPStart, RightRAPStart, CentreRAPStart, StartCluster;
138 int LeftRAP, RightRAP, CentreRAP, Cluster, dummy[5];
139 int loop;
140 UINT codeWords[28];
141 UINT bitStr[13];
142 char pattern[580];
143 char local_source[210]; /* A copy of source but with padding zeroes to make 208 bits */
144
145 variant = 0;
146
147 for (i = 0; i < 13; i++) {
148 bitStr[i] = 0;
149 }
150 for (i = 0; i < 28; i++) {
151 codeWords[i] = 0;
152 }
153
154 bitlen = (int)strlen(source);
155
156 for (i = 0; i < 208; i++) {
157 local_source[i] = '0';
158 }
159 for (i = 0; i < bitlen; i++) {
160 local_source[i] = source[i];
161 }
162 local_source[208] = '\0';
163
164 for (segment = 0; segment < 13; segment++) {
165 strpos = segment * 16;
166 for (i = 0; i < 16; i++) {
167 if (local_source[strpos + i] == '1') {
168 bitStr[segment] += (0x8000 >> i);
169 }
170 }
171 }
172
173 init928();
174 /* encode codeWords from bitStr */
175 cwCnt = encode928(bitStr, codeWords, bitlen);
176
177 switch (cc_width) {
178 case 2:
179 switch (cwCnt) {
180 case 6: variant = 0;
181 break;
182 case 8: variant = 1;
183 break;
184 case 9: variant = 2;
185 break;
186 case 11: variant = 3;
187 break;
188 case 12: variant = 4;
189 break;
190 case 14: variant = 5;
191 break;
192 case 17: variant = 6;
193 break;
194 }
195 break;
196 case 3:
197 switch (cwCnt) {
198 case 8: variant = 7;
199 break;
200 case 10: variant = 8;
201 break;
202 case 12: variant = 9;
203 break;
204 case 14: variant = 10;
205 break;
206 case 17: variant = 11;
207 break;
208 }
209 break;
210 case 4:
211 switch (cwCnt) {
212 case 8: variant = 12;
213 break;
214 case 11: variant = 13;
215 break;
216 case 14: variant = 14;
217 break;
218 case 17: variant = 15;
219 break;
220 case 20: variant = 16;
221 break;
222 }
223 break;
224 }
225
226 rows = ccaVariants[variant];
227 k = ccaVariants[17 + variant];
228 offset = ccaVariants[34 + variant];
229
230 /* Reed-Solomon error correction */
231
232 for (i = 0; i < 8; i++) {
233 rsCodeWords[i] = 0;
234 }
235 total = 0;
236 for (i = 0; i < cwCnt; i++) {
237 total = (codeWords[i] + rsCodeWords[k - 1]) % 929;
238 for (j = k - 1; j >= 0; j--) {
239 if (j == 0) {
240 rsCodeWords[j] = (929 - (total * ccaCoeffs[offset + j]) % 929) % 929;
241 } else {
242 rsCodeWords[j] = (rsCodeWords[j - 1] + 929 - (total * ccaCoeffs[offset + j]) % 929) % 929;
243 }
244 }
245 }
246
247 for (j = 0; j < k; j++) {
248 if (rsCodeWords[j] != 0) {
249 rsCodeWords[j] = 929 - rsCodeWords[j];
250 }
251 }
252
253 for (i = k - 1; i >= 0; i--) {
254 codeWords[cwCnt] = rsCodeWords[i];
255 cwCnt++;
256 }
257
258 /* Place data into table */
259 LeftRAPStart = aRAPTable[variant];
260 CentreRAPStart = aRAPTable[variant + 17];
261 RightRAPStart = aRAPTable[variant + 34];
262 StartCluster = aRAPTable[variant + 51] / 3;
263
264 LeftRAP = LeftRAPStart;
265 CentreRAP = CentreRAPStart;
266 RightRAP = RightRAPStart;
267 Cluster = StartCluster; /* Cluster can be 0, 1 or 2 for Cluster(0), Cluster(3) and Cluster(6) */
268
269 for (i = 0; i < rows; i++) {
270 strcpy(pattern, "");
271 offset = 929 * Cluster;
272 for (j = 0; j < 5; j++) {
273 dummy[j] = 0;
274 }
275 for (j = 0; j < cc_width; j++) {
276 dummy[j + 1] = codeWords[i * cc_width + j];
277 }
278 /* Copy the data into codebarre */
279 bin_append(rap_side[LeftRAP - 1], 10, pattern);
280 bin_append(pdf_bitpattern[offset + dummy[1]], 16, pattern);
281 strcat(pattern, "0");
282 if (cc_width == 3) {
283 bin_append(rap_centre[CentreRAP - 1], 10, pattern);
284 }
285 if (cc_width >= 2) {
286 bin_append(pdf_bitpattern[offset + dummy[2]], 16, pattern);
287 strcat(pattern, "0");
288 }
289 if (cc_width == 4) {
290 bin_append(rap_centre[CentreRAP - 1], 10, pattern);
291 }
292 if (cc_width >= 3) {
293 bin_append(pdf_bitpattern[offset + dummy[3]], 16, pattern);
294 strcat(pattern, "0");
295 }
296 if (cc_width == 4) {
297 bin_append(pdf_bitpattern[offset + dummy[4]], 16, pattern);
298 strcat(pattern, "0");
299 }
300 bin_append(rap_side[RightRAP - 1], 10, pattern);
301 strcat(pattern, "1"); /* stop */
302
303 /* so now pattern[] holds the string of '1's and '0's. - copy this to the symbol */
304 for (loop = 0; loop < (int) strlen(pattern); loop++) {
305 if (pattern[loop] == '1') {
306 set_module(symbol, i, loop);
307 }
308 }
309 symbol->row_height[i] = 2;
310 symbol->rows++;
311 symbol->width = strlen(pattern);
312
313 /* Set up RAPs and Cluster for next row */
314 LeftRAP++;
315 CentreRAP++;
316 RightRAP++;
317 Cluster++;
318
319 if (LeftRAP == 53) {
320 LeftRAP = 1;
321 }
322 if (CentreRAP == 53) {
323 CentreRAP = 1;
324 }
325 if (RightRAP == 53) {
326 RightRAP = 1;
327 }
328 if (Cluster == 3) {
329 Cluster = 0;
330 }
331 }
332
333 return 0;
334 }
335
336 /* CC-B 2D component */
cc_b(struct zint_symbol * symbol,char source[],int cc_width)337 static int cc_b(struct zint_symbol *symbol, char source[], int cc_width) {
338 int length, i, binloc;
339 #ifndef _MSC_VER
340 unsigned char data_string[(strlen(source) / 8) + 3];
341 #else
342 unsigned char* data_string = (unsigned char*) _alloca((strlen(source) / 8) + 3);
343 #endif
344 int chainemc[180], mclength;
345 int k, j, p, longueur, mccorrection[50], offset;
346 int total, dummy[5];
347 char pattern[580];
348 int variant, LeftRAPStart, CentreRAPStart, RightRAPStart, StartCluster;
349 int LeftRAP, CentreRAP, RightRAP, Cluster, loop;
350
351 length = strlen(source) / 8;
352
353 for (i = 0; i < length; i++) {
354 binloc = i * 8;
355
356 data_string[i] = 0;
357 for (p = 0; p < 8; p++) {
358 if (source[binloc + p] == '1') {
359 data_string[i] += (0x80 >> p);
360 }
361 }
362 }
363
364
365 mclength = 0;
366
367 /* "the CC-B component shall have codeword 920 in the first symbol character position" (section 9a) */
368 chainemc[mclength] = 920;
369 mclength++;
370
371 byteprocess(chainemc, &mclength, data_string, 0, length, 0);
372
373 /* Now figure out which variant of the symbol to use and load values accordingly */
374
375 variant = 0;
376
377 if (cc_width == 2) {
378 variant = 13;
379 if (mclength <= 33) {
380 variant = 12;
381 }
382 if (mclength <= 29) {
383 variant = 11;
384 }
385 if (mclength <= 24) {
386 variant = 10;
387 }
388 if (mclength <= 19) {
389 variant = 9;
390 }
391 if (mclength <= 13) {
392 variant = 8;
393 }
394 if (mclength <= 8) {
395 variant = 7;
396 }
397 }
398
399 if (cc_width == 3) {
400 variant = 23;
401 if (mclength <= 70) {
402 variant = 22;
403 }
404 if (mclength <= 58) {
405 variant = 21;
406 }
407 if (mclength <= 46) {
408 variant = 20;
409 }
410 if (mclength <= 34) {
411 variant = 19;
412 }
413 if (mclength <= 24) {
414 variant = 18;
415 }
416 if (mclength <= 18) {
417 variant = 17;
418 }
419 if (mclength <= 14) {
420 variant = 16;
421 }
422 if (mclength <= 10) {
423 variant = 15;
424 }
425 if (mclength <= 6) {
426 variant = 14;
427 }
428 }
429
430 if (cc_width == 4) {
431 variant = 34;
432 if (mclength <= 108) {
433 variant = 33;
434 }
435 if (mclength <= 90) {
436 variant = 32;
437 }
438 if (mclength <= 72) {
439 variant = 31;
440 }
441 if (mclength <= 54) {
442 variant = 30;
443 }
444 if (mclength <= 39) {
445 variant = 29;
446 }
447 if (mclength <= 30) {
448 variant = 28;
449 }
450 if (mclength <= 24) {
451 variant = 27;
452 }
453 if (mclength <= 18) {
454 variant = 26;
455 }
456 if (mclength <= 12) {
457 variant = 25;
458 }
459 if (mclength <= 8) {
460 variant = 24;
461 }
462 }
463
464 /* Now we have the variant we can load the data - from here on the same as MicroPDF417 code */
465 variant--;
466 assert(variant >= 0);
467 symbol->option_2 = MicroVariants[variant]; /* columns */
468 symbol->rows = MicroVariants[variant + 34]; /* rows */
469 k = MicroVariants[variant + 68]; /* number of EC CWs */
470 longueur = (symbol->option_2 * symbol->rows) - k; /* number of non-EC CWs */
471 i = longueur - mclength; /* amount of padding required */
472 offset = MicroVariants[variant + 102]; /* coefficient offset */
473
474 /* We add the padding */
475 while (i > 0) {
476 chainemc[mclength] = 900;
477 mclength++;
478 i--;
479 }
480
481 /* Reed-Solomon error correction */
482 longueur = mclength;
483 for (loop = 0; loop < 50; loop++) {
484 mccorrection[loop] = 0;
485 }
486 total = 0;
487 for (i = 0; i < longueur; i++) {
488 total = (chainemc[i] + mccorrection[k - 1]) % 929;
489 for (j = k - 1; j >= 0; j--) {
490 if (j == 0) {
491 mccorrection[j] = (929 - (total * Microcoeffs[offset + j]) % 929) % 929;
492 } else {
493 mccorrection[j] = (mccorrection[j - 1] + 929 - (total * Microcoeffs[offset + j]) % 929) % 929;
494 }
495 }
496 }
497
498 for (j = 0; j < k; j++) {
499 if (mccorrection[j] != 0) {
500 mccorrection[j] = 929 - mccorrection[j];
501 }
502 }
503 /* we add these codes to the string */
504 for (i = k - 1; i >= 0; i--) {
505 chainemc[mclength] = mccorrection[i];
506 mclength++;
507 }
508
509 /* Now get the RAP (Row Address Pattern) start values */
510 LeftRAPStart = RAPTable[variant];
511 CentreRAPStart = RAPTable[variant + 34];
512 RightRAPStart = RAPTable[variant + 68];
513 StartCluster = RAPTable[variant + 102] / 3;
514
515 /* That's all values loaded, get on with the encoding */
516
517 LeftRAP = LeftRAPStart;
518 CentreRAP = CentreRAPStart;
519 RightRAP = RightRAPStart;
520 Cluster = StartCluster;
521 /* Cluster can be 0, 1 or 2 for Cluster(0), Cluster(3) and Cluster(6) */
522
523 for (i = 0; i < symbol->rows; i++) {
524 strcpy(pattern, "");
525 offset = 929 * Cluster;
526 for (j = 0; j < 5; j++) {
527 dummy[j] = 0;
528 }
529 for (j = 0; j < symbol->option_2; j++) {
530 dummy[j + 1] = chainemc[i * symbol->option_2 + j];
531 }
532 /* Copy the data into codebarre */
533 bin_append(rap_side[LeftRAP - 1], 10, pattern);
534 bin_append(pdf_bitpattern[offset + dummy[1]], 16, pattern);
535 strcat(pattern, "0");
536 if (cc_width == 3) {
537 bin_append(rap_centre[CentreRAP - 1], 10, pattern);
538 }
539 if (cc_width >= 2) {
540 bin_append(pdf_bitpattern[offset + dummy[2]], 16, pattern);
541 strcat(pattern, "0");
542 }
543 if (cc_width == 4) {
544 bin_append(rap_centre[CentreRAP - 1], 10, pattern);
545 }
546 if (cc_width >= 3) {
547 bin_append(pdf_bitpattern[offset + dummy[3]], 16, pattern);
548 strcat(pattern, "0");
549 }
550 if (cc_width == 4) {
551 bin_append(pdf_bitpattern[offset + dummy[4]], 16, pattern);
552 strcat(pattern, "0");
553 }
554 bin_append(rap_side[RightRAP - 1], 10, pattern);
555 strcat(pattern, "1"); /* stop */
556
557 /* so now pattern[] holds the string of '1's and '0's. - copy this to the symbol */
558 for (loop = 0; loop < (int) strlen(pattern); loop++) {
559 if (pattern[loop] == '1') {
560 set_module(symbol, i, loop);
561 }
562 }
563 symbol->row_height[i] = 2;
564 symbol->width = strlen(pattern);
565
566 /* Set up RAPs and Cluster for next row */
567 LeftRAP++;
568 CentreRAP++;
569 RightRAP++;
570 Cluster++;
571
572 if (LeftRAP == 53) {
573 LeftRAP = 1;
574 }
575 if (CentreRAP == 53) {
576 CentreRAP = 1;
577 }
578 if (RightRAP == 53) {
579 RightRAP = 1;
580 }
581 if (Cluster == 3) {
582 Cluster = 0;
583 }
584 }
585
586 return 0;
587 }
588
589 /* CC-C 2D component - byte compressed PDF417 */
cc_c(struct zint_symbol * symbol,char source[],int cc_width,int ecc_level)590 static int cc_c(struct zint_symbol *symbol, char source[], int cc_width, int ecc_level) {
591 int length, i, p, binloc;
592 #ifndef _MSC_VER
593 unsigned char data_string[(strlen(source) / 8) + 4];
594 #else
595 unsigned char* data_string = (unsigned char*) _alloca((strlen(source) / 8) + 4);
596 #endif
597 int chainemc[1000], mclength, k;
598 int offset, longueur, loop, total, j, mccorrection[520];
599 int c1, c2, c3, dummy[35];
600 char pattern[580];
601
602 length = strlen(source) / 8;
603
604 for (i = 0; i < length; i++) {
605 binloc = i * 8;
606
607 data_string[i] = 0;
608 for (p = 0; p < 8; p++) {
609 if (source[binloc + p] == '1') {
610 data_string[i] += (0x80 >> p);
611 }
612 }
613 }
614
615 mclength = 0;
616
617 chainemc[mclength] = 0; /* space for length descriptor */
618 mclength++;
619 chainemc[mclength] = 920; /* CC-C identifier */
620 mclength++;
621
622 byteprocess(chainemc, &mclength, data_string, 0, length, 0);
623
624 chainemc[0] = mclength;
625
626 k = 1;
627 for (i = 1; i <= (ecc_level + 1); i++) {
628 k *= 2;
629 }
630
631 /* 796 - we now take care of the Reed Solomon codes */
632 switch (ecc_level) {
633 case 1: offset = 2;
634 break;
635 case 2: offset = 6;
636 break;
637 case 3: offset = 14;
638 break;
639 case 4: offset = 30;
640 break;
641 case 5: offset = 62;
642 break;
643 case 6: offset = 126;
644 break;
645 case 7: offset = 254;
646 break;
647 case 8: offset = 510;
648 break;
649 default: offset = 0;
650 break;
651 }
652
653 longueur = mclength;
654 for (loop = 0; loop < 520; loop++) {
655 mccorrection[loop] = 0;
656 }
657 total = 0;
658 for (i = 0; i < longueur; i++) {
659 total = (chainemc[i] + mccorrection[k - 1]) % 929;
660 for (j = k - 1; j >= 0; j--) {
661 if (j == 0) {
662 mccorrection[j] = (929 - (total * coefrs[offset + j]) % 929) % 929;
663 } else {
664 mccorrection[j] = (mccorrection[j - 1] + 929 - (total * coefrs[offset + j]) % 929) % 929;
665 }
666 }
667 }
668
669 for (j = 0; j < k; j++) {
670 if (mccorrection[j] != 0) {
671 mccorrection[j] = 929 - mccorrection[j];
672 }
673 }
674 /* we add these codes to the string */
675 for (i = k - 1; i >= 0; i--) {
676 chainemc[mclength] = mccorrection[i];
677 mclength++;
678 }
679
680 /* 818 - The CW string is finished */
681 c1 = (mclength / cc_width - 1) / 3;
682 c2 = ecc_level * 3 + (mclength / cc_width - 1) % 3;
683 c3 = cc_width - 1;
684
685 /* we now encode each row */
686 for (i = 0; i <= (mclength / cc_width) - 1; i++) {
687 for (j = 0; j < cc_width; j++) {
688 dummy[j + 1] = chainemc[i * cc_width + j];
689 }
690 k = (i / 3) * 30;
691 switch (i % 3) {
692 case 0:
693 dummy[0] = k + c1;
694 dummy[cc_width + 1] = k + c3;
695 offset = 0; /* cluster(0) */
696 break;
697 case 1:
698 dummy[0] = k + c2;
699 dummy[cc_width + 1] = k + c1;
700 offset = 929; /* cluster(3) */
701 break;
702 case 2:
703 dummy[0] = k + c3;
704 dummy[cc_width + 1] = k + c2;
705 offset = 1858; /* cluster(6) */
706 break;
707 }
708 strcpy(pattern, "");
709 bin_append(0x1FEA8, 17, pattern); /* Row start */
710
711 for (j = 0; j <= cc_width + 1; j++) {
712 bin_append(pdf_bitpattern[offset + dummy[j]], 16, pattern);
713 strcat(pattern, "0");
714 }
715 bin_append(0x3FA29, 18, pattern); /* Row Stop */
716
717 for (loop = 0; loop < (int) strlen(pattern); loop++) {
718 if (pattern[loop] == '1') {
719 set_module(symbol, i, loop);
720 }
721 }
722 symbol->row_height[i] = 3;
723 }
724 symbol->rows = (mclength / cc_width);
725 symbol->width = (int)strlen(pattern);
726
727 return 0;
728 }
729
calc_padding_cca(int binary_length,int cc_width)730 static int calc_padding_cca(int binary_length, int cc_width) {
731 int target_bitsize = 0;
732
733 switch (cc_width) {
734 case 2:
735 if (binary_length <= 167) {
736 target_bitsize = 167;
737 }
738 if (binary_length <= 138) {
739 target_bitsize = 138;
740 }
741 if (binary_length <= 118) {
742 target_bitsize = 118;
743 }
744 if (binary_length <= 108) {
745 target_bitsize = 108;
746 }
747 if (binary_length <= 88) {
748 target_bitsize = 88;
749 }
750 if (binary_length <= 78) {
751 target_bitsize = 78;
752 }
753 if (binary_length <= 59) {
754 target_bitsize = 59;
755 }
756 break;
757 case 3:
758 if (binary_length <= 167) {
759 target_bitsize = 167;
760 }
761 if (binary_length <= 138) {
762 target_bitsize = 138;
763 }
764 if (binary_length <= 118) {
765 target_bitsize = 118;
766 }
767 if (binary_length <= 98) {
768 target_bitsize = 98;
769 }
770 if (binary_length <= 78) {
771 target_bitsize = 78;
772 }
773 break;
774 case 4:
775 if (binary_length <= 197) {
776 target_bitsize = 197;
777 }
778 if (binary_length <= 167) {
779 target_bitsize = 167;
780 }
781 if (binary_length <= 138) {
782 target_bitsize = 138;
783 }
784 if (binary_length <= 108) {
785 target_bitsize = 108;
786 }
787 if (binary_length <= 78) {
788 target_bitsize = 78;
789 }
790 break;
791 }
792
793 return target_bitsize;
794 }
795
calc_padding_ccb(int binary_length,int cc_width)796 int calc_padding_ccb(int binary_length, int cc_width) {
797 int target_bitsize = 0;
798
799 switch (cc_width) {
800 case 2:
801 if (binary_length <= 336) {
802 target_bitsize = 336;
803 }
804 if (binary_length <= 296) {
805 target_bitsize = 296;
806 }
807 if (binary_length <= 256) {
808 target_bitsize = 256;
809 }
810 if (binary_length <= 208) {
811 target_bitsize = 208;
812 }
813 if (binary_length <= 160) {
814 target_bitsize = 160;
815 }
816 if (binary_length <= 104) {
817 target_bitsize = 104;
818 }
819 if (binary_length <= 56) {
820 target_bitsize = 56;
821 }
822 break;
823 case 3:
824 if (binary_length <= 768) {
825 target_bitsize = 768;
826 }
827 if (binary_length <= 648) {
828 target_bitsize = 648;
829 }
830 if (binary_length <= 536) {
831 target_bitsize = 536;
832 }
833 if (binary_length <= 416) {
834 target_bitsize = 416;
835 }
836 if (binary_length <= 304) {
837 target_bitsize = 304;
838 }
839 if (binary_length <= 208) {
840 target_bitsize = 208;
841 }
842 if (binary_length <= 152) {
843 target_bitsize = 152;
844 }
845 if (binary_length <= 112) {
846 target_bitsize = 112;
847 }
848 if (binary_length <= 72) {
849 target_bitsize = 72;
850 }
851 if (binary_length <= 32) {
852 target_bitsize = 32;
853 }
854 break;
855 case 4:
856 if (binary_length <= 1184) {
857 target_bitsize = 1184;
858 }
859 if (binary_length <= 1016) {
860 target_bitsize = 1016;
861 }
862 if (binary_length <= 840) {
863 target_bitsize = 840;
864 }
865 if (binary_length <= 672) {
866 target_bitsize = 672;
867 }
868 if (binary_length <= 496) {
869 target_bitsize = 496;
870 }
871 if (binary_length <= 352) {
872 target_bitsize = 352;
873 }
874 if (binary_length <= 264) {
875 target_bitsize = 264;
876 }
877 if (binary_length <= 208) {
878 target_bitsize = 208;
879 }
880 if (binary_length <= 152) {
881 target_bitsize = 152;
882 }
883 if (binary_length <= 96) {
884 target_bitsize = 96;
885 }
886 if (binary_length <= 56) {
887 target_bitsize = 56;
888 }
889 break;
890 }
891
892 return target_bitsize;
893 }
894
calc_padding_ccc(int binary_length,int * cc_width,int lin_width,int * ecc)895 int calc_padding_ccc(int binary_length, int *cc_width, int lin_width, int *ecc) {
896 int target_bitsize = 0;
897 int byte_length, codewords_used, ecc_level, ecc_codewords, rows;
898 int codewords_total, target_codewords, target_bytesize;
899 int i;
900
901 byte_length = binary_length / 8;
902 if (binary_length % 8 != 0) {
903 byte_length++;
904 }
905
906 codewords_used = (byte_length / 6) * 5;
907 codewords_used += byte_length % 6;
908
909 ecc_level = 7;
910 if (codewords_used <= 1280) {
911 ecc_level = 6;
912 }
913 if (codewords_used <= 640) {
914 ecc_level = 5;
915 }
916 if (codewords_used <= 320) {
917 ecc_level = 4;
918 }
919 if (codewords_used <= 160) {
920 ecc_level = 3;
921 }
922 if (codewords_used <= 40) {
923 ecc_level = 2;
924 }
925 *(ecc) = ecc_level;
926 ecc_codewords = 1;
927 for (i = 1; i <= (ecc_level + 1); i++) {
928 ecc_codewords *= 2;
929 }
930
931 codewords_used += ecc_codewords;
932 codewords_used += 3;
933
934 *(cc_width) = (lin_width - 62) / 17;
935 /* stop the symbol from becoming too high */
936 do {
937 *(cc_width) = *(cc_width) + 1;
938 rows = codewords_used / *(cc_width);
939 } while (rows > 90);
940
941 if (codewords_used % *(cc_width) != 0) {
942 rows++;
943 }
944
945 codewords_total = *(cc_width) * rows;
946
947 if (codewords_total > 928) { // PDF_MAX
948 return 0;
949 }
950
951 target_codewords = codewords_total - ecc_codewords;
952 target_codewords -= 3;
953
954 target_bytesize = 6 * (target_codewords / 5);
955 target_bytesize += target_codewords % 5;
956
957 target_bitsize = 8 * target_bytesize;
958
959 return target_bitsize;
960 }
961
cc_binary_string(struct zint_symbol * symbol,const char source[],char binary_string[],int cc_mode,int * cc_width,int * ecc,int lin_width)962 static int cc_binary_string(struct zint_symbol *symbol, const char source[], char binary_string[], int cc_mode, int *cc_width, int *ecc, int lin_width) { /* Handles all data encodation from section 5 of ISO/IEC 24723 */
963 int encoding_method, read_posn, d1, d2, alpha_pad;
964 int i, j, ai_crop, fnc1_latch;
965 long int group_val;
966 int ai90_mode, latch, remainder, binary_length;
967 char date_str[4];
968 #ifndef _MSC_VER
969 char general_field[strlen(source) + 1], general_field_type[strlen(source) + 1];
970 #else
971 char* general_field = (char*) _alloca(strlen(source) + 1);
972 char* general_field_type = (char*) _alloca(strlen(source) + 1);
973 #endif
974 int target_bitsize;
975
976 encoding_method = 1;
977 read_posn = 0;
978 ai_crop = 0;
979 fnc1_latch = 0;
980 alpha_pad = 0;
981 ai90_mode = 0;
982 *ecc = 0;
983 target_bitsize = 0;
984
985 if ((source[0] == '1') && ((source[1] == '0') || (source[1] == '1') || (source[1] == '7')) && (strlen(source) > 8)) {
986 /* Source starts (10), (11) or (17) */
987 encoding_method = 2;
988 }
989
990 if ((source[0] == '9') && (source[1] == '0')) {
991 /* Source starts (90) */
992 encoding_method = 3;
993 }
994
995 if (encoding_method == 1) {
996 strcat(binary_string, "0");
997 }
998
999 if (encoding_method == 2) {
1000 /* Encoding Method field "10" - date and lot number */
1001
1002 strcat(binary_string, "10");
1003
1004 if (source[1] == '0') {
1005 /* No date data */
1006 strcat(binary_string, "11");
1007 read_posn = 2;
1008 } else {
1009 /* Production Date (11) or Expiration Date (17) */
1010 date_str[0] = source[2];
1011 date_str[1] = source[3];
1012 date_str[2] = '\0';
1013 group_val = atoi(date_str) * 384;
1014
1015 date_str[0] = source[4];
1016 date_str[1] = source[5];
1017 group_val += (atoi(date_str) - 1) * 32;
1018
1019 date_str[0] = source[6];
1020 date_str[1] = source[7];
1021 group_val += atoi(date_str);
1022
1023 bin_append(group_val, 16, binary_string);
1024
1025 if (source[1] == '1') {
1026 /* Production Date AI 11 */
1027 strcat(binary_string, "0");
1028 } else {
1029 /* Expiration Date AI 17 */
1030 strcat(binary_string, "1");
1031 }
1032 read_posn = 8;
1033 }
1034
1035 if ((source[read_posn] == '1') && (source[read_posn + 1] == '0')) {
1036 /* Followed by AI 10 - strip this from general field */
1037 read_posn += 2;
1038 } else {
1039 /* An FNC1 character needs to be inserted in the general field */
1040 fnc1_latch = 1;
1041 }
1042 }
1043
1044 if (encoding_method == 3) {
1045 /* Encodation Method field of "11" - AI 90 */
1046 #ifndef _MSC_VER
1047 char ninety[strlen(source) + 1];
1048 #else
1049 char* ninety = (char*) _alloca(strlen(source) + 1);
1050 #endif
1051 char numeric_part[4];
1052 int alpha, alphanum, numeric, test1, test2, test3, next_ai_posn;
1053 int numeric_value, table3_letter;
1054
1055 /* "This encodation method may be used if an element string with an AI
1056 90 occurs at the start of the data message, and if the data field
1057 following the two-digit AI 90 starts with an alphanumeric string which
1058 complies with a specific format." (para 5.2.2) */
1059
1060 i = 0;
1061 do {
1062 ninety[i] = source[i + 2];
1063 i++;
1064 } while ((strlen(source) > i + 2) && ('[' != source[i + 2]));
1065 ninety[i] = '\0';
1066
1067 /* Find out if the AI 90 data is alphabetic or numeric or both */
1068
1069 alpha = 0;
1070 alphanum = 0;
1071 numeric = 0;
1072
1073 for (i = 0; i < (int) strlen(ninety); i++) {
1074
1075 if ((ninety[i] >= 'A') && (ninety[i] <= 'Z')) {
1076 /* Character is alphabetic */
1077 alpha += 1;
1078 }
1079
1080 if ((ninety[i] >= '0') && (ninety[i] <= '9')) {
1081 /* Character is numeric */
1082 numeric += 1;
1083 }
1084
1085 switch (ninety[i]) {
1086 case '*':
1087 case ',':
1088 case '-':
1089 case '.':
1090 case '/': alphanum += 1;
1091 break;
1092 }
1093
1094 if (!(((ninety[i] >= '0') && (ninety[i] <= '9')) || ((ninety[i] >= 'A') && (ninety[i] <= 'Z')))) {
1095 if ((ninety[i] != '*') && (ninety[i] != ',') && (ninety[i] != '-') && (ninety[i] != '.') && (ninety[i] != '/')) {
1096 /* An Invalid AI 90 character */
1097 strcpy(symbol->errtxt, "440: Invalid AI 90 data");
1098 return ZINT_ERROR_INVALID_DATA;
1099 }
1100 }
1101 }
1102
1103 /* must start with 0, 1, 2 or 3 digits followed by an uppercase character */
1104 test1 = -1;
1105 for (i = 3; i >= 0; i--) {
1106 if ((ninety[i] >= 'A') && (ninety[i] <= 'Z')) {
1107 test1 = i;
1108 }
1109 }
1110
1111 test2 = 0;
1112 for (i = 0; i < test1; i++) {
1113 if (!((ninety[i] >= '0') && (ninety[i] <= '9'))) {
1114 test2 = 1;
1115 }
1116 }
1117
1118 /* leading zeros are not permitted */
1119 test3 = 0;
1120 if ((test1 >= 1) && (ninety[0] == '0')) {
1121 test3 = 1;
1122 }
1123
1124 if ((test1 != -1) && (test2 != 1) && (test3 == 0)) {
1125 /* Encodation method "11" can be used */
1126 strcat(binary_string, "11");
1127
1128 numeric -= test1;
1129 alpha--;
1130
1131 /* Decide on numeric, alpha or alphanumeric mode */
1132 /* Alpha mode is a special mode for AI 90 */
1133
1134 if (alphanum > 0) {
1135 /* Alphanumeric mode */
1136 strcat(binary_string, "0");
1137 ai90_mode = 1;
1138 } else {
1139 if (alpha > numeric) {
1140 /* Alphabetic mode */
1141 strcat(binary_string, "11");
1142 ai90_mode = 2;
1143 } else {
1144 /* Numeric mode */
1145 strcat(binary_string, "10");
1146 ai90_mode = 3;
1147 }
1148 }
1149
1150 next_ai_posn = 2 + (int)strlen(ninety);
1151
1152 if (source[next_ai_posn] == '[') {
1153 /* There are more AIs afterwords */
1154 if ((source[next_ai_posn + 1] == '2') && (source[next_ai_posn + 2] == '1')) {
1155 /* AI 21 follows */
1156 ai_crop = 1;
1157 }
1158
1159 if ((source[next_ai_posn + 1] == '8') && (source[next_ai_posn + 2] == '0') && (source[next_ai_posn + 3] == '0') && (source[next_ai_posn + 4] == '4')) {
1160 /* AI 8004 follows */
1161 ai_crop = 2;
1162 }
1163 }
1164
1165 switch (ai_crop) {
1166 case 0: strcat(binary_string, "0");
1167 break;
1168 case 1: strcat(binary_string, "10");
1169 break;
1170 case 2: strcat(binary_string, "11");
1171 break;
1172 }
1173
1174 if (test1 == 0) {
1175 strcpy(numeric_part, "0");
1176 } else {
1177 for (i = 0; i < test1; i++) {
1178 numeric_part[i] = ninety[i];
1179 }
1180 numeric_part[i] = '\0';
1181 }
1182
1183 numeric_value = atoi(numeric_part);
1184
1185 table3_letter = -1;
1186 if (numeric_value < 31) {
1187 table3_letter = posn("BDHIJKLNPQRSTVWZ", ninety[test1]);
1188 }
1189
1190 if (table3_letter != -1) {
1191 /* Encoding can be done according to 5.2.2 c) 2) */
1192 /* five bit binary string representing value before letter */
1193 bin_append(numeric_value, 5, binary_string);
1194
1195 /* followed by four bit representation of letter from Table 3 */
1196 bin_append(table3_letter, 4, binary_string);
1197 } else {
1198 /* Encoding is done according to 5.2.2 c) 3) */
1199 bin_append(31, 5, binary_string);
1200 /* ten bit representation of number */
1201 bin_append(numeric_value, 10, binary_string);
1202
1203 /* five bit representation of ASCII character */
1204 bin_append(ninety[test1] - 65, 5, binary_string);
1205 }
1206
1207 read_posn = test1 + 3;
1208 } else {
1209 /* Use general field encodation instead */
1210 strcat(binary_string, "0");
1211 read_posn = 0;
1212 }
1213 }
1214
1215 /* Now encode the rest of the AI 90 data field */
1216 if (ai90_mode == 2) {
1217 /* Alpha encodation (section 5.2.3) */
1218 do {
1219 if ((source[read_posn] >= '0') && (source[read_posn] <= '9')) {
1220 bin_append(source[read_posn] + 4, 5, binary_string);
1221 }
1222
1223 if ((source[read_posn] >= 'A') && (source[read_posn] <= 'Z')) {
1224 bin_append(source[read_posn] - 65, 6, binary_string);
1225 }
1226
1227 if (source[read_posn] == '[') {
1228 bin_append(31, 5, binary_string);
1229 }
1230
1231 read_posn++;
1232 } while ((source[read_posn - 1] != '[') && (source[read_posn - 1] != '\0'));
1233 alpha_pad = 1; /* This is overwritten if a general field is encoded */
1234 }
1235
1236 if (ai90_mode == 1) {
1237 /* Alphanumeric mode */
1238 do {
1239 if ((source[read_posn] >= '0') && (source[read_posn] <= '9')) {
1240 bin_append(source[read_posn] - 43, 5, binary_string);
1241 }
1242
1243 if ((source[read_posn] >= 'A') && (source[read_posn] <= 'Z')) {
1244 bin_append(source[read_posn] - 33, 6, binary_string);
1245 }
1246
1247 switch (source[read_posn]) {
1248 case '[':
1249 bin_append(15, 5, binary_string);
1250 break;
1251 case '*':
1252 bin_append(58, 6, binary_string);
1253 break;
1254 case ',':
1255 bin_append(59, 6, binary_string);
1256 break;
1257 case '-':
1258 bin_append(60, 6, binary_string);
1259 break;
1260 case '.':
1261 bin_append(61, 6, binary_string);
1262 break;
1263 case '/':
1264 bin_append(62, 6, binary_string);
1265 break;
1266 }
1267
1268 read_posn++;
1269 } while ((source[read_posn - 1] != '[') && (source[read_posn - 1] != '\0'));
1270 }
1271
1272 read_posn += (2 * ai_crop);
1273
1274 /* The compressed data field has been processed if appropriate - the
1275 rest of the data (if any) goes into a general-purpose data compaction field */
1276
1277 j = 0;
1278 if (fnc1_latch == 1) {
1279 /* Encodation method "10" has been used but it is not followed by
1280 AI 10, so a FNC1 character needs to be added */
1281 general_field[j] = '[';
1282 j++;
1283 }
1284
1285 for (i = read_posn; i < (int) strlen(source); i++) {
1286 general_field[j] = source[i];
1287 j++;
1288 }
1289 general_field[j] = '\0';
1290
1291 if (strlen(general_field) != 0) {
1292 alpha_pad = 0;
1293 }
1294
1295 latch = 0;
1296 for (i = 0; i < (int) strlen(general_field); i++) {
1297 /* Table 13 - ISO/IEC 646 encodation */
1298 if ((general_field[i] < ' ') || (general_field[i] > 'z')) {
1299 general_field_type[i] = INVALID_CHAR;
1300 latch = 1;
1301 } else {
1302 general_field_type[i] = ISOIEC;
1303 }
1304
1305 if (general_field[i] == '#') {
1306 general_field_type[i] = INVALID_CHAR;
1307 latch = 1;
1308 }
1309 if (general_field[i] == '$') {
1310 general_field_type[i] = INVALID_CHAR;
1311 latch = 1;
1312 }
1313 if (general_field[i] == '@') {
1314 general_field_type[i] = INVALID_CHAR;
1315 latch = 1;
1316 }
1317 if (general_field[i] == 92) {
1318 general_field_type[i] = INVALID_CHAR;
1319 latch = 1;
1320 }
1321 if (general_field[i] == '^') {
1322 general_field_type[i] = INVALID_CHAR;
1323 latch = 1;
1324 }
1325 if (general_field[i] == 96) {
1326 general_field_type[i] = INVALID_CHAR;
1327 latch = 1;
1328 }
1329
1330 /* Table 12 - Alphanumeric encodation */
1331 if ((general_field[i] >= 'A') && (general_field[i] <= 'Z')) {
1332 general_field_type[i] = ALPHA_OR_ISO;
1333 }
1334 if (general_field[i] == '*') {
1335 general_field_type[i] = ALPHA_OR_ISO;
1336 }
1337 if (general_field[i] == ',') {
1338 general_field_type[i] = ALPHA_OR_ISO;
1339 }
1340 if (general_field[i] == '-') {
1341 general_field_type[i] = ALPHA_OR_ISO;
1342 }
1343 if (general_field[i] == '.') {
1344 general_field_type[i] = ALPHA_OR_ISO;
1345 }
1346 if (general_field[i] == '/') {
1347 general_field_type[i] = ALPHA_OR_ISO;
1348 }
1349
1350 /* Numeric encodation */
1351 if ((general_field[i] >= '0') && (general_field[i] <= '9')) {
1352 general_field_type[i] = ANY_ENC;
1353 }
1354 if (general_field[i] == '[') {
1355 /* FNC1 can be encoded in any system */
1356 general_field_type[i] = ANY_ENC;
1357 }
1358
1359 }
1360
1361 general_field_type[strlen(general_field)] = '\0';
1362
1363 if (latch == 1) {
1364 /* Invalid characters in input data */
1365 strcpy(symbol->errtxt, "441: Invalid characters in input data");
1366 return ZINT_ERROR_INVALID_DATA;
1367 }
1368
1369 for (i = 0; i < (int) strlen(general_field); i++) {
1370 if ((general_field_type[i] == ISOIEC) && (general_field[i + 1] == '[')) {
1371 general_field_type[i + 1] = ISOIEC;
1372 }
1373 }
1374
1375 for (i = 0; i < (int) strlen(general_field); i++) {
1376 if ((general_field_type[i] == ALPHA_OR_ISO) && (general_field[i + 1] == '[')) {
1377 general_field_type[i + 1] = ALPHA_OR_ISO;
1378 }
1379 }
1380
1381 latch = general_rules(general_field, general_field_type);
1382
1383 i = 0;
1384 do {
1385 switch (general_field_type[i]) {
1386 case NUMERIC:
1387
1388 if (i != 0) {
1389 if ((general_field_type[i - 1] != NUMERIC) && (general_field[i - 1] != '[')) {
1390 bin_append(0, 3, binary_string); /* Numeric latch */
1391 }
1392 }
1393
1394 if (general_field[i] != '[') {
1395 d1 = ctoi(general_field[i]);
1396 } else {
1397 d1 = 10;
1398 }
1399
1400 if (general_field[i + 1] != '[') {
1401 d2 = ctoi(general_field[i + 1]);
1402 } else {
1403 d2 = 10;
1404 }
1405
1406 bin_append((11 * d1) + d2 + 8, 7, binary_string);
1407
1408 i += 2;
1409 break;
1410
1411 case ALPHA:
1412
1413 if (i != 0) {
1414 if ((general_field_type[i - 1] == NUMERIC) || (general_field[i - 1] == '[')) {
1415 bin_append(0, 4, binary_string); /* Alphanumeric latch */
1416 }
1417 if (general_field_type[i - 1] == ISOIEC) {
1418 bin_append(4, 5, binary_string); /* ISO/IEC 646 latch */
1419 }
1420 }
1421
1422 if ((general_field[i] >= '0') && (general_field[i] <= '9')) {
1423 bin_append(general_field[i] - 43, 5, binary_string);
1424 }
1425
1426 if ((general_field[i] >= 'A') && (general_field[i] <= 'Z')) {
1427 bin_append(general_field[i] - 33, 6, binary_string);
1428 }
1429
1430 switch (general_field[i]) {
1431 case '[':
1432 bin_append(15, 5, binary_string);
1433 break;
1434 case '*':
1435 bin_append(58, 6, binary_string);
1436 break;
1437 case ',':
1438 bin_append(59, 6, binary_string);
1439 break;
1440 case '-':
1441 bin_append(60, 6, binary_string);
1442 break;
1443 case '.':
1444 bin_append(61, 6, binary_string);
1445 break;
1446 case '/':
1447 bin_append(62, 6, binary_string);
1448 break;
1449 }
1450
1451 i++;
1452 break;
1453
1454 case ISOIEC:
1455
1456 if (i != 0) {
1457 if ((general_field_type[i - 1] == NUMERIC) || (general_field[i - 1] == '[')) {
1458 bin_append(0, 4, binary_string); /* Alphanumeric latch */
1459 bin_append(4, 5, binary_string); /* ISO/IEC 646 latch */
1460 }
1461 if (general_field_type[i - 1] == ALPHA) {
1462 bin_append(4, 5, binary_string);; /* ISO/IEC 646 latch */
1463 }
1464 }
1465
1466 if ((general_field[i] >= '0') && (general_field[i] <= '9')) {
1467 bin_append(general_field[i] - 43, 5, binary_string);
1468 }
1469
1470 if ((general_field[i] >= 'A') && (general_field[i] <= 'Z')) {
1471 bin_append(general_field[i] - 1, 7, binary_string);
1472 }
1473
1474 if ((general_field[i] >= 'a') && (general_field[i] <= 'z')) {
1475 bin_append(general_field[i] - 7, 7, binary_string);
1476 }
1477
1478 if (general_field[i] == '[') strcat(binary_string, "01111"); /* FNC1/Numeric latch */
1479 if (general_field[i] == '!') strcat(binary_string, "11101000"); /* exclamation mark */
1480 if (general_field[i] == 34) strcat(binary_string, "11101001"); /* quotation mark */
1481 if (general_field[i] == 37) strcat(binary_string, "11101010"); /* percent sign */
1482 if (general_field[i] == '&') strcat(binary_string, "11101011"); /* ampersand */
1483 if (general_field[i] == 39) strcat(binary_string, "11101100"); /* apostrophe */
1484 if (general_field[i] == '(') strcat(binary_string, "11101101"); /* left parenthesis */
1485 if (general_field[i] == ')') strcat(binary_string, "11101110"); /* right parenthesis */
1486 if (general_field[i] == '*') strcat(binary_string, "11101111"); /* asterisk */
1487 if (general_field[i] == '+') strcat(binary_string, "11110000"); /* plus sign */
1488 if (general_field[i] == ',') strcat(binary_string, "11110001"); /* comma */
1489 if (general_field[i] == '-') strcat(binary_string, "11110010"); /* minus or hyphen */
1490 if (general_field[i] == '.') strcat(binary_string, "11110011"); /* period or full stop */
1491 if (general_field[i] == '/') strcat(binary_string, "11110100"); /* slash or solidus */
1492 if (general_field[i] == ':') strcat(binary_string, "11110101"); /* colon */
1493 if (general_field[i] == ';') strcat(binary_string, "11110110"); /* semicolon */
1494 if (general_field[i] == '<') strcat(binary_string, "11110111"); /* less-than sign */
1495 if (general_field[i] == '=') strcat(binary_string, "11111000"); /* equals sign */
1496 if (general_field[i] == '>') strcat(binary_string, "11111001"); /* greater-than sign */
1497 if (general_field[i] == '?') strcat(binary_string, "11111010"); /* question mark */
1498 if (general_field[i] == '_') strcat(binary_string, "11111011"); /* underline or low line */
1499 if (general_field[i] == ' ') strcat(binary_string, "11111100"); /* space */
1500
1501 i++;
1502 break;
1503 }
1504 } while (i + latch < (int) strlen(general_field));
1505
1506 binary_length = (int)strlen(binary_string);
1507 switch (cc_mode) {
1508 case 1:
1509 target_bitsize = calc_padding_cca(binary_length, *(cc_width));
1510 break;
1511 case 2:
1512 target_bitsize = calc_padding_ccb(binary_length, *(cc_width));
1513 break;
1514 case 3:
1515 target_bitsize = calc_padding_ccc(binary_length, cc_width, lin_width, ecc);
1516 break;
1517 }
1518
1519 if (target_bitsize == 0) {
1520 strcpy(symbol->errtxt, "442: Input too long for selected 2d component");
1521 return ZINT_ERROR_TOO_LONG;
1522 }
1523
1524 remainder = target_bitsize - binary_length;
1525
1526 if (latch == 1) {
1527 i = 0;
1528 /* There is still one more numeric digit to encode */
1529
1530 if ((remainder >= 4) && (remainder <= 6)) {
1531 bin_append(ctoi(general_field[i]) + 1, 4, binary_string);
1532 } else {
1533 bin_append((11 * ctoi(general_field[i])) + 18, 7, binary_string);
1534 /* This may push the symbol up to the next size */
1535 }
1536 }
1537
1538 if (strlen(binary_string) > 11805) { /* (2361 * 5) */
1539 strcpy(symbol->errtxt, "443: Input too long");
1540 return ZINT_ERROR_TOO_LONG;
1541 }
1542
1543
1544 binary_length = (int)strlen(binary_string);
1545 switch (cc_mode) {
1546 case 1:
1547 target_bitsize = calc_padding_cca(binary_length, *(cc_width));
1548 break;
1549 case 2:
1550 target_bitsize = calc_padding_ccb(binary_length, *(cc_width));
1551 break;
1552 case 3:
1553 target_bitsize = calc_padding_ccc(binary_length, cc_width, lin_width, ecc);
1554 break;
1555 }
1556
1557 if (target_bitsize == 0) {
1558 strcpy(symbol->errtxt, "444: Input too long for selected 2d component");
1559 return ZINT_ERROR_TOO_LONG;
1560 }
1561
1562 if (binary_length < target_bitsize) {
1563 /* Now add padding to binary string */
1564 if (alpha_pad == 1) {
1565 strcat(binary_string, "11111");
1566 alpha_pad = 0;
1567 /* Extra FNC1 character required after Alpha encodation (section 5.2.3) */
1568 }
1569
1570 if ((strlen(general_field) != 0) && (general_field_type[strlen(general_field) - 1] == NUMERIC)) {
1571 strcat(binary_string, "0000");
1572 }
1573
1574 while (strlen(binary_string) < (unsigned int) target_bitsize) {
1575 strcat(binary_string, "00100");
1576 }
1577
1578 if (strlen(binary_string) > (unsigned int) target_bitsize) {
1579 binary_string[target_bitsize] = '\0';
1580 }
1581 }
1582
1583 return 0;
1584 }
1585
linear_dummy_run(unsigned char * source,int length)1586 int linear_dummy_run(unsigned char *source, int length) {
1587 struct zint_symbol *dummy;
1588 int error_number;
1589 int linear_width;
1590
1591 dummy = ZBarcode_Create();
1592 dummy->symbology = BARCODE_EAN128_CC;
1593 dummy->option_1 = 3;
1594 error_number = ean_128(dummy, source, length);
1595 linear_width = dummy->width;
1596 ZBarcode_Delete(dummy);
1597
1598 if (error_number == 0) {
1599 return linear_width;
1600 } else {
1601 return 0;
1602 }
1603 }
1604
composite(struct zint_symbol * symbol,unsigned char source[],int length)1605 int composite(struct zint_symbol *symbol, unsigned char source[], int length) {
1606 int error_number, cc_mode, cc_width, ecc_level;
1607 int j, i, k;
1608 unsigned int rs = length + 1;
1609 unsigned int bs = 20 * rs;
1610 unsigned int pri_len;
1611 #ifndef _MSC_VER
1612 char reduced[rs];
1613 char binary_string[bs];
1614 #else
1615 char* reduced = (char*) _alloca(rs);
1616 char* binary_string = (char*) _alloca(bs);
1617 #endif
1618 struct zint_symbol *linear;
1619 int top_shift, bottom_shift;
1620 int linear_width = 0;
1621
1622 /* Perform sanity checks on input options first */
1623 error_number = 0;
1624 pri_len = (int)strlen(symbol->primary);
1625 if (pri_len == 0) {
1626 strcpy(symbol->errtxt, "445: No primary (linear) message in 2D composite");
1627 return ZINT_ERROR_INVALID_OPTION;
1628 }
1629
1630 if (length > 2990) {
1631 strcpy(symbol->errtxt, "446: 2D component input data too long");
1632 return ZINT_ERROR_TOO_LONG;
1633 }
1634
1635 cc_mode = symbol->option_1;
1636 if ((cc_mode == 3) && (symbol->symbology != BARCODE_EAN128_CC)) {
1637 /* CC-C can only be used with a GS1-128 linear part */
1638 strcpy(symbol->errtxt, "447: Invalid mode (CC-C only valid with GS1-128 linear component)");
1639 return ZINT_ERROR_INVALID_OPTION;
1640 }
1641
1642 error_number = gs1_verify(symbol, source, length, reduced);
1643 if (error_number != 0) {
1644 return error_number;
1645 }
1646
1647 if (symbol->symbology == BARCODE_EAN128_CC) {
1648 /* Do a test run of encoding the linear component to establish its width */
1649 linear_width = linear_dummy_run((unsigned char *) symbol->primary, pri_len);
1650 if (linear_width == 0) {
1651 strcpy(symbol->errtxt, "448: Invalid data");
1652 return ZINT_ERROR_INVALID_DATA;
1653 }
1654 }
1655
1656 switch (symbol->symbology) {
1657 /* Determine width of 2D component according to ISO/IEC 24723 Table 1 */
1658 case BARCODE_EANX_CC:
1659 switch (pri_len) {
1660 case 7: /* EAN-8 */
1661 case 10: /* EAN-8 + 2 */
1662 case 13: /* EAN-8 + 5 */
1663 cc_width = 3;
1664 break;
1665 case 12: /* EAN-13 */
1666 case 15: /* EAN-13 + 2 */
1667 case 18: /* EAN-13 + 5 */
1668 cc_width = 4;
1669 break;
1670 }
1671 break;
1672 case BARCODE_EAN128_CC: cc_width = 4;
1673 break;
1674 case BARCODE_RSS14_CC: cc_width = 4;
1675 break;
1676 case BARCODE_RSS_LTD_CC: cc_width = 3;
1677 break;
1678 case BARCODE_RSS_EXP_CC: cc_width = 4;
1679 break;
1680 case BARCODE_UPCA_CC: cc_width = 4;
1681 break;
1682 case BARCODE_UPCE_CC: cc_width = 2;
1683 break;
1684 case BARCODE_RSS14STACK_CC: cc_width = 2;
1685 break;
1686 case BARCODE_RSS14_OMNI_CC: cc_width = 2;
1687 break;
1688 case BARCODE_RSS_EXPSTACK_CC: cc_width = 4;
1689 break;
1690 }
1691
1692 memset(binary_string, 0, bs);
1693
1694 if (cc_mode < 1 || cc_mode > 3) {
1695 cc_mode = 1;
1696 }
1697
1698 if (cc_mode == 1) {
1699 i = cc_binary_string(symbol, reduced, binary_string, cc_mode, &cc_width, &ecc_level, linear_width);
1700 if (i == ZINT_ERROR_TOO_LONG) {
1701 cc_mode = 2;
1702 }
1703 }
1704
1705 if (cc_mode == 2) {
1706 /* If the data didn't fit into CC-A it is recalculated for CC-B */
1707 i = cc_binary_string(symbol, reduced, binary_string, cc_mode, &cc_width, &ecc_level, linear_width);
1708 if (i == ZINT_ERROR_TOO_LONG) {
1709 if (symbol->symbology != BARCODE_EAN128_CC) {
1710 return ZINT_ERROR_TOO_LONG;
1711 } else {
1712 cc_mode = 3;
1713 }
1714 }
1715 }
1716
1717 if (cc_mode == 3) {
1718 /* If the data didn't fit in CC-B (and linear part is GS1-128) it is recalculated for CC-C */
1719 i = cc_binary_string(symbol, reduced, binary_string, cc_mode, &cc_width, &ecc_level, linear_width);
1720 if (i == ZINT_ERROR_TOO_LONG) {
1721 return ZINT_ERROR_TOO_LONG;
1722 }
1723 }
1724
1725 switch (cc_mode) {
1726 /* Note that ecc_level is only relevant to CC-C */
1727 case 1: error_number = cc_a(symbol, binary_string, cc_width);
1728 break;
1729 case 2: error_number = cc_b(symbol, binary_string, cc_width);
1730 break;
1731 case 3: error_number = cc_c(symbol, binary_string, cc_width, ecc_level);
1732 break;
1733 }
1734
1735 if (error_number != 0) {
1736 return ZINT_ERROR_ENCODING_PROBLEM;
1737 }
1738
1739 /* 2D component done, now calculate linear component */
1740 linear = ZBarcode_Create(); /* Symbol contains the 2D component and Linear contains the rest */
1741
1742 linear->symbology = symbol->symbology;
1743
1744 if (linear->symbology != BARCODE_EAN128_CC) {
1745 /* Set the "component linkage" flag in the linear component */
1746 linear->option_1 = 2;
1747 } else {
1748 /* GS1-128 needs to know which type of 2D component is used */
1749 linear->option_1 = cc_mode;
1750 }
1751
1752 switch (symbol->symbology) {
1753 case BARCODE_EANX_CC: error_number = eanx(linear, (unsigned char *) symbol->primary, pri_len);
1754 break;
1755 case BARCODE_EAN128_CC: error_number = ean_128(linear, (unsigned char *) symbol->primary, pri_len);
1756 break;
1757 case BARCODE_RSS14_CC: error_number = rss14(linear, (unsigned char *) symbol->primary, pri_len);
1758 break;
1759 case BARCODE_RSS_LTD_CC: error_number = rsslimited(linear, (unsigned char *) symbol->primary, pri_len);
1760 break;
1761 case BARCODE_RSS_EXP_CC: error_number = rssexpanded(linear, (unsigned char *) symbol->primary, pri_len);
1762 break;
1763 case BARCODE_UPCA_CC: error_number = eanx(linear, (unsigned char *) symbol->primary, pri_len);
1764 break;
1765 case BARCODE_UPCE_CC: error_number = eanx(linear, (unsigned char *) symbol->primary, pri_len);
1766 break;
1767 case BARCODE_RSS14STACK_CC: error_number = rss14(linear, (unsigned char *) symbol->primary, pri_len);
1768 break;
1769 case BARCODE_RSS14_OMNI_CC: error_number = rss14(linear, (unsigned char *) symbol->primary, pri_len);
1770 break;
1771 case BARCODE_RSS_EXPSTACK_CC: error_number = rssexpanded(linear, (unsigned char *) symbol->primary, pri_len);
1772 break;
1773 }
1774
1775 if (error_number != 0) {
1776 strcpy(symbol->errtxt, linear->errtxt);
1777 strcat(symbol->errtxt, " in linear component ");
1778 ZBarcode_Delete(linear);
1779 return error_number;
1780 }
1781
1782 /* Merge the linear component with the 2D component */
1783
1784 top_shift = 0;
1785 bottom_shift = 0;
1786
1787 switch (symbol->symbology) {
1788 /* Determine horizontal alignment (according to section 12.3) */
1789 case BARCODE_EANX_CC:
1790 switch (pri_len) {
1791 case 7: /* EAN-8 */
1792 case 10: /* EAN-8 + 2 */
1793 case 13: /* EAN-8 + 5 */
1794 bottom_shift = 13;
1795 break;
1796 case 12: /* EAN-13 */
1797 case 15: /* EAN-13 + 2 */
1798 case 18: /* EAN-13 + 5 */
1799 bottom_shift = 2;
1800 break;
1801 }
1802 break;
1803 case BARCODE_EAN128_CC: if (cc_mode == 3) {
1804 bottom_shift = 7;
1805 }
1806 break;
1807 case BARCODE_RSS14_CC: bottom_shift = 4;
1808 break;
1809 case BARCODE_RSS_LTD_CC: bottom_shift = 9;
1810 break;
1811 case BARCODE_RSS_EXP_CC: k = 1;
1812 while ((!(module_is_set(linear, 1, k - 1))) && module_is_set(linear, 1, k)) {
1813 k++;
1814 }
1815 top_shift = k;
1816 break;
1817 case BARCODE_UPCA_CC: bottom_shift = 2;
1818 break;
1819 case BARCODE_UPCE_CC: bottom_shift = 2;
1820 break;
1821 case BARCODE_RSS14STACK_CC: top_shift = 1;
1822 break;
1823 case BARCODE_RSS14_OMNI_CC: top_shift = 1;
1824 break;
1825 case BARCODE_RSS_EXPSTACK_CC: k = 1;
1826 while ((!(module_is_set(linear, 1, k - 1))) && module_is_set(linear, 1, k)) {
1827 k++;
1828 }
1829 top_shift = k;
1830 break;
1831 }
1832
1833 if (top_shift != 0) {
1834 /* Move the 2d component of the symbol horizontally */
1835 for (i = 0; i <= symbol->rows; i++) {
1836 for (j = (symbol->width + top_shift); j >= top_shift; j--) {
1837 if (module_is_set(symbol, i, j - top_shift)) {
1838 set_module(symbol, i, j);
1839 } else {
1840 unset_module(symbol, i, j);
1841 }
1842 }
1843 for (j = 0; j < top_shift; j++) {
1844 unset_module(symbol, i, j);
1845 }
1846 }
1847 }
1848
1849 /* Merge linear and 2D components into one structure */
1850 for (i = 0; i <= linear->rows; i++) {
1851 symbol->row_height[symbol->rows + i] = linear->row_height[i];
1852 for (j = 0; j <= linear->width; j++) {
1853 if (module_is_set(linear, i, j)) {
1854 set_module(symbol, i + symbol->rows, j + bottom_shift);
1855 } else {
1856 unset_module(symbol, i + symbol->rows, j + bottom_shift);
1857 }
1858 }
1859 }
1860 if ((linear->width + bottom_shift) > symbol->width) {
1861 symbol->width = linear->width + bottom_shift;
1862 }
1863 if ((symbol->width + top_shift) > symbol->width) {
1864 symbol->width += top_shift;
1865 }
1866 symbol->rows += linear->rows;
1867 ustrcpy(symbol->text, (unsigned char *) linear->text);
1868
1869 ZBarcode_Delete(linear);
1870
1871 return error_number;
1872 }
1873