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