1 /* dmatrix.c Handles Data Matrix ECC 200 symbols */
2 
3 /*
4     libzint - the open source barcode library
5     Copyright (C) 2009-2017 Robin Stuart <rstuart114@gmail.com>
6 
7     developed from and including some functions from:
8         IEC16022 bar code generation
9         Adrian Kennard, Andrews & Arnold Ltd
10         with help from Cliff Hones on the RS coding
11 
12         (c) 2004 Adrian Kennard, Andrews & Arnold Ltd
13         (c) 2006 Stefan Schmidt <stefan@datenfreihafen.org>
14 
15     Redistribution and use in source and binary forms, with or without
16     modification, are permitted provided that the following conditions
17     are met:
18 
19     1. Redistributions of source code must retain the above copyright
20        notice, this list of conditions and the following disclaimer.
21     2. Redistributions in binary form must reproduce the above copyright
22        notice, this list of conditions and the following disclaimer in the
23        documentation and/or other materials provided with the distribution.
24     3. Neither the name of the project nor the names of its contributors
25        may be used to endorse or promote products derived from this software
26        without specific prior written permission.
27 
28     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
29     ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30     IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31     ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
32     FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33     DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34     OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36     LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37     OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38     SUCH DAMAGE.
39  */
40 
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <ctype.h>
44 #include <string.h>
45 #include <assert.h>
46 #include <math.h>
47 #ifdef _MSC_VER
48 #include <malloc.h>
49 /* ceilf (C99) not before MSVC++2013 (C++ 12.0) */
50 #if _MSC_VER < 1800
51 #define ceilf ceil
52 #endif
53 #endif
54 #include "reedsol.h"
55 #include "common.h"
56 #include "dmatrix.h"
57 
58 /* Annex M placement alorithm low level */
ecc200placementbit(int * array,const int NR,const int NC,int r,int c,const int p,const char b)59 static void ecc200placementbit(int *array, const int NR, const int NC, int r, int c, const int p, const char b) {
60     if (r < 0) {
61         r += NR;
62         c += 4 - ((NR + 4) % 8);
63     }
64     if (c < 0) {
65         c += NC;
66         r += 4 - ((NC + 4) % 8);
67     }
68     // Necessary for 26x32,26x40,26x48,36x120,36x144,72x120,72x144
69     if (r >= NR) {
70 #ifdef DEBUG
71         fprintf(stderr, "r >= NR:%i,%i at r=%i->", p, b, r);
72 #endif
73         r -= NR;
74 #ifdef DEBUG
75         fprintf(stderr, "%i,c=%i\n", r, c);
76 #endif
77     }
78 #ifdef DEBUG
79     if (0 != array[r * NC + c]) {
80         int a = array[r * NC + c];
81         fprintf(stderr, "Double:%i,%i->%i,%i at r=%i,c=%i\n", a >> 3, a & 7, p, b, r, c);
82         return;
83     }
84 #endif
85     // Check index limits
86     assert(r < NR);
87     assert(c < NC);
88     // Check double-assignment
89     assert(0 == array[r * NC + c]);
90     array[r * NC + c] = (p << 3) + b;
91 }
92 
ecc200placementblock(int * array,const int NR,const int NC,const int r,const int c,const int p)93 static void ecc200placementblock(int *array, const int NR, const int NC, const int r,
94         const int c, const int p) {
95     ecc200placementbit(array, NR, NC, r - 2, c - 2, p, 7);
96     ecc200placementbit(array, NR, NC, r - 2, c - 1, p, 6);
97     ecc200placementbit(array, NR, NC, r - 1, c - 2, p, 5);
98     ecc200placementbit(array, NR, NC, r - 1, c - 1, p, 4);
99     ecc200placementbit(array, NR, NC, r - 1, c - 0, p, 3);
100     ecc200placementbit(array, NR, NC, r - 0, c - 2, p, 2);
101     ecc200placementbit(array, NR, NC, r - 0, c - 1, p, 1);
102     ecc200placementbit(array, NR, NC, r - 0, c - 0, p, 0);
103 }
104 
ecc200placementcornerA(int * array,const int NR,const int NC,const int p)105 static void ecc200placementcornerA(int *array, const int NR, const int NC, const int p) {
106     ecc200placementbit(array, NR, NC, NR - 1, 0, p, 7);
107     ecc200placementbit(array, NR, NC, NR - 1, 1, p, 6);
108     ecc200placementbit(array, NR, NC, NR - 1, 2, p, 5);
109     ecc200placementbit(array, NR, NC, 0, NC - 2, p, 4);
110     ecc200placementbit(array, NR, NC, 0, NC - 1, p, 3);
111     ecc200placementbit(array, NR, NC, 1, NC - 1, p, 2);
112     ecc200placementbit(array, NR, NC, 2, NC - 1, p, 1);
113     ecc200placementbit(array, NR, NC, 3, NC - 1, p, 0);
114 }
115 
ecc200placementcornerB(int * array,const int NR,const int NC,const int p)116 static void ecc200placementcornerB(int *array, const int NR, const int NC, const int p) {
117     ecc200placementbit(array, NR, NC, NR - 3, 0, p, 7);
118     ecc200placementbit(array, NR, NC, NR - 2, 0, p, 6);
119     ecc200placementbit(array, NR, NC, NR - 1, 0, p, 5);
120     ecc200placementbit(array, NR, NC, 0, NC - 4, p, 4);
121     ecc200placementbit(array, NR, NC, 0, NC - 3, p, 3);
122     ecc200placementbit(array, NR, NC, 0, NC - 2, p, 2);
123     ecc200placementbit(array, NR, NC, 0, NC - 1, p, 1);
124     ecc200placementbit(array, NR, NC, 1, NC - 1, p, 0);
125 }
126 
ecc200placementcornerC(int * array,const int NR,const int NC,const int p)127 static void ecc200placementcornerC(int *array, const int NR, const int NC, const int p) {
128     ecc200placementbit(array, NR, NC, NR - 3, 0, p, 7);
129     ecc200placementbit(array, NR, NC, NR - 2, 0, p, 6);
130     ecc200placementbit(array, NR, NC, NR - 1, 0, p, 5);
131     ecc200placementbit(array, NR, NC, 0, NC - 2, p, 4);
132     ecc200placementbit(array, NR, NC, 0, NC - 1, p, 3);
133     ecc200placementbit(array, NR, NC, 1, NC - 1, p, 2);
134     ecc200placementbit(array, NR, NC, 2, NC - 1, p, 1);
135     ecc200placementbit(array, NR, NC, 3, NC - 1, p, 0);
136 }
137 
ecc200placementcornerD(int * array,const int NR,const int NC,const int p)138 static void ecc200placementcornerD(int *array, const int NR, const int NC, const int p) {
139     ecc200placementbit(array, NR, NC, NR - 1, 0, p, 7);
140     ecc200placementbit(array, NR, NC, NR - 1, NC - 1, p, 6);
141     ecc200placementbit(array, NR, NC, 0, NC - 3, p, 5);
142     ecc200placementbit(array, NR, NC, 0, NC - 2, p, 4);
143     ecc200placementbit(array, NR, NC, 0, NC - 1, p, 3);
144     ecc200placementbit(array, NR, NC, 1, NC - 3, p, 2);
145     ecc200placementbit(array, NR, NC, 1, NC - 2, p, 1);
146     ecc200placementbit(array, NR, NC, 1, NC - 1, p, 0);
147 }
148 
149 /* Annex M placement alorithm main function */
ecc200placement(int * array,const int NR,const int NC)150 static void ecc200placement(int *array, const int NR, const int NC) {
151     int r, c, p;
152     // invalidate
153     for (r = 0; r < NR; r++)
154         for (c = 0; c < NC; c++)
155             array[r * NC + c] = 0;
156     // start
157     p = 1;
158     r = 4;
159     c = 0;
160     do {
161         // check corner
162         if (r == NR && !c)
163             ecc200placementcornerA(array, NR, NC, p++);
164         if (r == NR - 2 && !c && NC % 4)
165             ecc200placementcornerB(array, NR, NC, p++);
166         if (r == NR - 2 && !c && (NC % 8) == 4)
167             ecc200placementcornerC(array, NR, NC, p++);
168         if (r == NR + 4 && c == 2 && !(NC % 8))
169             ecc200placementcornerD(array, NR, NC, p++);
170         // up/right
171         do {
172             if (r < NR && c >= 0 && !array[r * NC + c])
173                 ecc200placementblock(array, NR, NC, r, c, p++);
174             r -= 2;
175             c += 2;
176         } while (r >= 0 && c < NC);
177         r++;
178         c += 3;
179         // down/left
180         do {
181             if (r >= 0 && c < NC && !array[r * NC + c])
182                 ecc200placementblock(array, NR, NC, r, c, p++);
183             r += 2;
184             c -= 2;
185         } while (r < NR && c >= 0);
186         r += 3;
187         c++;
188     } while (r < NR || c < NC);
189     // unfilled corner
190     if (!array[NR * NC - 1])
191         array[NR * NC - 1] = array[NR * NC - NC - 2] = 1;
192 }
193 
194 /* calculate and append ecc code, and if necessary interleave */
ecc200(unsigned char * binary,const int bytes,const int datablock,const int rsblock,const int skew)195 static void ecc200(unsigned char *binary, const int bytes, const int datablock, const int rsblock, const int skew) {
196     int blocks = (bytes + 2) / datablock, b;
197     int n, p;
198     rs_init_gf(0x12d);
199     rs_init_code(rsblock, 1);
200     for (b = 0; b < blocks; b++) {
201         unsigned char buf[256], ecc[256];
202         p = 0;
203         for (n = b; n < bytes; n += blocks)
204             buf[p++] = binary[n];
205         rs_encode(p, buf, ecc);
206         p = rsblock - 1; // comes back reversed
207         for (n = b; n < rsblock * blocks; n += blocks) {
208             if (skew) {
209                 /* Rotate ecc data to make 144x144 size symbols acceptable */
210                 /* See http://groups.google.com/group/postscriptbarcode/msg/5ae8fda7757477da */
211                 if (b < 8) {
212                     binary[bytes + n + 2] = ecc[p--];
213                 } else {
214                     binary[bytes + n - 8] = ecc[p--];
215                 }
216             } else {
217                 binary[bytes + n] = ecc[p--];
218             }
219         }
220     }
221     rs_free();
222 }
223 
224 /* Return true (1) if a character is valid in X12 set */
isX12(const int source)225 static int isX12(const int source) {
226 
227     switch(source) {
228         case 13: // CR
229         case 42: // *
230         case 62: // >
231         case 32: // space
232             return 1;
233     }
234 
235     if ((source >= '0') && (source <= '9')) {
236         return 1;
237     }
238     if ((source >= 'A') && (source <= 'Z')) {
239         return 1;
240     }
241 
242     return 0;
243 }
244 
245 /* Insert a character into the middle of a string at position posn */
dminsert(char binary_string[],const int posn,const char newbit)246 static void dminsert(char binary_string[], const int posn, const char newbit) {
247     int i, end;
248 
249     end = (int) strlen(binary_string);
250     for (i = end + 1; i > posn; i--) {
251         binary_string[i] = binary_string[i - 1];
252     }
253     binary_string[posn] = newbit;
254 }
255 
insert_value(unsigned char binary_stream[],const int posn,const int streamlen,const int newbit)256 static void insert_value(unsigned char binary_stream[], const int posn, const int streamlen, const int newbit) {
257     int i;
258 
259     for(i = (int)streamlen; i > posn; i--) {
260         binary_stream[i] = binary_stream[i - 1];
261     }
262     binary_stream[posn] = (unsigned char) newbit;
263 }
264 
p_r_6_2_1(const unsigned char inputData[],const size_t position,const size_t sourcelen)265 static int p_r_6_2_1(const unsigned char inputData[], const size_t position, const size_t sourcelen) {
266     /* Annex P section (r)(6)(ii)(I)
267        "If one of the three X12 terminator/separator characters first
268         occurs in the yet to be processed data before a non-X12 character..."
269      */
270 
271     size_t i;
272     size_t nonX12Position = 0;
273     size_t specialX12Position = 0;
274     int retval = 0;
275 
276     for (i = position; i < sourcelen; i++) {
277         if (nonX12Position == 0) {
278             if (isX12(inputData[i]) != 1) {
279                 nonX12Position = i;
280             }
281         }
282 
283         if (specialX12Position == 0) {
284             if ((inputData[i] == (char) 13) ||
285                     (inputData[i] == '*') ||
286                     (inputData[i] == '>')) {
287                 specialX12Position = i;
288             }
289         }
290     }
291 
292     if ((nonX12Position != 0) && (specialX12Position != 0)) {
293         if (specialX12Position < nonX12Position) {
294             retval = 1;
295         }
296     }
297 
298     return retval;
299 }
300 
301 /* 'look ahead test' from Annex P */
look_ahead_test(const unsigned char inputData[],const size_t sourcelen,const size_t position,const int current_mode,const int gs1)302 static int look_ahead_test(const unsigned char inputData[], const size_t sourcelen, const size_t position, const int current_mode, const int gs1) {
303     float ascii_count, c40_count, text_count, x12_count, edf_count, b256_count, best_count;
304     const float stiction = (1.0F / 24.0F); // smallest change to act on, to get around floating point inaccuracies
305     int    best_scheme;
306     size_t sp;
307 
308     best_scheme = DM_NULL;
309 
310     /* step (j) */
311     if (current_mode == DM_ASCII) {
312         ascii_count = 0.0F;
313         c40_count = 1.0F;
314         text_count = 1.0F;
315         x12_count = 1.0F;
316         edf_count = 1.0F;
317         b256_count = 1.25F;
318     } else {
319         ascii_count = 1.0F;
320         c40_count = 2.0F;
321         text_count = 2.0F;
322         x12_count = 2.0F;
323         edf_count = 2.0F;
324         b256_count = 2.25F;
325     }
326 
327     switch (current_mode) {
328         case DM_C40: c40_count = 0.0F;
329             break;
330         case DM_TEXT: text_count = 0.0F;
331             break;
332         case DM_X12: x12_count = 0.0F;
333             break;
334         case DM_EDIFACT: edf_count = 0.0F;
335             break;
336         case DM_BASE256: b256_count = 0.0F;
337             break;
338     }
339 
340     sp = position;
341 
342     do {
343         if (sp == sourcelen) {
344             /* At the end of data ... step (k) */
345             ascii_count = ceilf(ascii_count);
346             b256_count = ceilf(b256_count);
347             edf_count = ceilf(edf_count);
348             text_count = ceilf(text_count);
349             x12_count = ceilf(x12_count);
350             c40_count = ceilf(c40_count);
351 
352             best_count = c40_count;
353             best_scheme = DM_C40; // (k)(7)
354 
355             if (x12_count < (best_count - stiction)) {
356                 best_count = x12_count;
357                 best_scheme = DM_X12; // (k)(6)
358             }
359 
360             if (text_count < (best_count - stiction)) {
361                 best_count = text_count;
362                 best_scheme = DM_TEXT; // (k)(5)
363             }
364 
365             if (edf_count < (best_count - stiction)) {
366                 best_count = edf_count;
367                 best_scheme = DM_EDIFACT; // (k)(4)
368             }
369 
370             if (b256_count < (best_count - stiction)) {
371                 best_count = b256_count;
372                 best_scheme = DM_BASE256; // (k)(3)
373             }
374 
375             if (ascii_count <= (best_count + stiction)) {
376                 best_scheme = DM_ASCII; // (k)(2)
377             }
378         } else {
379 
380             /* ascii ... step (l) */
381             if ((inputData[sp] >= '0') && (inputData[sp] <= '9')) {
382                 ascii_count += 0.5F; // (l)(1)
383             } else {
384                 if (inputData[sp] > 127) {
385                     ascii_count = ceilf(ascii_count) + 2.0F; // (l)(2)
386                 } else {
387                     ascii_count = ceilf(ascii_count) + 1.0F; // (l)(3)
388                 }
389             }
390 
391             /* c40 ... step (m) */
392             if ((inputData[sp] == ' ') ||
393                     (((inputData[sp] >= '0') && (inputData[sp] <= '9')) ||
394                     ((inputData[sp] >= 'A') && (inputData[sp] <= 'Z')))) {
395                 c40_count += (2.0F / 3.0F); // (m)(1)
396             } else {
397                 if (inputData[sp] > 127) {
398                     c40_count += (8.0F / 3.0F); // (m)(2)
399                 } else {
400                     c40_count += (4.0F / 3.0F); // (m)(3)
401                 }
402             }
403 
404             /* text ... step (n) */
405             if ((inputData[sp] == ' ') ||
406                     (((inputData[sp] >= '0') && (inputData[sp] <= '9')) ||
407                     ((inputData[sp] >= 'a') && (inputData[sp] <= 'z')))) {
408                 text_count += (2.0F / 3.0F); // (n)(1)
409             } else {
410                 if (inputData[sp] > 127) {
411                     text_count += (8.0F / 3.0F); // (n)(2)
412                 } else {
413                     text_count += (4.0F / 3.0F); // (n)(3)
414                 }
415             }
416 
417             /* x12 ... step (o) */
418             if (isX12(inputData[sp])) {
419                 x12_count += (2.0F / 3.0F); // (o)(1)
420             } else {
421                 if (inputData[sp] > 127) {
422                     x12_count += (13.0F / 3.0F); // (o)(2)
423                 } else {
424                     x12_count += (10.0F / 3.0F); // (o)(3)
425                 }
426             }
427 
428             /* edifact ... step (p) */
429             if ((inputData[sp] >= ' ') && (inputData[sp] <= '^')) {
430                 edf_count += (3.0F / 4.0F); // (p)(1)
431             } else {
432                 if (inputData[sp] > 127) {
433                     edf_count += 17.0F; // (p)(2) > Value changed from ISO
434                 } else {
435                     edf_count += 13.0F; // (p)(3) > Value changed from ISO
436                 }
437             }
438             if ((gs1 == 1) && (inputData[sp] == '[')) {
439                 edf_count += 13.0F; //  > Value changed from ISO
440             }
441 
442             /* base 256 ... step (q) */
443             if ((gs1 == 1) && (inputData[sp] == '[')) {
444                 b256_count += 4.0F; // (q)(1)
445             } else {
446                 b256_count += 1.0F; // (q)(2)
447             }
448         }
449 
450 
451         if (sp > (position + 3)) {
452             /* 4 data characters processed ... step (r) */
453 
454             /* step (r)(6) */
455             if (((c40_count + 1.0F) < (ascii_count - stiction)) &&
456                     ((c40_count + 1.0F) < (b256_count - stiction)) &&
457                     ((c40_count + 1.0F) < (edf_count - stiction)) &&
458                     ((c40_count + 1.0F) < (text_count - stiction))) {
459 
460                 if (c40_count < (x12_count - stiction)) {
461                     best_scheme = DM_C40;
462                 }
463 
464                 if ((c40_count >= (x12_count - stiction))
465                         && (c40_count <= (x12_count + stiction))) {
466                     if (p_r_6_2_1(inputData, sp, sourcelen) == 1) {
467                         // Test (r)(6)(ii)(i)
468                         best_scheme = DM_X12;
469                     } else {
470                         best_scheme = DM_C40;
471                     }
472                 }
473             }
474 
475             /* step (r)(5) */
476             if (((x12_count + 1.0F) < (ascii_count - stiction)) &&
477                     ((x12_count + 1.0F) < (b256_count - stiction)) &&
478                     ((x12_count + 1.0F) < (edf_count - stiction)) &&
479                     ((x12_count + 1.0F) < (text_count - stiction)) &&
480                     ((x12_count + 1.0F) < (c40_count - stiction))) {
481                 best_scheme = DM_X12;
482             }
483 
484             /* step (r)(4) */
485             if (((text_count + 1.0F) < (ascii_count - stiction)) &&
486                     ((text_count + 1.0F) < (b256_count - stiction)) &&
487                     ((text_count + 1.0F) < (edf_count - stiction)) &&
488                     ((text_count + 1.0F) < (x12_count - stiction)) &&
489                     ((text_count + 1.0F) < (c40_count - stiction))) {
490                 best_scheme = DM_TEXT;
491             }
492 
493             /* step (r)(3) */
494             if (((edf_count + 1.0F) < (ascii_count - stiction)) &&
495                     ((edf_count + 1.0F) < (b256_count - stiction)) &&
496                     ((edf_count + 1.0F) < (text_count - stiction)) &&
497                     ((edf_count + 1.0F) < (x12_count - stiction)) &&
498                     ((edf_count + 1.0F) < (c40_count - stiction))) {
499                 best_scheme = DM_EDIFACT;
500             }
501 
502             /* step (r)(2) */
503             if (((b256_count + 1.0F) <= (ascii_count + stiction)) ||
504                     (((b256_count + 1.0F) < (edf_count - stiction)) &&
505                     ((b256_count + 1.0F) < (text_count - stiction)) &&
506                     ((b256_count + 1.0F) < (x12_count - stiction)) &&
507                     ((b256_count + 1.0F) < (c40_count - stiction)))) {
508                 best_scheme = DM_BASE256;
509             }
510 
511             /* step (r)(1) */
512             if (((ascii_count + 1.0F) <= (b256_count + stiction)) &&
513                     ((ascii_count + 1.0F) <= (edf_count + stiction)) &&
514                     ((ascii_count + 1.0F) <= (text_count + stiction)) &&
515                     ((ascii_count + 1.0F) <= (x12_count + stiction)) &&
516                     ((ascii_count + 1.0F) <= (c40_count + stiction))) {
517                 best_scheme = DM_ASCII;
518             }
519         }
520 
521         sp++;
522     } while (best_scheme == DM_NULL); // step (s)
523 
524     return best_scheme;
525 }
526 
527 /* Encodes data using ASCII, C40, Text, X12, EDIFACT or Base 256 modes as appropriate
528    Supports encoding FNC1 in supporting systems */
dm200encode(struct zint_symbol * symbol,const unsigned char source[],unsigned char target[],int * last_mode,size_t * length_p,int process_buffer[],int * process_p)529 static int dm200encode(struct zint_symbol *symbol, const unsigned char source[], unsigned char target[], int *last_mode, size_t *length_p, int process_buffer[], int *process_p) {
530 
531     size_t sp;
532     int tp, i, gs1;
533     int current_mode, next_mode;
534     size_t inputlen = *length_p;
535     int debug = symbol->debug;
536 #ifndef _MSC_VER
537     char binary[2 * inputlen];
538 #else
539     char* binary = (char*) _alloca(2 * inputlen);
540 #endif
541 
542     sp = 0;
543     tp = 0;
544     memset(process_buffer, 0, 8);
545     *process_p = 0;
546     strcpy(binary, "");
547 
548     /* step (a) */
549     current_mode = DM_ASCII;
550     next_mode = DM_ASCII;
551 
552     if (symbol->input_mode == GS1_MODE) {
553         gs1 = 1;
554     } else {
555         gs1 = 0;
556     }
557 
558     if (gs1) {
559         target[tp] = 232;
560         tp++;
561         strcat(binary, " ");
562         if (debug) printf("FN1 ");
563     } /* FNC1 */
564 
565     if (symbol->output_options & READER_INIT) {
566         if (gs1) {
567             strcpy(symbol->errtxt, "519: Cannot encode in GS1 mode and Reader Initialisation at the same time");
568             return ZINT_ERROR_INVALID_OPTION;
569         } else {
570             target[tp] = 234;
571             tp++; /* Reader Programming */
572             strcat(binary, " ");
573             if (debug) printf("RP ");
574         }
575     }
576 
577     if (symbol->eci > 3) {
578         /* Encode ECI numbers according to Table 6 */
579         target[tp] = 241; /* ECI Character */
580         tp++;
581         if (symbol->eci <= 126) {
582             target[tp] = (unsigned char) symbol->eci + 1;
583             tp++;
584         }
585         if ((symbol->eci >= 127) && (symbol->eci <= 16382)) {
586             target[tp] = (unsigned char) ((symbol->eci - 127) / 254) + 128;
587             tp++;
588             target[tp] = (unsigned char) ((symbol->eci - 127) % 254) + 1;
589             tp++;
590         }
591         if (symbol->eci >= 16383) {
592             target[tp] = (unsigned char) ((symbol->eci - 16383) / 64516) + 192;
593             tp++;
594             target[tp] = (unsigned char) (((symbol->eci - 16383) / 254) % 254) + 1;
595             tp++;
596             target[tp] = (unsigned char) ((symbol->eci - 16383) % 254) + 1;
597             tp++;
598         }
599         if (debug) printf("ECI %d ", symbol->eci + 1);
600     }
601 
602     /* Check for Macro05/Macro06 */
603     /* "[)>[RS]05[GS]...[RS][EOT]" -> CW 236 */
604     /* "[)>[RS]06[GS]...[RS][EOT]" -> CW 237 */
605     if (tp == 0 && sp == 0 && inputlen >= 9
606             && source[0] == '[' && source[1] == ')' && source[2] == '>'
607             && source[3] == '\x1e' && source[4] == '0'
608             && (source[5] == '5' || source[5] == '6')
609             && source[6] == '\x1d'
610             && source[inputlen - 2] == '\x1e' && source[inputlen - 1] == '\x04') {
611         /* Output macro Codeword */
612         if (source[5] == '5') {
613             target[tp] = 236;
614             if (debug) printf("Macro05 ");
615         } else {
616             target[tp] = 237;
617             if (debug) printf("Macro06 ");
618         }
619         tp++;
620         strcat(binary, " ");
621         /* Remove macro characters from input string */
622         sp = 7;
623         inputlen -= 2;
624         *length_p -= 2;
625     }
626 
627 
628     while (sp < inputlen) {
629 
630         current_mode = next_mode;
631 
632         /* step (b) - ASCII encodation */
633         if (current_mode == DM_ASCII) {
634             next_mode = DM_ASCII;
635 
636             if (istwodigits(source, sp) && ((sp + 1) != inputlen)) {
637                 target[tp] = (unsigned char) ((10 * ctoi(source[sp])) + ctoi(source[sp + 1]) + 130);
638                 if (debug) printf("N%d ", target[tp] - 130);
639                 tp++;
640                 strcat(binary, " ");
641                 sp += 2;
642             } else {
643                 next_mode = look_ahead_test(source, inputlen, sp, current_mode, gs1);
644 
645                 if (next_mode != DM_ASCII) {
646                     switch (next_mode) {
647                         case DM_C40: target[tp] = 230;
648                             tp++;
649                             strcat(binary, " ");
650                             if (debug) printf("C40 ");
651                             break;
652                         case DM_TEXT: target[tp] = 239;
653                             tp++;
654                             strcat(binary, " ");
655                             if (debug) printf("TEX ");
656                             break;
657                         case DM_X12: target[tp] = 238;
658                             tp++;
659                             strcat(binary, " ");
660                             if (debug) printf("X12 ");
661                             break;
662                         case DM_EDIFACT: target[tp] = 240;
663                             tp++;
664                             strcat(binary, " ");
665                             if (debug) printf("EDI ");
666                             break;
667                         case DM_BASE256: target[tp] = 231;
668                             tp++;
669                             strcat(binary, " ");
670                             if (debug) printf("BAS ");
671                             break;
672                     }
673                 } else {
674                     if (source[sp] > 127) {
675                         target[tp] = 235; /* FNC4 */
676                         if (debug) printf("FN4 ");
677                         tp++;
678                         target[tp] = (source[sp] - 128) + 1;
679                         if (debug) printf("A%02X ", target[tp] - 1);
680                         tp++;
681                         strcat(binary, "  ");
682                     } else {
683                         if (gs1 && (source[sp] == '[')) {
684                             target[tp] = 232; /* FNC1 */
685                             if (debug) printf("FN1 ");
686                         } else {
687                             target[tp] = source[sp] + 1;
688                             if (debug) printf("A%02X ", target[tp] - 1);
689                         }
690                         tp++;
691                         strcat(binary, " ");
692                     }
693                     sp++;
694                 }
695             }
696 
697         }
698 
699         /* step (c) C40 encodation */
700         if (current_mode == DM_C40) {
701             int shift_set, value;
702 
703             next_mode = DM_C40;
704             if (*process_p == 0) {
705                 next_mode = look_ahead_test(source, inputlen, sp, current_mode, gs1);
706             }
707 
708             if (next_mode != DM_C40) {
709                 target[tp] = 254;
710                 tp++;
711                 strcat(binary, " "); /* Unlatch */
712                 next_mode = DM_ASCII;
713                 if (debug) printf("ASC ");
714             } else {
715                 if (source[sp] > 127) {
716                     process_buffer[*process_p] = 1;
717                     (*process_p)++;
718                     process_buffer[*process_p] = 30;
719                     (*process_p)++; /* Upper Shift */
720                     shift_set = c40_shift[source[sp] - 128];
721                     value = c40_value[source[sp] - 128];
722                 } else {
723                     shift_set = c40_shift[source[sp]];
724                     value = c40_value[source[sp]];
725                 }
726 
727                 if (gs1 && (source[sp] == '[')) {
728                     shift_set = 2;
729                     value = 27; /* FNC1 */
730                 }
731 
732                 if (shift_set != 0) {
733                     process_buffer[*process_p] = shift_set - 1;
734                     (*process_p)++;
735                 }
736                 process_buffer[*process_p] = value;
737                 (*process_p)++;
738 
739                 if (*process_p >= 3) {
740                     int iv;
741 
742                     iv = (1600 * process_buffer[0]) + (40 * process_buffer[1]) + (process_buffer[2]) + 1;
743                     target[tp] = (unsigned char) (iv / 256);
744                     tp++;
745                     target[tp] = iv % 256;
746                     tp++;
747                     strcat(binary, "  ");
748                     if (debug) printf("[%d %d %d] ", process_buffer[0], process_buffer[1], process_buffer[2]);
749 
750                     process_buffer[0] = process_buffer[3];
751                     process_buffer[1] = process_buffer[4];
752                     process_buffer[2] = process_buffer[5];
753                     process_buffer[3] = 0;
754                     process_buffer[4] = 0;
755                     process_buffer[5] = 0;
756                     *process_p -= 3;
757                 }
758                 sp++;
759             }
760         }
761 
762         /* step (d) Text encodation */
763         if (current_mode == DM_TEXT) {
764             int shift_set, value;
765 
766             next_mode = DM_TEXT;
767             if (*process_p == 0) {
768                 next_mode = look_ahead_test(source, inputlen, sp, current_mode, gs1);
769             }
770 
771             if (next_mode != DM_TEXT) {
772                 target[tp] = 254;
773                 tp++;
774                 strcat(binary, " "); /* Unlatch */
775                 next_mode = DM_ASCII;
776                 if (debug) printf("ASC ");
777             } else {
778                 if (source[sp] > 127) {
779                     process_buffer[*process_p] = 1;
780                     (*process_p)++;
781                     process_buffer[*process_p] = 30;
782                     (*process_p)++; /* Upper Shift */
783                     shift_set = text_shift[source[sp] - 128];
784                     value = text_value[source[sp] - 128];
785                 } else {
786                     shift_set = text_shift[source[sp]];
787                     value = text_value[source[sp]];
788                 }
789 
790                 if (gs1 && (source[sp] == '[')) {
791                     shift_set = 2;
792                     value = 27; /* FNC1 */
793                 }
794 
795                 if (shift_set != 0) {
796                     process_buffer[*process_p] = shift_set - 1;
797                     (*process_p)++;
798                 }
799                 process_buffer[*process_p] = value;
800                 (*process_p)++;
801 
802                 if (*process_p >= 3) {
803                     int iv;
804 
805                     iv = (1600 * process_buffer[0]) + (40 * process_buffer[1]) + (process_buffer[2]) + 1;
806                     target[tp] = (unsigned char) (iv / 256);
807                     tp++;
808                     target[tp] = iv % 256;
809                     tp++;
810                     strcat(binary, "  ");
811                     if (debug) printf("[%d %d %d] ", process_buffer[0], process_buffer[1], process_buffer[2]);
812 
813                     process_buffer[0] = process_buffer[3];
814                     process_buffer[1] = process_buffer[4];
815                     process_buffer[2] = process_buffer[5];
816                     process_buffer[3] = 0;
817                     process_buffer[4] = 0;
818                     process_buffer[5] = 0;
819                     *process_p -= 3;
820                 }
821                 sp++;
822             }
823         }
824 
825         /* step (e) X12 encodation */
826         if (current_mode == DM_X12) {
827             int value = 0;
828 
829             next_mode = DM_X12;
830             if (*process_p == 0) {
831                 next_mode = look_ahead_test(source, inputlen, sp, current_mode, gs1);
832             }
833 
834             if (next_mode != DM_X12) {
835                 target[tp] = 254;
836                 tp++;
837                 strcat(binary, " "); /* Unlatch */
838                 next_mode = DM_ASCII;
839                 if (debug) printf("ASC ");
840             } else {
841                 if (source[sp] == 13) {
842                     value = 0;
843                 }
844                 if (source[sp] == '*') {
845                     value = 1;
846                 }
847                 if (source[sp] == '>') {
848                     value = 2;
849                 }
850                 if (source[sp] == ' ') {
851                     value = 3;
852                 }
853                 if ((source[sp] >= '0') && (source[sp] <= '9')) {
854                     value = (source[sp] - '0') + 4;
855                 }
856                 if ((source[sp] >= 'A') && (source[sp] <= 'Z')) {
857                     value = (source[sp] - 'A') + 14;
858                 }
859 
860                 process_buffer[*process_p] = value;
861                 (*process_p)++;
862 
863                 if (*process_p >= 3) {
864                     int iv;
865 
866                     iv = (1600 * process_buffer[0]) + (40 * process_buffer[1]) + (process_buffer[2]) + 1;
867                     target[tp] = (unsigned char) (iv / 256);
868                     tp++;
869                     target[tp] = iv % 256;
870                     tp++;
871                     strcat(binary, "  ");
872                     if (debug) printf("[%d %d %d] ", process_buffer[0], process_buffer[1], process_buffer[2]);
873 
874                     process_buffer[0] = process_buffer[3];
875                     process_buffer[1] = process_buffer[4];
876                     process_buffer[2] = process_buffer[5];
877                     process_buffer[3] = 0;
878                     process_buffer[4] = 0;
879                     process_buffer[5] = 0;
880                     *process_p -= 3;
881                 }
882                 sp++;
883             }
884         }
885 
886         /* step (f) EDIFACT encodation */
887         if (current_mode == DM_EDIFACT) {
888             int value = 0;
889 
890             next_mode = DM_EDIFACT;
891             if (*process_p == 3) {
892                 next_mode = look_ahead_test(source, inputlen, sp, current_mode, gs1);
893             }
894 
895             if (next_mode != DM_EDIFACT) {
896                 process_buffer[*process_p] = 31;
897                 (*process_p)++;
898                 next_mode = DM_ASCII;
899             } else {
900                 value = source[sp];
901 
902                 if (source[sp] >= 64) {  // '@'
903                     value -= 64;
904                 }
905 
906                 process_buffer[*process_p] = value;
907                 (*process_p)++;
908                 sp++;
909             }
910 
911             if (*process_p >= 4) {
912                 target[tp] = (unsigned char) ((process_buffer[0] << 2) + ((process_buffer[1] & 0x30) >> 4));
913                 tp++;
914                 target[tp] = ((process_buffer[1] & 0x0f) << 4) + ((process_buffer[2] & 0x3c) >> 2);
915                 tp++;
916                 target[tp] = (unsigned char) (((process_buffer[2] & 0x03) << 6) + process_buffer[3]);
917                 tp++;
918                 strcat(binary, "   ");
919                 if (debug) printf("[%d %d %d %d] ", process_buffer[0], process_buffer[1], process_buffer[2], process_buffer[3]);
920 
921                 process_buffer[0] = process_buffer[4];
922                 process_buffer[1] = process_buffer[5];
923                 process_buffer[2] = process_buffer[6];
924                 process_buffer[3] = process_buffer[7];
925                 process_buffer[4] = 0;
926                 process_buffer[5] = 0;
927                 process_buffer[6] = 0;
928                 process_buffer[7] = 0;
929                 *process_p -= 4;
930             }
931         }
932 
933         /* step (g) Base 256 encodation */
934         if (current_mode == DM_BASE256) {
935             next_mode = look_ahead_test(source, inputlen, sp, current_mode, gs1);
936 
937             if (next_mode == DM_BASE256) {
938                 target[tp] = source[sp];
939                 if (debug) printf("B%02X ", target[tp]);
940                 tp++;
941                 sp++;
942                 strcat(binary, "b");
943             } else {
944                 next_mode = DM_ASCII;
945                 if (debug) printf("ASC ");
946             }
947         }
948 
949         if (tp > 1558) {
950             return 0;
951         }
952 
953     } /* while */
954 
955     /* Add length and randomising algorithm to b256 */
956     i = 0;
957     while (i < tp) {
958         if (binary[i] == 'b') {
959             if ((i == 0) || (binary[i - 1] != 'b')) {
960                 /* start of binary data */
961                 int binary_count; /* length of b256 data */
962 
963                 for (binary_count = 0; binary_count + i < tp && binary[binary_count + i] == 'b'; binary_count++);
964 
965                 if (binary_count <= 249) {
966                     dminsert(binary, i, 'b');
967                     insert_value(target, i, tp, binary_count);
968                     tp++;
969                 } else {
970                     dminsert(binary, i, 'b');
971                     dminsert(binary, i + 1, 'b');
972                     insert_value(target, i, tp, (binary_count / 250) + 249);
973                     tp++;
974                     insert_value(target, i + 1, tp, binary_count % 250);
975                     tp++;
976                 }
977             }
978         }
979         i++;
980     }
981 
982     for (i = 0; i < tp; i++) {
983         if (binary[i] == 'b') {
984             int prn, temp;
985 
986             prn = ((149 * (i + 1)) % 255) + 1;
987             temp = target[i] + prn;
988             if (temp <= 255) {
989                 target[i] = (unsigned char) (temp);
990             } else {
991                 target[i] = (unsigned char) (temp - 256);
992             }
993         }
994     }
995 
996     *(last_mode) = current_mode;
997     return tp;
998 }
999 
dm200encode_remainder(unsigned char target[],int target_length,const unsigned char source[],const size_t inputlen,const int last_mode,const int process_buffer[],const int process_p,const int symbols_left)1000 static int dm200encode_remainder(unsigned char target[], int target_length, const unsigned char source[], const size_t inputlen, const int last_mode, const int process_buffer[], const int process_p, const int symbols_left) {
1001     int debug = 0;
1002 
1003     switch (last_mode) {
1004         case DM_C40:
1005         case DM_TEXT:
1006             if (process_p == 1) // 1 data character left to encode.
1007             {
1008                 if (symbols_left > 1) {
1009                     target[target_length] = 254;
1010                     target_length++; // Unlatch and encode remaining data in ascii.
1011                 }
1012                 target[target_length] = source[inputlen - 1] + 1;
1013                 target_length++;
1014             } else if (process_p == 2) // 2 data characters left to encode.
1015             {
1016                 // Pad with shift 1 value (0) and encode as double.
1017                 int intValue = (1600 * process_buffer[0]) + (40 * process_buffer[1]) + 1; // ie (0 + 1).
1018                 target[target_length] = (unsigned char) (intValue / 256);
1019                 target_length++;
1020                 target[target_length] = (unsigned char) (intValue % 256);
1021                 target_length++;
1022                 if (symbols_left > 2) {
1023                     target[target_length] = 254; // Unlatch
1024                     target_length++;
1025                 }
1026             } else {
1027                 if (symbols_left > 0) {
1028                     target[target_length] = 254; // Unlatch
1029                     target_length++;
1030                 }
1031             }
1032             break;
1033 
1034         case DM_X12:
1035             if ((symbols_left == process_p) && (process_p == 1)) {
1036                 // Unlatch not required!
1037                 target[target_length] = source[inputlen - 1] + 1;
1038                 target_length++;
1039             } else {
1040                 target[target_length] = (254);
1041                 target_length++; // Unlatch.
1042 
1043                 if (process_p == 1) {
1044                     target[target_length] = source[inputlen - 1] + 1;
1045                     target_length++;
1046                 }
1047 
1048                 if (process_p == 2) {
1049                     target[target_length] = source[inputlen - 2] + 1;
1050                     target_length++;
1051                     target[target_length] = source[inputlen - 1] + 1;
1052                     target_length++;
1053                 }
1054             }
1055             break;
1056 
1057         case DM_EDIFACT:
1058             if (symbols_left <= 2) // Unlatch not required!
1059             {
1060                 if (process_p == 1) {
1061                     target[target_length] = source[inputlen - 1] + 1;
1062                     target_length++;
1063                 }
1064 
1065                 if (process_p == 2) {
1066                     target[target_length] = source[inputlen - 2] + 1;
1067                     target_length++;
1068                     target[target_length] = source[inputlen - 1] + 1;
1069                     target_length++;
1070                 }
1071             } else {
1072                 // Append edifact unlatch value (31) and empty buffer
1073                 if (process_p == 0) {
1074                     target[target_length] = (unsigned char) (31 << 2);
1075                     target_length++;
1076                 }
1077 
1078                 if (process_p == 1) {
1079                     target[target_length] = (unsigned char) ((process_buffer[0] << 2) + ((31 & 0x30) >> 4));
1080                     target_length++;
1081                     target[target_length] = (unsigned char) ((31 & 0x0f) << 4);
1082                     target_length++;
1083                 }
1084 
1085                 if (process_p == 2) {
1086                     target[target_length] = (unsigned char) ((process_buffer[0] << 2) + ((process_buffer[1] & 0x30) >> 4));
1087                     target_length++;
1088                     target[target_length] = (unsigned char) (((process_buffer[1] & 0x0f) << 4) + ((31 & 0x3c) >> 2));
1089                     target_length++;
1090                     target[target_length] = (unsigned char) (((31 & 0x03) << 6));
1091                     target_length++;
1092                 }
1093 
1094                 if (process_p == 3) {
1095                     target[target_length] = (unsigned char) ((process_buffer[0] << 2) + ((process_buffer[1] & 0x30) >> 4));
1096                     target_length++;
1097                     target[target_length] = (unsigned char) (((process_buffer[1] & 0x0f) << 4) + ((process_buffer[2] & 0x3c) >> 2));
1098                     target_length++;
1099                     target[target_length] = (unsigned char) (((process_buffer[2] & 0x03) << 6) + 31);
1100                     target_length++;
1101                 }
1102             }
1103             break;
1104     }
1105 
1106     if (debug) {
1107         int i;
1108         printf("\n\n");
1109         for (i = 0; i < target_length; i++)
1110             printf("%03d ", target[i]);
1111 
1112         printf("\n");
1113     }
1114 
1115     return target_length;
1116 }
1117 
1118 /* add pad bits */
add_tail(unsigned char target[],int tp,const int tail_length)1119 static void add_tail(unsigned char target[], int tp, const int tail_length) {
1120     int i, prn, temp;
1121 
1122     for (i = tail_length; i > 0; i--) {
1123         if (i == tail_length) {
1124             target[tp] = 129;
1125             tp++; /* Pad */
1126         } else {
1127             prn = ((149 * (tp + 1)) % 253) + 1;
1128             temp = 129 + prn;
1129             if (temp <= 254) {
1130                 target[tp] = (unsigned char) (temp);
1131                 tp++;
1132             } else {
1133                 target[tp] = (unsigned char) (temp - 254);
1134                 tp++;
1135             }
1136         }
1137     }
1138 }
1139 
data_matrix_200(struct zint_symbol * symbol,const unsigned char source[],const size_t in_length)1140 int data_matrix_200(struct zint_symbol *symbol,const unsigned char source[], const size_t in_length) {
1141 	int i, skew = 0;
1142    size_t inputlen=in_length;
1143     unsigned char binary[2200];
1144     int binlen;
1145     int process_buffer[8]; /* holds remaining data to finalised */
1146     int process_p; /* number of characters left to finalise */
1147     int symbolsize, optionsize, calcsize;
1148     int taillength, error_number = 0;
1149     int H, W, FH, FW, datablock, bytes, rsblock;
1150     int last_mode = DM_ASCII;
1151     unsigned char *grid = 0;
1152     int symbols_left;
1153 
1154     /* inputlen may be decremented by 2 if macro character is used */
1155     binlen = dm200encode(symbol, source, binary, &last_mode, &inputlen, process_buffer, &process_p);
1156 
1157     if (binlen == 0) {
1158         strcpy(symbol->errtxt, "520: Data too long to fit in symbol");
1159         return ZINT_ERROR_TOO_LONG;
1160     }
1161 
1162     if ((symbol->option_2 >= 1) && (symbol->option_2 <= DMSIZESCOUNT)) {
1163         optionsize = intsymbol[symbol->option_2 - 1];
1164     } else {
1165         optionsize = -1;
1166     }
1167 
1168     calcsize = DMSIZESCOUNT - 1;
1169     for (i = DMSIZESCOUNT - 1; i > -1; i--) {
1170         if (matrixbytes[i] >= (binlen + process_p)) {
1171             // Allow for the remaining data characters
1172             calcsize = i;
1173         }
1174     }
1175 
1176     if (symbol->option_3 == DM_SQUARE) {
1177         /* Skip rectangular symbols in square only mode */
1178         while (matrixH[calcsize] != matrixW[calcsize]) {
1179             calcsize++;
1180         }
1181         if (optionsize != -1) {
1182             strcpy(symbol->errtxt, "521: Can not force square symbols when symbol size is selected");
1183             error_number = ZINT_WARN_INVALID_OPTION;
1184         }
1185     } else if (symbol->option_3 != DM_DMRE) {
1186         /* Skip DMRE symbols */
1187         while (isDMRE[calcsize]) {
1188             calcsize++;
1189         }
1190     }
1191 
1192     symbolsize = optionsize;
1193     if (calcsize > optionsize) {
1194         symbolsize = calcsize;
1195         if (optionsize != -1) {
1196             strcpy(symbol->errtxt, "522: Input too long for selected symbol size");
1197             return ZINT_ERROR_TOO_LONG;
1198         }
1199     }
1200 
1201     // Now we know the symbol size we can handle the remaining data in the process buffer.
1202     symbols_left = matrixbytes[symbolsize] - binlen;
1203     binlen = dm200encode_remainder(binary, binlen, source, inputlen, last_mode, process_buffer, process_p, symbols_left);
1204 
1205     if (binlen > matrixbytes[symbolsize]) {
1206         strcpy(symbol->errtxt, "523: Data too long to fit in symbol");
1207         return ZINT_ERROR_TOO_LONG;
1208     }
1209 
1210     H = matrixH[symbolsize];
1211     W = matrixW[symbolsize];
1212     FH = matrixFH[symbolsize];
1213     FW = matrixFW[symbolsize];
1214     bytes = matrixbytes[symbolsize];
1215     datablock = matrixdatablock[symbolsize];
1216     rsblock = matrixrsblock[symbolsize];
1217 
1218     taillength = bytes - binlen;
1219 
1220     if (taillength != 0) {
1221         add_tail(binary, binlen, taillength);
1222     }
1223 
1224     // ecc code
1225     if (symbolsize == INTSYMBOL144) {
1226         skew = 1;
1227     }
1228     ecc200(binary, bytes, datablock, rsblock, skew);
1229     // Print Codewords
1230 #ifdef DEBUG
1231     {
1232         int CWCount;
1233 		int posCur;
1234         if (skew)
1235             CWCount = 1558 + 620;
1236         else
1237             CWCount = bytes + rsblock * (bytes / datablock);
1238         printf("Codewords (%i):", CWCount);
1239         for (posCur = 0; posCur < CWCount; posCur++)
1240             printf(" %3i", binary[posCur]);
1241         puts("\n");
1242     }
1243 #endif
1244     { // placement
1245         int x, y, NC, NR, *places;
1246         NC = W - 2 * (W / FW);
1247         NR = H - 2 * (H / FH);
1248         places = (int*) malloc(NC * NR * sizeof (int));
1249         ecc200placement(places, NR, NC);
1250         grid = (unsigned char*) malloc(W * H);
1251         memset(grid, 0, W * H);
1252         for (y = 0; y < H; y += FH) {
1253             for (x = 0; x < W; x++)
1254                 grid[y * W + x] = 1;
1255             for (x = 0; x < W; x += 2)
1256                 grid[(y + FH - 1) * W + x] = 1;
1257         }
1258         for (x = 0; x < W; x += FW) {
1259             for (y = 0; y < H; y++)
1260                 grid[y * W + x] = 1;
1261             for (y = 0; y < H; y += 2)
1262                 grid[y * W + x + FW - 1] = 1;
1263         }
1264 #ifdef DEBUG
1265         // Print position matrix as in standard
1266         for (y = NR - 1; y >= 0; y--) {
1267             for (x = 0; x < NC; x++) {
1268 				int v;
1269                 if (x != 0)
1270                     fprintf(stderr, "|");
1271                 v = places[(NR - y - 1) * NC + x];
1272                 fprintf(stderr, "%3d.%2d", (v >> 3), 8 - (v & 7));
1273             }
1274             fprintf(stderr, "\n");
1275         }
1276 #endif
1277         for (y = 0; y < NR; y++) {
1278             for (x = 0; x < NC; x++) {
1279                 int v = places[(NR - y - 1) * NC + x];
1280                 //fprintf (stderr, "%4d", v);
1281                 if (v == 1 || (v > 7 && (binary[(v >> 3) - 1] & (1 << (v & 7)))))
1282                     grid[(1 + y + 2 * (y / (FH - 2))) * W + 1 + x + 2 * (x / (FW - 2))] = 1;
1283             }
1284             //fprintf (stderr, "\n");
1285         }
1286         for (y = H - 1; y >= 0; y--) {
1287             int x;
1288             for (x = 0; x < W; x++) {
1289                 if (grid[W * y + x]) {
1290                     set_module(symbol, (H - y) - 1, x);
1291                 }
1292             }
1293             symbol->row_height[(H - y) - 1] = 1;
1294         }
1295         free(grid);
1296         free(places);
1297     }
1298 
1299     symbol->rows = H;
1300     symbol->width = W;
1301 
1302     return error_number;
1303 }
1304 
dmatrix(struct zint_symbol * symbol,const unsigned char source[],const size_t in_length)1305 int dmatrix(struct zint_symbol *symbol, const unsigned char source[], const size_t in_length) {
1306     int error_number;
1307 
1308     if (symbol->option_1 <= 1) {
1309         /* ECC 200 */
1310         error_number = data_matrix_200(symbol, source, in_length);
1311     } else {
1312         /* ECC 000 - 140 */
1313         strcpy(symbol->errtxt, "524: Older Data Matrix standards are no longer supported");
1314         error_number = ZINT_ERROR_INVALID_OPTION;
1315     }
1316 
1317     return error_number;
1318 }
1319